Skip to content

Commit

Permalink
Merge pull request #2425 from Thirumalai-Shaktivel/simd_02
Browse files Browse the repository at this point in the history
[C] Simd changes from LFortran
  • Loading branch information
Shaikh-Ubaid authored Nov 16, 2023
2 parents 03ce89b + 25ca1c8 commit 7772a0b
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 29 deletions.
9 changes: 7 additions & 2 deletions src/libasr/asr_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ void update_call_args(Allocator &al, SymbolTable *current_scope, bool implicit_i
}
return sym;
}

void handle_Var(ASR::expr_t* arg_expr, ASR::expr_t** expr_to_replace) {
if (ASR::is_a<ASR::Var_t>(*arg_expr)) {
ASR::Var_t* arg_var = ASR::down_cast<ASR::Var_t>(arg_expr);
Expand Down Expand Up @@ -1521,7 +1521,12 @@ void make_ArrayBroadcast_t_util(Allocator& al, const Location& loc,
if (ret_type == nullptr) {
// TODO: Construct appropriate return type here
// For now simply coping the type from expr1
ret_type = expr1_type;
if (ASRUtils::is_simd_array(expr1)) {
// TODO: Make this more general; do not check for SIMDArray
ret_type = ASRUtils::duplicate_type(al, expr1_type);
} else {
ret_type = expr1_type;
}
}
expr2 = ASRUtils::EXPR(ASR::make_ArrayBroadcast_t(al, loc, expr2, dest_shape, ret_type, value));

Expand Down
6 changes: 6 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4731,6 +4731,12 @@ inline ASR::ttype_t* make_Pointer_t_util(Allocator& al, const Location& loc, ASR

int64_t compute_trailing_zeros(int64_t number);

static inline bool is_simd_array(ASR::expr_t *v) {
return (ASR::is_a<ASR::Array_t>(*expr_type(v)) &&
ASR::down_cast<ASR::Array_t>(expr_type(v))->m_physical_type
== ASR::array_physical_typeType::SIMDArray);
}

} // namespace ASRUtils

} // namespace LCompilers
Expand Down
26 changes: 9 additions & 17 deletions src/libasr/codegen/asr_to_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1204,32 +1204,24 @@ R"( // Initialise Numpy
src = this->check_tmp_buffer() + out;
}

void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t& x) {
void visit_ArrayBroadcast(const ASR::ArrayBroadcast_t &x) {
/*
!LF$ attributes simd :: A
real :: A(8)
A = 1
We need to generate:
a = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
*/

CHECK_FAST_C(compiler_options, x)
if (x.m_value) {
ASR::expr_t* value = x.m_value;
LCOMPILERS_ASSERT(ASR::is_a<ASR::ArrayConstant_t>(*value));
ASR::ArrayConstant_t* array_const = ASR::down_cast<ASR::ArrayConstant_t>(value);
std::string array_const_str = "{";
for( size_t i = 0; i < array_const->n_args; i++ ) {
ASR::expr_t* array_const_arg = array_const->m_args[i];
this->visit_expr(*array_const_arg);
array_const_str += src + ", ";
}
array_const_str.pop_back();
array_const_str.pop_back();
array_const_str += "}";

src = array_const_str;
size_t size = ASRUtils::get_fixed_size_of_array(x.m_type);
std::string array_const_str = "{";
for( size_t i = 0; i < size; i++ ) {
this->visit_expr(*x.m_array);
array_const_str += src;
if (i < size - 1) array_const_str += ", ";
}
array_const_str += "}";
src = array_const_str;
}

void visit_ArraySize(const ASR::ArraySize_t& x) {
Expand Down
44 changes: 38 additions & 6 deletions src/libasr/codegen/asr_to_c_cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1049,13 +1049,14 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
}

void visit_ArrayPhysicalCast(const ASR::ArrayPhysicalCast_t& x) {
src = "";
this->visit_expr(*x.m_arg);
if (x.m_old == ASR::array_physical_typeType::FixedSizeArray &&
src = "";
this->visit_expr(*x.m_arg);
if (x.m_old == ASR::array_physical_typeType::FixedSizeArray &&
x.m_new == ASR::array_physical_typeType::SIMDArray) {
std::string arr_element_type = CUtils::get_c_type_from_ttype_t(ASRUtils::expr_type(x.m_arg));
int64_t size = ASRUtils::get_fixed_size_of_array(ASRUtils::expr_type(x.m_arg));
std::string cast = arr_element_type + " __attribute__ (( vector_size(sizeof(" + arr_element_type + ") * " + std::to_string(size) + ") ))";
std::string cast = arr_element_type + " __attribute__ (( vector_size(sizeof("
+ arr_element_type + ") * " + std::to_string(size) + ") ))";
src = "(" + cast + ") " + src;
}
}
Expand Down Expand Up @@ -1245,7 +1246,37 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
bool is_value_dict = ASR::is_a<ASR::Dict_t>(*m_value_type);
bool alloc_return_var = false;
std::string indent(indentation_level*indentation_spaces, ' ');
if (ASR::is_a<ASR::Var_t>(*x.m_target)) {
if (ASRUtils::is_simd_array(x.m_target)) {
this->visit_expr(*x.m_target);
target = src;
if (ASR::is_a<ASR::Var_t>(*x.m_value) ||
ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
std::string arr_element_type = CUtils::get_c_type_from_ttype_t(
ASRUtils::expr_type(x.m_value));
std::string size = std::to_string(ASRUtils::get_fixed_size_of_array(
ASRUtils::expr_type(x.m_target)));
std::string value;
if (ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
ASR::ArraySection_t *arr = ASR::down_cast<ASR::ArraySection_t>(x.m_value);
this->visit_expr(*arr->m_v);
value = src;
if(!ASR::is_a<ASR::ArrayBound_t>(*arr->m_args->m_left)) {
this->visit_expr(*arr->m_args->m_left);
int n_dims = ASRUtils::extract_n_dims_from_ttype(arr->m_type) - 1;
value += "->data + (" + src + " - "+ value +"->dims["
+ std::to_string(n_dims) +"].lower_bound)";
} else {
value += "->data";
}
} else if (ASR::is_a<ASR::Var_t>(*x.m_value)) {
this->visit_expr(*x.m_value);
value = src + "->data";
}
src = indent + "memcpy(&"+ target +", "+ value +", sizeof("
+ arr_element_type + ") * "+ size +");\n";
return;
}
} else if (ASR::is_a<ASR::Var_t>(*x.m_target)) {
ASR::Var_t* x_m_target = ASR::down_cast<ASR::Var_t>(x.m_target);
visit_Var(*x_m_target);
target = src;
Expand Down Expand Up @@ -1398,6 +1429,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
}

void visit_Associate(const ASR::Associate_t &x) {
std::string indent(indentation_level*indentation_spaces, ' ');
if (ASR::is_a<ASR::ArraySection_t>(*x.m_value)) {
self().visit_expr(*x.m_target);
std::string target = std::move(src);
Expand All @@ -1422,7 +1454,7 @@ PyMODINIT_FUNC PyInit_lpython_module_)" + fn_name + R"((void) {
}
c += left + ":" + right + ":" + step + ",";
}
src = target + "= " + value + "; // TODO: " + value + "(" + c + ")\n";
src = indent + target + "= " + value + "; // TODO: " + value + "(" + c + ")\n";
} else {
throw CodeGenError("Associate only implemented for ArraySection so far");
}
Expand Down
4 changes: 1 addition & 3 deletions src/libasr/pass/array_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1586,9 +1586,7 @@ class ArrayOpVisitor : public ASR::CallReplacerOnExpressionsVisitor<ArrayOpVisit
}

void visit_Assignment(const ASR::Assignment_t &x) {
if (ASR::is_a<ASR::Array_t>(*ASRUtils::expr_type(x.m_target)) &&
ASR::down_cast<ASR::Array_t>(ASRUtils::expr_type(x.m_target))->m_physical_type
== ASR::array_physical_typeType::SIMDArray) {
if (ASRUtils::is_simd_array(x.m_target)) {
return;
}
if( (ASR::is_a<ASR::Pointer_t>(*ASRUtils::expr_type(x.m_target)) &&
Expand Down
2 changes: 1 addition & 1 deletion src/libasr/pass/print_arr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class PrintArrVisitor : public PassUtils::PassVisitor<PrintArrVisitor>
std::vector<ASR::expr_t*> print_body;
ASR::stmt_t* empty_print_endl;
ASR::stmt_t* print_stmt;
if (x.m_values[0] != nullptr && ASR::is_a<ASR::StringFormat_t>(*x.m_values[0])) {
if (x.n_values > 0 && ASR::is_a<ASR::StringFormat_t>(*x.m_values[0])) {
empty_print_endl = ASRUtils::STMT(ASR::make_Print_t(al, x.base.base.loc,
nullptr, 0, nullptr, nullptr));
ASR::StringFormat_t* format = ASR::down_cast<ASR::StringFormat_t>(x.m_values[0]);
Expand Down

0 comments on commit 7772a0b

Please sign in to comment.