From 761c009d4d6c00cc56de00614acf00dfcf85f0c1 Mon Sep 17 00:00:00 2001 From: Michal Harakal Date: Wed, 24 Jun 2026 06:30:11 +0200 Subject: [PATCH] feat(context): expose ExecutionContext.isRecording (eager-vs-trace routing) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a default-false `isRecording` to the lang-core `ExecutionContext` interface; `GraphExecutionContext` overrides it (currentTape?.isRecording). This lets modules that keep an eager fast-path bypassing `ops.*` (e.g. RoPE's raw-array INTERLEAVED rotation) detect tracing and emit a graph-traceable `ctx.ops.*` path instead — so they export to StableHLO while keeping the fast path for eager inference — WITHOUT depending on the compile-dag module (transformer-core only sees lang-core). Backward-compatible: existing ExecutionContext implementations inherit the default. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../sk/ainet/lang/graph/exec/GraphExecutionContext.kt | 5 +++-- .../kotlin/sk/ainet/context/ExecutionContext.kt | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/skainet-compile/skainet-compile-dag/src/commonMain/kotlin/sk/ainet/lang/graph/exec/GraphExecutionContext.kt b/skainet-compile/skainet-compile-dag/src/commonMain/kotlin/sk/ainet/lang/graph/exec/GraphExecutionContext.kt index c52a076b..e20ee89c 100644 --- a/skainet-compile/skainet-compile-dag/src/commonMain/kotlin/sk/ainet/lang/graph/exec/GraphExecutionContext.kt +++ b/skainet-compile/skainet-compile-dag/src/commonMain/kotlin/sk/ainet/lang/graph/exec/GraphExecutionContext.kt @@ -28,9 +28,10 @@ public interface GraphExecutionContext : ExecutionContext, TrainingExecutionCont public val tapeStack: TapeStack /** - * Whether operations should be recorded + * Whether operations should be recorded. Overrides [ExecutionContext.isRecording] so modules + * can route eager-vs-trace without depending on the graph module. */ - public val isRecording: Boolean get() = currentTape?.isRecording == true + override val isRecording: Boolean get() = currentTape?.isRecording == true /** diff --git a/skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/context/ExecutionContext.kt b/skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/context/ExecutionContext.kt index acca44e6..042cf722 100644 --- a/skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/context/ExecutionContext.kt +++ b/skainet-lang/skainet-lang-core/src/commonMain/kotlin/sk/ainet/context/ExecutionContext.kt @@ -23,6 +23,15 @@ public interface ExecutionContext { public val phase: Phase public val inTraining: Boolean get() = phase == Phase.TRAIN + /** + * Whether this context is currently *recording* a trace/graph (vs. plain eager execution). + * Defaults to `false` (eager); the graph/tape context overrides it. Modules with an eager + * fast-path that bypasses `ops.*` (e.g. RoPE's raw-array interleaved rotation) can check this + * to emit a graph-traceable `ctx.ops.*` path instead when recording, so they export to + * StableHLO while keeping the fast path for eager inference. + */ + public val isRecording: Boolean get() = false + public val tensorDataFactory: TensorDataFactory /**