Skip to content

@ccallable: Emit a header file with given name - #1861

Merged
certik merged 5 commits into
lcompilers:mainfrom
Smit-create:i-1797
May 28, 2023
Merged

@ccallable: Emit a header file with given name#1861
certik merged 5 commits into
lcompilers:mainfrom
Smit-create:i-1797

Conversation

@Smit-create

@Smit-createSmit-create commented May 26, 2023

Copy link
Copy Markdown
Collaborator

Fixes#1797

@Smit-create
Smit-create requested a review from certikMay 26, 2023 07:09
Comment threadsrc/libasr/codegen/asr_to_c.cpp Outdated
@certik

Copy link
Copy Markdown
Contributor

Let's add a test for this?

@Smit-create
Smit-create requested a review from certikMay 28, 2023 03:34
@Smit-create
Smit-create marked this pull request as ready for review May 28, 2023 03:46

@certikcertik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great.

We should add a test that calls this from C and includes the header file, to ensure that everything actually works. We can do that in a next PR.

@certik
certik merged commit 9e8b2db into lcompilers:mainMay 28, 2023
@Smit-create
Smit-create deleted the i-1797 branch May 28, 2023 04:05
@Smit-create

Copy link
Copy Markdown
CollaboratorAuthor

Thanks @certik. The test is added and it works.

Comment on lines +46 to +51
@ccallable(header="_test_bindc_03_my_header.h")
def test_emit_header_ccallable() -> i32:
i: i32 = 5
assert i == 5
i = i*5
return i + 10

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See this test. The header file will be created and will be used in the original file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, the generated file contains the header file?

I think we still need a handwritten file that includes it, to be sure that all the arguments are compatible.

@Smit-createSmit-createMay 28, 2023

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

% lpython --show-c integration_tests/bindc_03.py > b.c
Will generate two file.

  1. main file:
#include<complex.h>
#include<inttypes.h>
#include"_test_bindc_03_my_header.h"
#include"bindc_03b.h"
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<string.h>
#include<lfortran_intrinsics.h>structdimension_descriptor
{
int32_t lower_bound, length;
};
structArrayWrapped {
void* array;
};
structi32
{
int32_t *data;
structdimension_descriptor dims[32];
int32_t n_dims;
bool is_allocated;
};
inlinevoidstruct_deepcopy_ArrayWrapped(structArrayWrapped* src, structArrayWrapped* dest);
// Implementationsint32_t__lpython_overloaded_4___lpython_floordiv(int32_t a, int32_t b)
{
int32_t _lpython_return_variable;
double r;
int32_t result;
r = (double)(a)/(double)(b);
result = (int32_t)(r);
if (r >= 0.00000000000000000e+00 || (double)(result) == r) {
_lpython_return_variable = result;
return _lpython_return_variable;
}
_lpython_return_variable = result - 1;
return _lpython_return_variable;
}
int32_t__lpython_overloaded_2___mod(int32_t a, int32_t b)
{
int32_t _lpython_return_variable;
_lpython_return_variable = a - __lpython_overloaded_4___lpython_floordiv(a, b)*b;
return _lpython_return_variable;
}
float_lfortran_caimag(floatcomplex x);
double_lfortran_zaimag(doublecomplex x);
voidgpy(void* a, int32_t value, bool offset_value)
{
g(a, value, offset_value);
}
voidf(void* q_void)
{
int32_t el;
int32_t i;
structi32 q_value;
structi32* q = &q_value;
q->n_dims = 1;
q->dims[0].lower_bound = 0;
q->dims[0].length = 0;
q->data = (int32_t*) q_void;
for (i=0; i<=10 - 1; i++) {
{
void* q2;
q2 = (void*) &q->data[(i - q->dims[0].lower_bound)];
gpy(q2, i*i, (bool)(__lpython_overloaded_2___mod(i, 2)));
el = q->data[(i - q->dims[0].lower_bound)];
printf("%d\n", el);
ASSERT(el == i*i + __lpython_overloaded_2___mod(i, 2));
}
}
}
voidh(void* q_void)
{
int32_t el;
int32_t i;
structi32 q_value;
structi32* q = &q_value;
q->n_dims = 1;
q->dims[0].lower_bound = 0;
q->dims[0].length = 0;
q->data = (int32_t*) q_void;
for (i=0; i<=10 - 1; i++) {
{
el = q->data[(i - q->dims[0].lower_bound)];
printf("%d\n", el);
ASSERT(el == i*i + __lpython_overloaded_2___mod(i, 2));
}
}
}
voidrun()
{
void* a;
structArrayWrapped array_wrapped_value;
structArrayWrapped* array_wrapped = &array_wrapped_value;
structArrayWrapped array_wrapped1_value;
structArrayWrapped* array_wrapped1 = &array_wrapped1_value;
uint64_t q;
int32_t size;
void* x;
array_wrapped->array = a;
size = 10;
a = get_array(size);
ASSERT(a != NULL);
array_wrapped->array = a;
f(array_wrapped->array);
q = (uint64_t)(a);
x = (void*)(q);
array_wrapped->array = x;
f(array_wrapped->array);
struct_deepcopy_ArrayWrapped(array_wrapped, array_wrapped1);
h(array_wrapped1->array);
ASSERT(test_emit_header_ccallable() == 35);
}
void_lpython_main_program()
{
run();
}
intmain(int argc, char* argv[])
{
_lpython_set_argv(argc, argv);
_lpython_main_program();
return0;
}
voidstruct_deepcopy_ArrayWrapped(structArrayWrapped* src, structArrayWrapped* dest) {
dest->array = src->array;
}
  1. header file:
#ifndef _TEST_BINDC_03_MY_HEADER_H
#define_TEST_BINDC_03_MY_HEADER_H
#include<complex.h>
#include<inttypes.h>
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#include<string.h>
#include<lfortran_intrinsics.h>int32_ttest_emit_header_ccallable()
{
int32_t _lpython_return_variable;
int32_t i;
i = 5;
ASSERT(i == 5);
i = i*5;
_lpython_return_variable = i + 10;
return _lpython_return_variable;
}
#endif

@Smit-createSmit-createMay 28, 2023

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need a handwritten file that includes it, to be sure that all the arguments are compatible.

Yeah, you're right. ccallable needs to be updated in the LLVM backend so that it can call from C.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test_emit_header_ccallable must be in a C file, not a header file, otherwise the function will be generated twice by the C compiler and you will get linking errors.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@ccallable: emit a header file

2 participants

@Smit-create@certik