Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

GH-29021: Convert umath_linalg to multi-phase init (PEP 489)#29030

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
AA-Turner wants to merge1 commit intonumpy:main
base:main
Choose a base branch
Loading
fromAA-Turner:multi-phase/umath_linalg
Open
Changes fromall commits
Commits
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
Convert umath_linalg to multi-phase init (PEP 489)
  • Loading branch information
@AA-Turner
AA-Turner committedMay 22, 2025
commit6876e2461a19a8282f439d0e57b4724b00893a3d
63 changes: 33 additions & 30 deletionsnumpy/linalg/umath_linalg.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4688,57 +4688,40 @@ static PyMethodDef UMath_LinAlgMethods[] = {
{NULL,NULL,0,NULL}/* Sentinel */
};

staticstructPyModuleDefmoduledef= {
PyModuleDef_HEAD_INIT,
UMATH_LINALG_MODULE_NAME,
NULL,
-1,
UMath_LinAlgMethods,
NULL,
NULL,
NULL,
NULL
};

PyMODINIT_FUNCPyInit__umath_linalg(void)
staticint
_umath_linalg_exec(PyObject*m)
{
PyObject*m;
PyObject*d;
PyObject*version;

m=PyModule_Create(&moduledef);
if (m==NULL) {
returnNULL;
}

import_array();
import_ufunc();
import_array1(-1);
import_umath1(-1);

d=PyModule_GetDict(m);
if (d==NULL) {
returnNULL;
return-1;
}

version=PyUnicode_FromString(umath_linalg_version_string);
if (version==NULL) {
returnNULL;
return-1;
}
intret=PyDict_SetItemString(d,"__version__",version);
Py_DECREF(version);
if (ret<0) {
returnNULL;
return-1;
}

/* Load the ufunc operators into the module's namespace */
if (addUfuncs(d)<0) {
returnNULL;
return-1;
}

#ifPY_VERSION_HEX<0x30d00b3&& !HAVE_EXTERNAL_LAPACK
lapack_lite_lock=PyThread_allocate_lock();
if (lapack_lite_lock==NULL) {
PyErr_NoMemory();
returnNULL;
return-1;
}
#endif

Expand All@@ -4748,10 +4731,30 @@ PyMODINIT_FUNC PyInit__umath_linalg(void)
PyDict_SetItemString(d,"_ilp64",Py_False);
#endif

#ifPy_GIL_DISABLED
// signal this module supports running with the GIL disabled
PyUnstable_Module_SetGIL(m,Py_MOD_GIL_NOT_USED);
return0;
}

staticstructPyModuleDef_Slot_umath_linalg_slots[]= {
{Py_mod_exec, (void*)_umath_linalg_exec},
#ifPY_VERSION_HEX >=0x030c00f0// Python 3.12+
{Py_mod_multiple_interpreters,Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED},
#endif
#ifPY_VERSION_HEX >=0x030d00f0// Python 3.13+
// signal that this module supports running without an active GIL
{Py_mod_gil,Py_MOD_GIL_NOT_USED},
#endif
{0,NULL},
};

staticstructPyModuleDefmoduledef= {
PyModuleDef_HEAD_INIT,/* m_base */
"_umath_linalg",/* m_name */
NULL,/* m_doc */
0,/* m_size */
Copy link
Member

Choose a reason for hiding this comment

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

For now, in a future PR this can be changed.

Suggested change
0,/* m_size*/
-1,/* m_size*/

Copy link
Author

Choose a reason for hiding this comment

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

See also my note in#29025 (comment). Briefly, I was mistaken in my understanding of the documentation,-1 is only valid for single-phase initialisation, and is forbidden for multi-phase.

The safest thing reinitialisation-wise would be to use themultiple interpreter opt-out suggested by CPython. This would enforce that each extension module is only imported & initialised once per process.

However, this causestest_reloading.py::test_full_reimport() to fail. Is that an acceptable trade-off? Multi-phase init (and at some point, isolated modules) opens the door to proper support for reloading/reimportingnumpy.

cc@encukou re the best way to do a gradual migration to multi-phase

In the case ofumath_linalg, we might be fine globals-wise, butmultiarray will definitely need a solution here.

Choose a reason for hiding this comment

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

I'vejust updated the HOWTO, seehere before it gets to main docs.

Basically, to allow re-import, clear the "loaded" flag inPyModuleDef'sm_clear. Note that thiswill do an actual reload of the module (sans C globals), that is,exec will run. (With single-phase, the module dict contents are stashed away and reused. You could emulatethat, but )

The PyMutex stuff in the updated HOWTO is 3.13+ non-limited API, but isn't necessary in the medium term (on CPython you're protected by the GIL; even free-threading builds use an import lock which isn't likely to go away). For the long-term (or alternate CAPI implementations) you could add no-op shims.

ThePy_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED flag will only allow loading in the main interpreter; that's redundant if you're limited to one module per process.

Copy link
Member

Choose a reason for hiding this comment

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

However, this causes test_reloading.py::test_full_reimport() to fail. Is that an acceptable trade-off?

I am not opposed to breaking the test/changing the behavior. The ask would be to summarize how things change for:

  • Potentialsubinterpreter users (Ithink that just doesn't work at all anymore, but not sure).
  • Users forimportlib.reload(), currently they get a warning that this is a bad idea. A full-blown error may not be so bad, though.

UMath_LinAlgMethods,/* m_methods */
_umath_linalg_slots,/* m_slots */
};

returnm;
PyMODINIT_FUNCPyInit__umath_linalg(void) {
returnPyModuleDef_Init(&moduledef);
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp