-
Notifications
You must be signed in to change notification settings - Fork 329
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
Fixed #1066 Permanently Remove Recompile #1067
Conversation
@NimaSarajpoor All tests are passing locally. Basically, I've completely removed the need to need a Update It looks like the |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1067 +/- ##
==========================================
- Coverage 97.33% 97.30% -0.03%
==========================================
Files 93 93
Lines 15219 15212 -7
==========================================
- Hits 14813 14802 -11
- Misses 406 410 +4 ☔ View full report in Codecov by Sentry. |
@seanlaw |
@seanlaw If we decide to keep |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@seanlaw
I added a few comments for your consideration.
@@ -54,12 +54,15 @@ def _set(module_name, func_name, flag): | |||
module = importlib.import_module(f".{module_name}", package="stumpy") | |||
func = getattr(module, func_name) | |||
try: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular advantage in using try-except block? If not, what do you think about using a simple if-block?
if numba.config.DISABLE_JIT: # pragma no cover
# update fastmath if in JIT mode
py_func = func.py_func # Copy raw Python function (independent of `njit`)
njit_signature = func.targetoptions.copy() # Copy the `njit` arguments
njit_signature.pop("nopython", None) # Pop redundant `nopython` declaration
njit_signature["fastmath"] = flag # Apply new `fastmath` flag
func = njit(py_func, **njit_signature) # Assign `njit` function with new target
# Monkey-patch [njit] func into global space
setattr(module, func_name, func)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular advantage in using try-except block? If not, what do you think about using a simple if-block?
If I think about "normal" usage, njit
is ALWAYS "on". So it feels "wrong" to check numba.config.DISABLE_JIT
as njit
should be assumed to always be there. Attempting to access the fastmath
attributes via try
at least assumes that njit
is always "on", the default behavior. Note that I would only consider try/except
when the function is called infrequently/rarely.
I will think about this more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I think about "normal" usage, njit is ALWAYS "on". So it feels "wrong" to check numba.config.DISABLE_JIT as njit should be assumed to always be there.
Makes sense!! Thanks for helping me understand your view! The if-block might seem cleaner but it creates branching here which is not the case when we think about the regular scenario.
@@ -156,7 +156,6 @@ def test_snippets(): | |||
fastmath._set( | |||
"core", "_calculate_squared_distance", {"nsz", "arcp", "contract", "afn"} | |||
) | |||
cache._recompile() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To remove cache._recompile()
, we need to find an alternative approach for updating all relevant callers of the function core._calculate_squared_distance
whose fastmath flag was updated in previous line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I did not appreciate this and did not capture this in my original code. I will explore more
@@ -203,7 +169,6 @@ def _save(): | |||
None | |||
""" | |||
_enable() | |||
_recompile() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing _recompile
here means that _save
only does cache._enable()
, which does nothing if a njit function is already compiled. The reason that tests/test_cache.py::test_cache_save_after_clear
is still passing is because both ref_cache
and comp_cache
are now empty.
Lines 11 to 27 in bbc97e4
def test_cache_save_after_clear(): | |
T = np.random.rand(10) | |
m = 3 | |
stump(T, m) | |
cache.save() | |
ref_cache = cache._get_cache() | |
cache.clear() | |
# testing cache._clear() | |
assert len(cache._get_cache()) == 0 | |
cache.save() | |
comp_cache = cache._get_cache() | |
# testing cache._save() after cache._clear() | |
assert sorted(ref_cache) == sorted(comp_cache) |
To have a better test, we should move up the first call of cache.save()
, and put it just before calling the function stumpy.stump
. This way we know that we have some files in ref. Then, the test in this version should fail and expose the issue to us.
However, when I made such change, I noticed that the tests are NOT failing still. The returned cache files is still an empty list. There is a deeper issue here. According to Numba's document:
If not defined, Numba picks the cache directory in the following order:
In-tree cache. Put the cache next to the corresponding source file under a pycache directory following how .pyc files are stored.
So, I turned on NUMBA_CACHE_DIR
and noticed that it writes to the local git directory "stumpy", in the path ./stumpy/__pycache__
, however, cache._get_cache()
reads the files from the following path, which is where stumpy is installed.
.../miniconda3/envs/py310/lib/python3.10/site-packages/stumpy/__pycache__
and that's why it returns 0 files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I turned on NUMBA_CACHE_DIR and noticed that it writes to the local git directory "stumpy", in the path ./stumpy/pycache, however, cache._get_cache() reads the files from the following path, which is where stumpy is installed.
This is unexpected behavior. I will look into this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I turned on NUMBA_CACHE_DIR and noticed that ...
Correction: "I turned on NUMBA_DEBUG_CACHE
"
Thanks @NimaSarajpoor!
It's clear that I do not understand the importance of |
Pull Request Checklist
Below is a simple checklist but please do not hesitate to ask for assistance!
black
(i.e.,python -m pip install black
orconda install -c conda-forge black
)flake8
(i.e.,python -m pip install flake8
orconda install -c conda-forge flake8
)pytest-cov
(i.e.,python -m pip install pytest-cov
orconda install -c conda-forge pytest-cov
)black --exclude=".*\.ipynb" --extend-exclude=".venv" --diff ./
in the root stumpy directoryflake8 --extend-exclude=.venv ./
in the root stumpy directory./setup.sh dev && ./test.sh
in the root stumpy directory