Skip to content

Commit

Permalink
Merge pull request lcompilers#1388 from czgdp1807/arr_struct_2
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 committed Dec 30, 2022
2 parents 51bbc8e + 08f4940 commit 90ca0a6
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 56 deletions.
2 changes: 2 additions & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,8 @@ RUN(NAME structs_14 LABELS cpython llvm c)
RUN(NAME structs_15 LABELS cpython llvm c)
RUN(NAME structs_16 LABELS cpython llvm c)
RUN(NAME structs_17 LABELS cpython llvm c)
RUN(NAME structs_18 LABELS llvm c
EXTRAFILES structs_18b.c)
RUN(NAME sizeof_01 LABELS llvm c
EXTRAFILES sizeof_01b.c)
RUN(NAME enum_01 LABELS cpython llvm c)
Expand Down
110 changes: 110 additions & 0 deletions integration_tests/structs_18.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
from ltypes import i8, dataclass, i32, f32, c32, f64, i16, i64, c64, ccallable, packed, ccall, CPtr, p_c_pointer, empty_c_void_p, pointer
from numpy import empty, int8, int16, int32, int64, float32, complex64, complex128, float64
from copy import deepcopy

@packed
@dataclass
class buffer_struct:
buffer8: i8[32]
buffer1: i32[32]
buffer2: f32[32]
buffer3: c32[32]
buffer4: f64[32]
buffer5: i16[32]
buffer6: i64[32]
buffer7: c64[32]

@ccallable
@packed
@dataclass
class buffer_struct_clink:
buffer8: i8[32]
buffer1: i32[32]
buffer2: f32[32]
buffer3: c32[32]
buffer4: f64[32]
buffer5: i16[32]
buffer6: i64[32]
buffer7: c64[32]

@ccall
def sum_buffer_i16(arr: i16[:], size: i32) -> i16:
pass

@ccall
def fill_buffer(buffer_cptr: CPtr):
pass

def f():
i: i32
buffer8_var: i8[32] = empty(32, dtype=int8)
buffer1_var: i32[32] = empty(32, dtype=int32)
buffer2_var: f32[32] = empty(32, dtype=float32)
buffer3_var: c32[32] = empty(32, dtype=complex64)
buffer4_var: f64[32] = empty(32, dtype=float64)
buffer5_var: i16[32] = empty(32, dtype=int16)
buffer6_var: i64[32] = empty(32, dtype=int64)
buffer7_var: c64[32] = empty(32, dtype=complex128)
buffer_: buffer_struct = buffer_struct(deepcopy(buffer8_var), deepcopy(buffer1_var),
deepcopy(buffer2_var), deepcopy(buffer3_var),
deepcopy(buffer4_var), deepcopy(buffer5_var),
deepcopy(buffer6_var), deepcopy(buffer7_var))
buffer_clink_: buffer_struct_clink = buffer_struct_clink(deepcopy(buffer8_var), deepcopy(buffer1_var),
deepcopy(buffer2_var), deepcopy(buffer3_var),
deepcopy(buffer4_var), deepcopy(buffer5_var),
deepcopy(buffer6_var), deepcopy(buffer7_var))
buffer_clink_cptr: CPtr = empty_c_void_p()
print(buffer_.buffer8[15])
print(buffer_.buffer1[15])
print(buffer_.buffer2[15])
print(buffer_.buffer3[15])
print(buffer_.buffer4[15])
print(buffer_.buffer5[15])
print(buffer_.buffer6[15])
print(buffer_.buffer7[15])
print(buffer_clink_.buffer8[15])
print(buffer_clink_.buffer1[15])
print(buffer_clink_.buffer2[15])
print(buffer_clink_.buffer3[15])
print(buffer_clink_.buffer4[15])
print(buffer_clink_.buffer5[15])
print(buffer_clink_.buffer6[15])
print(buffer_clink_.buffer7[15])

p_c_pointer(pointer(buffer_clink_), buffer_clink_cptr)
fill_buffer(buffer_clink_cptr)

for i in range(32):
buffer_.buffer8[i] = i8(i + 1)
buffer_.buffer1[i] = i32(i + 3)
buffer_.buffer2[i] = f32(i + 5)
buffer_.buffer3[i] = c32(i + 7)
buffer_.buffer4[i] = f64(i + 9)
buffer_.buffer5[i] = i16(i + 11)
buffer_.buffer6[i] = i64(i + 13)
buffer_.buffer7[i] = c64(i + 15)

