Skip to content

fixed device timers for cuda and refactored the ComputeKernels - #1

Merged
urvijsaroliya merged 2 commits into
mainfrom
kernel-device-sync-refactor
Aug 24, 2026
Merged

urvijsaroliya merged 2 commits into
mainfrom
kernel-device-sync-refactor

Conversation

@urvijsaroliya

Copy link
Copy Markdown
Owner

Background: ComputeKernel subclasses return (host_dt, device_dt), and the workflow relies on both fields: run_count mode accumulates device_dt, run_time mode accumulates host_dt (simulation.py). On the cuda and cpu paths, both fields were produced by time.time() around asynchronous launches with no synchronization, so both measured kernel submission while the actual GPU work ran untimed.

Consequences: device_dt on CUDA was meaningless. The xpu path was always correct via dpctl.SyclTimer; this PR brings the other backends to the same semantics.

Changes

  • Unified timing interface: timed_regions(device) yields per-region timers with common implementation on all backends: host_dt = wall time including device execution, device_dt = device-only execution time, host_dt ≥ device_dt.

    1. CudaEventTimer: CUDA event pair + sync at exit (entry sync so previously pending async work isn't billed to the kernel).
    2. SyclQueueTimer: wraps dpctl.SyclTimer; the q.wait() now lives in the timer, not in each kernel body.
    3. HostTimer: perf_counter; wall = execution on synchronous NumPy.
  • Kernels collapse to a single code path – the duplicated if device == "xpu" branches are removed from all seven kernels; xpu's run-per-queue and average behavior is preserved via the region generator.

  • Fixes a queue mismatch in GenerateRandomNumber (xpu) — the RNG launched on the default queue while the timer watched queue q; allocations now carry the timed queue.

  • time.time() → time.perf_counter() (monotonic).

  • ComputeKernel.sync (previously dead code, no call sites) delegates to a new module-level device_sync(device); kept for API compatibility.

  • ScatterAdd left as shipped (kernel body still lacks implementation), wrapped for contract consistency and flagged.

Validation: all kernels smoke-tested on cpu (host_dt == device_dt > 0, registries intact); on GH200, host_dt ≥ device_dt holds with the difference at launch-overhead scale, and calibrated run_time budgets now correspond to actual device occupancy.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

CUDA synchronization, compatibility delegation, and one XPU queue allocation remain incorrect.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Introduces unified CPU, CUDA, and XPU kernel timing while consolidating duplicated backend paths.

Changes:

  • Adds backend-specific timer abstractions.
  • Refactors seven compute kernels around timed_regions.
  • Adds device synchronization and queue-aware allocation support.
File summaries
File Description
src/SimAIBench/kernel.py Implements unified timing and refactors compute kernels.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/SimAIBench/kernel.py Outdated
for q in default_queues:
q.wait()
elif device == "cuda" and CUPY_AVAILABLE:
cp.cuda.Stream.null.synchronize()

@urvijsaroliya urvijsaroliya Aug 24, 2026 •

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Use this instead:
cp.cuda.Device().synchronize()

Comment thread src/SimAIBench/kernel.py Outdated
Comment thread src/SimAIBench/kernel.py
with t:
y = xp.empty(n, dtype=xp.float32, **t.alloc_kwargs)
x = xp.empty(n, dtype=xp.float32, **t.alloc_kwargs)
idx = xp.random.randint(0, n, size=n, dtype=xp.int32)
Comment thread src/SimAIBench/kernel.py Outdated
Comment on lines 617 to 624
def sync(self,device:str):
"""Deprecated: use module-level device_sync().
"""
if device=="xpu":
for q in default_queues:
q.wait()
else:
pass

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

CUDA synchronization and the deprecated synchronization API do not yet satisfy their documented behavior.

Review details

Suppressed comments (2)

src/SimAIBench/kernel.py:542

  • Synchronizing only Stream.null does not drain pending work on another current CUDA stream. Because _tic is started immediately afterward while the events are recorded on the current stream, host_dt can include that earlier work, violating the stated per-kernel timing semantics. Synchronize the device before starting the host clock.
        cp.cuda.Stream.null.synchronize()

src/SimAIBench/kernel.py:619

  • The deprecation text promises the new module-level behavior, but this method still retains its old XPU-only implementation, so ComputeKernel.sync("cuda") remains a no-op instead of preserving compatibility by delegating. Forward directly to device_sync.
        """Deprecated: use module-level device_sync().
        """
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

ScatterAdd still creates its XPU index array outside the timed queue.

Review details

Suppressed comments (1)

src/SimAIBench/kernel.py:724

  • On XPU, idx is still allocated on dpnp's default queue rather than the queue measured by SyclQueueTimer. Consequently q.wait() does not cover this operation, so the timing can omit it and the method may return with random-number work outstanding. Create the index array on t's queue as well.
                idx = xp.random.randint(0, n, size=n, dtype=xp.int32)
  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@urvijsaroliya
urvijsaroliya merged commit 9f95d7b into main Aug 24, 2026
1 check passed
@urvijsaroliya
urvijsaroliya deleted the kernel-device-sync-refactor branch August 24, 2026 10:15
@urvijsaroliya
urvijsaroliya restored the kernel-device-sync-refactor branch August 24, 2026 14:26
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.

2 participants