Skip to content

Recompile stale BASE_DIR#415

Merged
kennykos merged 12 commits intomainfrom
kennykos/recompile
May 5, 2026
Merged

Recompile stale BASE_DIR#415
kennykos merged 12 commits intomainfrom
kennykos/recompile

Conversation

@kennykos
Copy link
Copy Markdown
Collaborator

Closes #100, #234.

Features

1. AST-hashed compilation directories
pk_cpp output directories now include an AST_<hash> subdirectory that encodes a structural hash of the compiled workunit. On each invocation, PyKokkos computes the current AST hash and compares it against the on-disk directory name; if the AST hashes differ, recompilation is triggered. This replaces the previous approach which did not check if the compiled AST matched the current AST.

2. Incremental recompilation on AST change
When a workunit's AST hash changes, initialize_directory renames the old AST_<hash> directory to the new hash rather than discarding it. Only CMakeCache.txt and cmake.check_cache are deleted (as they contain hardcoded absolute paths that CMake rejects after a rename), while all object files and link artifacts in build/ are preserved. This allows CMake to perform an incremental rebuild rather than compiling from scratch.

3. Recompilation unit test
Adds test_recompilation which verifies end-to-end that modifying a @pk.workunit body triggers a correct recompile. The test writes a buggy kernel (arr[i] += 2), runs it and asserts the output, then overwrites it with the fixed kernel (arr[i] += 1) and asserts the recompiled output, confirming that stale builds are invalidated and that the new kernel produces correct results.

We add a hashing to the AST directly
to check if the workunit needs to be
recompiled.

NOTE: Ideally, we could edit the functor.hpp directly so we do not need
to bring in all of Kokkos again, but this approach works for now.
@kennykos kennykos requested review from JBludau and gliga April 29, 2026 21:31

# get parser signature
signature = ast.dump(self.tree)
self.signature = hashlib.md5(signature.encode()).hexdigest()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how expensive is this? I assume our ast's for kernels are small that this should not be an issue?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't do a performance test. This block is only done when the workunit is first seen by pykokkos, so it is a startup cost that will not add overhead during repeated execution.

In most cases the ast's should be relatively small; e.g., in my Ewald code, the slowest time for this block of code is 0.013 seconds.

Comment thread pykokkos/core/cpp_setup.py Outdated
Comment thread tests/test_recompile.py Outdated
Comment thread tests/test_recompile.py
except AssertionError as e:
raise AssertionError(
f"kernel is incorrect\nactual: {arr_correct}\ndesired: {expected}"
) from e
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test does not check that values of signature on disk changed or something was renamed

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept it abstract in case we want to change in implementation details down the road (i.e., if we want to move away from renaming or change the directory structure).

Copy link
Copy Markdown
Contributor

@gliga gliga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, good change. See comments.

@gliga
Copy link
Copy Markdown
Contributor

gliga commented Apr 30, 2026

I do not like the renaming part, but we can keep it and see when/if it breaks.

@gliga
Copy link
Copy Markdown
Contributor

gliga commented Apr 30, 2026

Are we ever going to change the name of that directory? It has been a while that we wanted to move to .pykokkos or we can use .pk

@kennykos kennykos changed the title Recompile stale pk_cpp Recompile stale BASE_DIR Apr 30, 2026
@kennykos
Copy link
Copy Markdown
Collaborator Author

Are we ever going to change the name of that directory? It has been a while that we wanted to move to .pykokkos or we can use .pk

Changed to .pykokkos in #416.

Comment thread pykokkos/core/cpp_setup.py Outdated
Comment thread pykokkos/core/cpp_setup.py
Comment thread pykokkos/core/cpp_setup.py Outdated
Comment on lines +195 to +196
if ast_signature is not None:
out_dir = out_dir / f"AST_{ast_signature}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm so we have a hierarchy which has the ast signature as the highest priority ... but is there cases where the ast signature would not trigger but the others would?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, consider the scenario:

  • workunit v0 is compiled with pk.float arrays;
  • an edit is made and we now have ATS has for workunit v1;
  • workunit v1 is compiled with pk.double arrays;
  • workunit v1 is called again with pk.float arrays. In this case, the type hash would trigger, but the ats hash would not as it is out of date.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but doesn't the AST change if we change types from float to double? Even unmanaged Views change their type, I am surprised that this would not trigger an AST hash fail

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the AST will change, but we want to keep both float and double types cached in this scenario to avoid excessive recompilation (e.g., an adaptive time-stepper may use a float and double execution to get error estimates)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Could you add a comment explaining this intent? Future selves will thank us for it

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in a3a23c8

Comment thread tests/test_recompile.py Outdated
* Change ordering of comments for clarity;
* remove vestigial try/except blocks
@kennykos kennykos requested a review from JBludau April 30, 2026 19:36
@kennykos
Copy link
Copy Markdown
Collaborator Author

@JBludau I want to make sure you're aware of the new commit a810722.

@kennykos kennykos requested review from JBludau and removed request for JBludau May 5, 2026 14:32
Copy link
Copy Markdown
Contributor

@JBludau JBludau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kennykos I think the hierarchy of rebuilds could have a comment to express the intent, but non blocking.

@kennykos kennykos merged commit 67436b3 into main May 5, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ENH, DOC: recompile on change

3 participants