Skip to content

Accelerator substrate, CPU vertical slice, and a working 1D Euler HIP contract - #160

Merged
eric2003 merged 28 commits into
eric2003:masterfrom
lql341:pr/euler-weno5-unified
Sep 19, 2026
Merged

eric2003 merged 28 commits into
eric2003:masterfrom
lql341:pr/euler-weno5-unified

Conversation

@lql341

@lql341 lql341 commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

Accelerator work for the production solver plus the standalone 1D Euler port, in the state validated on Kunshan.

Accelerator substrate and CPU vertical slice

  • FluxBackend extended to multi-equation Euler Rusanov, with a numerical bridge test against the port EulerBackend.
  • CPU accelerator substrate: device buffer management through AccelBackend, Euler domain views and state contract, registry create/invalidate lifecycle, init/restart lifecycle, CPU domain state backend, CPU primitive adapter, and residual mapping by face boundary mask.
  • Main solver integration: gated 3D CPU batch flux path, accelerator states owned by SimuContext with a mutable context passed through the solve task, MRField lifecycle binding after INIT_FLOWFIELD, and a RungeKutta capability guard with the guarded stage seam.

1D Euler port

  • WENO5 in the unified EulerBackend interface, with device management unified on AccelBackend/DeviceBuffer.
  • HIP build fix: <hip/hip_runtime.h> was included from inside namespace oneflow_1d in OneDWeno5.h, which broke the standard library headers it pulls in.
  • HIP contract registered with the HIP. CTest prefix and hardware;hip;dcu labels (cmake/OneFLOWEulerContract.cmake); without the labels the standard DCU runner (ctest -L hardware -R HIP) discovers nothing.
  • ci/kunshan/euler-dcu-gtest.slurm: load the CMake module before resolving cmake and pass the DTK amd_comgr_DIR, so the runner works on the cluster.

Validation (Kunshan, standard suites from ci/kunshan/README.md, measured on ef36b928)

Suite Partition Result
cpu-regression (five cases) kshcnormal normal 1e-8 5/5, strict 1e-15 5/5
dcu-single (HIP contract) kshdnormal, dcu:1 GoogleTest 9/9, CTest 9/9

Out of scope on purpose

  • The DCU/HIP vertical slice for the 3D main solver is not included: its 50-step stability gate is still open and it shows no end-to-end speedup yet, so it is not ready to be reviewed as done.
  • Accelerator tests that depend on the above are not registered here.

This is the first step toward satisfying the WENO5 unlock condition from
the optimization plan: '接口能够复用到 WENO5,而不复制一套显存生命周期管理'.

Changes:

1) OneDEuler.h: Add EulerMethod enum (Rusanov=0, Weno5=1)

2) OneDEulerBackend.h: Add 'method' field to EulerProblem (default Rusanov,
   backward compatible — existing callers are unaffected)

3) OneDEulerBackend.cpp (CPU):
   - CpuEulerBackend::Advance dispatches on problem.method
   - WENO5 path calls OneDCpuLaxWeno5Step via existing CPU implementation
   - FullTrace not yet supported for WENO5 (throws with clear message)

4) OneDWeno5.h / OneDWeno5.hip:
   - New HipWeno5StepRaw() function that launches the existing WENO5 HIP
     kernels (FillPadded, SplitFlux, Reconstruct, AssembleResidual, Update)
     using raw device pointers
   - Conditionally compiled under ONEFLOW_1D_USE_HIP

5) OneDEulerPersistent.hip (HIP):
   - HipState conditionally allocates WENO5 buffers (padded, positive,
     negative) when method==Weno5, using the same 3-ghost-cell stride
   - HipEulerBackend::Advance dispatches on problem.method
   - WENO5 path calls HipWeno5StepRaw for each step, NoTrace only
   - Rusanov path unchanged (backward compatible)

6) tests/euler/euler_backend_contract_test.cpp:
   - ProblemWeno5() helper
   - Weno5NoTraceMatchesCpuReference: backend WENO5 path matches old
     OneDCpuLaxWeno5Step (3 steps, periodic, smooth IC)
   - Weno5DiffersFromRusanov: validates the two methods give different
     results (higher order != first order)
   - Weno5RejectsFullTrace: validates the unsupported-path guard

