Skip to content

Commit 404a43d

Browse files
committed
Pull request #10: Port part of the np.array function
Merge in ~STEPAN.SINDELAR_ORACLE.COM/numpy-hpy from ss/array_array to labs-hpy-port * commit '5222b83f0faa5dd99b1a3c6a659940831c1873a1': HPyArray_AssignArray Add forgotten capi_warn Make PyArray_Descr memcopy work for both legacy/pure layout Add HPyType helpers generation for scalars Replace h_array_type_global with HPyArray_Type HPyArray_SetBaseObject HPyDataMem_UserNEW, HPyDataMem_UserNEW_ZEROED HPyArray_NewFromDescr_int: check PyCapsule using HPy Fully ported HPyArray_NewFromDescr_int (missing: PyArray_SetBaseObject and PyCapsule) HPyArray_NewLikeArrayWithShape Use HPy Type helpers instead of HPy_AsStruct everywhere Fix: use HPyArray_GetNDim Call new HPyArray_NewLikeArray HPyArray_NewCopy Checkpoint: np.array works Checkpoint in debugging Port np.array to HPy: args parsing Set legacy slots of PyCLongDoubleArrType, PyCDoubleArrType, PyCFloatArrType
2 parents 0e4a5a7 + 5222b83 commit 404a43d

28 files changed

+1255
-210
lines changed

numpy/core/include/numpy/ndarrayobject.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ extern "C" {
2626
#define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)
2727
#define HPyArray_DescrCheck(ctx, op) HPy_TypeCheck(ctx, op, HPyArrayDescr_Type)
2828

29+
2930
#define PyArray_Check(op) PyObject_TypeCheck(op, &PyArray_Type)
3031
#define PyArray_CheckExact(op) (((PyObject*)(op))->ob_type == &PyArray_Type)
3132
#define HPyArray_Check(ctx, op) HPy_TypeCheck(ctx, op, HPyArray_Type)
@@ -184,6 +185,13 @@ PyArray_DiscardWritebackIfCopy(PyArrayObject *arr)
184185
descr = _new_; \
185186
} while(0)
186187

188+
#define HPyArray_DESCR_REPLACE(ctx, descr) do { \
189+
HPy _new_; \
190+
_new_ = HPyArray_DescrNew(ctx, descr); \
191+
HPy_Close(ctx, descr); \
192+
descr = _new_; \
193+
} while(0)
194+
187195
/* Copy should always return contiguous array */
188196
#define PyArray_Copy(obj) PyArray_NewCopy(obj, NPY_CORDER)
189197

@@ -252,6 +260,7 @@ NPY_TITLE_KEY_check(PyObject *key, PyObject *value)
252260
#define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value)))
253261

254262
#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
263+
#define HPY_DEPRECATE(ctx, msg) HPyErr_WarnEx(ctx,ctx->h_DeprecationWarning,msg,1)
255264
#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)
256265

257266
#ifdef __cplusplus

