8000 MNT: Reorganize non-constant global statics into structs by ngoldbaum · Pull Request #26607 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

MNT: Reorganize non-constant global statics into structs #26607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
baee891
MNT: move interned strings into a single global struct
ngoldbaum May 30, 2024
69075c1
MNT: move cached imports into a global struct
ngoldbaum May 21, 2024
e5c1bd6
MNT: move cpu dispatch registry into global data struct
ngoldbaum May 30, 2024
7719cf2
MNT: move ndarray.__array_*__ references to global data struct
ngoldbaum May 30, 2024
3cbb68d
MNT: move sys.flags.optimize cache to global data struct
ngoldbaum May 30, 2024
2ffcc71
MNT: set up tuple for truediv in global data struct
ngoldbaum May 30, 2024
d2ca21b
MNT: move unpack_bits LUT into global static struct
ngoldbaum May 30, 2024
a1f7200
MNT: move references to int(1) and int(0) to global static struct
ngoldbaum May 30, 2024
26c243d
MNT: move initialization of global ArrayMethods to module initialization
ngoldbaum May 30, 2024
536e5fb
MNT: move initialization of global tuples to global data struct
ngoldbaum May 30, 2024
0c22126
8000 MNT: move default extobj contextvar to global data dict
ngoldbaum May 30, 2024
90b1f38
MNT: move PyArray_SetStringFunction internals into global data struct
ngoldbaum May 30, 2024
6a296c4
BUG: remove questionable static initialization of an array object
ngoldbaum May 30, 2024
398f095
MNT: split global data struct into two structs
ngoldbaum Jun 3, 2024
8f84875
MNT: add PyArrayMethodObject caches to static data struct
ngoldbaum Jun 5, 2024
402a83c
MNT: move some thread-unsafe state in thread-unsafe state struct
ngoldbaum Jun 5, 2024
e43275a
MNT: make data structs static instead of heap-allocated
ngoldbaum Jun 5, 2024
b706536
MNT: apply sebastian's refactoring suggestions
ngoldbaum Jun 6, 2024
c237038
MNT: move static data structs into their own file
ngoldbaum Jun 7, 2024
98ae65d
MNT: Add more global state I missed to the thread_unsafe_state struct
ngoldbaum Jun 7, 2024
a334ddc
MNT: verify all entries in npy_interned_str and npy_static_pydata are…
ngoldbaum Jun 11, 2024
9ed317f
Apply suggestions from code review
ngoldbaum Jun 13, 2024
3ae66b1
MAINT: apply more of Sebastian's suggestions
ngoldbaum Jun 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
MNT: move interned strings into a single global struct
  • Loading branch information
ngoldbaum committed Jun 19, 2024
commit baee89118b90c676b2bcb1ad26a9a81035ebe63d
4 changes: 2 additions & 2 deletions numpy/_core/src/multiarray/array_converter.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ static int
pyscalar_mode_conv(PyObject *obj, scalar_policy *policy)
{
PyObject *strings[3] = {
npy_ma_str_convert, npy_ma_str_preserve,
npy_ma_str_convert_if_no_array};
npy_ma_str->convert, npy_ma_str->preserve,
npy_ma_str->convert_if_no_array};

/* First quick pass using the identity (should practically always match) */
for (int i = 0; i < 3; i++) {
Expand Down
8 changes: 4 additions & 4 deletions numpy/_core/src/multiarray/arrayfunction_override.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ get_array_function(PyObject *obj)
return ndarray_array_function;
}

PyObject *array_f 10000 unction = PyArray_LookupSpecial(obj, npy_ma_str_array_function);
PyObject *array_function = PyArray_LookupSpecial(obj, npy_ma_str->array_function);
if (array_function == NULL && PyErr_Occurred()) {
PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */
}
Expand Down Expand Up @@ -175,7 +175,7 @@ array_function_method_impl(PyObject *func, PyObject *types, PyObject *args,
}
}