Test matrix (CPU, no HIP needed):
  Existing: ReportsBackendIdentity, FullTraceMatchesCpuReference,
    NoTraceMatchesCpuReference, LifecycleCanBeReused, RejectsInvalidRequests
  New:      Weno5NoTraceMatchesCpuReference, Weno5DiffersFromRusanov,
    Weno5RejectsFullTrace

Total: 8 CPU tests (5 original + 3 new)
…ions

Issues found during CPU regression testing (8/8 PASSED after fix):

1) ports/kunshan/oneflow_1d_hip/CMakeLists.txt:
   - Fixed contract test source path: tests/euler_backend_contract_test.cpp
     → tests/euler/euler_backend_contract_test.cpp (file was moved by upstream)
   - Added OneDWeno5.cpp to CPU test target (needed for
     OneDCpuLaxWeno5Step called from WENO5 dispatch path)

2) tests/euler/euler_backend_contract_test.cpp:
   - Added missing using declarations: EulerMethod, EulerRkStages, Weno5Trace

Regression: 8/8 PASSED
  ReportsBackendIdentity         PASSED
  FullTraceMatchesCpuReference   PASSED
  NoTraceMatchesCpuReference     PASSED
  LifecycleCanBeReused           PASSED
  RejectsInvalidRequests         PASSED
  Weno5NoTraceMatchesCpuReference PASSED  (new)
  Weno5DiffersFromRusanov        PASSED  (new)
  Weno5RejectsFullTrace          PASSED  (new)
The port-level CMakeLists.txt already included OneDWeno5.cpp (fixed in
6f341ce), but the repository-root tests/euler/CMakeLists.txt was missed.
This caused a linker error for OneDCpuLaxWeno5Step when building through
the root CMake.

After fix: 8/8 CPU contract tests PASSED.
Eliminates duplicate HIP memory management between ports/kunshan and
codes/accel.  HipState now uses DeviceBuffer<T> (RAII) and AccelBackend
for allocation/copy, while retaining HIP-specific stream/event/kernel
management.

Changes:
1) ports/kunshan/oneflow_1d_hip/CMakeLists.txt:
   - Add accel source files (AccelBackend, AccelRuntime, CpuBackend,
     HipBackend, HipKernel) to all HIP targets
   - Add accel include paths and compile definitions
   - oneflow_accel_attach() macro for clean reuse across 7 HIP targets

2) OneDEulerPersistent.hip:
   - HipState: raw double* (8-11 ptrs) → DeviceBuffer<double> (RAII)
   - hipMalloc/hipFree → DeviceBuffer::Resize/Reset (via AccelBackend)
   - hipMemcpy/hipMemcpyAsync → AccelBackend::Copy (unified path)
   - hipStreamCreate/Destroy, hipEvent*, hipLaunchKernelGGL → unchanged
   - Release() simplified: only stream/event cleanup, memory auto-freed
   - CopyToDevice/CopyToHost helpers wrap AccelBackend::Copy

3) EulerMain.cpp, EulerStatefulBenchmark.cpp, EulerGpuOnlyBenchmark.cpp:
   - Add InitializeAccelRuntime(0,1) at start of main()

4) euler_backend_contract_test.cpp:
   - Static HipRuntimeInit ensures AccelRuntime is initialized before
     HIP tests run (GTest provides main, can't inject init code)

Verified:
- CPU contract test: 8/8 PASSED (no regression)
- CPU bridge test: 4/4 PASSED (machine precision)
- HIP path: compile-ready, needs Kunshan for runtime validation
The HIP build of the 1D Euler port failed because <hip/hip_runtime.h>
was included from inside namespace oneflow_1d in OneDWeno5.h, which
breaks the standard library headers it pulls in. Move the include to
the top of the file.

Also align the port CMake target, the persistent state helper and the
root contract test with the AccelBackend-based device management, and
record the verified one-card HIP contract evidence.

Fork-only working notes are excluded from this commit.
Add cmake/OneFLOWEulerContract.cmake, which registers the 1D Euler HIP
contract test with the HIP. CTest prefix and the hardware;hip;dcu
labels, and wire it into tests/euler behind ONEFLOW_ENABLE_HIP_TESTS.

Without the labels the standard DCU runner (ctest -L hardware -R HIP)
discovers nothing, so the one-card HIP contract cannot be validated.

Only the HIP contract registration is taken here; the accelerator
substrate test targets are not part of this change.
Phase 1 of GPU backend integration: making FluxBackend capable of
real CFD flux computation beyond scalar convection.

Changes:
1) AccelViews.h:
   - Add gamma field to FaceStateView (ratio of specific heats)
   - Document equation-major layout convention: data[eq * nFaces + face]
   - This matches the main solver's MRField and the port's CI(c,i,nx)

