Repository navigation
Conversation
(Mismatching prototype vs. system-provided sort on macOS)
…appers. (Work remains, some of the comments need to go back in etc...)
) Ported from #2968 (review for UB/OpenACC hazards): - findroots/findroots_gpu wrote into vf_list[20] without a bound check. The inserts are now bounded by BVK_MAX_ROOTS (= size of vf_list). - nf == 0 now ABSORBs (before, it read an unset vf_list[0]), and the index is clamped to nf-1 because rand01() may return 1.0. - SHARE used Phonon_simple's PHONON_SIMPLE guard while defining incompatible nbose/fatalerror/omega_q/zridd/findroots, so instruments combining it with Phonon_simple or Magnon_bcc could not compile. The guard is now PHONON_BVK_PG, and the helpers are prefixed bvk_. - #define DV became BVK_DV: it clobbered the DECLARE variable DV of Phonon_simple, Magnon_bcc and others. - #define pi removed: it broke components that declare a variable named pi. Test_Phonon_BvK_PG relied on the leaked macro and now uses PI. No numerical change: Test_Phonon_BvK_PG (-n 1e6 --seed=1) is bit-identical. Phonon_BvK_PG + Phonon_simple + Magnon_bcc now builds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…SHARE The component is NOACC (its root finder takes a function pointer), so it runs on the CPU. The routine directives still made nvc build these helpers, and by implication the James Avery eigen solver they call, for the device. eigen.c's fprintf then fails to compile: "NVC++-S-1058-Call to variadic function not supported - fprintf". CPU output is unchanged (Test_Phonon_BvK_PG bit-identical). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…op NOACC eigen.c/.h (James Avery Hermitian eigen solver): - Replace the per-call malloc scratch in eigensystem_hermitian, QHQ, T_QTQ, reflect_region, apply_reflection and matrix_inplace_multiply with fixed-size stack arrays of EIGEN_MAXN (default 12, overridable). On the CPU, n > EIGEN_MAXN aborts with a message. This also removes the leaks of the old row/vHA/col/Q_tmp buffers. - memset/memcpy become plain loops. - Guard the non-convergence fprintf with #ifndef OPENACC. The TIME_EIGENSYSTEMS counter/timing is now CPU-only. - Mark the device-path functions "#pragma acc routine seq" (prototypes and definitions). Phonon_BvK_PG.comp: - TRACE no longer writes shared state. The phonon mode moves from a SHARE global into p_call[13], read by bvk_omega_q. p_call, eigenvectormode, q and q_x/q_y/q_z move from DECLARE into TRACE locals; unused DECLARE members (Matrix, i, j, qx, qy, qz) are gone. - One root finder for CPU and GPU: bvk_zridd/bvk_findroots no longer take a function pointer, and the last_fh/last_x2 globals become findroots locals passed by pointer. bvk_zridd_gpu and bvk_findroots_gpu are removed. - The globals read on the device (verbose, shape, M, Delta, astar, cstar, r_j13, Phi1..Phi14) get "acc declare create" and an "acc update device" at the end of INITIALIZE. - The NaN check in bvk_omega_q (fprintf/abort) is CPU-only. - Restore "#pragma acc routine seq" on the SHARE helpers and remove NOACC. CPU output is bit-identical to bd2d044: Test_Phonon_BvK_PG, --seed=1, 8 parameter sets on 12 MPI ranks and 4 single-process sets, including Verbose=7, DISP=1 and DISP=2. GPU execution is not tested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sqrt3 macro had an L suffix, so the TRACE lines qk/qh and q_Bragg[1] (x / sqrt3) were computed in long double. nvc cannot do x87 long double on the device and failed with "Accelerator restriction: unsupported operation: X87TODP" in class_Phonon_BvK_PG_trace. Numerical behaviour: on arm64 and MSVC (long double == double) output is bit-identical. On x86_64 (80-bit long double) weights change in the last bits: Test_Phonon_BvK_PG --seed=1 -n 1e5, built for x86_64 and run under Rosetta, has identical counts in every bin and integrated intensities within ~1e-8 relative. A few near-zero-weight events change more, probably because the nearest-Bragg-point choice flips on a tie. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…o 'exit') - nrerror(): guard the body (printf + exit) with #ifndef OPENACC, like bvk_fatalerror. The illegal-mode branch in TRACE now ABSORBs after nrerror; only the GPU reaches that line, and there it avoids indexing eigenvalue/index arrays with an out-of-range mode. - TRACE "Did not hit sample surface from inside": exit(1) on the CPU, ABSORB under OPENACC. The rest of the device path (TRACE, bvk_omega_q, bvk_zridd, bvk_findroots, eigen.c) has no exit/abort/fprintf left when preprocessed with -DOPENACC. CPU output is bit-identical to cfe4e8a on arm64 and x86_64 (Test_Phonon_BvK_PG --seed=1: defaults, phononmode=3, phononmode=12, E_steps=1, DISP=1; data and stdout). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #2344. It replaces the stop-gap in bd2d044 (pragmas removed, component NOACC) with a real OpenACC port.
What changed
mcstas-comps/share/eigen.c/eigen.h(James Avery Hermitian eigen solver)eigensystem_hermitian,QHQ,T_QTQ,reflect_region,apply_reflectionandmatrix_inplace_multiplyused tomallocscratch on every call, many times per neutron. They now use fixed-size stack arrays sized byEIGEN_MAXN. It defaults to 12 and can be overridden with#ifndef. On the CPU,n > EIGEN_MAXNaborts with a message. This also removes the leaks:row,vHA,colandQ_tmpwere never freed.memset/memcpyare now plain loops.fprintfis wrapped in#ifndef OPENACC. TheTIME_EIGENSYSTEMScall counter and timing are CPU-only (#if TIME_EIGENSYSTEMS && !defined(OPENACC)).#pragma acc routine seqis on every device-path function, on both the prototype and the definition.mccode-complex-libwrappers, with no type-punning.D/Lineigensystem_hermitianare sizedEIGEN_MAXN+1, becauseT_QTQ(n)readsDin[n]. That element is unused padding, but with exactlynelements the read was out of bounds, as it already was on the heap before.mcstas-comps/contrib/Phonon_BvK_PG.compmodemoves intop_call[13]and is read bybvk_omega_q.p_call,eigenvectormode,qandq_x/q_y/q_zmove from DECLARE to TRACE locals.Matrix,i,j,qx,qy,qz.bvk_zridd/bvk_findrootsno longer take a function pointer.last_fh/last_x2globals becomebvk_findrootslocals passed by pointer.bvk_zridd_gpu/bvk_findroots_gpuare removed. They used a different bracketing, and their high-side upper bound used the wrong range.bvk_fatalerror,bvk_zriddreturnsUNUSEDinstead of0.0. That line is only reachable on the GPU, where the bracket is now dropped instead of adding av_f = 0root.verbose,shape,M,Delta,astar,cstar,r_j13andPhi1..Phi14get#pragma acc declare create(...)in SHARE and#pragma acc update device(...)at the end of INITIALIZE.bvk_omega_q(fprintf/abort) is CPU-only.#pragma acc routine seqlines are back on the SHARE helpers, andNOACCis removed.sqrt3is now adoubleliteral (3a6b482). It used to have anLsuffix, soqk,qhandq_Bragg[1]in TRACE were computed in long double. nvc failed on that withAccelerator restriction: unsupported operation: X87TODPinclass_Phonon_BvK_PG_trace.Numerical behaviour
Changed in the last bits on x86_64 only, because of the
sqrt3fix. b49a15d alone is bit-identical on both arm64 and x86_64.Test_Phonon_BvK_PG --seed=1 -n 1e5, built for x86_64 and run under Rosetta, was checked for the default parameters,phononmode=3,phononmode=12andphononmode=7 l=2.5 E=8. The per-bin counts are identical, so the trajectories are the same. Integrated intensities agree to about 1e-8 relative, far below the statistical error. A few events with near-zero weight (about 1e-36) change more, probably because the nearest-Bragg-point choice flips on a tie.phononmode=7stays bit-identical.What was tested
macOS arm64, clang,
mccode-devmicromamba env. Base was bd2d044, new was b49a15d.Test_Phonon_BvK_PG,--seed=1, throughmcrun(12 MPI ranks for both base and new), with 8 parameter sets:phononmode=3phononmode=12phononmode=7 l=2.5 E=8E_steps_low=1 E_steps_high=1 phononmode=2DISP=1 phononmode=5DISP=2 phononmode=1Verbose=2 phononmode=4Each set is
-n 1e5, except theDISPsets (1e4) and theVerboseset (1e3). Every monitor's data is bit-identical. Only the# Dateheader differs.Single-process runs (binary run directly), comparing data and stdout exactly, with 4 sets:
-n 1e5DISP=1DISP=2Verbose=7 phononmode=12: about 195k lines that print every eigen-solver Q matrix and eigenvalue setAll are bit-identical, data and stdout.
Warnings: the generated C compiled with
clang -std=c99 -Wall -Wextragives the same 77 warnings as the base. All of them are pre-existing, and none are new.-DOPENACCsyntax check: the generated C was syntax-checked with clang and stubopenacc.h/accelmath.hheaders, so the#ifndef OPENACCbranches are at least well-formed.Not tested:
nvclocally. Theubuntu-24.04.conda.classic.gcc.openmpi.openaccCI job compiles with nvc (-n0), and that is the first real check of this port. Nobody has run it on a GPU.Open questions
mccode-complex-lib. The device path callscreal,cimag,conjandcabs(eigen.c) andcexp(TRACE), plus the library'sinlinewrappers, which have noacc routine. I expect nvc to generate implicit device routines for them, but I have not verified it. If nvc rejects them, the fix belongs inmccode-complex-lib.h, orcexp(cplx(0,x))can becomecplx(cos(x),sin(x)). The latter might not be bit-identical on every libm.bvk_omega_qtogether witheigensystem_hermitiankeeps about 13 KB of stack arrays per thread (several 12×12cdoublematrices). That may need a larger device stack or a smaller footprint.verboseandshapeare still SHARE globals, so two instances with different shapes or verbosity would interfere. Movingshapeinto DECLARE is simple.verboseis read insidebvk_omega_q, so it would have to be passed in.rand01()==1.0edge, not changed here. Withmode_input == 12,mode = round(12*rand01() - 0.5)gives 12 whenrand01()returns exactly 1.0.nrerrorthen callsexit. A clamp would be a one-line follow-up.exiton the device.nrerrorand TRACE still callexit. That matches Phonon_simple, which builds under nvc, but it would be cleaner toABSORBon the GPU.Refs #2988
🤖 Generated with Claude Code