@@ -637,7 +637,8 @@ def get_rtlib_dir():
637
637
638
638
def get_type_info (arg ):
639
639
# return_type -> (`type_format`, `variable type`, `array struct name`)
640
- # See: https://docs.python.org/3/c-api/arg.html for more info on type_format
640
+ # See: https://docs.python.org/3/c-api/arg.html for more info on `type_format`
641
+ # `array struct name`: used by the C backend
641
642
if arg == f64 :
642
643
return ('d' , "double" , 'r64' )
643
644
elif arg == f32 :
@@ -652,7 +653,10 @@ def get_type_info(arg):
652
653
t = get_type_info (arg ._type )
653
654
if t [2 ] == '' :
654
655
raise NotImplementedError ("Type %r not implemented" % arg )
655
- return ('O' , ["PyArrayObject *" , "struct " + t [2 ]+ " *" , t [1 ]+ " *" ], '' )
656
+ n = ''
657
+ if not isinstance (arg ._dims , slice ):
658
+ n = arg ._dims ._name
659
+ return ('O' , ["PyArrayObject *" , "struct " + t [2 ]+ " *" , t [1 ]+ " *" , n ], '' )
656
660
else :
657
661
raise NotImplementedError ("Type %r not implemented" % arg )
658
662
@@ -684,7 +688,6 @@ def get_data_type(t):
684
688
self .return_type_format = ""
685
689
self .array_as_return_type = ()
686
690
self .arg_types = {}
687
- counter = 1
688
691
for t in types .keys ():
689
692
if t == "return" :
690
693
type = get_type_info (types [t ])
@@ -697,18 +700,19 @@ def get_data_type(t):
697
700
else :
698
701
type = get_type_info (types [t ])
699
702
self .arg_type_formats += type [0 ]
700
- self .arg_types [counter ] = type [1 ]
701
- counter += 1
703
+ self .arg_types [t ] = type [1 ]
702
704
# ----------------------------------------------------------------------
703
- # `arg_0` is used as the return variable
704
- # arguments are declared as `arg_1`, `arg_2`, ...
705
+ # `_<fn_name>_return_value`: used as the return variables
705
706
variables_decl = "// Declare return variables and arguments\n "
706
707
if self .return_type != "" :
707
- variables_decl += " " + get_data_type (self .return_type ) + "arg_" \
708
- + str ( 0 ) + " ;\n "
708
+ variables_decl += " " + get_data_type (self .return_type ) \
709
+ + "_" + self . fn_name + "_return_value ;\n "
709
710
elif self .array_as_return_type :
710
711
variables_decl += " " + get_data_type ( \
711
- self .array_as_return_type [1 ][1 ][:- 2 ]) + "arg_" + str (0 ) + ";\n "
712
+ self .array_as_return_type [1 ][1 ][:- 2 ]) + "_" + self .fn_name \
713
+ + "_return_value;\n "
714
+ else :
715
+ variables_decl = ""
712
716
# ----------------------------------------------------------------------
713
717
# `PyArray_AsCArray` is used to convert NumPy Arrays to C Arrays
714
718
# `fill_array_details` contains array operations to be
@@ -719,16 +723,18 @@ def get_data_type(t):
719
723
parse_args = ""
720
724
pass_args = ""
721
725
numpy_init = ""
726
+ prefix_comma = False
722
727
for i , t in self .arg_types .items ():
723
- if i > 1 :
728
+ if prefix_comma :
724
729
parse_args += ", "
725
730
pass_args += ", "
731
+ prefix_comma = True
726
732
if isinstance (t , list ):
727
733
if numpy_init == "" :
728
734
numpy_init = "// Initialize NumPy\n import_array();\n \n "
729
735
fill_array_details += f"""\n
730
- // fill array details for args[ { i - 1 } ]
731
- if (PyArray_NDIM(arg_ { i } ) != 1) {{
736
+ // fill array details for { i }
737
+ if (PyArray_NDIM({ i } ) != 1) {{
732
738
PyErr_SetString(PyExc_TypeError,
733
739
"Only 1 dimension is implemented for now.");
734
740
return NULL;
@@ -738,9 +744,9 @@ def get_data_type(t):
738
744
{{
739
745
{ t [2 ]} array;
740
746
// Create C arrays from numpy objects:
741
- PyArray_Descr *descr = PyArray_DescrFromType(PyArray_TYPE(arg_ { i } ));
747
+ PyArray_Descr *descr = PyArray_DescrFromType(PyArray_TYPE({ i } ));
742
748
npy_intp dims[1];
743
- if (PyArray_AsCArray((PyObject **)&arg_ { i } , (void *)&array, dims, 1, descr) < 0) {{
749
+ if (PyArray_AsCArray((PyObject **)&{ i } , (void *)&array, dims, 1, descr) < 0) {{
744
750
PyErr_SetString(PyExc_TypeError, "error converting to c array");
745
751
return NULL;
746
752
}}
@@ -751,11 +757,11 @@ def get_data_type(t):
751
757
s_array_{ i } ->dims[0].length = dims[0];
752
758
s_array_{ i } ->is_allocated = false;
753
759
}}"""
754
- pass_args += "s_array_" + str ( i )
760
+ pass_args += "s_array_" + i
755
761
else :
756
- pass_args += "arg_" + str ( i )
757
- variables_decl += " " + get_data_type (t ) + "arg_" + str ( i ) + ";\n "
758
- parse_args += "&arg_ " + str ( i )
762
+ pass_args += i
763
+ variables_decl += " " + get_data_type (t ) + i + ";\n "
764
+ parse_args += "&" + i
759
765
760
766
if parse_args != "" :
761
767
parse_args = f"""\n // Parse the arguments from Python
@@ -768,24 +774,24 @@ def get_data_type(t):
768
774
fill_return_details = ""
769
775
if self .return_type != "" :
770
776
fill_return_details = f"""\n \n // Call the C function
771
- arg_0 = { self .fn_name } ({ pass_args } );
777
+ _ { self . fn_name } _return_value = { self .fn_name } ({ pass_args } );
772
778
773
779
// Build and return the result as a Python object
774
- return Py_BuildValue("{ self .return_type_format } ", arg_0 );"""
780
+ return Py_BuildValue("{ self .return_type_format } ", _ { self . fn_name } _return_value );"""
775
781
else :
776
782
if self .array_as_return_type :
777
783
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
+ _ { self . fn_name } _return_value .data = malloc(sizeof({ self .array_as_return_type [1 ][2 ][:- 2 ]} ));
785
+ _ { self . fn_name } _return_value .n_dims = 1;
786
+ _ { self . fn_name } _return_value .dims[0].lower_bound = 0;
787
+ _ { self . fn_name } _return_value. dims[0].length = { self . array_as_return_type [ 1 ][ 3 ] } ;
788
+ _ { self . fn_name } _return_value .is_allocated = false;
789
+ { self .fn_name } ({ pass_args } , &_ { self . fn_name } _return_value );
784
790
785
791
// 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]);
792
+ PyObject* list_obj = PyList_New({ self . array_as_return_type [ 1 ][ 3 ] } );
793
+ for (int i = 0; i < { self . array_as_return_type [ 1 ][ 3 ] } ; i++) {{
794
+ PyObject* element = PyFloat_FromDouble(_ { self . fn_name } _return_value .data[i]);
789
795
PyList_SetItem(list_obj, i, element);
790
796
}}
791
797
return list_obj;"""
0 commit comments