2) CpuFluxBackend.cpp:
   - Multi-equation Euler Rusanov (LaxFriedrichs) flux implementation
   - Supports nEquations=3 (1D Euler) and nEquations>=4 (3D NS)
   - Conserved→primitive conversion, physical flux, wave speed,
     Rusanov numerical flux: F = 0.5*(F_L+F_R) - 0.5*|lambda|*(Q_R-Q_L)
   - Multi-equation AddFaceFlux with equation-major layout
   - Scalar path preserved for backward compatibility

3) HipFluxBackend.hip:
   - HIP kernels for multi-equation Euler Rusanov flux
   - Device functions: ConservedToPrimitive, PhysicalFlux, MaxWaveSpeed
   - CalcInvFluxEulerKernel and AddFaceFluxEulerKernel
   - Scalar path preserved for backward compatibility

4) HipSmoke.cpp:
   - Extended smoke test with Euler Rusanov validation
   - TestEulerRusanov(): smooth 1D Euler IC, CPU vs HIP flux comparison,
     residual accumulation, physicality checks

Verified:
- Local CPU: CpuFluxBackend Euler (3eq) and NS (5eq) produce finite,
  physically reasonable fluxes
- Contract test: 8/8 still PASSED (no regression)
- HIP kernels: compile-ready, need Kunshan for runtime validation
Phase 2 of GPU backend integration: proves that the new FluxBackend's
Euler Rusanov implementation produces numerically identical results to
the port's validated Face kernel.

Bridge test:
- Sets up smooth 1D Euler IC (same as contract test)
- Path A: EulerBackend::Step → EulerTrace::numericalFlux (port, validated)
- Path B: CpuFluxBackend::CalcInvFlux (new, codes/accel)
- Maps port's nx+1 face indexing to bridge's nx faces correctly
- Compares at 4 resolutions: nx=32, 64, 128, 256

Result: max abs diff ≤ 2.22e-16 (machine precision) at all resolutions.
This validates the integration seam between codes/accel and ports/kunshan.

CMake: bridge test added to tests/euler/CMakeLists.txt as standalone
executable (not gtest — it has its own main()).
The target depends on codes/accel/src/EulerInvFluxCapability.cpp and
tests/euler_inv_flux_capability_test.cpp, which belong to the main-solver
HIP flux guard and are not part of this change. Leaving it registered
breaks CMake generation.
ISimuTask::Execute now takes SimuContext&; update the contract task in
tests/main so it still overrides the interface.
@lql341 lql341 changed the title 1D Euler port: WENO5 scheme, AccelBackend device management, HIP contract wiring Accelerator substrate, CPU vertical slice, and a working 1D Euler HIP contract Sep 19, 2026
lql341 added a commit to lql341/OneFLOW that referenced this pull request Sep 19, 2026
- Fix the ahead count: the earlier 100 missed commit bc6d395, the real
  value is 102.
- Stop pinning the doc's own commit: its own commit advances dev, so
  point at git rev-parse instead of a hard-coded sha.
- Scope the gate claim correctly: only PR eric2003#160 ran the Kunshan gates;
  PR eric2003#159 is docs-only and rule 1 does not apply to it.
- Add the exact commands used to reproduce T1 and T2, including the
  amd_comgr_DIR caveat on the upstream runner.
@eric2003
eric2003 merged commit 6e9e369 into eric2003:master Sep 19, 2026
4 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.

2 participants