feat: model full debug and add TileIR JIT overrides - #237
Conversation
|
@almightychang I just merged #236 and it overlaps substantially with this impl. Sorry, I never flagged on #210 that work was already in flight and I only realized the overlap after merging and looking at this PR for the first time. Otherwise, this PR looks good. There are some ideas here that I'd like to see in main with you as author, if you're up for it:
If you're up for the env-override follow-up, it's yours. Sorry again! |
Full device debug only works at optimization level zero, but the two independent options allowed callers to construct combinations that tileiras rejects. Model level selection and full debug as one choice and reject unsupported levels as a recoverable JIT error. Keep lineinfo and memcheck independent. Preserve the existing opt-level byte and flags bit layout so cache keys and entry encoding remain unchanged, with a regression test against the previous representation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Sam, Joochul Chang <almightychang@icloud.com>
9121046 to
eef759b
Compare
Wrappers need to switch an already-built application into debug or sanitizer compilation without changing its source. Resolve optimization, memcheck, and lineinfo overrides once at the existing stage-2 option boundary, before cache-key construction. Unset variables preserve code settings, explicit off values disable them, and malformed or non-Unicode values return through the existing JIT error path. A debug override replaces an explicit optimized level, relying on the optimization model that makes the resulting O0 plus device-debug pair valid. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Sam, Joochul Chang <almightychang@icloud.com>
eef759b to
900a473
Compare
|
@elibol
In particular, the tests now pin the critical case where code requests optimization level 3 but Validation was run in the |
Summary
This PR has been rewritten on top of
mainafter #236 landed with most of the original implementation. The remaining scope is:Optimization::Level(u8) | Optimization::FullDebugWhy the optimization model comes first
On current
main,device_debug=trueplus an explicit optimized level produces an argv combination thattileirasrejects (optimized debugging is currently not supported; only O0 is accepted with--device-debug). Without environment overrides, both setters come from one call site, so that behavior was a reasonable API choice for the new compile options.The override changes who produces the combination: an application can set level 3 while a wrapper independently enables debug through the environment. Neither party made an invalid local choice, but the failure would surface later during JIT in a process the wrapper does not own. Making full debug a distinct optimization state prevents that cross-party invalid combination;
FullDebugowns both--opt-level 0and--device-debug.Only the
opt_level/device_debugpair is folded together.lineinfoandsanitize_memcheckremain independent because the measured combinations are accepted bytileiras(-O3 --lineinfo,-O0 -g --sanitize=memcheck, and-O3 --sanitize=memcheck).This modeling change does not change cache identity.
FullDebugstill encodes opt level 0 and device-debug in flags bit 0; lineinfo remains bit 1 and memcheck bit 2. The L2 key regression test compares the new representation with the previous encoding across every valid combination. The cache domain, entry format version, and entry header layout are unchanged.Environment overrides
CUTILE_JIT_OPTIMIZATION=0|1|2|3|debugCUTILE_JIT_SANITIZE=memcheck|noneCUTILE_JIT_LINEINFO=1|0(alsotrue/false,yes/no, andon/off)Each variable has three states: unset preserves the code setting, an explicit value overrides it (including explicit off), and an invalid or non-Unicode value returns a clear JIT error. The values are read once per process with
OnceLockin the existingTileirasOptions::from_compile_optionsresolution point, before the L2 cache key is constructed.CUTILE_JIT_LINEINFOis included for completeness because #236 added lineinfo to the programmatic surface after the original PR was written. I am happy to remove that override if the additional knob is not wanted.Validation
Validated in the
cutile-ci:13.3container used to mirror.github/workflows/pr.yml:cargo buildcargo fmt -- --checkcargo clippy --all-featurescargo test --no-runbash scripts/run_cpu_tests.sh--nocapturebash scripts/run_all.sh(CPU section passed; GPU-dependent sections failed becauselibcuda.sowas unavailable)compiler2_e2ewas confirmed to execute rather than silently skip: it printed its target and produced non-empty cubins with the real CUDA 13.3tileiras. In particular, application code specifyingopt_level(3)plusCUTILE_JIT_OPTIMIZATION=debugresolved to--opt-level 0 --device-debugand compiled successfully. The real backend also accepted the directly tested default, O0, debug, debug+memcheck, O3+memcheck, and lineinfo argv combinations.GPU launch paths were not validated on this machine because the container had no CUDA driver (
libcuda.so, driver error 303); those paths rely on CI with a compatible GPU and driver. The local wrapper also lacks the workflow'sseccomp=unconfinedoption, so the ThreadSanitizer command stopped atsetarch: Operation not permitted; the dedicated CI job remains the verification for that check.