Skip to content

Commit d4e2f74

Browse files
authored
Merge pull request #1002 from Madhav2310/sinh_&_cosh_functions
Implemented ``sinh`` and ``cosh`` numpy intrinsic functions
2 parents dda429c + 54e5bd0 commit d4e2f74

18 files changed

+204
-22
lines changed

integration_tests/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ RUN(NAME elemental_01 LABELS cpython llvm)
172172
RUN(NAME elemental_02 LABELS cpython llvm)
173173
RUN(NAME elemental_03 LABELS cpython llvm)
174174
RUN(NAME elemental_04 LABELS cpython llvm)
175+
RUN(NAME elemental_05 LABELS cpython llvm)
175176
RUN(NAME elemental_06 LABELS cpython llvm)
176177
RUN(NAME test_random LABELS cpython llvm)
177178
RUN(NAME test_os LABELS cpython llvm)

integration_tests/elemental_05.py

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
from ltypes import i32, f64, f32
2+
from numpy import empty, sinh, cosh, reshape, int32, float64, sin
3+
4+
def verify1d(array: f32[:], result: f32[:], size: i32):
5+
i: i32
6+
eps: f32 = 1e-6
7+
8+
for i in range(size):
9+
assert abs(sinh(sinh(array[i])) - result[i]) <= eps
10+
11+
def verifynd(array: f64[:, :, :, :], result: f64[:, :, :, :], size1: i32, size2: i32, size3: i32, size4: i32):
12+
i: i32; size: i32;
13+
eps: f64 = 1e-12
14+
shape: i32[1] = empty((1,), dtype=int32)
15+
size = size1 * size2 * size3 * size4
16+
shape[0] = size
17+
array1d: f64[12800] = reshape(array, shape)
18+
result1d: f64[12800] = reshape(result, shape)
19+
20+
for i in range(size):
21+
assert abs((sinh(array1d[i]) + 2)/2 - result1d[i]) <= eps
22+
23+
24+
def elemental_sinh():
25+
i: i32; j: i32; k: i32; l: i32; size: i32;
26+
27+
array1d: f32[10] = empty(10)
28+
sinh1d: f32[10] = empty(10)
29+
30+
for i in range(10):
31+
array1d[i] = i/10.0
32+
33+
sinh1d = sinh(sinh(array1d))
34+
verify1d(array1d, sinh1d, 10)
35+
36+
arraynd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2))
37+
sinhnd: f64[40, 10, 16, 2] = empty((40, 10, 16, 2))
38+
size = 40 * 10 * 16 * 2
39+
40+
for i in range(40):
41+
for j in range(10):
42+
for k in range(16):
43+
for l in range(2):
44+
arraynd[i, j, k, l] = float(i + 2*j + 3*k + 4*k)/size
45+
46+
sinhnd = (sinh(arraynd) + 2)/2
47+
48+
verifynd(arraynd, sinhnd, 40, 10, 16, 2)
49+
50+
def verify2d(array: f64[:, :], result: f64[:, :], size1: i32, size2: i32):
51+
i: i32; j: i32;
52+
eps: f64 = 1e-12
53+
54+
for i in range(size1):
55+
for j in range(size2):
56+
assert abs(cosh(5 + array[i, j])**2 - result[i, j]) <= eps
57+
58+
def elemental_cosh():
59+
i: i32; j: i32
60+
61+
array2d: f64[20, 10] = empty((20, 10))
62+
cosh2d: f64[20, 10] = empty((20, 10))
63+
64+
for i in range(20):
65+
for j in range(10):
66+
array2d[i, j] = (i + 2*j)/200.0
67+
68+
cosh2d = cosh(5 + (array2d))**2
69+
verify2d(array2d, cosh2d, 20, 10)
70+
71+
def elemental_cosh_():
72+
i: i32
73+
j: i32
74+
75+
array2d: f64[20, 10] = empty((20, 10))
76+
cosh2d: f64[20, 10] = empty((20, 10))
77+
78+
for i in range(20):
79+
for j in range(10):
80+
array2d[i, j] = (i + 2*j)/200.0
81+
82+
cosh2d = cosh(5 + (array2d))**2
83+
verify2d(array2d, cosh2d, 20, 10)
84+
85+
def elemental_trig_identity():
86+
i: i32; j: i32; k: i32; l: i32
87+
eps: f64 = 1e-12
88+
89+
arraynd: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64)
90+
91+
identity1: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64)
92+
identity2: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64)
93+
identity3: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64)
94+
identity4: f64[10, 5, 2, 4] = empty((10, 5, 2, 4), dtype=float64)
95+
96+
observed1d_1: f64[400] = empty(400, dtype=float64)
97+
observed1d_2: f64[400] = empty(400, dtype=float64)
98+
observed1d_3: f64[400] = empty(400, dtype=float64)
99+
observed1d_4: f64[400] = empty(400, dtype=float64)
100+
101+
for i in range(10):
102+
for j in range(5):
103+
for k in range(2):
104+
for l in range(4):
105+
arraynd[i, j, k, l] = sin(float(i + j + k + l))
106+
107+
identity1 = 1.0 - cosh(arraynd)**2 + sinh(arraynd)**2
108+
identity2 = cosh(-1 * arraynd) - cosh(arraynd)
109+
identity3 = sinh(-1 * arraynd) + sinh(arraynd)
110+
identity4 = (cosh(arraynd/4 + arraynd/2) -
111+
cosh(arraynd/4) * cosh(arraynd/2) -
112+
sinh(arraynd/4) * sinh(arraynd/2))
113+
114+
newshape: i32[1] = empty(1, dtype=int)
115+
newshape[0] = 400
116+
117+
observed1d_1 = reshape(identity1, newshape)
118+
observed1d_2 = reshape(identity2, newshape)
119+
observed1d_3 = reshape(identity3, newshape)
120+
observed1d_4 = reshape(identity4, newshape)
121+
122+
for i in range(400):
123+
assert abs(observed1d_1[i] - 0.0) <= eps
124+
assert abs(observed1d_2[i] - 0.0) <= eps
125+
assert abs(observed1d_3[i] - 0.0) <= eps
126+
assert abs(observed1d_4[i] - 0.0) <= eps
127+
128+
129+
elemental_sinh()
130+
elemental_cosh()
131+
elemental_trig_identity()

