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

Skip to content

Commit 9b8fa1e

Browse files
authored
Merge pull request #1775 from certik/uint4
Implement unsigned arrays support
2 parents e9453fd + 5562678 commit 9b8fa1e

File tree

9 files changed

+244
-2
lines changed

9 files changed

+244
-2
lines changed

integration_tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ RUN(NAME expr_15 LABELS cpython llvm c)
329329

330330
RUN(NAME expr_01u LABELS cpython llvm c)
331331
RUN(NAME expr_02u LABELS cpython llvm c)
332+
RUN(NAME expr_03u LABELS cpython llvm c)
332333

333334
RUN(NAME loop_01 LABELS cpython llvm c)
334335
RUN(NAME loop_02 LABELS cpython llvm c wasm wasm_x86 wasm_x64)

integration_tests/expr_03u.py

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
from lpython import u8, u16, u32, u64, i8, i32, TypeVar
2+
from numpy import (empty, uint8, uint16, uint32, uint64, int8, int16, int32,
3+
int64, size)
4+
5+
n = TypeVar("n")
6+
def add_i8(n: i32, x: i8[n], y: i8[n]) -> i8[n]:
7+
return x + y
8+
9+
def add_i8_loop(n: i32, x: i8[n], y: i8[n]) -> i8[n]:
10+
z: i8[n] = empty(n, dtype=int8)
11+
i: i32
12+
for i in range(n):
13+
z[i] = x[i] + y[i]
14+
return z
15+
16+
def add_u8(n: i32, x: u8[n], y: u8[n]) -> u8[n]:
17+
return x + y
18+
19+
def add_u8_loop(n: i32, x: u8[n], y: u8[n]) -> u8[n]:
20+
z: u8[n] = empty(n, dtype=uint8)
21+
i: i32
22+
for i in range(n):
23+
z[i] = x[i] + y[i]
24+
return z
25+
26+
def add_u16(n: i32, x: u16[n], y: u16[n]) -> u16[n]:
27+
return x + y
28+
29+
def add_u16_loop(n: i32, x: u16[n], y: u16[n]) -> u16[n]:
30+
z: u16[n] = empty(n, dtype=uint16)
31+
i: i32
32+
for i in range(n):
33+
z[i] = x[i] + y[i]
34+
return z
35+
36+
def add_u32(n: i32, x: u32[n], y: u32[n]) -> u32[n]:
37+
return x + y
38+
39+
def add_u32_loop(n: i32, x: u32[n], y: u32[n]) -> u32[n]:
40+
z: u32[n] = empty(n, dtype=uint32)
41+
i: i32
42+
for i in range(n):
43+
z[i] = x[i] + y[i]
44+
return z
45+
46+
def add_u64(n: i32, x: u64[n], y: u64[n]) -> u64[n]:
47+
return x + y
48+
49+
def add_u64_loop(n: i32, x: u64[n], y: u64[n]) -> u64[n]:
50+
z: u64[n] = empty(n, dtype=uint64)
51+
i: i32
52+
for i in range(n):
53+
z[i] = x[i] + y[i]
54+
return z
55+
56+
def main_i8():
57+
x: i8[3] = empty(3, dtype=int8)
58+
y: i8[3] = empty(3, dtype=int8)
59+
z: i8[3] = empty(3, dtype=int8)
60+
x[0] = i8(1)
61+
x[1] = i8(2)
62+
x[2] = i8(3)
63+
y[0] = i8(2)
64+
y[1] = i8(3)
65+
y[2] = i8(4)
66+
z = add_i8(size(x), x, y)
67+
assert z[0] == i8(3)
68+
assert z[1] == i8(5)
69+
assert z[2] == i8(7)
70+
z = add_i8_loop(size(x), x, y)
71+
assert z[0] == i8(3)
72+
assert z[1] == i8(5)
73+
assert z[2] == i8(7)
74+
75+
def main_u8():
76+
x: u8[3] = empty(3, dtype=uint8)
77+
y: u8[3] = empty(3, dtype=uint8)
78+
z: u8[3] = empty(3, dtype=uint8)
79+
x[0] = u8(1)
80+
x[1] = u8(2)
81+
x[2] = u8(3)
82+
y[0] = u8(2)
83+
y[1] = u8(3)
84+
y[2] = u8(4)
85+
z = add_u8(size(x), x, y)
86+
assert z[0] == u8(3)
87+
assert z[1] == u8(5)
88+
assert z[2] == u8(7)
89+
z = add_u8_loop(size(x), x, y)
90+
assert z[0] == u8(3)
91+
assert z[1] == u8(5)
92+
assert z[2] == u8(7)
93+
94+
def main_u16():
95+
x: u16[3] = empty(3, dtype=uint16)
96+
y: u16[3] = empty(3, dtype=uint16)
97+
z: u16[3] = empty(3, dtype=uint16)
98+
x[0] = u16(1)
99+
x[1] = u16(2)
100+
x[2] = u16(3)
101+
y[0] = u16(2)
102+
y[1] = u16(3)
103+
y[2] = u16(4)
104+
z = add_u16(size(x), x, y)
105+
assert z[0] == u16(3)
106+
assert z[1] == u16(5)
107+
assert z[2] == u16(7)
108+
z = add_u16_loop(size(x), x, y)
109+
assert z[0] == u16(3)
110+
assert z[1] == u16(5)
111+
assert z[2] == u16(7)
112+
113+
def main_u32():
114+
x: u32[3] = empty(3, dtype=uint32)
115+
y: u32[3] = empty(3, dtype=uint32)
116+
z: u32[3] = empty(3, dtype=uint32)
117+
x[0] = u32(1)
118+
x[1] = u32(2)
119+
x[2] = u32(3)
120+
y[0] = u32(2)
121+
y[1] = u32(3)
122+
y[2] = u32(4)
123+
z = add_u32(size(x), x, y)
124+
assert z[0] == u32(3)
125+
assert z[1] == u32(5)
126+
assert z[2] == u32(7)
127+
z = add_u32_loop(size(x), x, y)
128+
assert z[0] == u32(3)
129+
assert z[1] == u32(5)
130+
assert z[2] == u32(7)
131+
132+
def main_u64():
133+
x: u64[3] = empty(3, dtype=uint64)
134+
y: u64[3] = empty(3, dtype=uint64)
135+
z: u64[3] = empty(3, dtype=uint64)
136+
x[0] = u64(1)
137+
x[1] = u64(2)
138+
x[2] = u64(3)
139+
y[0] = u64(2)
140+
y[1] = u64(3)
141+
y[2] = u64(4)
142+
z = add_u64(size(x), x, y)
143+
assert z[0] == u64(3)
144+
assert z[1] == u64(5)
145+
assert z[2] == u64(7)
146+
z = add_u64_loop(size(x), x, y)
147+
assert z[0] == u64(3)
148+
assert z[1] == u64(5)
149+
assert z[2] == u64(7)
150+
151+
main_i8()
152+
main_u8()
153+
main_u16()
154+
main_u32()
155+
main_u64()
156+
157+
# Not implemented yet in LPython:
158+
#if __name__ == "__main__":
159+
# main()