numpy/core/include/numpy/ndarraytypes.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,15 @@ typedef struct {
613613
#define PyDataType_FLAGCHK(dtype, flag) \
614614
(((dtype)->flags & (flag)) == (flag))
615615

616+
#define HPyDataType_FLAGCHK(ctx, dtype, flag) \
617+
((PyArray_Descr_AsStruct(ctx, dtype)->flags & (flag)) == (flag))
618+
616619
#define PyDataType_REFCHK(dtype) \
617620
PyDataType_FLAGCHK(dtype, NPY_ITEM_REFCOUNT)
618621

622+
#define HPyDataType_REFCHK(ctx, dtype) \
623+
HPyDataType_FLAGCHK(ctx, dtype, NPY_ITEM_REFCOUNT)
624+
619625
typedef struct _PyArray_Descr {
620626
PyObject_HEAD
621627
/*
@@ -1584,13 +1590,19 @@ PyArray_DESCR(const PyArrayObject *arr)
15841590
}
15851591

15861592
static NPY_INLINE HPy
1587-
HPyArray_GetBase(HPyContext *ctx, HPy arr)
1593+
HPyArray_BASE(HPyContext *ctx, HPy h_arr, PyArrayObject *arr_obj)
15881594
{
1589-
HPyField f_base = HPyArray_AsFields(ctx, arr)->f_base;
1590-
if (f_base._i == 0) {
1595+
PyArrayObject_fields *arr = (PyArrayObject_fields*) arr_obj;
1596+
if (HPyField_IsNull(arr->f_base)) {
15911597
return HPy_NULL;
15921598
}
1593-
return HPyField_Load(ctx, arr, HPyArray_AsFields(ctx, arr)->f_base);
1599+
return HPyField_Load(ctx, h_arr, arr->f_base);
1600+
}
1601+
1602+
static NPY_INLINE HPy
1603+
HPyArray_GetBase(HPyContext *ctx, HPy arr)
1604+
{
1605+
return HPyArray_BASE(ctx, arr, (PyArrayObject*) HPyArray_AsFields(ctx, arr));
15941606
}
15951607

15961608
static NPY_INLINE void
@@ -1653,7 +1665,7 @@ PyArray_NDIM(const PyArrayObject *arr)
16531665
static NPY_INLINE int
16541666
HPyArray_GetNDim(HPyContext *ctx, HPy arr)
16551667
{
1656-
return ((PyArrayObject_fields *) HPy_AsStructLegacy(ctx, arr))->nd;
1668+
return ((PyArrayObject_fields *) PyArrayObject_AsStruct(ctx, arr))->nd;
16571669
}
16581670

16591671
static NPY_INLINE void *
@@ -2070,6 +2082,8 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
20702082
void *reserved[3];
20712083
} PyArray_DTypeMeta;
20722084

2085+
HPyType_LEGACY_HELPERS(PyArray_DTypeMeta);
2086+
20732087
#endif /* NPY_INTERNAL_BUILD */
20742088

20752089

numpy/core/src/common/array_assign.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ PyArray_AssignArray(PyArrayObject *dst, PyArrayObject *src,
3030
PyArrayObject *wheremask,
3131
NPY_CASTING casting);
3232

33+
34+
NPY_NO_EXPORT int
35+
HPyArray_AssignArray(HPyContext *ctx, HPy h_dst, HPy h_src,
36+
HPy h_wheremask,
37+
NPY_CASTING casting);
38+
3339
NPY_NO_EXPORT int
3440
PyArray_AssignRawScalar(PyArrayObject *dst,
3541
PyArray_Descr *src_dtype, char *src_data,

numpy/core/src/common/npy_import.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,18 @@ npy_cache_import(const char *module, const char *attr, PyObject **cache)
2929
}
3030
}
3131

32+
// HPY TODO: global cache...
33+
NPY_INLINE static void
34+
npy_hpy_cache_import(HPyContext *ctx, const char *module, const char *attr, HPy *cache)
35+
{
36+
if (NPY_UNLIKELY(HPy_IsNull(*cache))) {
37+
HPy mod = HPyImport_ImportModule(ctx, module);
38+
39+
if (HPy_IsNull(mod)) {
40+
*cache = HPy_GetAttr_s(ctx, mod, attr);
41+
HPy_Close(ctx, mod);
42+
}
43+
}
44+
}
45+
3246
#endif /* NUMPY_CORE_SRC_COMMON_NPY_IMPORT_H_ */

numpy/core/src/multiarray/abstractdtypes.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ initialize_and_map_pytypes_to_dtypes(HPyContext *ctx)
125125
HPy_Close(ctx, h_PyArray_PyIntAbstractDType);
126126
goto cleanup;
127127
}
128-
PyArray_DTypeMeta *int_abstract_dtype_data = (PyArray_DTypeMeta *) HPy_AsStructLegacy(ctx, h_PyArray_PyIntAbstractDType);
128+
PyArray_DTypeMeta *int_abstract_dtype_data = PyArray_DTypeMeta_AsStruct(ctx, h_PyArray_PyIntAbstractDType);
129129
int_abstract_dtype_data->dt_slots = &pyintabstractdtype_slots;
130130
int_abstract_dtype_data->flags = NPY_DT_ABSTRACT;
131131
int_abstract_dtype_data->scalar_type = &PyLong_Type;
@@ -137,7 +137,7 @@ initialize_and_map_pytypes_to_dtypes(HPyContext *ctx)
137137
HPy_Close(ctx, h_PyArray_PyFloatAbstractDType);
138138
goto cleanup;
139139
}
140-
PyArray_DTypeMeta *float_abstract_dtype_data = (PyArray_DTypeMeta *) HPy_AsStructLegacy(ctx, h_PyArray_PyFloatAbstractDType);
140+
PyArray_DTypeMeta *float_abstract_dtype_data = PyArray_DTypeMeta_AsStruct(ctx, h_PyArray_PyFloatAbstractDType);
141141
float_abstract_dtype_data->dt_slots = &pyfloatabstractdtype_slots;
142142
float_abstract_dtype_data->flags = NPY_DT_ABSTRACT;
143143
float_abstract_dtype_data->scalar_type = &PyFloat_Type;
@@ -149,7 +149,7 @@ initialize_and_map_pytypes_to_dtypes(HPyContext *ctx)
149149
HPy_Close(ctx, h_PyArray_PyComplexAbstractDType);
150150
goto cleanup;
151151
}
152-
PyArray_DTypeMeta *complex_abstract_dtype_data = (PyArray_DTypeMeta *) HPy_AsStructLegacy(ctx, h_PyArray_PyComplexAbstractDType);
152+
PyArray_DTypeMeta *complex_abstract_dtype_data = PyArray_DTypeMeta_AsStruct(ctx, h_PyArray_PyComplexAbstractDType);
153153
complex_abstract_dtype_data->dt_slots = &pycomplexabstractdtype_slots;
154154
complex_abstract_dtype_data->flags = NPY_DT_ABSTRACT;
155155
complex_abstract_dtype_data->scalar_type = &PyComplex_Type;