PyObject *implementation = PyObject_GetAttr(func, npy_ma_str_implementation);
PyObject *implementation = PyObject_GetAttr(func, npy_ma_str->implementation);
if (implementation == NULL) {
return NULL;
}
Expand Down Expand Up @@ -321,12 +321,12 @@ array_implement_c_array_function_creation(
}

/* The like argument must be present in the keyword arguments, remove it */
if (PyDict_DelItem(kwargs, npy_ma_str_like) < 0) {
if (PyDict_DelItem(kwargs, npy_ma_str->like) < 0) {
goto finish;
}

/* Fetch the actual symbol (the long way right now) */
numpy_module = PyImport_Import(npy_ma_str_numpy);
numpy_module = PyImport_Import(npy_ma_str->numpy);
if (numpy_module == NULL) {
goto finish;
}
Expand Down
4 changes: 2 additions & 2 deletions numpy/_core/src/multiarray/arraywrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ npy_find_array_wrap(
}
}
else {
PyObject *new_wrap = PyArray_LookupSpecial_OnInstance(obj, npy_ma_str_array_wrap);
PyObject *new_wrap = PyArray_LookupSpecial_OnInstance(obj, npy_ma_str->array_wrap);
if (new_wrap == NULL) {
if (PyErr_Occurred()) {
goto fail;
Expand Down Expand Up @@ -160,7 +160,7 @@ npy_apply_wrap(
else {
/* Replace passed wrap/wrap_type (borrowed refs) with new_wrap/type. */
new_wrap = PyArray_LookupSpecial_OnInstance(
original_out, npy_ma_str_array_wrap);
original_out, npy_ma_str->array_wrap);
if (new_wrap != NULL) {
wrap = new_wrap;
wrap_type = (PyObject *)Py_TYPE(original_out);
Expand Down
2 changes: 1 addition & 1 deletion numpy/_core/src/multiarray/conversion_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1440,7 +1440,7 @@ PyArray_DeviceConverterOptional(PyObject *object, NPY_DEVICE *device)
}

if (PyUnicode_Check(object) &&
PyUnicode_Compare(object, npy_ma_str_cpu) == 0) {
PyUnicode_Compare(object, npy_ma_str->cpu) == 0) {
*device = NPY_DEVICE_CPU;
return NPY_SUCCEED;
}
Expand Down
10 changes: 5 additions & 5 deletions numpy/_core/src/multiarray/ctors.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ PyArray_NewFromDescr_int(
ndarray_array_finalize = PyObject_GetAttr(
(PyObject *)&PyArray_Type, npy_ma_str_array_finalize);
}
func = PyObject_GetAttr((PyObject *)subtype, npy_ma_str_array_finalize);
func = PyObject_GetAttr((PyObject *)subtype, npy_ma_str->array_finalize);
if (func == NULL) {
goto fail;
}
Expand Down Expand Up @@ -2045,7 +2045,7 @@ PyArray_FromStructInterface(PyObject *input)
PyObject *attr;
char endian = NPY_NATBYTE;

attr = PyArray_LookupSpecial_OnInstance(input, npy_ma_str_array_struct);
attr = PyArray_LookupSpecial_OnInstance(input, npy_ma_str->array_struct);
if (attr == NULL) {
if (PyErr_Occurred()) {
return NULL;
Expand Down Expand Up @@ -2169,7 +2169,7 @@ PyArray_FromInterface(PyObject *origin)
npy_intp dims[NPY_MAXDIMS], strides[NPY_MAXDIMS];
int dataflags = NPY_ARRAY_BEHAVED;

iface = PyArray_LookupSpecial_OnInstance(origin, npy_ma_str_array_interface);
iface = PyArray_LookupSpecial_OnInstance(origin, npy_ma_str->array_interface);

if (iface == NULL) {
if (PyErr_Occurred()) {
Expand Down Expand Up @@ -2472,7 +2472,7 @@ check_or_clear_and_warn_error_if_due_to_copy_kwarg(PyObject *kwnames)
goto restore_error;
}
int copy_kwarg_unsupported = PyUnicode_Contains(
str_value, npy_ma_str_array_err_msg_substr);
str_value, npy_ma_str->array_err_msg_substr);
Py_DECREF(str_value);
if (copy_kwarg_unsupported == -1) {
goto restore_error;
Expand Down Expand Up @@ -2524,7 +2524,7 @@ PyArray_FromArrayAttr_int(PyObject *op, PyArray_Descr *descr, int copy,
PyObject *new;
PyObject *array_meth;

array_meth = PyArray_LookupSpecial_OnInstance(op, npy_ma_str_array);
array_meth = PyArray_LookupSpecial_OnInstance(op, npy_ma_str->array);
if (array_meth == NULL) {
if (PyErr_Occurred()) {
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion numpy/_core/src/multiarray/descriptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2717,7 +2717,7 @@ arraydescr_reduce(PyArray_Descr *self, PyObject *NPY_UNUSED(args))
Py_DECREF(ret);
return NULL;
}
obj = PyObject_GetAttr(mod, npy_ma_str_dtype);
obj = PyObject_GetAttr(mod, npy_ma_str->dtype);
Py_DECREF(mod);
if (obj == NULL) {
Py_DECREF(ret);
Expand Down
4 changes: 2 additions & 2 deletions numpy/_core/src/multiarray/dlpack.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ from_dlpack(PyObject *NPY_UNUSED(self),


PyObject *capsule = PyObject_VectorcallMethod(
npy_ma_str___dlpack__, call_args, nargsf, call_kwnames);
npy_ma_str->__dlpack__, call_args, nargsf, call_kwnames);
if (capsule == NULL) {
/*
* TODO: This path should be deprecated in NumPy 2.1. Once deprecated
Expand All @@ -563,7 +563,7 @@ from_dlpack(PyObject *NPY_UNUSED(self),
/* max_version may be unsupported, try without kwargs */
PyErr_Clear();
capsule = PyObject_VectorcallMethod(
npy_ma_str___dlpack__, call_args, nargsf, NULL);
npy_ma_str->__dlpack__, call_args, nargsf, NULL);
}
if (capsule == NULL) {
return NULL;
Expand Down
4 changes: 2 additions & 2 deletions numpy/_core/src/multiarray/item_selection.c
Original file line number Diff line number Diff line change
Expand Up @@ -2262,10 +2262,10 @@ PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int axis2)
}

/* Handle negative axes with standard Python indexing rules */
if (check_and_adjust_axis_msg(&axis1, ndim, npy_ma_str_axis1) < 0) {
if (check_and_adjust_axis_msg(&axis1, ndim, npy_ma_str->axis1) < 0) {
return NULL;
}
if (check_and_adjust_axis_msg(&axis2, ndim, npy_ma_str_axis2) < 0) {
if (check_and_adjust_axis_msg(&axis2, ndim, npy_ma_str->axis2) < 0) {
return NULL;
}
if (axis1 == axis2) {
Expand Down
2 changes: 1 addition & 1 deletion numpy/_core/src/multiarray/methods.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ any_array_ufunc_overrides(PyObject *args, PyObject *kwds)
}
Py_DECREF(out_kwd_obj);
/* check where if it exists */
where_obj = PyDict_GetItemWithError(kwds, npy_ma_str_where);
where_obj = PyDict_GetItemWithError(kwds, npy_ma_str->where);
if (where_obj == NULL) {
if (PyErr_Occurred()) {
return -1;
Expand Down
117 changes: 52 additions & 65 deletions numpy/_core/src/multiarray/multiarraymodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ PyArray_GetPriority(PyObject *obj, double default_)
return NPY_SCALAR_PRIORITY;
}

ret = PyArray_LookupSpecial_OnInstance(obj, npy_ma_str_array_priority);
ret = PyArray_LookupSpecial_OnInstance(obj, npy_ma_str->array_priority);
if (ret == NULL) {
if (PyErr_Occurred()) {
/* TODO[gh-14801]: propagate crashes during attribute access? */
Expand Down Expand Up @@ -3493,7 +3493,7 @@ array_can_cast_safely(PyObject *NPY_UNUSED(self),
* weak-promotion branch is in practice identical to dtype one.
*/
if (get_npy_promotion_state() == NPY_USE_WEAK_PROMOTION) {
PyObject *descr = PyObject_GetAttr(from_obj, npy_ma_str_dtype);
PyObject *descr = PyObject_GetAttr(from_obj, npy_ma_str->dtype);
if (descr == NULL) {
goto finish;
}
Expand Down Expand Up @@ -4771,115 +4771,102 @@ set_flaginfo(PyObject *d)
return;
}

NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_current_allocator = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_function = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_struct = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_interface = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_priority = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_wrap = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_finalize = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_implementation = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_axis1 = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_axis2 = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_like = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_numpy = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_where = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_convert = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_preserve = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_convert_if_no_array = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_cpu = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_dtype = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_err_msg_substr = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str___dlpack__ = NULL;
NPY_VISIBILITY_HIDDEN npy_ma_str_struct *npy_ma_str = NULL;

static int
intern_strings(void)
{
npy_ma_str_current_allocator = PyUnicode_InternFromString("current_allocator");
if (npy_ma_str_current_allocator == NULL) {
// this is module-level global heap allocation, it is currently
// never freed
npy_ma_str = PyMem_Calloc(sizeof(npy_ma_str_struct), 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this (and the others like it) check that it is not called twice?

npy_ma_str->current_allocator = PyUnicode_InternFromString("current_allocator");
if (npy_ma_str->current_allocator == NULL) {
return -1;
}
npy_ma_str_array = PyUnicode_InternFromString("__array__");
if (npy_ma_str_array == NULL) {
npy_ma_str->array = PyUnicode_InternFromString("__array__");
if (npy_ma_str->array == NULL) {
return -1;
}
npy_ma_str_array_function = PyUnicode_InternFromString("__array_function__");
if (npy_ma_str_array_function == NULL) {
npy_ma_str->array_function = PyUnicode_InternFromString("__array_function__");
if (npy_ma_str->array_function == NULL) {
return -1;
}
npy_ma_str_array_struct = PyUnicode_InternFromString("__array_struct__");
if (npy_ma_str_array_struct == NULL) {
npy_ma_str->array_struct = PyUnicode_InternFromString("__array_struct__");
if (npy_ma_str->array_struct == NULL) {
return -1;
}
npy_ma_str_array_priority = PyUnicode_InternFromString("__array_priority__");
if (npy_ma_str_array_priority == NULL) {
npy_ma_str->array_priority = PyUnicode_InternFromString("__array_priority__");
if (npy_ma_str->array_priority == NULL) {
return -1;
}
npy_ma_str_array_interface = PyUnicode_InternFromString("__array_interface__");
if (npy_ma_str_array_interface == NULL) {
npy_ma_str->array_interface = PyUnicode_InternFromString("__array_interface__");
if (npy_ma_str->array_interface == NULL) {
return -1;
}
npy_ma_str_array_wrap = PyUnicode_InternFromString("__array_wrap__");
if (npy_ma_str_array_wrap == NULL) {
npy_ma_str->array_wrap = PyUnicode_InternFromString("__array_wrap__");
if (npy_ma_str->array_wrap == NULL) {
return -1;
}
npy_ma_str_array_finalize = PyUnicode_InternFromString("__array_finalize__");
if (npy_ma_str_array_finalize == NULL) {
npy_ma_str->array_finalize = PyUnicode_InternFromString("__array_finalize__");
if (npy_ma_str->array_finalize == NULL) {
return -1;
}
npy_ma_str_implementation = PyUnicode_InternFromString("_implementation");
if (npy_ma_str_implementation == NULL) {
npy_ma_str->implementation = PyUnicode_InternFromString("_implementation");
if (npy_ma_str->implementation == NULL) {
return -1;
}
npy_ma_str_axis1 = PyUnicode_InternFromString("axis1");
if (npy_ma_str_axis1 == NULL) {
npy_ma_str->axis1 = PyUnicode_InternFromString("axis1");
if (npy_ma_str->axis1 == NULL) {
return -1;
}
npy_ma_str_axis2 = PyUnicode_InternFromString("axis2");
if (npy_ma_str_axis2 == NULL) {
npy_ma_str->axis2 = PyUnicode_InternFromString("axis2");
if (npy_ma_str->axis2 == NULL) {
return -1;
}
npy_ma_str_like = PyUnicode_InternFromString("like");
if (npy_ma_str_like == NULL) {
npy_ma_str->like = PyUnicode_InternFromString("like");
if (npy_ma_str->like == NULL) {
return -1;
}
npy_ma_str_numpy = PyUnicode_InternFromString("numpy");
if (npy_ma_str_numpy == NULL) {
npy_ma_str->numpy = PyUnicode_InternFromString("numpy");
if (npy_ma_str->numpy == NULL) {
return -1;
}
npy_ma_str_where = PyUnicode_InternFromString("where");
if (npy_ma_str_where == NULL) {
npy_ma_str->where = PyUnicode_InternFromString("where");
if (npy_ma_str->where == NULL) {
return -1;
}
/* scalar policies */
npy_ma_str_convert = PyUnicode_InternFromString("convert");
if (npy_ma_str_convert == NULL) {
npy_ma_str->convert = PyUnicode_InternFromString("convert");
if (npy_ma_str->convert == NULL) {
return -1;
}
npy_ma_str_preserve = PyUnicode_InternFromString("preserve");
if (npy_ma_str_preserve == NULL) {
npy_ma_str->preserve = PyUnicode_InternFromString("preserve");
if (npy_ma_str->preserve == NULL) {
return -1;
}
npy_ma_str_convert_if_no_array = PyUnicode_InternFromString("convert_if_no_array");
if (npy_ma_str_convert_if_no_array == NULL) {
npy_ma_str->convert_if_no_array = PyUnicode_InternFromString("convert_if_no_array");
if (npy_ma_str->convert_if_no_array == NULL) {
return -1;
}
npy_ma_str_cpu = PyUnicode_InternFromString("cpu");
if (npy_ma_str_cpu == NULL) {
npy_ma_str->cpu = PyUnicode_InternFromString("cpu");
if (npy_ma_str->cpu == NULL) {
return -1;
}
npy_ma_str_dtype = PyUnicode_InternFromString("dtype");
if (npy_ma_str_dtype == NULL) {
npy_ma_str->dtype = PyUnicode_InternFromString("dtype");
if (npy_ma_str->dtype == NULL) {
return -1;
}
npy_ma_str_array_err_msg_substr = PyUnicode_InternFromString(
npy_ma_str->array_err_msg_substr = PyUnicode_InternFromString(
"__array__() got an unexpected keyword argument 'copy'");
if (npy_ma_str_array_err_msg_substr == NULL) {
if (npy_ma_str->array_err_msg_substr == NULL) {
return -1;
}
npy_ma_str___dlpack__ = PyUnicode_InternFromString("__dlpack__");
if (npy_ma_str___dlpack__ == NULL) {
npy_ma_str->out = PyUnicode_InternFromString("out");
if (npy_ma_str->out == NULL) {
return -1;
}
npy_ma_str->__dlpack__ = PyUnicode_InternFromString("__dlpack__");
if (npy_ma_str->__dlpack__ == NULL) {
return -1;
}
return 0;
Expand Down
Loading
0