for i in range(32):
print(i, buffer_.buffer8[i], buffer_clink_.buffer8[i])
print(i, buffer_clink_.buffer1[i], buffer_.buffer1[i])
print(i, buffer_clink_.buffer2[i], buffer_.buffer2[i])
print(i, buffer_clink_.buffer3[i], buffer_.buffer3[i])
print(i, buffer_clink_.buffer4[i], buffer_.buffer4[i])
print(i, buffer_clink_.buffer5[i], buffer_.buffer5[i])
print(i, buffer_clink_.buffer6[i], buffer_.buffer6[i])
print(i, buffer_clink_.buffer7[i], buffer_.buffer7[i])
assert buffer_.buffer8[i] == i8(i + 1)
assert buffer_clink_.buffer8[i] == i8(i + 2)
assert buffer_clink_.buffer8[i] - buffer_.buffer8[i] == i8(1)
assert buffer_clink_.buffer1[i] - buffer_.buffer1[i] == i32(1)
assert buffer_clink_.buffer2[i] - buffer_.buffer2[i] == f32(1)
assert buffer_clink_.buffer3[i] - buffer_.buffer3[i] == c32(1)
assert buffer_clink_.buffer4[i] - buffer_.buffer4[i] == f64(1)
assert buffer_clink_.buffer5[i] - buffer_.buffer5[i] == i16(1)
assert buffer_clink_.buffer6[i] - buffer_.buffer6[i] == i64(1)
assert buffer_clink_.buffer7[i] - buffer_.buffer7[i] == c64(1)

print(sum_buffer_i16(buffer_.buffer5, 32))
assert sum_buffer_i16(buffer_clink_.buffer5, 32) == i16(880)

f()
35 changes: 35 additions & 0 deletions integration_tests/structs_18b.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "structs_18b.h"
#include <complex.h>

int16_t sum_buffer_i16(int16_t data[], int32_t size) {
int16_t sum_buffer = 0;
for( int32_t i = 0; i < size; i++ ) {
sum_buffer += data[i];
}
return sum_buffer;
}

struct __attribute__((packed)) buffer_c {
int8_t buffer8[32];
int32_t buffer1[32];
float buffer2[32];
float complex buffer3[32];
double buffer4[32];
int16_t buffer5[32];
int64_t buffer6[32];
double complex buffer7[32];
};

void fill_buffer(void* buffer_cptr) {
struct buffer_c* buffer_clink_ = (struct buffer_c*) buffer_cptr;
for(int32_t i = 0; i < 32; i++) {
buffer_clink_->buffer8[i] = i + 2;
buffer_clink_->buffer1[i] = i + 4;
buffer_clink_->buffer2[i] = i + 6;
buffer_clink_->buffer3[i] = CMPLXF(i + 8, 0);
buffer_clink_->buffer4[i] = i + 10;
buffer_clink_->buffer5[i] = i + 12;
buffer_clink_->buffer6[i] = i + 14;
buffer_clink_->buffer7[i] = CMPLXL(i + 16, 0);
}
}
4 changes: 4 additions & 0 deletions integration_tests/structs_18b.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <inttypes.h>

int16_t sum_buffer_i16(int16_t data[], int32_t size);
void fill_buffer(void* buffer_cptr);
19 changes: 19 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,25 @@ static inline ASR::symbol_t *get_asr_owner(const ASR::symbol_t *sym) {
return ASR::down_cast<ASR::symbol_t>(s->asr_owner);
}

static inline ASR::symbol_t *get_asr_owner(const ASR::expr_t *expr) {
switch( expr->type ) {
case ASR::exprType::Var: {
return ASRUtils::get_asr_owner(ASR::down_cast<ASR::Var_t>(expr)->m_v);
}
case ASR::exprType::StructInstanceMember: {
return ASRUtils::get_asr_owner(ASR::down_cast<ASR::StructInstanceMember_t>(expr)->m_m);
}
case ASR::exprType::GetPointer: {
return ASRUtils::get_asr_owner(ASR::down_cast<ASR::GetPointer_t>(expr)->m_arg);
}
default: {
throw LCompilersException("Cannot find the ASR owner of underlying symbol of expression "
+ std::to_string(expr->type));
}
}
return nullptr;
}

// Returns the Module_t the symbol is in, or nullptr if not in a module
// or no asr_owner yet
static inline ASR::Module_t *get_sym_module0(const ASR::symbol_t *sym) {
Expand Down
42 changes: 21 additions & 21 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
ASR::dimension_t* m_dims, int n_dims,
bool use_ref, bool dummy,
bool declare_value, bool is_fixed_size,
bool is_pointer=false) {
bool is_pointer=false,
ASR::abiType m_abi=ASR::abiType::Source) {
std::string indent(indentation_level*indentation_spaces, ' ');
std::string type_name_copy = type_name;
type_name = c_ds_api->get_array_type(type_name, encoded_type_name, array_types_decls);
Expand Down Expand Up @@ -132,7 +133,11 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
sub.pop_back();
}
} else {
sub = format_type_c("", type_name, v_m_name, use_ref, dummy);
if( m_abi == ASR::abiType::BindC ) {
sub = format_type_c("", type_name_copy, v_m_name + "[]", use_ref, dummy);
} else {
sub = format_type_c("", type_name, v_m_name, use_ref, dummy);
}
}
}

