Repository navigation
Conversation
|
Claude Code Review Head SHA: 9eb641e Files changed:
Findings: |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2111 +/- ##
=======================================
Coverage 61.95% 61.95%
=======================================
Files 86 86
Lines 22909 22909
Branches 3379 3379
=======================================
Hits 14193 14193
Misses 6207 6207
Partials 2509 2509 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
sbryngelson
left a comment
There was a problem hiding this comment.
Thanks for tracking this down. The main question is the inline comment on line 350: the fix relies on -cudalib=nvtx3 alone, and that has only been checked on three NVHPC releases. I would like that confirmed for the other CUDA >= 12.9 releases in the CI matrix before merging.
Separately, no CI job covers NVHPC 26.9, the release this PR fixes. Adding { nvhpc: '26.9', target: gpu } to the matrix in .github/workflows/test.yml would catch a regression here.
| target_link_libraries(${a_target} PRIVATE nvhpcwrapnvtx) | ||
| # -cudalib=nvtx3 links NVHPC's NVTX wrapper under each release's name | ||
| # (-lnvhpcwrapnvtx in 25.9 and 26.3, -lnvhpcnvtx in 26.9), so it is not named here. | ||
| target_link_options(${a_target} PRIVATE "-cudalib=nvtx3") |
There was a problem hiding this comment.
This is my main concern. With the explicit nvhpcwrapnvtx removed, -cudalib=nvtx3 is now the only thing that puts the NVTX wrapper on the link line. The description says this was checked with -dryrun on 25.9, 26.3 and 26.9. Other releases also reach this branch (CUDA >= 12.9), for example 25.5, 25.7, 25.11 and 26.1, which CI builds. If any of them accepts -cudalib=nvtx3 but does not add the wrapper, nvtxRangePushA / nvtxRangePushEx (bound in src/common/m_nvtx.f90) end up unresolved and every GPU target fails to link. The old explicit library used to cover that case.
Could you run the same -dryrun check on the other releases in the CI matrix, or confirm that the GPU CI jobs for those versions actually link and not only configure?
Related: -cudalib only means something to nvfortran. If one of these targets is ever linked by a different compiler driver (for example after C/C++ sources are added), the flag is ignored and nothing else provides the NVTX symbols. Setting LINKER_LANGUAGE Fortran on these targets would guarantee the flag takes effect.
There was a problem hiding this comment.
- Compatibility with the other NVHPC releases
Checked on 25.5, 25.7, 25.9, 25.11, 26.1, 26.3 and 26.9. MFC's actual m_nvtx.f90, with calls to nvtxRangePushA, nvtxRangePushEx and nvtxRangePop, links and runs with only -cudalib=nvtx3 under both -acc and -mp=gpu.
Using the environment settings from the CI images, FindCUDAToolkit finds CUDA 12.9 or newer and reports no CUDA::nvToolsExt, so these configurations exercise the changed branch.
For MFC itself, syscheck and pre_process build with both --gpu acc and --gpu mp on 25.5, 25.7, 25.11 and 26.1. All four targets build with both on 26.3 and 26.9. The release-by-release results are in the description.
- Fortran link driver
Added LINKER_LANGUAGE Fortran to the targets in the -cudalib=nvtx3 branch, so nvfortran continues to drive the link if C or C++ sources are added later.
| @@ -345,7 +345,8 @@ exit 0 | |||
| if (TARGET CUDA::nvToolsExt) # CUDA <= 12.8 | |||
There was a problem hiding this comment.
This branch is chosen by what FindCUDAToolkit finds (TARGET CUDA::nvToolsExt), not by the CUDA version nvfortran actually links against. On the NVHPC cuda_multi images (CI, docker.yml), CMake can find an older CUDA that still ships libnvToolsExt while nvfortran defaults to CUDA >= 12.9. Then the build links a mismatched NVTX library and skips -cudalib=nvtx3. Would it be simpler to always pass -cudalib=nvtx3 for NVHPC and let the driver choose?
There was a problem hiding this comment.
I checked whether the branch could be removed. NVHPC 21.7, 21.11, 22.2 and 22.3 reject -cudalib=nvtx3. Versions 22.11, 23.11 and 24.5 accept it but leave the NVTX calls unresolved when it is used alone. Those releases still need the CUDA::nvToolsExt path.
I also forced all four pairings of CMake's CUDA and nvfortran's CUDA on each of two releases: 25.5 with CUDA 11.8/12.9, and 26.9 with CUDA 12.9/13.3. With this PR, the NVTX test calls link and run in all eight combinations.
In the case you described on 25.5—CMake finding 11.8 while nvfortran uses 12.9—the build links 11.8's libnvToolsExt, which resolves the calls. That branch is unchanged. The reverse pairing also works with -cudalib=nvtx3 alone. On 26.9, all four pairings use the changed branch and pass; master fails all four because it explicitly requests the old wrapper name.
These are checks of the NVTX calls, rather than full CFD regression runs for every pairing.
4870e05 to
b327136
Compare
|
@claude full review |
1 similar comment
|
@claude full review |
Added { nvhpc: '26.9', target: gpu } to the matrix. The existing GPU job builds both OpenACC and OpenMP variants, so it covers compilation and linking on 26.9. It does not execute the numerical regression tests; the separate 26.9 hypoelasticity issue and its reproducer are documented in the PR description. |
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
sbryngelson
left a comment
There was a problem hiding this comment.
Thanks, the CMake change looks right to me: -cudalib=nvtx3 already pulls in the wrapper, so dropping the explicit library name is the clean fix. A few comments inline. The main one is that this turns a 26.9 link failure into a build that silently produces wrong hypoelastic results, so I'd like some guard for that before or alongside merging.
| # -cudalib=nvtx3 lets the NVHPC driver link its NVTX wrapper, whose name changes between releases. | ||
| # Only nvfortran understands the flag, so it must drive the link. | ||
| target_link_options(${a_target} PRIVATE "-cudalib=nvtx3") | ||
| set_target_properties(${a_target} PROPERTIES LINKER_LANGUAGE Fortran) |
There was a problem hiding this comment.
Once this lands, NVHPC 26.9 builds succeed, but per the PR description 26.9 at -O2 miscompiles any(i == shear_indices) in m_variables_conversion.fpp and the hypoelasticity tests fail. Today users get a loud link error. After this, they get wrong physics with no diagnostic. Could we add a message(WARNING ...) (or FATAL_ERROR) when CMAKE_Fortran_COMPILER_VERSION is 26.9, or land the code workaround together with this?
There was a problem hiding this comment.
I've included the workaround in this PR as a separate commit, before the link fix.
IS_SHEAR(idx) replaces all five any(... == shear_indices) checks with three explicit comparisons.
With the workaround, the hypoelasticity tests pass on the current code with NVHPC 26.9: 61 of 61 on CPU with the CI job's flags, and 62 of 62 on an H100 with both --gpu acc and --gpu mp, with MPI enabled.
Without the workaround, 13 of the first 23 tests fail on the H100 in each GPU mode before the run aborts. Failures were also reproduced on CPU.
The compiler bug and a reproducer are documented in the description.
| - { nvhpc: '26.1', target: gpu } | ||
| - { nvhpc: '26.3', target: cpu } | ||
| - { nvhpc: '26.3', target: gpu } | ||
| - { nvhpc: '26.9', target: gpu } |
There was a problem hiding this comment.
Two notes on this job:
- It only builds (
--dry-run), so nothing in CI runs tests on 26.9. A fix or regression of the hypoelasticity miscompile would go unnoticed. A follow-up 26.9 job that runs just the hypoelastic tests (allowed to fail) would cover that. - The matrix has
continue-on-error: true, so this job cannot fail the workflow. It will only catch a link regression if someone reads its log. That policy predates this PR, so not a blocker, but worth knowing.
Also, the 26.9 testing in the description used the tarball, not nvcr.io/nvidia/nvhpc:26.9-devel-cuda_multi-ubuntu22.04. The job is still pending; let's confirm the image exists and fits on the runner before merging.
There was a problem hiding this comment.
-
A 26.9 test job: added as a regular
{ nvhpc: '26.9', target: cpu }entry. I read your suggestion as a job that runs the tests, which on the GitHub-hosted runners means the CPU target. With the workaround in, it is an ordinary matrix entry that runs the full suite like the other releases, not a separate hypoelasticity-only job. On 26.9 with that job's flags (--test-all --no-mpi,FFLAGS=-tp=px -Kieee -noswitcherror), the hypoelasticity tests give 61 passed, 0 failed. The full suite without MPI passed earlier on 26.9 (714 passed, 0 failed). -
The GPU job's steps on 26.9: the case-optimized
3D_sphbubcollapsebuild passes. If you meant running the tests on a GPU in CI: the self-hosted Phoenix NVHPC jobs use 25.5 (toolchain/modules), so that would need 26.9 there. Until then, the H100 runs above cover the workaround on a device. -
continue-on-error: agreed, left as is.
|
|
||
| cmakelist: &cmakelist | ||
| - 'CMakeLists.txt' | ||
| - 'cmake/**' |
There was a problem hiding this comment.
This line is also in #2019; one of the two PRs should drop it. Related: ALWAYS_RUN_ALL_PREFIXES in toolchain/mfc/test/coverage.py lists toolchain/cmake/ but not cmake/. cmake/ changes still trigger the full run through the fallback rule, but adding the prefix there would keep the two lists in agreement.
There was a problem hiding this comment.
Since #2019 was closed without merging, I've kept cmake/** here.
I've also added cmake/ to ALWAYS_RUN_ALL_PREFIXES, with a unit test for cmake/MFCTargets.cmake. As you noted, the fallback already selected the full suite, so this makes the rule explicit rather than changing test selection. The description now states that distinction.
NVHPC 26.9 at -O2 and above vectorizes any(idx == shear_indices) inside a loop to always true, so every normal stress component was counted as shear and its elastic energy added twice. The hypoelasticity tests failed on 26.9 (CPU and GPU); 25.9 and 26.3 are not affected. An IS_SHEAR Fypp macro writes the test as three comparisons, which 26.9 compiles correctly at -O2 and with -Minline. Results are unchanged with GNU and NVHPC 26.3. Co-authored-by: ruru25254649 <ruru.2525.4649@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JcWJMEPdfRnApebSDv7mrf
For CUDA >= 12.9 the targets linked nvhpcwrapnvtx by name in addition
to -cudalib=nvtx3. NVHPC 26.9 renamed that library to libnvhpcnvtx, so
every NVHPC build, CPU or GPU, stops at its first link (syscheck):
/usr/bin/ld: cannot find -lnvhpcwrapnvtx
-cudalib=nvtx3 already links the wrapper under each release's name
(-lnvhpcwrapnvtx through 26.3, -lnvhpcnvtx on 26.9), so the explicit
name is dropped. Checked on every CI release, 25.5 to 26.3, and on 26.9:
the flag alone links MFC's NVTX calls, and CMake takes this branch in
the CI images. LINKER_LANGUAGE Fortran keeps nvfortran, the only driver
that understands the flag, on the link.
The CUDA <= 12.8 branch stays: NVHPC 21.7 to 22.3 reject
-cudalib=nvtx3, and 22.11 to 24.5 accept it but leave the NVTX symbols
undefined.
CI: add 26.9 CPU (full suite) and GPU (build) jobs. Add cmake/** to the
cmakelist filter in file-filter.yml, which lists CMakeLists.txt and
toolchain/cmake/** but not the cmake/ directory added in MFlowCode#1552, so a PR
that only changes cmake/*.cmake skipped the build matrix. Also name
cmake/ in the coverage run-all prefixes next to toolchain/cmake/; such
changes already ran the full suite through the fallback, so only the
rule becomes explicit.
Co-authored-by: ruru25254649 <ruru.2525.4649@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcWJMEPdfRnApebSDv7mrf
9eb641e to
5666e4f
Compare
Lines of Code
|
|
@platelett I noticed you have a workaround for the |
Thanks for sharing and for reporting it to NVIDIA. Good to know a fix is on the way! |
Every MFC build with NVHPC 26.9, CPU or GPU, fails at its first link:
Once it links, 26.9 computes wrong hypoelastic results, because of a compiler bug. This PR fixes the link and works around the bug:
libnvhpcnvtx, andMFCTargets.cmakenames the old one. This PR stops naming it: the-cudalib=nvtx3flag already on that line links the wrapper under each release's own name. Checked on every NVHPC release in CI (25.5 to 26.3) plus 26.9.-O2and above, 26.9 evaluatesany(i == shear_indices)inside a loop as always true, so normal stresses get the shear (doubled) elastic energy. The five such comparisons are now written out as three==tests, which 26.9 compiles correctly.cmake/directory.Change
cmake/MFCTargets.cmake. For CUDA ≥ 12.9 (noCUDA::nvToolsExt), the targets linked the wrapper twice:LINKER_LANGUAGE Fortranis set on the targets in that branch. Only nvfortran understands-cudalib, so this keeps it driving the link if C or C++ sources are ever added. MFC has none today, so nothing changes now.CUDA::nvToolsExt) is unchanged. It has to stay: on the releases that take it,-cudalib=nvtx3alone does not link (table below).src/common/include/macros.fpp,m_variables_conversion.fpp,m_riemann_state.fpp. A newIS_SHEAR(idx)Fypp macro spells out the test asidx == shear_indices(1) .or. idx == shear_indices(2) .or. idx == shear_indices(3). It replacesany(... == shear_indices)at all five sites. The two forms mean the same thing; only the code 26.9 generates differs. The compiler bug and a reproducer are below..github/workflows/test.yml. Adds{ nvhpc: '26.9', target: cpu }and{ nvhpc: '26.9', target: gpu }. They run the same steps as the other releases: the CPU job runs the full suite, and the GPU job builds, including the case-optimized build..github/file-filter.yml. Adds'cmake/**'to thecmakelistfilter. The filter listsCMakeLists.txtandtoolchain/cmake/**, but not thecmake/directory added in #1552, so a PR that changes onlycmake/*.cmakeskips the build and test matrix. #2019 had the same line but was closed without merging.toolchain/mfc/test/coverage.py. Addscmake/toALWAYS_RUN_ALL_PREFIXES, next totoolchain/cmake/. This changes no test selection: acmake/change already ran the full suite through the "unattributable change" fallback. It makes the rule explicit, socmake/andtoolchain/cmake/are handled by the same named rule. A unit test covers it.Side effects
-lnvhpcwrapnvtxwas a duplicate of what-cudalib=nvtx3adds.any()means.cmake/.Testing
On this PR's head, with NVHPC 26.9 and the CI jobs' flags (
FFLAGS=-tp=px -Kieee -noswitcherror):--test-all --no-mpi --only Hypoelasticity)3D_sphbubcollapse,--gpu acc)--gpu acc--gpu mp./mfc.sh precheckCI builds 26.9 for GPUs but does not run it there; the H100 rows cover that.
Earlier, on the previous master (
5791dd2f):--gpu accsuite on an H100, without the workaround: 47 failed, all hypoelasticity.The NVHPC 26.9 any() miscompile
At
-O2and above, 26.9 evaluatesany(i == shear_indices)inside a loop as always true. In 2D,shear_indices = [stress%beg + 1, 0, 0], so the normal stress τ_xx is counted as shear, and its elastic energy is added twice:pre_process(s_convert_primitive_to_conservative_variables), so the initial energy is wrong;m_variables_conversionandm_riemann_stateduring the run.For 34F3999B, the initial
Eis off by exactly τ²/(4G) in every cell (2.5e8 in patch 1, where G = 0.1).-O0/-O3,-fcheck=all), with every other NVHPC release tested (21.11 to 26.3) at-O2, and with 26.9 at-O1or-O2 -Mnovect.-O2gets it wrong even withshear_indices = [0, 0, 0].-Minline. A helper function that wrapsany()still miscompiles once inlined, so the macro spells the comparisons out.nvfortran -O2 r2.f90 && ./a.outprintse = 2.0on 26.9, and1.0on 26.3 and 25.9.Which releases take which NVTX branch, and what -cudalib=nvtx3 links
In the CI images' environment. "Link and run": MFC's
src/common/m_nvtx.f90linked with only-cudalib=nvtx3and run, with-accand with-mp=gpu.Releases that take the
-cudalib=nvtx3branch (CUDA ≥ 12.9):-cudalib=nvtx3adds--gpu acc/--gpu mpbuild-lnvhpcwrapnvtx -lnvtx3interopnvtxRangePushExsyscheckandpre_processbuild with both-lnvhpcwrapnvtx -lnvtx3interopnvtxRangePushExsyscheckandpre_processbuild with both-lnvhpcwrapnvtx -lnvtx3interop--gpu accbuilds (H100 node)-lnvhpcwrapnvtx -lnvtx3interopnvtxRangePushExsyscheckandpre_processbuild with both-lnvhpcwrapnvtx -lnvtx3interopnvtxRangePushExsyscheckandpre_processbuild with both-lnvhpcwrapnvtx -lnvtx3interopnvtxRangePushEx-lnvhpcnvtx -lnvtx3interopReleases with CUDA ≤ 12.8, which take the
CUDA::nvToolsExtbranch (checked with CMake for 21.11–24.5):-cudalib=nvtx3alonenvfortran-Error-Switch -cudalib with unknown keyword nvtx3nvtxRangePushA/nvtxRangePushEx(it adds only-lnvhpcwrapnvtx)So the version check has to stay. Always passing
-cudalib=nvtx3would break the clusters intoolchain/modulesthat use NVHPC 21.11–22.11.When CMake and nvfortran use different CUDA versions. A
cuda_multiinstall bundles more than one CUDA:FindCUDAToolkitfinds (PATH,CUDAToolkit_ROOT);-gpu=cudaX.YorNVHPC_CUDA_HOME.Every pairing was forced this way, and MFC's NVTX calls were linked and run:
-cudalib=nvtx3CUDA::nvToolsExt(11.8'slibnvToolsExt)-cudalib=nvtx3CUDA::nvToolsExt-cudalib=nvtx3cannot find -lnvhpcwrapnvtx-cudalib=nvtx3cannot find -lnvhpcwrapnvtx-cudalib=nvtx3cannot find -lnvhpcwrapnvtx-cudalib=nvtx3cannot find -lnvhpcwrapnvtxOn 25.5, the reviewer's case (CMake finds 11.8, nvfortran uses 12.9) links 11.8's
libnvToolsExt, which resolves the calls on its own. 26.9 bundles only CUDA 12.9 and 13.3, so every pairing takes this PR's branch, and master fails all four.NVTX on GPUs
--gpu acc, 2× H100 NVL--gpu acc, 2× H100 NVLnsys, H100 (./mfc.sh run ... --nsys,2D_riemann_test, 50 steps)TIMESTEP×50,COMPUTE-RHS×150,RHS-RIEMANN-SOLVER×300,RHS-RECONSTRUCTION×300ld: cannot find -lnvhpcwrapnvtxContribution Policy
All contributions are expected to demonstrate:
If these expectations are not met, we would prefer to implement the changes ourselves rather than spend time reviewing low-effort submissions.
Acknowledgement
This PR is from Diablo (Tsinghua University) participating in the SC26 Student Cluster Competition.