@@ -744,14 +744,18 @@ static struct PyUSMArrayObject *PyUSMNdArray_ARRAYOBJ(PyObject *obj)
744
744
DPEXRT_DEBUG (
745
745
drt_debug_print ("DPEXRT-DEBUG: usm array was passed directly\n" ));
746
746
arrayobj = obj ;
747
+ Py_INCREF (arrayobj );
747
748
}
748
749
else if (PyObject_HasAttrString (obj , "_array_obj" )) {
750
+ // PyObject_GetAttrString gives reference
749
751
arrayobj = PyObject_GetAttrString (obj , "_array_obj" );
750
752
751
753
if (!arrayobj )
752
754
return NULL ;
753
- if (!PyObject_TypeCheck (arrayobj , & PyUSMArrayType ))
755
+ if (!PyObject_TypeCheck (arrayobj , & PyUSMArrayType )) {
756
+ Py_DECREF (arrayobj );
754
757
return NULL ;
758
+ }
755
759
}
756
760
757
761
struct PyUSMArrayObject * pyusmarrayobj =
@@ -803,17 +807,13 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
803
807
PyGILState_STATE gstate ;
804
808
npy_intp itemsize = 0 ;
805
809
806
- // Increment the ref count on obj to prevent CPython from garbage
807
- // collecting the array.
808
- // TODO: add extra description why do we need this
809
- Py_IncRef (obj );
810
-
811
810
DPEXRT_DEBUG (drt_debug_print (
812
811
"DPEXRT-DEBUG: In DPEXRT_sycl_usm_ndarray_from_python at %s, line %d\n" ,
813
812
__FILE__ , __LINE__ ));
814
813
815
814
// Check if the PyObject obj has an _array_obj attribute that is of
816
815
// dpctl.tensor.usm_ndarray type.
816
+ // arrayobj is a new reference, reference of obj is borrowed
817
817
if (!(arrayobj = PyUSMNdArray_ARRAYOBJ (obj ))) {
818
818
DPEXRT_DEBUG (drt_debug_print (
819
819
"DPEXRT-ERROR: PyUSMNdArray_ARRAYOBJ check failed at %s, line %d\n" ,
@@ -832,6 +832,7 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
832
832
data = (void * )UsmNDArray_GetData (arrayobj );
833
833
nitems = product_of_shape (shape , ndim );
834
834
itemsize = (npy_intp )UsmNDArray_GetElementSize (arrayobj );
835
+
835
836
if (!(qref = UsmNDArray_GetQueueRef (arrayobj ))) {
836
837
DPEXRT_DEBUG (drt_debug_print (
837
838
"DPEXRT-ERROR: UsmNDArray_GetQueueRef returned NULL at "
@@ -850,6 +851,9 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
850
851
goto error ;
851
852
}
852
853
854
+ Py_XDECREF (arrayobj );
855
+ Py_IncRef (obj );
856
+
853
857
arystruct -> data = data ;
854
858
arystruct -> sycl_queue = qref ;
855
859
arystruct -> nitems = nitems ;
@@ -906,7 +910,7 @@ static int DPEXRT_sycl_usm_ndarray_from_python(PyObject *obj,
906
910
__FILE__ , __LINE__ ));
907
911
gstate = PyGILState_Ensure ();
908
912
// decref the python object
909
- Py_DECREF ( obj );
913
+ Py_XDECREF (( PyObject * ) arrayobj );
910
914
// release the GIL
911
915
PyGILState_Release (gstate );
912
916
@@ -938,26 +942,31 @@ static PyObject *box_from_arystruct_parent(usmarystruct_t *arystruct,
938
942
drt_debug_print ("DPEXRT-DEBUG: In box_from_arystruct_parent.\n" ));
939
943
940
944
if (!(arrayobj = PyUSMNdArray_ARRAYOBJ (arystruct -> parent ))) {
945
+ Py_XDECREF (arrayobj );
941
946
DPEXRT_DEBUG (
942
947
drt_debug_print ("DPEXRT-DEBUG: Arrayobj cannot be boxed from "
943
948
"parent as parent pointer is NULL.\n" ));
944
949
return NULL ;
945
950
}
946
951
947
952
if ((void * )UsmNDArray_GetData (arrayobj ) != arystruct -> data ) {
953
+ Py_XDECREF (arrayobj );
948
954
DPEXRT_DEBUG (drt_debug_print (
949
955
"DPEXRT-DEBUG: Arrayobj cannot be boxed "
950
956
"from parent as data pointer in the arystruct is not the same as "
951
957
"the data pointer in the parent object.\n" ));
952
958
return NULL ;
953
959
}
954
960
955
- if (UsmNDArray_GetNDim (arrayobj ) != ndim )
961
+ if (UsmNDArray_GetNDim (arrayobj ) != ndim ) {
962
+ Py_XDECREF (arrayobj );
956
963
return NULL ;
964
+ }
957
965
958
966
p = arystruct -> shape_and_strides ;
959
967
shape = UsmNDArray_GetShape (arrayobj );
960
968
strides = UsmNDArray_GetStrides (arrayobj );
969
+ Py_XDECREF (arrayobj );
961
970
962
971
// Ensure the shape of the array to be boxed matches the shape of the
963
972
// original parent.
0 commit comments