Skip to content

Commit 1b7ff7b

Browse files
Thirumalai-Shaktivelcertik
authored andcommitted
Handle array as return variable using the lpython decorator
1 parent 21a7be2 commit 1b7ff7b

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from numpy import array
2+
from lpython import i32, f64, lpython
3+
4+
@lpython
5+
def multiply(n: i32, x: f64[:]) -> f64[:]:
6+
i: i32
7+
for i in range(n):
8+
x[i] *= 5.0
9+
return x
10+
11+
def test():
12+
x: f64[3] = array([11.0, 12.0, 13.0, 14., 15.])
13+
print(multiply(5, x))
14+
15+
test()

src/runtime/lpython/lpython.py

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -682,29 +682,36 @@ def get_data_type(t):
682682
self.arg_type_formats = ""
683683
self.return_type = ""
684684
self.return_type_format = ""
685+
self.array_as_return_type = ()
685686
self.arg_types = {}
686687
counter = 1
687688
for t in types.keys():
688689
if t == "return":
689690
type = get_type_info(types[t])
690-
self.return_type_format = type[0]
691-
self.return_type = type[1]
691+
if type[0] == 'O':
692+
self.array_as_return_type = type
693+
continue
694+
else:
695+
self.return_type_format = type[0]
696+
self.return_type = type[1]
692697
else:
693698
type = get_type_info(types[t])
694699
self.arg_type_formats += type[0]
695700
self.arg_types[counter] = type[1]
696701
counter += 1
697702
# ----------------------------------------------------------------------
698-
# `arg_0`: used as the return variables
703+
# `arg_0` is used as the return variable
699704
# arguments are declared as `arg_1`, `arg_2`, ...
700-
variables_decl = ""
705+
variables_decl = "// Declare return variables and arguments\n"
701706
if self.return_type != "":
702-
variables_decl = "// Declare return variables and arguments\n"
703707
variables_decl += " " + get_data_type(self.return_type) + "arg_" \
704708
+ str(0) + ";\n"
709+
elif self.array_as_return_type:
710+
variables_decl += " " + get_data_type( \
711+
self.array_as_return_type[1][1][:-2]) + "arg_" + str(0) + ";\n"
705712
# ----------------------------------------------------------------------
706713
# `PyArray_AsCArray` is used to convert NumPy Arrays to C Arrays
707-
# `fill_array_details` contains arrays operations to be
714+
# `fill_array_details` contains array operations to be
708715
# performed on the arguments
709716
# `parse_args` are used to capture the args from CPython
710717
# `pass_args` are the args that are passed to the shared library function
@@ -766,7 +773,24 @@ def get_data_type(t):
766773
// Build and return the result as a Python object
767774
return Py_BuildValue("{self.return_type_format}", arg_0);"""
768775
else:
769-
fill_return_details = f"""{self.fn_name}({pass_args});
776+
if self.array_as_return_type:
777+
fill_return_details = f"""
778+
arg_0.data = malloc(sizeof({self.array_as_return_type[1][2][:-2]}));
779+
arg_0.n_dims = 1;
780+
arg_0.dims[0].lower_bound = 0;
781+
arg_0.dims[0].length = arg_1;
782+
arg_0.is_allocated = false;
783+
{self.fn_name}({pass_args}, &arg_0);
784+
785+
// Build and return the result as a Python object
786+
PyObject* list_obj = PyList_New(arg_1);
787+
for (int i = 0; i < arg_1; i++) {{
788+
PyObject* element = PyFloat_FromDouble(arg_0.data[i]);
789+
PyList_SetItem(list_obj, i, element);
790+
}}
791+
return list_obj;"""
792+
else:
793+
fill_return_details = f"""{self.fn_name}({pass_args});
770794
Py_RETURN_NONE;"""
771795

772796
# ----------------------------------------------------------------------
@@ -856,4 +880,8 @@ def __call__(self, *args, **kwargs):
856880
# import the symbol from the shared library
857881
function = getattr(__import__("lpython_module_" + self.fn_name),
858882
self.fn_name)
859-
return function(*args, **kwargs)
883+
if self.array_as_return_type:
884+
from numpy import array
885+
return array(function(*args, **kwargs))
886+
else:
887+
return function(*args, **kwargs)

0 commit comments

Comments
 (0)