src/libasr/pass/array_op.cpp

+16-8
Original file line numberDiff line numberDiff line change
@@ -705,47 +705,55 @@ class ArrayOpVisitor : public PassUtils::PassVisitor<ArrayOpVisitor>
705705
if( doloop == nullptr ) {
706706
ASR::expr_t* ref = PassUtils::create_array_ref(arr_expr, idx_vars_value, al);
707707
ASR::expr_t* res = PassUtils::create_array_ref(result_var, idx_vars, al);
708+
ASR::expr_t *lexpr = nullptr, *rexpr = nullptr;
709+
if( rank_left > 0 ) {
710+
lexpr = ref;
711+
rexpr = other_expr;
712+
} else {
713+
rexpr = ref;
714+
lexpr = other_expr;
715+
}
708716
ASR::expr_t* op_el_wise = nullptr;
709717
switch( x.class_type ) {
710718
case ASR::exprType::IntegerBinOp:
711719
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_IntegerBinOp_t(
712720
al, x.base.base.loc,
713-
ref, (ASR::binopType)x.m_op, other_expr, x.m_type, nullptr));
721+
lexpr, (ASR::binopType)x.m_op, rexpr, x.m_type, nullptr));
714722
break;
715723
case ASR::exprType::RealBinOp:
716724
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_RealBinOp_t(
717725
al, x.base.base.loc,
718-
ref, (ASR::binopType)x.m_op, other_expr, x.m_type, nullptr));
726+
lexpr, (ASR::binopType)x.m_op, rexpr, x.m_type, nullptr));
719727
break;
720728
case ASR::exprType::ComplexBinOp:
721729
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_ComplexBinOp_t(
722730
al, x.base.base.loc,
723-
ref, (ASR::binopType)x.m_op, other_expr, x.m_type, nullptr));
731+
lexpr, (ASR::binopType)x.m_op, rexpr, x.m_type, nullptr));
724732
break;
725733
case ASR::exprType::LogicalBinOp:
726734
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_LogicalBinOp_t(
727735
al, x.base.base.loc,
728-
ref, (ASR::logicalbinopType)x.m_op, other_expr, x.m_type, nullptr));
736+
lexpr, (ASR::logicalbinopType)x.m_op, rexpr, x.m_type, nullptr));
729737
break;
730738
case ASR::exprType::IntegerCompare:
731739
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_IntegerCompare_t(
732740
al, x.base.base.loc,
733-
ref, (ASR::cmpopType)x.m_op, other_expr, x.m_type, nullptr));
741+
lexpr, (ASR::cmpopType)x.m_op, rexpr, x.m_type, nullptr));
734742
break;
735743
case ASR::exprType::RealCompare:
736744
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_RealCompare_t(
737745
al, x.base.base.loc,
738-
ref, (ASR::cmpopType)x.m_op, other_expr, x.m_type, nullptr));
746+
lexpr, (ASR::cmpopType)x.m_op, rexpr, x.m_type, nullptr));
739747
break;
740748
case ASR::exprType::ComplexCompare:
741749
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_ComplexCompare_t(
742750
al, x.base.base.loc,
743-
ref, (ASR::cmpopType)x.m_op, other_expr, x.m_type, nullptr));
751+
lexpr, (ASR::cmpopType)x.m_op, rexpr, x.m_type, nullptr));
744752
break;
745753
case ASR::exprType::LogicalCompare:
746754
op_el_wise = LFortran::ASRUtils::EXPR(ASR::make_LogicalCompare_t(
747755
al, x.base.base.loc,
748-
ref, (ASR::cmpopType)x.m_op, other_expr, x.m_type, nullptr));
756+
lexpr, (ASR::cmpopType)x.m_op, rexpr, x.m_type, nullptr));
749757
break;
750758
default:
751759
throw LCompilersException("The desired operation is not supported yet for arrays.");

