Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Implement unsigned arrays support #1775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions integration_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ RUN(NAME expr_15 LABELS cpython llvm c)

RUN(NAME expr_01u LABELS cpython llvm c)
RUN(NAME expr_02u LABELS cpython llvm c)
RUN(NAME expr_03u LABELS cpython llvm c)

RUN(NAME loop_01 LABELS cpython llvm c)
RUN(NAME loop_02 LABELS cpython llvm c wasm wasm_x86 wasm_x64)
Expand Down
159 changes: 159 additions & 0 deletions integration_tests/expr_03u.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
from lpython import u8, u16, u32, u64, i8, i32, TypeVar
from numpy import (empty, uint8, uint16, uint32, uint64, int8, int16, int32,
int64, size)

n = TypeVar("n")
def add_i8(n: i32, x: i8[n], y: i8[n]) -> i8[n]:
return x + y

def add_i8_loop(n: i32, x: i8[n], y: i8[n]) -> i8[n]:
z: i8[n] = empty(n, dtype=int8)
i: i32
for i in range(n):
z[i] = x[i] + y[i]
return z

def add_u8(n: i32, x: u8[n], y: u8[n]) -> u8[n]:
return x + y

def add_u8_loop(n: i32, x: u8[n], y: u8[n]) -> u8[n]:
z: u8[n] = empty(n, dtype=uint8)
i: i32
for i in range(n):
z[i] = x[i] + y[i]
return z

def add_u16(n: i32, x: u16[n], y: u16[n]) -> u16[n]:
return x + y

def add_u16_loop(n: i32, x: u16[n], y: u16[n]) -> u16[n]:
z: u16[n] = empty(n, dtype=uint16)
i: i32
for i in range(n):
z[i] = x[i] + y[i]
return z

def add_u32(n: i32, x: u32[n], y: u32[n]) -> u32[n]:
return x + y

def add_u32_loop(n: i32, x: u32[n], y: u32[n]) -> u32[n]:
z: u32[n] = empty(n, dtype=uint32)
i: i32
for i in range(n):
z[i] = x[i] + y[i]
return z

def add_u64(n: i32, x: u64[n], y: u64[n]) -> u64[n]:
return x + y

def add_u64_loop(n: i32, x: u64[n], y: u64[n]) -> u64[n]:
z: u64[n] = empty(n, dtype=uint64)
i: i32
for i in range(n):
z[i] = x[i] + y[i]
return z

def main_i8():
x: i8[3] = empty(3, dtype=int8)
y: i8[3] = empty(3, dtype=int8)
z: i8[3] = empty(3, dtype=int8)
x[0] = i8(1)
x[1] = i8(2)
x[2] = i8(3)
y[0] = i8(2)
y[1] = i8(3)
y[2] = i8(4)
z = add_i8(size(x), x, y)
assert z[0] == i8(3)
assert z[1] == i8(5)
assert z[2] == i8(7)
z = add_i8_loop(size(x), x, y)
assert z[0] == i8(3)
assert z[1] == i8(5)
assert z[2] == i8(7)

def main_u8():
x: u8[3] = empty(3, dtype=uint8)
y: u8[3] = empty(3, dtype=uint8)
z: u8[3] = empty(3, dtype=uint8)
x[0] = u8(1)
x[1] = u8(2)
x[2] = u8(3)
y[0] = u8(2)
y[1] = u8(3)
y[2] = u8(4)
z = add_u8(size(x), x, y)
assert z[0] == u8(3)
assert z[1] == u8(5)
assert z[2] == u8(7)
z = add_u8_loop(size(x), x, y)
assert z[0] == u8(3)
assert z[1] == u8(5)
assert z[2] == u8(7)

def main_u16():
x: u16[3] = empty(3, dtype=uint16)
y: u16[3] = empty(3, dtype=uint16)
z: u16[3] = empty(3, dtype=uint16)
x[0] = u16(1)
x[1] = u16(2)
x[2] = u16(3)
y[0] = u16(2)
y[1] = u16(3)
y[2] = u16(4)
z = add_u16(size(x), x, y)
assert z[0] == u16(3)
assert z[1] == u16(5)
assert z[2] == u16(7)
z = add_u16_loop(size(x), x, y)
assert z[0] == u16(3)
assert z[1] == u16(5)
assert z[2] == u16(7)

def main_u32():
x: u32[3] = empty(3, dtype=uint32)
y: u32[3] = empty(3, dtype=uint32)
z: u32[3] = empty(3, dtype=uint32)
x[0] = u32(1)
x[1] = u32(2)
x[2] = u32(3)
y[0] = u32(2)
y[1] = u32(3)
y[2] = u32(4)
z = add_u32(size(x), x, y)
assert z[0] == u32(3)
assert z[1] == u32(5)
assert z[2] == u32(7)
z = add_u32_loop(size(x), x, y)
assert z[0] == u32(3)
assert z[1] == u32(5)
assert z[2] == u32(7)

def main_u64():
x: u64[3] = empty(3, dtype=uint64)
y: u64[3] = empty(3, dtype=uint64)
z: u64[3] = empty(3, dtype=uint64)
x[0] = u64(1)
x[1] = u64(2)
x[2] = u64(3)
y[0] = u64(2)
y[1] = u64(3)
y[2] = u64(4)
z = add_u64(size(x), x, y)
assert z[0] == u64(3)
assert z[1] == u64(5)
assert z[2] == u64(7)
z = add_u64_loop(size(x), x, y)
assert z[0] == u64(3)
assert z[1] == u64(5)
assert z[2] == u64(7)

main_i8()
main_u8()
main_u16()
main_u32()
main_u64()

# Not implemented yet in LPython:
#if __name__ == "__main__":
# main()
21 changes: 21 additions & 0 deletions src/libasr/asr_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,8 @@ static inline bool is_value_constant(ASR::expr_t *a_value) {
}
if (ASR::is_a<ASR::IntegerConstant_t>(*a_value)) {
// OK
} else if (ASR::is_a<ASR::UnsignedIntegerConstant_t>(*a_value)) {
// OK
} else if (ASR::is_a<ASR::RealConstant_t>(*a_value)) {
// OK
} else if (ASR::is_a<ASR::ComplexConstant_t>(*a_value)) {
Expand Down Expand Up @@ -1674,6 +1676,12 @@ inline bool ttype_set_dimensions(ASR::ttype_t *x,
Integer_type->m_dims = m_dims;
return true;
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t* Integer_type = ASR::down_cast<ASR::UnsignedInteger_t>(x);
Integer_type->n_dims = n_dims;
Integer_type->m_dims = m_dims;
return true;
}
case ASR::ttypeType::Real: {
ASR::Real_t* Real_type = ASR::down_cast<ASR::Real_t>(x);
Real_type->n_dims = n_dims;
Expand Down Expand Up @@ -1737,6 +1745,7 @@ static inline bool is_aggregate_type(ASR::ttype_t* asr_type) {
}
return ASRUtils::is_array(asr_type) ||
!(ASR::is_a<ASR::Integer_t>(*asr_type) ||
ASR::is_a<ASR::UnsignedInteger_t>(*asr_type) ||
ASR::is_a<ASR::Real_t>(*asr_type) ||
ASR::is_a<ASR::Complex_t>(*asr_type) ||
ASR::is_a<ASR::Logical_t>(*asr_type));
Expand All @@ -1752,6 +1761,13 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t,
return ASRUtils::TYPE(ASR::make_Integer_t(al, t->base.loc,
tnew->m_kind, dimsp, dimsn));
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t* tnew = ASR::down_cast<ASR::UnsignedInteger_t>(t);
ASR::dimension_t* dimsp = dims ? dims->p : tnew->m_dims;
size_t dimsn = dims ? dims->n : tnew->n_dims;
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, t->base.loc,
tnew->m_kind, dimsp, dimsn));
}
case ASR::ttypeType::Real: {
ASR::Real_t* tnew = ASR::down_cast<ASR::Real_t>(t);
ASR::dimension_t* dimsp = dims ? dims->p : tnew->m_dims;
Expand Down Expand Up @@ -1841,6 +1857,11 @@ static inline ASR::ttype_t* duplicate_type_without_dims(Allocator& al, const ASR
return ASRUtils::TYPE(ASR::make_Integer_t(al, loc,
tnew->m_kind, nullptr, 0));
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t* tnew = ASR::down_cast<ASR::UnsignedInteger_t>(t);
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
tnew->m_kind, nullptr, 0));
}
case ASR::ttypeType::Real: {
ASR::Real_t* tnew = ASR::down_cast<ASR::Real_t>(t);
return ASRUtils::TYPE(ASR::make_Real_t(al, loc,
Expand Down
4 changes: 4 additions & 0 deletions src/libasr/codegen/asr_to_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
el_type = getIntType(a_kind);
break;
}
case ASR::ttypeType::UnsignedInteger: {
el_type = getIntType(a_kind);
break;
}
case ASR::ttypeType::Real: {
el_type = getFPType(a_kind);
break;
Expand Down
4 changes: 4 additions & 0 deletions src/libasr/codegen/c_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ namespace CUtils {
type_src = "int" + std::to_string(kind * 8) + "_t";
break;
}
case ASR::ttypeType::UnsignedInteger: {
type_src = "uint" + std::to_string(kind * 8) + "_t";
break;
}
case ASR::ttypeType::Logical: {
type_src = "bool";
break;
Expand Down
21 changes: 20 additions & 1 deletion src/libasr/pass/array_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
al, loc, left, (ASR::binopType)x->m_op,
right, x->m_type, nullptr));

case ASR::exprType::UnsignedIntegerBinOp:
return ASRUtils::EXPR(ASR::make_UnsignedIntegerBinOp_t(
al, loc, left, (ASR::binopType)x->m_op,
right, x->m_type, nullptr));

case ASR::exprType::RealBinOp:
return ASRUtils::EXPR(ASR::make_RealBinOp_t(
al, loc, left, (ASR::binopType)x->m_op,
Expand All @@ -330,6 +335,11 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
al, loc, left, (ASR::cmpopType)x->m_op,
right, x->m_type, nullptr));

case ASR::exprType::UnsignedIntegerCompare:
return ASRUtils::EXPR(ASR::make_UnsignedIntegerCompare_t(
al, loc, left, (ASR::cmpopType)x->m_op,
right, x->m_type, nullptr));

case ASR::exprType::RealCompare:
return ASRUtils::EXPR(ASR::make_RealCompare_t(
al, loc, left, (ASR::cmpopType)x->m_op,
Expand All @@ -355,7 +365,8 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
case ASR::exprType::RealCompare:
case ASR::exprType::ComplexCompare:
case ASR::exprType::LogicalCompare:
case ASR::exprType::IntegerCompare: {
case ASR::exprType::IntegerCompare:
case ASR::exprType::UnsignedIntegerCompare: {
ASR::ttype_t* arr_expr_type = ASRUtils::expr_type(arr_expr);
ASR::dimension_t* m_dims;
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(arr_expr_type, m_dims);
Expand Down Expand Up @@ -647,6 +658,10 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
replace_ArrayOpCommon(x, "_integer_bin_op_res");
}

void replace_UnsignedIntegerBinOp(ASR::UnsignedIntegerBinOp_t* x) {
replace_ArrayOpCommon(x, "_unsigned_integer_bin_op_res");
}

void replace_ComplexBinOp(ASR::ComplexBinOp_t* x) {
replace_ArrayOpCommon<ASR::ComplexBinOp_t>(x, "_complex_bin_op_res");
}
Expand All @@ -659,6 +674,10 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
replace_ArrayOpCommon<ASR::IntegerCompare_t>(x, "_integer_comp_op_res");
}

void replace_UnsignedIntegerCompare(ASR::UnsignedIntegerCompare_t* x) {
replace_ArrayOpCommon<ASR::UnsignedIntegerCompare_t>(x, "_unsigned_integer_comp_op_res");
}

void replace_RealCompare(ASR::RealCompare_t* x) {
replace_ArrayOpCommon<ASR::RealCompare_t>(x, "_real_comp_op_res");
}
Expand Down
17 changes: 17 additions & 0 deletions src/libasr/pass/pass_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ namespace LCompilers {
m_dims = x_type_ref->m_dims;
break;
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t* x_type_ref = ASR::down_cast<ASR::UnsignedInteger_t>(t2);
n_dims = x_type_ref->n_dims;
m_dims = x_type_ref->m_dims;
break;
}
case ASR::ttypeType::Real: {
ASR::Real_t* x_type_ref = ASR::down_cast<ASR::Real_t>(t2);
n_dims = x_type_ref->n_dims;
Expand Down Expand Up @@ -69,6 +75,17 @@ namespace LCompilers {
}
break;
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t* x_type_ref = ASR::down_cast<ASR::UnsignedInteger_t>(t2);
if( create_new ) {
new_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(*al, x_type->base.loc, x_type_ref->m_kind,
m_dims, n_dims));
} else {
x_type_ref->n_dims = n_dims;
x_type_ref->m_dims = m_dims;
}
break;
}
case ASR::ttypeType::Real: {
ASR::Real_t* x_type_ref = ASR::down_cast<ASR::Real_t>(t2);
if( create_new ) {
Expand Down
15 changes: 15 additions & 0 deletions src/lpython/semantics/python_ast_to_asr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,21 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
}
return ASRUtils::TYPE(ASR::make_Integer_t(al, loc, t->m_kind, new_dims.p, new_dims.size()));
}
case ASR::ttypeType::UnsignedInteger: {
ASR::UnsignedInteger_t *t = ASR::down_cast<ASR::UnsignedInteger_t>(return_type);
fill_expr_in_ttype_t(func_calls, t->m_dims, t->n_dims);
fix_exprs_ttype_t(func_calls, args, f);
Vec<ASR::dimension_t> new_dims;
new_dims.reserve(al, t->n_dims);
for( size_t i = 0; i < func_calls.size(); i += 2 ) {
ASR::dimension_t new_dim;
new_dim.loc = func_calls[i]->base.loc;
new_dim.m_start = func_calls[i];
new_dim.m_length = func_calls[i + 1];
new_dims.push_back(al, new_dim);
}
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, t->m_kind, new_dims.p, new_dims.size()));
}
case ASR::ttypeType::Real: {
ASR::Real_t *t = ASR::down_cast<ASR::Real_t>(return_type);
fill_expr_in_ttype_t(func_calls, t->m_dims, t->n_dims);
Expand Down
4 changes: 3 additions & 1 deletion src/lpython/semantics/python_comptime_eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ struct ProceduresDatabase {
"float32", "float64",
"reshape", "array", "int16",
"complex64", "complex128",
"int8", "exp", "exp2"}},
"int8", "exp", "exp2",
"uint8", "uint16", "uint32", "uint64",
"size"}},
{"math", {"sin", "cos", "tan",
"asin", "acos", "atan",
"exp", "exp2", "expm1"}},
Expand Down