Skip to content

Commit 10ae760

Browse files
committed
Pull request #12: Use HPyGlobal for global type vars
Merge in ~STEPAN.SINDELAR_ORACLE.COM/numpy-hpy from fa/hpy_global to labs-hpy-port * commit '4f2d3de9229a9c7d2ae6a978cda04ab2262209a8': Use HPyGlobal for global type vars
2 parents 404a43d + 4f2d3de commit 10ae760

File tree

6 files changed

+71
-31
lines changed

6 files changed

+71
-31
lines changed

numpy/core/include/numpy/ndarrayobject.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,38 @@ extern "C" {
2424
/* C-API that requires previous API to be defined */
2525

2626
#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)
27-
#define HPyArray_DescrCheck(ctx, op) HPy_TypeCheck(ctx, op, HPyArrayDescr_Type)
2827

28+
extern NPY_NO_EXPORT HPyGlobal HPyArrayDescr_Type;
29+
static NPY_INLINE int
30+
HPyArray_DescrCheck(HPyContext *ctx, HPy op)
31+
{
32+
HPy array_descr_type = HPyGlobal_Load(ctx, HPyArrayDescr_Type);
33+
int res = HPy_TypeCheck(ctx, op, array_descr_type);
34+
HPy_Close(ctx, array_descr_type);
35+
return res;
36+
}
2937

3038
#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
3139
#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
32-
#define HPyArray_Check(ctx, op) HPy_TypeCheck(ctx, op, HPyArray_Type)
33-
#define HPyArray_CheckExact(ctx, op) HPy_Is(ctx, op, HPyArray_Type)
40+
41+
extern NPY_NO_EXPORT HPyGlobal HPyArray_Type;
42+
static NPY_INLINE int
43+
HPyArray_Check(HPyContext *ctx, HPy op)
44+
{
45+
HPy array_type = HPyGlobal_Load(ctx, HPyArray_Type);
46+
int res = HPy_TypeCheck(ctx, op, array_type);
47+
HPy_Close(ctx, array_type);
48+
return res;
49+
}
50+
51+
static NPY_INLINE int
52+
HPyArray_CheckExact(HPyContext *ctx, HPy op)
53+
{
54+
HPy array_type = HPyGlobal_Load(ctx, HPyArray_Type);
55+
int res = HPy_Is(ctx, HPy_Type(ctx, op), array_type);
56+
HPy_Close(ctx, array_type);
57+
return res;
58+
}
3459

3560
#define PyArray_HasArrayInterfaceType(op, type, context, out) \
3661
((((out)=PyArray_FromStructInterface(op)) != Py_NotImplemented) || \

numpy/core/include/numpy/ndarraytypes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,6 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
20862086

20872087
#endif /* NPY_INTERNAL_BUILD */
20882088

2089-
20902089
/*
20912090
* Use the keyword NPY_DEPRECATED_INCLUDES to ensure that the header files
20922091
* npy_*_*_deprecated_api.h are only included from here and nowhere else.

numpy/core/src/multiarray/arrayobject.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ array_might_be_written(PyArrayObject *obj);
2828
static const int NPY_ARRAY_WARN_ON_WRITE = (1 << 31);
2929

3030
extern NPY_NO_EXPORT HPyType_Spec PyArray_Type_spec;
31-
extern NPY_NO_EXPORT HPy HPyArray_Type;
31+
extern NPY_NO_EXPORT HPyGlobal HPyArray_Type;
3232
extern NPY_NO_EXPORT HPyType_Spec PyArrayFlags_Type_Spec;
33+
extern NPY_NO_EXPORT HPyGlobal HPyArrayDescr_Type;
3334

3435
NPY_NO_EXPORT int
3536
HPyArray_ElementStrides(HPyContext *ctx, HPy obj);

numpy/core/src/multiarray/ctors.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -912,8 +912,11 @@ HPyArray_NewFromDescr_int(
912912
* (since that function does nothing), or, for backward compatibility,
913913
* if it is None.
914914
*/
915-
if (!HPy_Is(ctx, h_subtype, HPyArray_Type)) {
916-
HPy ndarray_array_finalize = HPy_GetAttr_s(ctx, HPyArray_Type, "__array_finalize__");
915+
HPy array_type = HPyGlobal_Load(ctx, HPyArray_Type);
916+
if (!HPy_Is(ctx, h_subtype, array_type)) {
917+
HPy ndarray_array_finalize = HPy_GetAttr_s(ctx, array_type, "__array_finalize__");
918+
HPy_Close(ctx, array_type);
919+
917920
HPy func = HPy_GetAttr_s(ctx, h_subtype, "__array_finalize__");
918921
if (HPy_IsNull(func)) {
919922
HPy_Close(ctx, ndarray_array_finalize);
@@ -977,6 +980,8 @@ HPyArray_NewFromDescr_int(
977980
}
978981
}
979982
}
983+
} else {
984+
HPy_Close(ctx, array_type);
980985
}
981986
return result;
982987

@@ -1223,15 +1228,10 @@ HPyArray_NewLikeArrayWithShape(HPyContext *ctx, HPy prototype, NPY_ORDER order,
12231228

12241229
/* If it's not KEEPORDER, this is simple */
12251230
if (order != NPY_KEEPORDER) {
1226-
ret = HPyArray_NewFromDescr(ctx,
1227-
subok ? HPy_Type(ctx, prototype) : HPyArray_Type,
1228-
dtype,
1229-
ndim,
1230-
dims,
1231-
NULL,
1232-
NULL,
1233-
order,
1234-
subok ? prototype : HPy_NULL);
1231+
HPy type = subok ? HPy_Type(ctx, prototype) : HPyGlobal_Load(ctx, HPyArray_Type);
1232+
ret = HPyArray_NewFromDescr(ctx, type, dtype, ndim, dims, NULL, NULL,
1233+
order, subok ? prototype : HPy_NULL);
1234+
HPy_Close(ctx, type);
12351235
}
12361236
/* KEEPORDER needs some analysis of the strides */
12371237
else {
@@ -3213,11 +3213,13 @@ HPyArray_Zeros(HPyContext *ctx, int nd, npy_intp const *dims, HPy type, int is_f
32133213
type = HPyArray_DescrFromType(ctx, NPY_DEFAULT_TYPE);
32143214
}
32153215

3216+
HPy array_type = HPyGlobal_Load(ctx, HPyArray_Type);
32163217
ret = HPyArray_NewFromDescr_int(
3217-
ctx, HPyArray_Type, type,
3218+
ctx, array_type, type,
32183219
nd, dims, NULL, NULL,
32193220
is_f_order, HPy_NULL, HPy_NULL,
32203221
1, 0);
3222+
HPy_Close(ctx, array_type);
32213223

32223224
if (HPy_IsNull(ret)) {
32233225
// HPY TODO: note that HPyArray_NewFromDescr_int still steals 'type_descr' on error

numpy/core/src/multiarray/descriptor.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,8 @@ HPyArray_DescrNew(HPyContext *ctx, HPy h_base);
4343

4444
NPY_NO_EXPORT PyArray_DTypeMeta PyArrayDescr_TypeFull;
4545
NPY_NO_EXPORT PyTypeObject *_PyArrayDescr_Type_p;
46-
// HPY TODO: HACK storing handle in a global variable...
4746
// the variable is defined in multiarraymodule.c for now,
4847
// should be in/accesible via HPY API eventually
49-
NPY_NO_EXPORT HPy HPyArrayDescr_Type;
48+
NPY_NO_EXPORT extern HPyGlobal HPyArrayDescr_Type;
5049

5150
#endif /* NUMPY_CORE_SRC_MULTIARRAY_DESCRIPTOR_H_ */

numpy/core/src/multiarray/multiarraymodule.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ set_legacy_print_mode(PyObject *NPY_UNUSED(self), PyObject *args)
111111

112112
NPY_NO_EXPORT PyTypeObject* _PyArray_Type_p = NULL;
113113
NPY_NO_EXPORT HPyContext *numpy_global_ctx = NULL;
114-
NPY_NO_EXPORT HPy HPyArray_Type;
115-
NPY_NO_EXPORT HPy HPyArrayDescr_Type;
114+
NPY_NO_EXPORT HPyGlobal HPyArray_Type;
115+
NPY_NO_EXPORT HPyGlobal HPyArrayDescr_Type;
116116

117117
/* Only here for API compatibility */
118118
NPY_NO_EXPORT PyTypeObject PyBigArray_Type;
@@ -1693,6 +1693,7 @@ _hpy_array_fromobject_generic(
16931693
HPyContext *ctx, HPy op, HPy type, _PyArray_CopyMode copy, NPY_ORDER order,
16941694
npy_bool subok, int ndmin)
16951695
{
1696+
HPy array_type = HPy_NULL;
16961697
HPy ret = HPy_NULL;
16971698
PyArrayObject *oparr;
16981699
HPy oldtype = HPy_NULL;
@@ -1704,14 +1705,15 @@ _hpy_array_fromobject_generic(
17041705
HPyErr_SetString(ctx, ctx->h_ValueError,
17051706
"ndmin bigger than allowable number of dimensions "
17061707
"NPY_MAXDIMS (=%d)"/*, HPY TODO: NPY_MAXDIMS*/);
1707-
return HPy_NULL;
1708+
goto fail;
17081709
}
17091710
/* fast exit if simple call */
17101711
// HPY TODO (API): original code uses "check exact"
17111712
// HPy version has to use two calls HPy_Type and HPy_Is
17121713
// It would be faster to check subok first and then exact or subclass check
1713-
if (HPy_Is(ctx, HPy_Type(ctx, op), HPyArray_Type) ||
1714-
(subok && HPy_TypeCheck(ctx, op, HPyArray_Type))) {
1714+
array_type = HPyGlobal_Load(ctx, HPyArray_Type);
1715+
if (HPy_Is(ctx, HPy_Type(ctx, op), array_type) ||
1716+
(subok && HPy_TypeCheck(ctx, op, array_type))) {
17151717
oparr = PyArrayObject_AsStruct(ctx, op);
17161718
if (HPy_IsNull(type)) {
17171719
if (copy != NPY_COPY_ALWAYS && STRIDING_OK(oparr, order)) {
@@ -1722,7 +1724,7 @@ _hpy_array_fromobject_generic(
17221724
if (copy == NPY_COPY_NEVER) {
17231725
HPyErr_SetString(ctx, ctx->h_ValueError,
17241726
"Unable to avoid copy while creating a new array.");
1725-
return HPy_NULL;
1727+
goto fail;
17261728
}
17271729
ret = HPyArray_NewCopy(ctx, op, order);
17281730
goto finish;
@@ -1740,9 +1742,9 @@ _hpy_array_fromobject_generic(
17401742
}
17411743
else {
17421744
if (copy == NPY_COPY_NEVER) {
1743-
PyErr_SetString(PyExc_ValueError,
1745+
HPyErr_SetString(ctx, ctx->h_ValueError,
17441746
"Unable to avoid copy while creating a new array.");
1745-
return HPy_NULL;
1747+
goto fail;
17461748
}
17471749
capi_warn("np.array: PyArray_NewCopy");
17481750
PyObject *py_ret = (PyObject *) PyArray_NewCopy(oparr, order);
@@ -1768,7 +1770,7 @@ _hpy_array_fromobject_generic(
17681770
}
17691771
else if ((order == NPY_FORTRANORDER)
17701772
/* order == NPY_ANYORDER && */
1771-
|| (HPy_TypeCheck(ctx, op, HPyArray_Type) &&
1773+
|| (HPy_TypeCheck(ctx, op, array_type) &&
17721774
PyArray_ISFORTRAN(oparr))) {
17731775
flags |= NPY_ARRAY_F_CONTIGUOUS;
17741776
}
@@ -1783,6 +1785,8 @@ _hpy_array_fromobject_generic(
17831785
0, 0, flags, HPy_NULL);
17841786

17851787
finish:
1788+
HPy_Close(ctx, array_type);
1789+
17861790
if (HPy_IsNull(ret)) {
17871791
return ret;
17881792
}
@@ -1798,6 +1802,10 @@ _hpy_array_fromobject_generic(
17981802
// * steals a reference to ret
17991803
// */
18001804
// return _prepend_ones(ret, nd, ndmin, order);
1805+
1806+
fail:
1807+
HPy_Close(ctx, array_type);
1808+
return HPy_NULL;
18011809
}
18021810

18031811
#undef STRIDING_OK
@@ -4921,7 +4929,12 @@ static HPyModuleDef moduledef = {
49214929
.doc = NULL,
49224930
.size = -1,
49234931
.legacy_methods = array_module_methods,
4924-
.defines = array_module_hpy_methods
4932+
.defines = array_module_hpy_methods,
4933+
.globals = {
4934+
&HPyArrayDescr_Type,
4935+
&HPyArray_Type,
4936+
NULL
4937+
}
49254938
};
49264939

49274940
/* Initialization function for the module */
@@ -5000,7 +5013,8 @@ static HPy init__multiarray_umath_impl(HPyContext *ctx) {
50005013
// HPY TODO: storing the types to globals to support legacy code, and HPy code w/o module state
50015014
_PyArrayDescr_Type_p = (PyTypeObject*) HPy_AsPyObject(ctx, h_PyArrayDescr_Type);
50025015
PyArrayDTypeMeta_Type = (PyTypeObject*) HPy_AsPyObject(ctx, h_PyArrayDTypeMeta_Type);
5003-
HPyArrayDescr_Type = HPy_Dup(ctx, h_PyArrayDescr_Type);
5016+
5017+
HPyGlobal_Store(ctx, &HPyArrayDescr_Type, h_PyArrayDescr_Type);
50045018

50055019
HPy_Close(ctx, h_PyArrayDTypeMeta_Type);
50065020
HPy_Close(ctx, h_PyArrayDescr_Type);
@@ -5018,7 +5032,7 @@ static HPy init__multiarray_umath_impl(HPyContext *ctx) {
50185032
goto err;
50195033
}
50205034
_PyArray_Type_p = (PyTypeObject*)HPy_AsPyObject(ctx, h_array_type);
5021-
HPyArray_Type = HPy_Dup(ctx, h_array_type);
5035+
HPyGlobal_Store(ctx, &HPyArray_Type, h_array_type);
50225036
PyArray_Type.tp_weaklistoffset = offsetof(PyArrayObject_fields, weakreflist);
50235037
HPy_Close(ctx, h_array_type);
50245038

0 commit comments

Comments
 (0)