numpy/core/src/multiarray/alloc.c

Lines changed: 82 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ PyDataMem_Handler default_handler = {
407407
PyObject *PyDataMem_DefaultHandler;
408408

409409
#if (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x07030600)
410-
PyObject *current_handler;
410+
HPy current_handler;
411411
#endif
412412

413413
int uo_index=0; /* user_override index */
@@ -416,15 +416,26 @@ int uo_index=0; /* user_override index */
416416

417417
NPY_NO_EXPORT void *
418418
PyDataMem_UserNEW(size_t size, PyObject *mem_handler)
419+
{
420+
HPyContext *ctx = npy_get_context();
421+
HPy h = HPy_FromPyObject(ctx, mem_handler);
422+
void *res = HPyDataMem_UserNEW(ctx, size, h);
423+
HPy_Close(ctx, h);
424+
return res;
425+
}
426+
427+
NPY_NO_EXPORT void *
428+
HPyDataMem_UserNEW(HPyContext *ctx, size_t size, HPy mem_handler)
419429
{
420430
void *result;
421-
PyDataMem_Handler *handler = (PyDataMem_Handler *) PyCapsule_GetPointer(mem_handler, "mem_handler");
431+
PyDataMem_Handler *handler = (PyDataMem_Handler *) HPyCapsule_GetPointer(ctx, mem_handler, "mem_handler");
422432
if (handler == NULL) {
423433
return NULL;
424434
}
425435
assert(size != 0);
426436
result = handler->allocator.malloc(handler->allocator.ctx, size);
427437
if (_PyDataMem_eventhook != NULL) {
438+
capi_warn("HPyDataMem_UserNEW_ZEROED: GIL usage if _PyDataMem_eventhook is set");
428439
NPY_ALLOW_C_API_DEF
429440
NPY_ALLOW_C_API
430441
if (_PyDataMem_eventhook != NULL) {
@@ -439,14 +450,25 @@ PyDataMem_UserNEW(size_t size, PyObject *mem_handler)
439450

440451
NPY_NO_EXPORT void *
441452
PyDataMem_UserNEW_ZEROED(size_t nmemb, size_t size, PyObject *mem_handler)
453+
{
454+
HPyContext *ctx = npy_get_context();
455+
HPy h = HPy_FromPyObject(ctx, mem_handler);
456+
void *res = HPyDataMem_UserNEW_ZEROED(ctx, nmemb, size, h);
457+
HPy_Close(ctx, h);
458+
return res;
459+
}
460+
461+
NPY_NO_EXPORT void *
462+
HPyDataMem_UserNEW_ZEROED(HPyContext *ctx, size_t nmemb, size_t size, HPy mem_handler)
442463
{
443464
void *result;
444-
PyDataMem_Handler *handler = (PyDataMem_Handler *) PyCapsule_GetPointer(mem_handler, "mem_handler");
465+
PyDataMem_Handler *handler = (PyDataMem_Handler *) HPyCapsule_GetPointer(ctx, mem_handler, "mem_handler");
445466
if (handler == NULL) {
446467
return NULL;
447468
}
448469
result = handler->allocator.calloc(handler->allocator.ctx, nmemb, size);
449470
if (_PyDataMem_eventhook != NULL) {
471+
capi_warn("HPyDataMem_UserNEW_ZEROED: GIL usage if _PyDataMem_eventhook is set");
450472
NPY_ALLOW_C_API_DEF
451473
NPY_ALLOW_C_API
452474
if (_PyDataMem_eventhook != NULL) {
@@ -519,77 +541,76 @@ PyDataMem_UserRENEW(void *ptr, size_t size, PyObject *mem_handler)
519541
NPY_NO_EXPORT PyObject *
520542
PyDataMem_SetHandler(PyObject *handler)
521543
{
522-
PyObject *old_handler;
523-
#if (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x07030600)
524-
PyObject *token;
525-
if (PyContextVar_Get(current_handler, NULL, &old_handler)) {
526-
return NULL;
527-
}
528-
if (handler == NULL) {
529-
handler = PyDataMem_DefaultHandler;
530-
}
531-
token = PyContextVar_Set(current_handler, handler);
532-
if (token == NULL) {
533-
Py_DECREF(old_handler);
534-
return NULL;
535-
}
536-
Py_DECREF(token);
537-
return old_handler;
538-
#else
539-
PyObject *p;
540-
p = PyThreadState_GetDict();
541-
if (p == NULL) {
542-
return NULL;
543-
}
544-
old_handler = PyDict_GetItemString(p, "current_allocator");
545-
if (old_handler == NULL) {
546-
old_handler = PyDataMem_DefaultHandler
547-
}
548-
Py_INCREF(old_handler);
549-
if (handler == NULL) {
550-
handler = PyDataMem_DefaultHandler;
551-
}
552-
const int error = PyDict_SetItemString(p, "current_allocator", handler);
553-
if (error) {
554-
Py_DECREF(old_handler);
555-
return NULL;
556-
}
557-
return old_handler;
558-
#endif
544+
hpy_abort_not_implemented("PyDataMem_SetHandler");
545+
// PyObject *old_handler;
546+
// #if (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x07030600)
547+
// PyObject *token;
548+
// if (PyContextVar_Get(current_handler, NULL, &old_handler)) {
549+
// return NULL;
550+
// }
551+
// if (handler == NULL) {
552+
// handler = PyDataMem_DefaultHandler;
553+
// }
554+
// token = PyContextVar_Set(current_handler, handler);
555+
// if (token == NULL) {
556+
// Py_DECREF(old_handler);
557+
// return NULL;
558+
// }
559+
// Py_DECREF(token);
560+
// return old_handler;
561+
// #else
562+
// PyObject *p;
563+
// p = PyThreadState_GetDict();
564+
// if (p == NULL) {
565+
// return NULL;
566+
// }
567+
// old_handler = PyDict_GetItemString(p, "current_allocator");
568+
// if (old_handler == NULL) {
569+
// old_handler = PyDataMem_DefaultHandler
570+
// }
571+
// Py_INCREF(old_handler);
572+
// if (handler == NULL) {
573+
// handler = PyDataMem_DefaultHandler;
574+
// }
575+
// const int error = PyDict_SetItemString(p, "current_allocator", handler);
576+
// if (error) {
577+
// Py_DECREF(old_handler);
578+
// return NULL;
579+
// }
580+
// return old_handler;
581+
// #endif
559582
}
560583

561-
/*NUMPY_API
584+
/*
562585
* Return the policy that will be used to allocate data
563586
* for the next PyArrayObject. On failure, return NULL.
564587
*/
565-
NPY_NO_EXPORT PyObject *
566-
PyDataMem_GetHandler()
588+
NPY_NO_EXPORT HPy
589+
HPyDataMem_GetHandler(HPyContext *ctx)
567590
{
568-
PyObject *handler;
591+
HPy handler;
569592
#if (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x07030600)
570-
if (PyContextVar_Get(current_handler, NULL, &handler)) {
571-
return NULL;
593+
if (HPyContextVar_Get(ctx, current_handler, HPy_NULL, &handler)) {
594+
return HPy_NULL;
572595
}
573596
return handler;
574597
#else
575-
PyObject *p = PyThreadState_GetDict();
576-
if (p == NULL) {
577-
return NULL;
578-
}
579-
handler = PyDict_GetItemString(p, "current_allocator");
580-
if (handler == NULL) {
581-
handler = PyCapsule_New(&default_handler, "mem_handler", NULL);
582-
if (handler == NULL) {
583-
return NULL;
584-
}
585-
}
586-
else {
587-
Py_INCREF(handler);
588-
}
589-
return handler;
598+
hpy_abort_not_implemented("HPyDataMem_GetHandler on older Pypy versions");
590599
#endif
591600
}
592601

602+
/*NUMPY_API
603+
*/
604+
NPY_NO_EXPORT PyObject *
605+
PyDataMem_GetHandler()
606+
{
607+
HPyContext *ctx = npy_get_context();
608+
HPy h = HPyDataMem_GetHandler(ctx);
609+
PyObject *res = HPy_AsPyObject(ctx, h);
610+
HPy_Close(ctx, h);
611+
return res;
612+
}
613+
593614
NPY_NO_EXPORT PyObject *
594615
get_handler_name(PyObject *NPY_UNUSED(self), PyObject *args)
595616
{

numpy/core/src/multiarray/alloc.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ PyDataMem_UserNEW(npy_uintp sz, PyObject *mem_handler);
1616
NPY_NO_EXPORT void *
1717
PyDataMem_UserNEW_ZEROED(size_t nmemb, size_t size, PyObject *mem_handler);
1818

19+
NPY_NO_EXPORT void *
20+
HPyDataMem_UserNEW(HPyContext *ctx, size_t size, HPy mem_handler);
21+
22+
NPY_NO_EXPORT void *
23+
HPyDataMem_UserNEW_ZEROED(HPyContext *ctx, size_t nmemb, size_t size, HPy mem_handler);
24+
1925
NPY_NO_EXPORT void
2026
PyDataMem_UserFREE(void * p, npy_uintp sd, PyObject *mem_handler);
2127

@@ -42,12 +48,15 @@ npy_free_cache_dim_array(PyArrayObject * arr)
4248

4349
extern PyDataMem_Handler default_handler;
4450
#if (!defined(PYPY_VERSION_NUM) || PYPY_VERSION_NUM >= 0x07030600)
45-
extern PyObject *current_handler; /* PyContextVar/PyCapsule */
51+
extern HPy current_handler; /* PyContextVar/PyCapsule */
4652
#endif
4753

4854
NPY_NO_EXPORT PyObject *
4955
get_handler_name(PyObject *NPY_UNUSED(self), PyObject *obj);
5056
NPY_NO_EXPORT PyObject *
5157
get_handler_version(PyObject *NPY_UNUSED(self), PyObject *obj);
5258

59+
NPY_NO_EXPORT HPy
60+
HPyDataMem_GetHandler(HPyContext *ctx);
61+
5362
#endif /* NUMPY_CORE_SRC_MULTIARRAY_ALLOC_H_ */

0 commit comments

Comments
 (0)