diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 85e0336b0..0b1f8156c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,10 +107,15 @@ jobs: - uses: actions/checkout@v4 - name: "Main Script" run: | + # This test makes sure that loopy can run with kernels loaded from disk cache. curl -L -O https://tiker.net/ci-support-v0 . ./ci-support-v0 build_py_project_in_conda_env ( test_py_project ) + + # See https://github.com/inducer/loopy/pull/828 why this is disabled. + # export LOOPY_ABORT_ON_CACHE_MISS=1 + ( test_py_project ) examples: diff --git a/doc/ref_other.rst b/doc/ref_other.rst index 538f0cdb9..81b6eca1e 100644 --- a/doc/ref_other.rst +++ b/doc/ref_other.rst @@ -25,6 +25,13 @@ Controlling caching is suppressed. +.. envvar:: LOOPY_ABORT_ON_CACHE_MISS + + If set to a string that :func:`pytools.strtobool` evaluates as ``True``, + loopy will raise an exception if a cache miss occurs. This can be useful + for debugging cache-related issues. For example, it can be used to automatically test whether caching is successful for a particular code, by setting this variable to ``True`` and re-running the code. + + .. autofunction:: set_caching_enabled .. autoclass:: CacheMode diff --git a/loopy/__init__.py b/loopy/__init__.py index 7a1942f3d..8060ee0bc 100644 --- a/loopy/__init__.py +++ b/loopy/__init__.py @@ -509,6 +509,9 @@ def register_symbol_manglers(kernel, manglers): not strtobool(os.environ.get("CG_NO_CACHE", "false"))) +ABORT_ON_CACHE_MISS = strtobool(os.environ.get("LOOPY_ABORT_ON_CACHE_MISS", "false")) + + def set_caching_enabled(flag): """Set whether :mod:`loopy` is allowed to use disk caching for its various code generation stages. diff --git a/loopy/codegen/__init__.py b/loopy/codegen/__init__.py index 3de36e242..e7decb8f2 100644 --- a/loopy/codegen/__init__.py +++ b/loopy/codegen/__init__.py @@ -549,7 +549,8 @@ def all_code(self): def generate_code_v2(t_unit: TranslationUnit) -> CodeGenerationResult: # {{{ cache retrieval - from loopy import CACHING_ENABLED + + from loopy import ABORT_ON_CACHE_MISS, CACHING_ENABLED from loopy.kernel import LoopKernel from loopy.translation_unit import make_program @@ -563,6 +564,8 @@ def generate_code_v2(t_unit: TranslationUnit) -> CodeGenerationResult: except KeyError: logger.debug(f"TranslationUnit with entrypoints {t_unit.entrypoints}:" " code generation cache miss") + if ABORT_ON_CACHE_MISS: + raise # }}} diff --git a/test/test_c_execution.py b/test/test_c_execution.py index 9943d41df..33e50e3ab 100644 --- a/test/test_c_execution.py +++ b/test/test_c_execution.py @@ -93,10 +93,11 @@ def __get_kernel(order="C"): def test_c_target_strides_nonsquare(): from loopy.target.c import ExecutableCTarget + rng = np.random.default_rng(seed=42) def __get_kernel(order="C"): indices = ["i", "j", "k"] - sizes = tuple(np.random.randint(1, 11, size=len(indices))) + sizes = tuple(rng.integers(1, 11, size=len(indices))) # create domain strings domain_template = "{{ [{iname}]: 0 <= {iname} < {size} }}" domains = [] @@ -141,9 +142,11 @@ def __get_kernel(order="C"): def test_c_optimizations(): from loopy.target.c import ExecutableCTarget + rng = np.random.default_rng(seed=42) + def __get_kernel(order="C"): indices = ["i", "j", "k"] - sizes = tuple(np.random.randint(1, 11, size=len(indices))) + sizes = tuple(rng.integers(1, 11, size=len(indices))) # create domain strings domain_template = "{{ [{iname}]: 0 <= {iname} < {size} }}" domains = []