Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ on:
- ".github/ISSUE_TEMPLATE/**"

pull_request:
branches: [main]
paths-ignore:
- "*.md"
- "docs/**"
Expand All @@ -33,7 +32,7 @@ jobs:

defaults:
run:
shell: bash -l {0}
shell: bash -el {0}

steps:
- name: Checkout repository
Expand Down Expand Up @@ -65,7 +64,7 @@ jobs:

defaults:
run:
shell: bash -l {0}
shell: bash -el {0}

steps:
- name: Checkout repository
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# scikit-SUNDAE Changelog

## [v1.1.1](https://github.com/NREL/scikit-sundae/tree/v1.1.1)

### Bug Fixes
- Ensures exception propagations work correctly with numpy 2.4 releases ([#43](https://github.com/NREL/scikit-sundae/pull/43))

## [v1.1.0](https://github.com/NREL/scikit-sundae/tree/v1.1.0)

### New Features
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ dynamic = ["version"]
requires-python = ">=3.10,<3.15"
license = "BSD-3-Clause"
license-files = ["LICENSE*"]
description = "Python bindings to SUNDIALS differential aglebraic equation solvers."
description = "Python bindings to SUNDIALS differential algebraic equation solvers."
keywords = ["sundials", "dae", "ode", "integrator", "ivp", "cvode", "ida"]
authors = [
{ name = "Corey R. Randall" },
Expand Down
2 changes: 1 addition & 1 deletion src/sksundae/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@

__all__ = ['ida', 'utils', 'cvode', 'jacband', 'SUNDIALS_VERSION']

__version__ = '1.1.0'
__version__ = '1.1.1'
2 changes: 1 addition & 1 deletion src/sksundae/_cy_common.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ elif SUNDIALS_INT_TYPE == "long int":

cdef svec2np(N_Vector nvec, np.ndarray[DTYPE_t, ndim=1] np_array):
"""Fill a numpy array with values from an N_Vector."""
cdef sunrealtype* nvec_ptr
cdef sunrealtype* nv_ptr

nv_ptr = N_VGetArrayPointer(nvec)
ptr2np(nv_ptr, np_array)
Expand Down
38 changes: 30 additions & 8 deletions src/sksundae/_cy_cvode.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ cimport numpy as np

from scipy import sparse as sp
from scipy.optimize._numdiff import group_columns
from cpython.exc cimport PyErr_CheckSignals, PyErr_Occurred
from cpython.exc cimport (
PyErr_Fetch, PyErr_NormalizeException,
PyObject, PyErr_CheckSignals, PyErr_Occurred, # PyErr_GetRaisedException,
)

# PyErr_Fetch and PyErr_NormalizeException are deprecated at 3.12. When support
# for <3.12 is dropped, replace with PyErr_GetRaisedException.

# Extern cdef headers
from .c_cvode cimport *
Expand Down Expand Up @@ -235,8 +241,18 @@ cdef void _err_handler(int line, const char* func, const char* file,
const char* msg, int err_code, void* err_user_data,
SUNContext ctx) except *:
"""Custom error handler for shorter messages (no line or file)."""

if not PyErr_Occurred():
cdef PyObject *errtype, *errvalue, *errtraceback

if PyErr_Occurred():
aux = <AuxData> err_user_data
# aux.pyerr = <object> PyErr_GetRaisedException()

PyErr_Fetch(&errtype, &errvalue, &errtraceback)
PyErr_NormalizeException(&errtype, &errvalue, &errtraceback)

aux.pyerr = <object> errvalue

else:
decoded_func = func.decode("utf-8")
decoded_msg = msg.decode("utf-8").replace(", ,", ",").strip()
print(f"\n[{decoded_func}, Error: {err_code}] {decoded_msg}\n")
Expand All @@ -262,6 +278,7 @@ cdef class AuxData:
cdef bint with_userdata
cdef bint is_constrained

cdef object pyerr # Exception
cdef object rhsfn # Callable
cdef object userdata # Any
cdef object eventsfn # Callable
Expand All @@ -272,6 +289,7 @@ cdef class AuxData:
cdef object jactimes # CVODEJacTimes

def __cinit__(self, sunindextype NEQ, object options):
self.pyerr = None
self.np_yy = np.empty(NEQ, DTYPE)
self.np_yp = np.empty(NEQ, DTYPE)

Expand Down Expand Up @@ -740,7 +758,7 @@ cdef class CVODE:

# 16) Set optional inputs
SUNContext_ClearErrHandlers(self.ctx)
SUNContext_PushErrHandler(self.ctx, _err_handler, NULL)
SUNContext_PushErrHandler(self.ctx, _err_handler, <void*> self.aux)

cdef sunrealtype first_step = <sunrealtype> self._options["first_step"]
flag = CVodeSetInitStep(self.mem, first_step)
Expand Down Expand Up @@ -921,10 +939,12 @@ cdef class CVODE:

ind += 1

if stop:
break
if self.aux.pyerr is not None:
raise self.aux.pyerr
elif PyErr_CheckSignals() == -1:
return
elif stop:
break

if self.aux.eventsfn:
i_ev, t_ev, y_ev = _collect_events(self.aux)
Expand Down Expand Up @@ -1004,10 +1024,12 @@ cdef class CVODE:

ind += 1

if stop:
break
if self.aux.pyerr is not None:
raise self.aux.pyerr
elif PyErr_CheckSignals() == -1:
return
elif stop:
break

if self.aux.eventsfn:
i_ev, t_ev, y_ev = _collect_events(self.aux)
Expand Down
40 changes: 32 additions & 8 deletions src/sksundae/_cy_ida.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ cimport numpy as np

from scipy import sparse as sp
from scipy.optimize._numdiff import group_columns
from cpython.exc cimport PyErr_CheckSignals, PyErr_Occurred
from cpython.exc cimport (
PyErr_Fetch, PyErr_NormalizeException,
PyObject, PyErr_CheckSignals, PyErr_Occurred, # PyErr_GetRaisedException,
)

# PyErr_Fetch and PyErr_NormalizeException are deprecated at 3.12. When support
# for <3.12 is dropped, replace with PyErr_GetRaisedException.

# Extern cdef headers
from .c_ida cimport *
Expand Down Expand Up @@ -239,8 +245,18 @@ cdef void _err_handler(int line, const char* func, const char* file,
const char* msg, int err_code, void* err_user_data,
SUNContext ctx) except *:
"""Custom error handler for shorter messages (no line or file)."""

if not PyErr_Occurred():
cdef PyObject *errtype, *errvalue, *errtraceback

if PyErr_Occurred():
aux = <AuxData> err_user_data
# aux.pyerr = <object> PyErr_GetRaisedException()

PyErr_Fetch(&errtype, &errvalue, &errtraceback)
PyErr_NormalizeException(&errtype, &errvalue, &errtraceback)

aux.pyerr = <object> errvalue

else:
decoded_func = func.decode("utf-8")
decoded_msg = msg.decode("utf-8").replace(", ,", ",").strip()
print(f"\n[{decoded_func}, Error: {err_code}] {decoded_msg}\n")
Expand All @@ -267,6 +283,7 @@ cdef class AuxData:
cdef bint with_userdata
cdef bint is_constrained

cdef object pyerr # Exception
cdef object resfn # Callable
cdef object userdata # Any
cdef object eventsfn # Callable
Expand All @@ -277,6 +294,7 @@ cdef class AuxData:
cdef object jactimes # IDAJacTimes

def __cinit__(self, sunindextype NEQ, object options):
self.pyerr = None
self.np_yy = np.empty(NEQ, DTYPE)
self.np_yp = np.empty(NEQ, DTYPE)
self.np_rr = np.empty(NEQ, DTYPE)
Expand Down Expand Up @@ -764,7 +782,9 @@ cdef class IDA:

# 15) Set optional inputs
SUNContext_ClearErrHandlers(self.ctx)
SUNContext_PushErrHandler(self.ctx, _err_handler, NULL)
SUNContext_PushErrHandler(self.ctx, _err_handler, <void*> self.aux)

# Set algebraic variable indices

np_algidx = np.ones(self.NEQ, DTYPE)
if self._options["algebraic_idx"] is not None:
Expand Down Expand Up @@ -992,10 +1012,12 @@ cdef class IDA:

ind += 1

if stop:
break
if self.aux.pyerr is not None:
raise self.aux.pyerr
elif PyErr_CheckSignals() == -1:
return
elif stop:
break

if self.aux.eventsfn:
i_ev, t_ev, y_ev, yp_ev = _collect_events(self.aux)
Expand Down Expand Up @@ -1083,10 +1105,12 @@ cdef class IDA:

ind += 1

if stop:
break
if self.aux.pyerr is not None:
raise self.aux.pyerr
elif PyErr_CheckSignals() == -1:
return
elif stop:
break

if self.aux.eventsfn:
i_ev, t_ev, y_ev, yp_ev = _collect_events(self.aux)
Expand Down