From e68ea2b0a45fd07d82d72fe114030e6118fee0d7 Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Tue, 21 Jul 2026 18:23:01 +0200 Subject: [PATCH 1/7] Patches for 2 rare, potential pitfalls: 1) Over/underrun of reflection list in calc_xsect() 2) Add guard for rand01()==1.0 edge case --- mcstas-comps/samples/PowderN.comp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/mcstas-comps/samples/PowderN.comp b/mcstas-comps/samples/PowderN.comp index 36f6baf586..81809bea1c 100644 --- a/mcstas-comps/samples/PowderN.comp +++ b/mcstas-comps/samples/PowderN.comp @@ -745,7 +745,10 @@ SHARE /* check if a line_info element has been recorded already - not on OpenACC */ #ifndef OPENACC if (v >= line_info->v_min && v <= line_info->v_max && line_info->neutron_passed >= CHAR_BUF_LENGTH) { - line = (int)floor (v - line_info->v_min) * CHAR_BUF_LENGTH / (line_info->v_max - line_info->v_min); + double frac = (v - line_info->v_min) / (line_info->v_max - line_info->v_min); + line = (int)floor(frac * CHAR_BUF_LENGTH); + if (line < 0) line = 0; + if (line >= CHAR_BUF_LENGTH) line = CHAR_BUF_LENGTH - 1; Nq = line_info->xs_Nq[line]; *sum = line_info->xs_sum[line]; if (!Nq && *sum == 0) { @@ -1172,10 +1175,11 @@ TRACE if (neutrontype == 3) { /* Make coherent scattering event */ if (line_info.count > 0) { /* choose line */ - if (Nq > 1) + if (Nq > 1) { line = floor (Nq * rand01 ()); /* Select between Nq powder lines */ - else - line = 0; + if (line >= Nq) line = (int)Nq - 1; /* guard rand01()==1.0 edge case */ + } else + line = 0; if (line_info.w_v[line]) arg = line_info.q_v[line] * (1 + line_info.w_v[line] * randnorm ()) / (2.0 * v); else From 8162da309ec01e05039319fa8dfcdfc221759a3d Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Tue, 21 Jul 2026 21:34:44 +0200 Subject: [PATCH 2/7] Fix for unbound labeldir var, temporarily test BNL only --- .github/workflows/mcstas-conda-testsuite.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/mcstas-conda-testsuite.yml b/.github/workflows/mcstas-conda-testsuite.yml index 629e2cf7ca..e4a394071d 100644 --- a/.github/workflows/mcstas-conda-testsuite.yml +++ b/.github/workflows/mcstas-conda-testsuite.yml @@ -107,7 +107,7 @@ jobs: export TMPDIR=${HOME}/tmp fi # Run the test with 2 core mpi - ${MCTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=2 + ${MCTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=2 --instr=BNL_H8_simple - name: 'Tar output files' id: tar-package @@ -207,7 +207,7 @@ jobs: # predict, so identify it via the source artifact/tarball name # instead of hardcoding it. if [[ "$tgz" == *"ubuntu-latest"* ]]; then - REFLABEL=$(basename "$labeldir") + REFLABEL=$(basename "$tgz") fi rm -rf "$work" done From 198304ccabaffa38e0c95553c7b6f2225bfc3ae7 Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Tue, 21 Jul 2026 21:52:57 +0200 Subject: [PATCH 3/7] Remodel from basictest solution --- .github/workflows/mcstas-conda-testsuite.yml | 36 +++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/mcstas-conda-testsuite.yml b/.github/workflows/mcstas-conda-testsuite.yml index e4a394071d..5aa7e2a31a 100644 --- a/.github/workflows/mcstas-conda-testsuite.yml +++ b/.github/workflows/mcstas-conda-testsuite.yml @@ -200,31 +200,33 @@ jobs: for tgz in downloaded_artifacts/*/*.tgz; do work=$(mktemp -d) tar xzf "$tgz" -C "$work" - mv "$work"/run_test-suite/* mcstas-nightly/ - - # Linux (ubuntu-latest) is the reference platform; the label - # name itself embeds a version string and timestamp we can't - # predict, so identify it via the source artifact/tarball name - # instead of hardcoding it. - if [[ "$tgz" == *"ubuntu-latest"* ]]; then - REFLABEL=$(basename "$tgz") - fi + artifact_name=$(basename "$(dirname "$tgz")") + + for labeldir in "$work"/run_test-suite/*/; do + if [[ "$artifact_name" == *"ubuntu-latest"* ]]; then + REFLABEL=$(basename "$labeldir") + fi + mv $labeldir mcstas-nightly/ + done + done rm -rf "$work" - done if [ -z "$REFLABEL" ]; then - echo "ERROR: could not identify the Linux/reference column (ubuntu-latest artifact missing?)" - exit 1 + echo "WARNING: could not identify the ubuntu-latest/conda reference column" + else + echo "REFLABEL=$REFLABEL" >> "$GITHUB_ENV" + echo "Reference column: $REFLABEL" fi - echo "REFLABEL=$REFLABEL" >> "$GITHUB_ENV" - echo "Reference column: $REFLABEL" - ls mcstas-nightly - - name: 'Run mcviewtest across all platform columns' id: viewtest run: | - cd "$PWD/mcstas-nightly" && mcviewtest --reflabel "$REFLABEL" --nobrowse + cd "$PWD/mcstas-nightly" + if [ -z "$REFLABEL" ]; then + mcviewtest --reflabel "$REFLABEL" --nobrowse + else + mcviewtest --reflabel --nobrowse + fi - name: 'Tar mcstas-nightly output (all platform folders + comparison table)' id: tar-package From 31195549d90de6adf126c2bfadcb9c8e9a08f585 Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Tue, 21 Jul 2026 22:05:58 +0200 Subject: [PATCH 4/7] Now works again. Use mpi=auto and sync McStas <-> McXtrace --- .github/workflows/mcstas-conda-testsuite.yml | 3 +- .../workflows/mcxtrace-conda-testsuite.yml | 36 +++++++++---------- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/.github/workflows/mcstas-conda-testsuite.yml b/.github/workflows/mcstas-conda-testsuite.yml index 5aa7e2a31a..d27ac04dd2 100644 --- a/.github/workflows/mcstas-conda-testsuite.yml +++ b/.github/workflows/mcstas-conda-testsuite.yml @@ -107,8 +107,7 @@ jobs: export TMPDIR=${HOME}/tmp fi # Run the test with 2 core mpi - ${MCTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=2 --instr=BNL_H8_simple - + ${MCTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=auto - name: 'Tar output files' id: tar-package if: always() diff --git a/.github/workflows/mcxtrace-conda-testsuite.yml b/.github/workflows/mcxtrace-conda-testsuite.yml index ff0247e779..bce716a2e1 100644 --- a/.github/workflows/mcxtrace-conda-testsuite.yml +++ b/.github/workflows/mcxtrace-conda-testsuite.yml @@ -107,7 +107,7 @@ jobs: export TMPDIR=${HOME}/tmp fi # Run the test with 2 core mpi - ${MXTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=2 + ${MXTEST_EXECUTABLE} --verbose --testdir $PWD --suffix ${{ matrix.os }}_${{ matrix.mpi }} --mpi=auto - name: 'Tar output files' id: tar-package @@ -201,35 +201,33 @@ jobs: for tgz in downloaded_artifacts/*/*.tgz; do work=$(mktemp -d) tar xzf "$tgz" -C "$work" - labeldir=$(ls -d "$work"/run_test-suite/*/) - mv "$labeldir" mcxtrace-nightly/ - - # Linux (ubuntu-latest) is the reference platform; the label - # name itself embeds a version string and timestamp we can't - # predict, so identify it via the source artifact/tarball name - # instead of hardcoding it. - if [[ "$tgz" == *"ubuntu-latest"* ]]; then + artifact_name=$(basename "$(dirname "$tgz")") + + for labeldir in "$work"/run_test-suite/*/; do + if [[ "$artifact_name" == *"ubuntu-latest"* ]]; then REFLABEL=$(basename "$labeldir") fi + mv $labeldir mcxtrace-nightly/ + done + done rm -rf "$work" - done if [ -z "$REFLABEL" ]; then - echo "ERROR: could not identify the Linux/reference column (ubuntu-latest artifact missing?)" - exit 1 - fi - + echo "WARNING: could not identify the ubuntu-latest/conda reference column" + else echo "REFLABEL=$REFLABEL" >> "$GITHUB_ENV" echo "Reference column: $REFLABEL" - ls mcxtrace-nightly + fi - name: 'Run mxviewtest across all platform columns' id: viewtest run: | - set -e - set -u - set -x - cd "$PWD/mcxtrace-nightly" && mxviewtest --reflabel "$REFLABEL" --nobrowse + cd "$PWD/mcxtrace-nightly" + if [ -z "$REFLABEL" ]; then + mxviewtest --reflabel "$REFLABEL" --nobrowse + else + mxviewtest --reflabel --nobrowse + fi - name: 'Tar mcxtrace-nightly output (all platform folders + comparison table)' id: tar-package From dd80dd25695c1cdd49a9311c7669ca540aa0d33b Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Wed, 22 Jul 2026 09:08:36 +0200 Subject: [PATCH 5/7] Port edge-case protection from McStas PowderN to McXtrace --- mcxtrace-comps/samples/PowderN.comp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mcxtrace-comps/samples/PowderN.comp b/mcxtrace-comps/samples/PowderN.comp index 554381372c..6599e9548e 100644 --- a/mcxtrace-comps/samples/PowderN.comp +++ b/mcxtrace-comps/samples/PowderN.comp @@ -596,7 +596,10 @@ SHARE /* check if a line_info element has been recorded already - not on OpenACC */ #ifndef OPENACC if (k >= line_info->k_min && k <= line_info->k_max && line_info->photon_passed >= CHAR_BUF_LENGTH) { - line = (int)floor (k - line_info->k_min) * CHAR_BUF_LENGTH / (line_info->k_max - line_info->k_min); + double frac = (k - line_info->k_min) / (line_info->k_max - line_info->k_min); + line = (int)floor(frac * CHAR_BUF_LENGTH); + if (line < 0) line = 0; + if (line >= CHAR_BUF_LENGTH) line = CHAR_BUF_LENGTH - 1; Nq = line_info->xs_Nq[line]; *sum = line_info->xs_sum[line]; if (!Nq && *sum == 0) { @@ -1070,9 +1073,10 @@ TRACE if (photontype == 3) { /* Make coherent scattering event */ if (line_info.count > 0) { /* choose line */ - if (Nq > 1) + if (Nq > 1) { line = floor (Nq * rand01 ()); /* Select between Nq powder lines */ - else + if (line >= Nq) line = (int)Nq - 1; /* guard rand01()==1.0 edge case */ + } else line = 0; if (line_info.w[line]) arg = line_info.q[line] * (1 + line_info.w[line] * randnorm ()) / (2.0 * k); From 2919822acaaddd24e05cc026122d0c935a859bec Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Wed, 9 Sep 2026 20:37:49 +0200 Subject: [PATCH 6/7] Manual patch with @Lomholy's version from https://github.com/mccode-dev/McCode/pull/2622 --- mcstas-comps/samples/PowderN.comp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/mcstas-comps/samples/PowderN.comp b/mcstas-comps/samples/PowderN.comp index 81809bea1c..33eb31cdee 100644 --- a/mcstas-comps/samples/PowderN.comp +++ b/mcstas-comps/samples/PowderN.comp @@ -165,7 +165,6 @@ * density: [g/cm^3] Density of material. rho=density/weight/1e24*N_A. * nb_atoms: [1] Number of sub-unit per unit cell, that is ratio of sigma for chemical formula to sigma per unit cell * target_index: [1] Relative index of component to focus incoherent scattering at, e.g. next is +1 -* order: [1] Flag that determines whether the intensity should (1) not (0) be dampened by weighting multiple scattering * * CALCULATED PARAMETERS: * line_info: [struct] internal structure containing many members/info @@ -206,7 +205,7 @@ SETTING PARAMETERS (string reflections="NULL", string geometry="NULL", radius=0, yheight=0, xwidth=0, zdepth=0, thickness=0, pack=1, Vc=0, sigma_abs=0, sigma_inc=0, delta_d_d=0, p_inc=0.1, p_transmit=0.1, DW=0, nb_atoms=1, d_omega=0, d_phi=0, tth_sign=0, p_interact=0.8, - concentric=0, density=0, weight=0, barns=1, Strain=0, focus_flip=0, int target_index=0, int order=1) + concentric=0, density=0, weight=0, barns=1, Strain=0, focus_flip=0, int target_index=0) DEPENDENCY "@NCRYSTALFLAGS@" @@ -452,9 +451,7 @@ SHARE struct line_data* list = NULL; list = (struct line_data*)malloc (nhkl * sizeof (struct line_data)); if (!list) { - exit (fprintf (stderr, - "PowderN: %s: Error: Could not allocate line array\n", - info->compname)); + exit (fprintf (stderr, "PowderN: %s: Error: Could not allocate line array\n", info->compname)); } info->sigma_a = ncrystal_info_getxsectabsorption (ncobj); info->sigma_i = ncrystalpowdern_determine_sigma_inc (ncobj); @@ -608,9 +605,7 @@ SHARE /* allocate line_data array */ list = (struct line_data*)malloc (size * sizeof (struct line_data)); if (!list) { - exit (fprintf (stderr, - "PowderN: %s: Error: Could not allocate line array\n", - info->compname)); + exit (fprintf (stderr, "PowderN: %s: Error: Could not allocate line array\n", info->compname)); } for (i = 0; i < size; i++) { @@ -1145,11 +1140,7 @@ TRACE } else { dt = dt * (t3 - t2) + (t2 - t0); /* Possibly also 'backside' part */ } - if (order) { - my_s = line_info.my_s_v2_sum / (v * v) + line_info.my_inc; - } else { - my_s = line_info.my_inc; - } + my_s = line_info.my_s_v2_sum / (v * v) + line_info.my_inc; /* Total attenuation from scattering */ lfree = 0; ntype = rand01 (); @@ -1179,7 +1170,7 @@ TRACE line = floor (Nq * rand01 ()); /* Select between Nq powder lines */ if (line >= Nq) line = (int)Nq - 1; /* guard rand01()==1.0 edge case */ } else - line = 0; + line = 0; if (line_info.w_v[line]) arg = line_info.q_v[line] * (1 + line_info.w_v[line] * randnorm ()) / (2.0 * v); else From 036cd2a5b5e713d5346ac37c07a77882858c3e71 Mon Sep 17 00:00:00 2001 From: Peter Willendrup Date: Wed, 9 Sep 2026 21:27:44 +0200 Subject: [PATCH 7/7] Trigger 'RUNALL' if > 5 comps were changed. --- .github/workflows/mcstas-basictest.yml | 7 +++++-- .github/workflows/mcxtrace-basictest.yml | 11 +++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mcstas-basictest.yml b/.github/workflows/mcstas-basictest.yml index 27c8218145..3ddf1beeb0 100644 --- a/.github/workflows/mcstas-basictest.yml +++ b/.github/workflows/mcstas-basictest.yml @@ -429,13 +429,14 @@ jobs: export DIFFBASE=$(git merge-base origin/main HEAD) fi echo "Diffing against: $DIFFBASE" - + export RUNALL="NO" export CHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcstas-comps | xargs -n1 basename | sed 's/\.comp//g' | sort | uniq | xargs echo) export NUMCHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcstas-comps | wc -l | xargs echo) cd - compindex=0 if [ "$NUMCHANGEDCOMPS" != "0" ]; then + if [ "$NUMCHANGEDCOMPS" -lt "5" ]; then for comp in $CHANGEDCOMPS; do echo Finding tests including component $comp @@ -448,10 +449,12 @@ jobs: echo No matching tests found fi done + else + export RUNALL="YES" + fi fi cd src - export RUNALL="NO" export CHANGEDINSTR=$(git diff --name-only $DIFFBASE HEAD | grep '\.instr$' | grep mcstas-comps | xargs -n1 basename | sed 's/\.instr//g' | sort | uniq | xargs echo | sed 's/ /,/g') export NUMCHANGEDINSTR=$(git diff --name-only $DIFFBASE HEAD | grep '\.instr$' | grep mcstas-comps | wc -l | xargs echo) echo ---- diff --git a/.github/workflows/mcxtrace-basictest.yml b/.github/workflows/mcxtrace-basictest.yml index 4f9cb5a0bd..36ded9b846 100644 --- a/.github/workflows/mcxtrace-basictest.yml +++ b/.github/workflows/mcxtrace-basictest.yml @@ -436,13 +436,14 @@ jobs: export DIFFBASE=$(git merge-base origin/main HEAD) fi echo "Diffing against: $DIFFBASE" - - export CHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcxtrace-comps | xargs -n1 basename | sed 's/\.comp//g' | sort | uniq | xargs echo) - export NUMCHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcxtrace-comps | wc -l | xargs echo) + export RUNALL="NO" + export CHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcstas-comps | xargs -n1 basename | sed 's/\.comp//g' | sort | uniq | xargs echo) + export NUMCHANGEDCOMPS=$(git diff --name-only $DIFFBASE HEAD | grep '\.comp$' | grep mcstas-comps | wc -l | xargs echo) cd - compindex=0 if [ "$NUMCHANGEDCOMPS" != "0" ]; then + if [ "$NUMCHANGEDCOMPS" -lt "5" ]; then for comp in $CHANGEDCOMPS; do echo Finding tests including component $comp @@ -455,10 +456,12 @@ jobs: echo No matching tests found fi done + else + export RUNALL="YES" + fi fi cd src - export RUNALL="NO" export CHANGEDINSTR=$(git diff --name-only $DIFFBASE HEAD | grep '\.instr$' | grep mcxtrace-comps | xargs -n1 basename | sed 's/\.instr//g' | sort | uniq | xargs echo | sed 's/ /,/g') export NUMCHANGEDINSTR=$(git diff --name-only $DIFFBASE HEAD | grep '\.instr$' | grep mcxtrace-comps | wc -l | xargs echo) echo ----