src/runtime/lpython_intrinsic_numpy.py

+42
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,48 @@ def _lfortran_stan(x: f32) -> f32:
7474
def tan(x: f32) -> f32:
7575
return _lfortran_stan(x)
7676

77+
78+
########## sinh ##########
79+
80+
@ccall
81+
def _lfortran_dsinh(x: f64) -> f64:
82+
pass
83+
84+
@overload
85+
@vectorize
86+
def sinh(x: f64) -> f64:
87+
return _lfortran_dsinh(x)
88+
89+
@ccall
90+
def _lfortran_ssinh(x: f32) -> f32:
91+
pass
92+
93+
@overload
94+
@vectorize
95+
def sinh(x: f32) -> f32:
96+
return _lfortran_ssinh(x)
97+
98+
########## cosh ##########
99+
100+
@ccall
101+
def _lfortran_dcosh(x: f64) -> f64:
102+
pass
103+
104+
@overload
105+
@vectorize
106+
def cosh(x: f64) -> f64:
107+
return _lfortran_dcosh(x)
108+
109+
@ccall
110+
def _lfortran_scosh(x: f32) -> f32:
111+
pass
112+
113+
@overload
114+
@vectorize
115+
def cosh(x: f32) -> f32:
116+
return _lfortran_scosh(x)
117+
118+
77119
########## log ##########
78120

79121
@ccall

tests/reference/asr-array_01_decl-39cf894.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-array_01_decl-39cf894.stdout",
9-
"stdout_hash": "85bcc57879d6a94bf5e51e106e7ffbe00137da998cdd03ca9771397e",
9+
"stdout_hash": "5ecf6039e91c9a83a28aeb6a43fdc4d72d9561a3d8f0542ccdf019a3",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-array_01_decl-39cf894.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/asr-array_02_decl-e8f6874.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-array_02_decl-e8f6874.stdout",
9-
"stdout_hash": "d255150e3a3cab32c1c10b7d87e6bf41a5c08b1a02a3262aa03ca643",
9+
"stdout_hash": "4a38b14377eb0d1bb08af1a3ac8298d87507a01528f564d6c2c77ed0",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-array_02_decl-e8f6874.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/asr-elemental_01-b58df26.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-elemental_01-b58df26.stdout",
9-
"stdout_hash": "8196b92c8852e196721b484ed4cbf08597f08e14d03ac317778f7b09",
9+
"stdout_hash": "cf4ee24dc8526427340655eeda0cf3810220555b1f021271612787c6",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-elemental_01-b58df26.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/asr-test_numpy_03-e600a49.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-test_numpy_03-e600a49.stdout",
9-
"stdout_hash": "5b56db1f6eae87e55daa8941552f6b701c87a2b5da2847b4efa88ee7",
9+
"stdout_hash": "a02228cec6fd33552a8d2c9789cd3ef12793d9d86dcae2cca85772a2",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-test_numpy_03-e600a49.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/asr-test_numpy_04-ecbb614.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-test_numpy_04-ecbb614.stdout",
9-
"stdout_hash": "dd38ca7e26c58fbd295e5114536da8096c4b3d706e70149d033bf015",
9+
"stdout_hash": "fcf50d51c7ac3174a6204e49aaaf2f0de1c075237dc013ca0292ce67",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-test_numpy_04-ecbb614.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/asr-vec_01-66ac423.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "asr-vec_01-66ac423.stdout",
9-
"stdout_hash": "5c6c944844a7321b1d638d30ef7bd55ff73157280cdf4be5eb1a8323",
9+
"stdout_hash": "27e2d720253a51fcc8522c2c43f572c4fc1d55adf4b351eb407867fe",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/asr-vec_01-66ac423.stdout

+1-1
Large diffs are not rendered by default.

tests/reference/pass_loop_vectorise-vec_01-be9985e.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"outfile": null,
77
"outfile_hash": null,
88
"stdout": "pass_loop_vectorise-vec_01-be9985e.stdout",
9-
"stdout_hash": "b791badfb88621d1820f169e435b1d34cb0a8a9c359139c151e42d66",
9+
"stdout_hash": "5e63d66337232a414c2dcc035de82b554cd346fe7d579429deddb397",
1010
"stderr": null,
1111
"stderr_hash": null,
1212
"returncode": 0

tests/reference/pass_loop_vectorise-vec_01-be9985e.stdout

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)