Skip to content

Instantly share code, notes, and snippets.

@rgommers
Created July 17, 2024 19:54
Show Gist options
  • Save rgommers/7c722bfd79c48753900d86668884faf6 to your computer and use it in GitHub Desktop.
Save rgommers/7c722bfd79c48753900d86668884faf6 to your computer and use it in GitHub Desktop.
f2py snippet for a LAPACK function with a callback
/******************* See f2py2e/cb_rules.py: buildcallback *******************/
/********************* cb_cselect_in_gees__user__routines *********************/
typedef struct {
PyObject *capi;
PyTupleObject *args_capi;
int nofargs;
jmp_buf jmpbuf;
} cb_cselect_in_gees__user__routines_t;
#if defined(F2PY_THREAD_LOCAL_DECL) && !defined(F2PY_USE_PYTHON_TLS)
static F2PY_THREAD_LOCAL_DECL cb_cselect_in_gees__user__routines_t *_active_cb_cselect_in_gees__user__routines = NULL;
static cb_cselect_in_gees__user__routines_t *swap_active_cb_cselect_in_gees__user__routines(cb_cselect_in_gees__user__routines_t *ptr) {
cb_cselect_in_gees__user__routines_t *prev = _active_cb_cselect_in_gees__user__routines;
_active_cb_cselect_in_gees__user__routines = ptr;
return prev;
}
static cb_cselect_in_gees__user__routines_t *get_active_cb_cselect_in_gees__user__routines(void) {
return _active_cb_cselect_in_gees__user__routines;
}
#else
static cb_cselect_in_gees__user__routines_t *swap_active_cb_cselect_in_gees__user__routines(cb_cselect_in_gees__user__routines_t *ptr) {
char *key = "__f2py_cb_cb_cselect_in_gees__user__routines";
return (cb_cselect_in_gees__user__routines_t *)F2PySwapThreadLocalCallbackPtr(key, ptr);
}
static cb_cselect_in_gees__user__routines_t *get_active_cb_cselect_in_gees__user__routines(void) {
char *key = "__f2py_cb_cb_cselect_in_gees__user__routines";
return (cb_cselect_in_gees__user__routines_t *)F2PyGetThreadLocalCallbackPtr(key);
}
#endif
@rgommers
Copy link
Author

Also the error handling may need to be looked at more closely, since it uses a global

static PyObject *_flapack_error;

which is modified from within functions.

@ngoldbaum
Copy link

The static pyobjects are fine since they refer to global objects that are read-only after module initialization.

@ngoldbaum
Copy link

ngoldbaum commented Jul 17, 2024

F2PySwapThreadLocalCallbackPtr uses the PyThreadState C API to implement thread-local state if it can't do it using the low-level thread local C declaration modifier.

The actual definition of F2PY_THREAD_LOCAL_DECL seems reasonable. We also check for _Thread_local in NumPy but I doubt it matters much for this use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment