docs: add Ansys Mechanical (MAPDL) best-practices Readme - #12
Conversation
…est practices Adds the missing best-practices doc for Ansys Mechanical (MAPDL), covering: - required legacy X11/Motif libraries on Amazon Linux 2023, where Ansys bundles each one, the libpng12 build recipe, and three dependency traps - scheduler execution: non-root requirement (-ssh + Intel MPI), HOME, module guard in non-login shells, dnf vs yum, -machines carrying the core count - EFA settings and how to verify the efa libfabric provider is in use - memory-first performance guidance: in-core vs out-of-core, sizing to the model's memory requirement, node-adding vs core-adding, under-population with flexible-cores pinning - scratch-space/concurrency planning for shared filesystems and how heavy sharing distorts benchmark timings - the exit-code trap: fixed-iteration benchmark models exit non-zero after a successful run; success must be judged from RUN COMPLETED + Elapsed Time - the V26 Cluster benchmark set table (from the package's JOBS.CONFIG) Performance section intentionally TBC.
…from dnf Only mesa-libGLU is packaged for AL2023. libXp and Motif are not in the repositories, libpng12 is EOL and absent, the old libxcb-* sonames were removed upstream years ago, and AL2023 does not support EPEL. Also notes the operational advantage of the shared-filesystem compat dir on ParallelCluster: ephemeral compute nodes need no per-node install.
- link r7i/r8i (and NVMe-carrying variants) like the other instance types - make the filesystem-exhaustion warning generic instead of citing our setup - exit codes: still scan logs for genuine errors; robust success test is RUN COMPLETED + Elapsed Time + no unexpected *** ERROR *** entries - explain why the package's default increments (16/32/64/128) map poorly onto the 24-CCD x 8-core topology of Hpc7a/Hpc8a and recommend 24/48/96/192 via INCREMENT LIST for even L3/CCD loading - recommend local NVMe instance store (/scratch on ParallelCluster) for solver scratch on Hpc6id/r7id/r8id/i-family: faster and cheaper than shared FS, and removes out-of-core I/O from the shared filesystem entirely
AnsysMechanical.sbatch: - success detection from the OUTPUT, not the exit code: RUN COMPLETED + final Elapsed Time + no unexpected *** ERROR *** entries. Fixed-iteration benchmark decks exit non-zero after a successful run, so exit-code gating silently discarded valid results (incl. recording). - refuse to run as root (ssh remote launch + Intel MPI both fail as root) - guard for non-login shells; guard unset/unwritable HOME - dnf with yum fallback for mesa-libGLU; test for the library itself - optional legacy-libs compat dir (ANSYS_COMPAT_DIR) for AL2023 - SCRATCH_MODE=auto|nvme|shared: run the solve from node-local instance-store NVMe (/scratch) when available on all nodes. Verified single- AND multi-node: per-node workdir creation, inputs as symlinks read by the master, output copied back to the shared FS, per-node scratch reclaim (warm nodes are reused). Out-of-core solves benefit most and shared-FS contention is removed. - record memory_mode (InCore/OutOfCore), scratch_mode and MAPDL's own elapsed seconds alongside the wall time dynamodb/record-benchmark.sh: - fix Elapsed-Time fallback parse: the summary line ends with a Date field, so taking the LAST number recorded the YEAR as the solve time; now parses the value immediately after '='. Readme.md: document the verified multi-node NVMe mechanics (per-node mkdir, master-only inputs, output copy-back, per-node reclaim) and point at the sbatch.
|
Thanks for putting this together — the README fills a real gap, and changing the official fixed-iteration benchmark handling away from raw MAPDL exit-code gating is directionally correct. I validated the current tip (
Blocking: solve verdict can invert success and failureThe current classifier is whitespace-sensitive and removes individual context lines rather than classifying complete MAPDL error blocks: unexpected_errs=$(grep -A2 '^ \*\*\* ERROR' "$output_file" \
| grep -v 'iterations exceeds' | grep -c '^ \*\*\* ERROR' || true)I ran the exact PR logic against representative fixtures. Results: Two underlying issues:
[ "$solve_ok" -eq 1 ] && exit 0 || exit "$_rec_rc"Please parse complete, indentation-insensitive MAPDL error blocks and whitelist only the exact known benign fixed-iteration/user-request signature. Normalize a nonzero status only when that exact signature, final Blocking: failed stage-out can delete the only solver logThe shared-filesystem copy result is discarded and local scratch is then deleted unconditionally: cp -f "$output_file" "$shared_dir/" 2>/dev/null
srun ... rm -rf "$workdir"If the shared filesystem is full, unavailable, or denies the write, this destroys the only MAPDL output. The job may still exit zero and even record a result from the already-parsed local log. Make successful durable stage-out a prerequisite for cleanup and success. On copy failure, retain Recorder validity/replayThe zero-argument parser scans only Please:
Documentation/operational correctionsThese should be addressed in the same update:
Given how subtle the verdict boundary is, please add fixture-driven shell tests for: normal completion, exact benign fixed-iteration termination, genuine errors with varied indentation, truncated output with I’m holding approval/merge on the three behavioral blockers: verdict/status normalization, destructive stage-out, and invalid recorder timing/replay. Happy to re-review immediately after an update. |
…e timing Addresses the three behavioural blockers from review, plus the documentation and operational corrections, and adds the requested fixture-driven tests. Blocker 1 - the solve verdict could invert success and failure. The old classifier removed individual context lines and anchored on '^ \*\*\* ERROR' (exactly one leading space). Reproducing it against fixtures confirmed all six reported cases, and two more: fixture rc old verdict new verdict normal completion 0 ok ok fixed-iteration stop 1 REJECTED (wrong) accepted, rc->0 column-zero real error 2 ACCEPTED (wrong) failed, rc=2 deep-indent real error 2 ACCEPTED (wrong) failed, rc=2 truncated output 0 SUCCESS (wrong) failed, rc=3 clean output, unrelated rc 42 MASKED to 0 (wrong) failed, rc=42 zero elapsed 0 ACCEPTED (wrong) failed, rc=3 negative elapsed 0 SUCCESS (wrong) failed, rc=3 Verdict logic now lives in lib/mapdl-verdict.sh, sourced by the sbatch so it is testable. It classifies complete, indentation-insensitive error blocks; whitelists only the exact iteration-limit/user-request signature; requires RUN COMPLETED, a positive elapsed time and zero unexpected blocks; normalises a non-zero status only when that benign signature explains it; and synthesises a non-zero status when MAPDL returns 0 for an unverified run. An error block with an empty body now counts as unexpected rather than being invisible. Blocker 2 - a failed stage-out could delete the only solver log. mapdl_stage_out() verifies the destination exists, is non-empty and matches the source byte count. Scratch reclamation is gated on it; on failure the job retains /scratch, prints the node and path needed for recovery, and fails. Blocker 3 - recorder validity and replay. Discovery now includes the launcher's output-<jobid>.log. Timing must be finite and > 0 whether explicit or derived. Automatically derived timing additionally requires RUN COMPLETED and no unexpected error blocks. Explicit valid values stay authoritative and DynamoDB failure stays non-fatal. --dry-run now emits pure JSON on stdout (banner moved to stderr) so it can be piped to a parser. Also: - Per-host core counts come from SLURM_TASKS_PER_NODE instead of ntasks/nodes; the job aborts if the -machines total does not equal SLURM_NPROCS. README and launcher now agree, and neither rounds. - HOME is recovered from the passwd database; a temporary HOME is only used for single-node runs, since -ssh needs the real ~/.ssh identity. - libpng 1.2.59 recipe gains a verified sha256 (4bd4b5ce...1e9e, matching SourceForge's published file metadata), the GPG signature alternative, prerequisites, and an explicit EOL/security trade-off with scoping guidance. - Library paths are scoped to the tested 2026 R1, with a find recipe for other releases; the "2023 and newer" claim now covers only the general guidance. - EFA: distinguishes the fail-closed pinned-provider case from the silent TCP fallback that occurs without the provider filter. - Root refusal is grounded in the SSH identity and least privilege, not an Open MPI diagnostic. - Performance claims qualified to the configurations actually tested. Tests (tests/run-tests.sh; no Slurm, solver, credentials or network): 63 cases. 28 verdict/stage-out, 17 recorder, 18 end-to-end runs of the assembled sbatch with stubbed scheduler/solver commands - which also closes the gap that the launcher had only ever been syntax-checked, never executed.
|
Thanks — this was a good catch, and validating against fixtures rather than reading the diff was the right call. All three blockers were real. Fixed in I reproduced your exact expression against the fixtures first, to be sure I was fixing the reported behaviour and not my reading of it. It confirms all six of your rows, plus two more I hadn't considered:
The last two are the ones I'd missed: Verdict / status normalisationMoved into It parses complete error blocks (marker matched anywhere on the line, block ends at a blank line, the next marker, or a box rule), and classifies each block whole rather than filtering lines — so removing a matching detail line can no longer leave its header behind to be counted. Only the exact iteration-limit/user-request signature is whitelisted.
One extra fail-open case surfaced while testing: an error block with an empty body printed a blank line, which Stage-out
RecorderDiscovery includes Two incidental fixes found by the new tests: Documentation and operational itemsAll seven addressed. Two worth calling out:
The remaining items: Tests
That last suite also closes a gap I should have flagged myself in the previous revision: the launcher had only ever been Performance section remains TBC at the data owner's request. Ready for re-review. |
Summary
apps/AnsysMechanical/shipped only an sbatch and the DynamoDB recorder — unlike CFX/Fluent/Abaqus there was no best-practices doc. This addsapps/AnsysMechanical/Readme.md, written from running the full official V26 Cluster benchmark set (all six models, DMP, Intel MPI + EFA) on AWS ParallelCluster 3.16 / Amazon Linux 2023.What it covers
ansys.elinks a legacy X11/Motif stack absent from AL2023. Table of every missing library and where Ansys bundles it, a build recipe forlibpng12(not bundled, not in any repo, cannot be faked with a libpng16 symlink due to versioned symbols), and three dependency traps discovered the hard way.-sshneeds the inter-node keypair; Intel MPI refuses root);HOMEmust be set;moduleguard for non-login shells;dnfvsyum;-machinescarries the core count (no-npin DMP).efalibfabric provider is actually in use (I_MPI_DEBUG=5) — TCP fallback is silent.Utils/flexible-corespinning lists (and why lowering--ntasks-per-nodealone is insufficient).RUN COMPLETED+Elapsed Timein the output (as Ansys's own runBench.py does). Automation gating on exit code silently drops valid results — including the recorder wiring in the current sbatch.Testing
Every item was hit and verified while running the official V26 Cluster set (V26direct-4/5/6, V26iter-4/5/6) across hpc8a/hpc7a/hpc6a/hpc6id/c8i on ParallelCluster 3.16, AL2023, FSx for Lustre PERSISTENT_2.
Not included
Performance numbers — the Performance section is intentionally TBC; measured scaling/instance-comparison charts to follow separately.