src/libasr/asr_utils.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,8 @@ static inline bool is_value_constant(ASR::expr_t *a_value) {
618618
}
619619
if (ASR::is_a<ASR::IntegerConstant_t>(*a_value)) {
620620
// OK
621+
} else if (ASR::is_a<ASR::UnsignedIntegerConstant_t>(*a_value)) {
622+
// OK
621623
} else if (ASR::is_a<ASR::RealConstant_t>(*a_value)) {
622624
// OK
623625
} else if (ASR::is_a<ASR::ComplexConstant_t>(*a_value)) {
@@ -1674,6 +1676,12 @@ inline bool ttype_set_dimensions(ASR::ttype_t *x,
16741676
Integer_type->m_dims = m_dims;
16751677
return true;
16761678
}
1679+
case ASR::ttypeType::UnsignedInteger: {
1680+
ASR::UnsignedInteger_t* Integer_type = ASR::down_cast<ASR::UnsignedInteger_t>(x);
1681+
Integer_type->n_dims = n_dims;
1682+
Integer_type->m_dims = m_dims;
1683+
return true;
1684+
}
16771685
case ASR::ttypeType::Real: {
16781686
ASR::Real_t* Real_type = ASR::down_cast<ASR::Real_t>(x);
16791687
Real_type->n_dims = n_dims;
@@ -1737,6 +1745,7 @@ static inline bool is_aggregate_type(ASR::ttype_t* asr_type) {
17371745
}
17381746
return ASRUtils::is_array(asr_type) ||
17391747
!(ASR::is_a<ASR::Integer_t>(*asr_type) ||
1748+
ASR::is_a<ASR::UnsignedInteger_t>(*asr_type) ||
17401749
ASR::is_a<ASR::Real_t>(*asr_type) ||
17411750
ASR::is_a<ASR::Complex_t>(*asr_type) ||
17421751
ASR::is_a<ASR::Logical_t>(*asr_type));
@@ -1752,6 +1761,13 @@ static inline ASR::ttype_t* duplicate_type(Allocator& al, const ASR::ttype_t* t,
17521761
return ASRUtils::TYPE(ASR::make_Integer_t(al, t->base.loc,
17531762
tnew->m_kind, dimsp, dimsn));
17541763
}
1764+
case ASR::ttypeType::UnsignedInteger: {
1765+
ASR::UnsignedInteger_t* tnew = ASR::down_cast<ASR::UnsignedInteger_t>(t);
1766+
ASR::dimension_t* dimsp = dims ? dims->p : tnew->m_dims;
1767+
size_t dimsn = dims ? dims->n : tnew->n_dims;
1768+
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, t->base.loc,
1769+
tnew->m_kind, dimsp, dimsn));
1770+
}
17551771
case ASR::ttypeType::Real: {
17561772
ASR::Real_t* tnew = ASR::down_cast<ASR::Real_t>(t);
17571773
ASR::dimension_t* dimsp = dims ? dims->p : tnew->m_dims;
@@ -1841,6 +1857,11 @@ static inline ASR::ttype_t* duplicate_type_without_dims(Allocator& al, const ASR
18411857
return ASRUtils::TYPE(ASR::make_Integer_t(al, loc,
18421858
tnew->m_kind, nullptr, 0));
18431859
}
1860+
case ASR::ttypeType::UnsignedInteger: {
1861+
ASR::UnsignedInteger_t* tnew = ASR::down_cast<ASR::UnsignedInteger_t>(t);
1862+
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc,
1863+
tnew->m_kind, nullptr, 0));
1864+
}
18441865
case ASR::ttypeType::Real: {
18451866
ASR::Real_t* tnew = ASR::down_cast<ASR::Real_t>(t);
18461867
return ASRUtils::TYPE(ASR::make_Real_t(al, loc,

src/libasr/codegen/asr_to_llvm.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,10 @@ class ASRToLLVMVisitor : public ASR::BaseVisitor<ASRToLLVMVisitor>
477477
el_type = getIntType(a_kind);
478478
break;
479479
}
480+
case ASR::ttypeType::UnsignedInteger: {
481+
el_type = getIntType(a_kind);
482+
break;
483+
}
480484
case ASR::ttypeType::Real: {
481485
el_type = getFPType(a_kind);
482486
break;

src/libasr/codegen/c_utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ namespace CUtils {
257257
type_src = "int" + std::to_string(kind * 8) + "_t";
258258
break;
259259
}
260+
case ASR::ttypeType::UnsignedInteger: {
261+
type_src = "uint" + std::to_string(kind * 8) + "_t";
262+
break;
263+
}
260264
case ASR::ttypeType::Logical: {
261265
type_src = "bool";
262266
break;

src/libasr/pass/array_op.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
310310
al, loc, left, (ASR::binopType)x->m_op,
311311
right, x->m_type, nullptr));
312312

313+
case ASR::exprType::UnsignedIntegerBinOp:
314+
return ASRUtils::EXPR(ASR::make_UnsignedIntegerBinOp_t(
315+
al, loc, left, (ASR::binopType)x->m_op,
316+
right, x->m_type, nullptr));
317+
313318
case ASR::exprType::RealBinOp:
314319
return ASRUtils::EXPR(ASR::make_RealBinOp_t(
315320
al, loc, left, (ASR::binopType)x->m_op,
@@ -330,6 +335,11 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
330335
al, loc, left, (ASR::cmpopType)x->m_op,
331336
right, x->m_type, nullptr));
332337

338+
case ASR::exprType::UnsignedIntegerCompare:
339+
return ASRUtils::EXPR(ASR::make_UnsignedIntegerCompare_t(
340+
al, loc, left, (ASR::cmpopType)x->m_op,
341+
right, x->m_type, nullptr));
342+
333343
case ASR::exprType::RealCompare:
334344
return ASRUtils::EXPR(ASR::make_RealCompare_t(
335345
al, loc, left, (ASR::cmpopType)x->m_op,
@@ -355,7 +365,8 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
355365
case ASR::exprType::RealCompare:
356366
case ASR::exprType::ComplexCompare:
357367
case ASR::exprType::LogicalCompare:
358-
case ASR::exprType::IntegerCompare: {
368+
case ASR::exprType::IntegerCompare:
369+
case ASR::exprType::UnsignedIntegerCompare: {
359370
ASR::ttype_t* arr_expr_type = ASRUtils::expr_type(arr_expr);
360371
ASR::dimension_t* m_dims;
361372
size_t n_dims = ASRUtils::extract_dimensions_from_ttype(arr_expr_type, m_dims);
@@ -647,6 +658,10 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
647658
replace_ArrayOpCommon(x, "_integer_bin_op_res");
648659
}
649660

661+
void replace_UnsignedIntegerBinOp(ASR::UnsignedIntegerBinOp_t* x) {
662+
replace_ArrayOpCommon(x, "_unsigned_integer_bin_op_res");
663+
}
664+
650665
void replace_ComplexBinOp(ASR::ComplexBinOp_t* x) {
651666
replace_ArrayOpCommon<ASR::ComplexBinOp_t>(x, "_complex_bin_op_res");
652667
}
@@ -659,6 +674,10 @@ class ReplaceArrayOp: public ASR::BaseExprReplacer<ReplaceArrayOp> {
659674
replace_ArrayOpCommon<ASR::IntegerCompare_t>(x, "_integer_comp_op_res");
660675
}
661676

677+
void replace_UnsignedIntegerCompare(ASR::UnsignedIntegerCompare_t* x) {
678+
replace_ArrayOpCommon<ASR::UnsignedIntegerCompare_t>(x, "_unsigned_integer_comp_op_res");
679+
}
680+
662681
void replace_RealCompare(ASR::RealCompare_t* x) {
663682
replace_ArrayOpCommon<ASR::RealCompare_t>(x, "_real_comp_op_res");
664683
}

src/libasr/pass/pass_utils.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ namespace LCompilers {
1818
m_dims = x_type_ref->m_dims;
1919
break;
2020
}
21+
case ASR::ttypeType::UnsignedInteger: {
22+
ASR::UnsignedInteger_t* x_type_ref = ASR::down_cast<ASR::UnsignedInteger_t>(t2);
23+
n_dims = x_type_ref->n_dims;
24+
m_dims = x_type_ref->m_dims;
25+
break;
26+
}
2127
case ASR::ttypeType::Real: {
2228
ASR::Real_t* x_type_ref = ASR::down_cast<ASR::Real_t>(t2);
2329
n_dims = x_type_ref->n_dims;
@@ -69,6 +75,17 @@ namespace LCompilers {
6975
}
7076
break;
7177
}
78+
case ASR::ttypeType::UnsignedInteger: {
79+
ASR::UnsignedInteger_t* x_type_ref = ASR::down_cast<ASR::UnsignedInteger_t>(t2);
80+
if( create_new ) {
81+
new_type = ASRUtils::TYPE(ASR::make_UnsignedInteger_t(*al, x_type->base.loc, x_type_ref->m_kind,
82+
m_dims, n_dims));
83+
} else {
84+
x_type_ref->n_dims = n_dims;
85+
x_type_ref->m_dims = m_dims;
86+
}
87+
break;
88+
}
7289
case ASR::ttypeType::Real: {
7390
ASR::Real_t* x_type_ref = ASR::down_cast<ASR::Real_t>(t2);
7491
if( create_new ) {

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,21 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
733733
}
734734
return ASRUtils::TYPE(ASR::make_Integer_t(al, loc, t->m_kind, new_dims.p, new_dims.size()));
735735
}
736+
case ASR::ttypeType::UnsignedInteger: {
737+
ASR::UnsignedInteger_t *t = ASR::down_cast<ASR::UnsignedInteger_t>(return_type);
738+
fill_expr_in_ttype_t(func_calls, t->m_dims, t->n_dims);
739+
fix_exprs_ttype_t(func_calls, args, f);
740+
Vec<ASR::dimension_t> new_dims;
741+
new_dims.reserve(al, t->n_dims);
742+
for( size_t i = 0; i < func_calls.size(); i += 2 ) {
743+
ASR::dimension_t new_dim;
744+
new_dim.loc = func_calls[i]->base.loc;
745+
new_dim.m_start = func_calls[i];
746+
new_dim.m_length = func_calls[i + 1];
747+
new_dims.push_back(al, new_dim);
748+
}
749+
return ASRUtils::TYPE(ASR::make_UnsignedInteger_t(al, loc, t->m_kind, new_dims.p, new_dims.size()));
750+
}
736751
case ASR::ttypeType::Real: {
737752
ASR::Real_t *t = ASR::down_cast<ASR::Real_t>(return_type);
738753
fill_expr_in_ttype_t(func_calls, t->m_dims, t->n_dims);

src/lpython/semantics/python_comptime_eval.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ struct ProceduresDatabase {
2525
"float32", "float64",
2626
"reshape", "array", "int16",
2727
"complex64", "complex128",
28-
"int8", "exp", "exp2"}},
28+
"int8", "exp", "exp2",
29+
"uint8", "uint16", "uint32", "uint64",
30+
"size"}},
2931
{"math", {"sin", "cos", "tan",
3032
"asin", "acos", "atan",
3133
"exp", "exp2", "expm1"}},

0 commit comments

Comments
 (0)