Expand All @@ -154,13 +159,7 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
ASR::dimension_t* m_dims = nullptr;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(mem_type, m_dims);
sub += indent + convert_variable_decl(*mem_var, true, true, true, true, mem_var_name) + ";\n";
if( mem_var->m_abi == ASR::abiType::BindC &&
ASRUtils::is_fixed_size_array(m_dims, n_dims) ) {
int64_t fixed_size_array = ASRUtils::get_fixed_size_of_array(m_dims, n_dims);
sub += indent + "memcpy(" + name + "->" + itr.first + ", " + mem_var_name + ", " +
std::to_string(fixed_size_array) + "*sizeof(" +
CUtils::get_c_type_from_ttype_t(mem_type) + "));\n";
} else {
if( !ASRUtils::is_fixed_size_array(m_dims, n_dims) ) {
sub += indent + name + "->" + itr.first + " = " + mem_var_name + ";\n";
}
} else if( ASR::is_a<ASR::Struct_t>(*mem_type) ) {
Expand Down Expand Up @@ -253,15 +252,15 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
if( is_array ) {
bool is_fixed_size = true;
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
if( v.m_abi == ASR::abiType::BindC && is_fixed_size ) {
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( is_fixed_size && is_struct_type_member ) {
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
sub = type_name + " " + force_declare_name + dims;
} else {
std::string encoded_type_name = "i" + std::to_string(t->m_kind * 8);
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
Expand All @@ -271,7 +270,8 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
(v.m_intent != ASRUtils::intent_in &&
v.m_intent != ASRUtils::intent_inout &&
v.m_intent != ASRUtils::intent_out &&
!is_struct_type_member) || force_declare, is_fixed_size);
!is_struct_type_member) || force_declare,
is_fixed_size, false, v.m_abi);
}
} else {
bool is_fixed_size = true;
Expand All @@ -285,15 +285,15 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
if( is_array ) {
bool is_fixed_size = true;
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
if( v.m_abi == ASR::abiType::BindC && is_fixed_size ) {
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( is_fixed_size && is_struct_type_member ) {
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
sub = type_name + " " + force_declare_name + dims;
} else {
std::string encoded_type_name = "r" + std::to_string(t->m_kind * 8);
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
Expand All @@ -318,15 +318,15 @@ class ASRToCVisitor : public BaseCCPPVisitor<ASRToCVisitor>
if( is_array ) {
bool is_fixed_size = true;
dims = convert_dims_c(t->n_dims, t->m_dims, v_m_type, is_fixed_size, true);
if( v.m_abi == ASR::abiType::BindC && is_fixed_size ) {
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( is_fixed_size && is_struct_type_member ) {
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
sub = type_name + " " + force_declare_name + dims;
} else {
std::string encoded_type_name = "c" + std::to_string(t->m_kind * 8);
bool is_struct_type_member = ASR::is_a<ASR::StructType_t>(
*ASR::down_cast<ASR::symbol_t>(v.m_parent_symtab->asr_owner));
if( !force_declare ) {
force_declare_name = std::string(v.m_name);
}
Expand Down Expand Up @@ -1126,8 +1126,8 @@ R"(
ASR::ttype_t* x_mv_type = ASRUtils::expr_type(x.m_v);
ASR::dimension_t* m_dims;
int n_dims = ASRUtils::extract_dimensions_from_ttype(x_mv_type, m_dims);
bool is_data_only_array = (ASRUtils::is_fixed_size_array(m_dims, n_dims) &&
ASRUtils::expr_abi(x.m_v) == ASR::abiType::BindC);
bool is_data_only_array = ASRUtils::is_fixed_size_array(m_dims, n_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_v));
if( is_data_only_array ) {
out += "[";
} else {
Expand Down
8 changes: 4 additions & 4 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,10 +732,10 @@ R"(#include <stdio.h>
size_t n_target_dims = ASRUtils::extract_dimensions_from_ttype(m_target_type, m_target_dims);
ASR::dimension_t* m_value_dims = nullptr;
size_t n_value_dims = ASRUtils::extract_dimensions_from_ttype(m_value_type, m_value_dims);
bool is_target_data_only_array = (ASRUtils::expr_abi(x.m_target) == ASR::abiType::BindC &&
ASRUtils::is_fixed_size_array(m_target_dims, n_target_dims));
bool is_value_data_only_array = (ASRUtils::expr_abi(x.m_value) == ASR::abiType::BindC &&
ASRUtils::is_fixed_size_array(m_value_dims, n_value_dims));
bool is_target_data_only_array = ASRUtils::is_fixed_size_array(m_target_dims, n_target_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_target));
bool is_value_data_only_array = ASRUtils::is_fixed_size_array(m_value_dims, n_value_dims) &&
ASR::is_a<ASR::StructType_t>(*ASRUtils::get_asr_owner(x.m_value));
if( is_target_data_only_array || is_value_data_only_array ) {
int64_t target_size = -1, value_size = -1;
if( !is_target_data_only_array ) {
Expand Down
Loading

0 comments on commit 90ca0a6

Please sign in to comment.