Skip to content
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

Python: Issue warning when re-loading the same module #178

Merged
merged 1 commit into from
Oct 13, 2023
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ jobs:

- name: Run tests
run: |
pytest -v python/
cd python/
pytest -v
python example.py
env:
BRIDGESTAN: ${{ github.workspace }}
Expand Down
6 changes: 2 additions & 4 deletions docs/internals/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,13 @@ Running

.. code-block:: shell

cd python/
pytest -v
pytest -v python/

Will run the "default" grouping. To run the other group(s), run

.. code-block:: shell

cd python/
pytest --run-type=ad_hessian -v
pytest --run-type=ad_hessian -v python/

The set up for this can be seen in :file:`tests/conftest.py` and is based on the
`Pytest documentation examples <https://docs.pytest.org/en/7.1.x/example/simple.html#control-skipping-of-tests-according-to-command-line-option>`__.
Expand Down
11 changes: 9 additions & 2 deletions python/bridgestan/model.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import ctypes
import warnings
from pathlib import Path
from typing import List, Optional, Tuple

import numpy as np
import numpy.typing as npt
from dllist import dllist
from numpy.ctypeslib import ndpointer

from .__version import __version_info__
from .compile import windows_dll_path_setup, compile_model
from .compile import compile_model, windows_dll_path_setup
from .util import validate_readable

FloatArray = npt.NDArray[np.float64]
Expand Down Expand Up @@ -68,7 +70,12 @@ def __init__(
model_data = f.read()

windows_dll_path_setup()
self.lib_path = model_lib
self.lib_path = str(Path(model_lib).absolute().resolve())
if self.lib_path in dllist():
warnings.warn(
f"Loading a shared object {self.lib_path} that has already been loaded.\n"
"If the file has changed since the last time it was loaded, this load may not update the library!"
)
self.stanlib = ctypes.CDLL(self.lib_path)

self.data = model_data or ""
Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ authors = [
{ name = "Edward Roualdes", email = "eroualdes@csuchico.edu" },
]
requires-python = ">=3.9"
dependencies = ["numpy"]
dependencies = ["numpy", "dllist"]
dynamic = ["version"]

[tool.setuptools.dynamic]
Expand Down
14 changes: 11 additions & 3 deletions python/test/test_stanmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@


def test_constructor():

# implicit destructor tests in success and fail cases

# test empty data
Expand Down Expand Up @@ -595,7 +594,6 @@ def _grad_multi(x):


def test_gaussian():

lib = str(STAN_FOLDER / "gaussian" / "gaussian_model.so")
data = str(STAN_FOLDER / "gaussian" / "gaussian.data.json")

Expand All @@ -616,7 +614,6 @@ def test_gaussian():


def test_fr_gaussian():

lib = str(STAN_FOLDER / "fr_gaussian" / "fr_gaussian_model.so")
data = str(STAN_FOLDER / "fr_gaussian" / "fr_gaussian.data.json")
model = bs.StanModel(lib, data)
Expand Down Expand Up @@ -709,6 +706,17 @@ def f():
assert x == 500 # 2 calls per print, 10 threads, 25 iterations


def test_reload_warning():
lib = STAN_FOLDER / "fr_gaussian" / "fr_gaussian_model.so"
data = str(STAN_FOLDER / "fr_gaussian" / "fr_gaussian.data.json")
model = bs.StanModel(str(lib), data)


relative_lib = lib.relative_to(STAN_FOLDER.parent)
assert not relative_lib.is_absolute()
with pytest.warns(UserWarning, match="may not update the library"):
model2 = bs.StanModel(str(relative_lib), data)

@pytest.fixture(scope="module")
def recompile_simple():
"""Recompile simple_model with autodiff hessian enable, then clean-up/restore it after test"""
Expand Down