From 3ac1ea62893fc44e07cbcfd11838c502e7f7785c Mon Sep 17 00:00:00 2001 From: Premas Date: Tue, 13 Aug 2024 14:04:17 -0500 Subject: [PATCH 01/12] add sections --- docs/cheaha/system_testing.md | 11 +++++++++++ mkdocs.yml | 1 + 2 files changed, 12 insertions(+) create mode 100644 docs/cheaha/system_testing.md diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md new file mode 100644 index 0000000..3edd955 --- /dev/null +++ b/docs/cheaha/system_testing.md @@ -0,0 +1,11 @@ +# System Performance Testing with Phoronix Test Suite Benchmarks + +The Phoronix Test Suite is an open-source benchmarking and comprehensive performance testing tool designed to assess and analyze the performance of hardware systems. It offers a wide range of benchmarks that cover various aspects of system performance, including CPU, GPU, memory, storage, network, file system and many more. + +Although the Phoronix Test Suite is available as a module on Cheaha, we need to install or load the missing dependencies required by individual benchmarks. To streamline this process, we are containerizing the Phoronix Test Suite along with the required benchmarks and dependencies. This approach allows us to run the benchmarks directly on both CPU and GPU for comprehensive evaluation. The containerized version of the Phoronix Test Suite is currently available in the Gitlab registry for testing. + +## CPU Performance Testing + +We have used Gromacs software for testing the performance of multi-core and multi-node CPU. + +## GPU Benchmark Testing diff --git a/mkdocs.yml b/mkdocs.yml index e4dddc1..23e98ba 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -46,6 +46,7 @@ nav: - Cheaha: - Archiving Modules: cheaha/archiving_modules.md - Shell Commands: cheaha/shell_commands.md + - System Testing: cheaha/system_testing.md - Gitlab Runner: - Personal Gitlab Runner Setup: gitlab_runner/personal_gitlab_runner_setup.md - Openstack: From 08b966fc63447c296f54cd479c5b56a1b1f2ba06 Mon Sep 17 00:00:00 2001 From: Premas Date: Tue, 13 Aug 2024 14:59:38 -0500 Subject: [PATCH 02/12] add links --- docs/cheaha/system_testing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 3edd955..6f80d98 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -2,7 +2,7 @@ The Phoronix Test Suite is an open-source benchmarking and comprehensive performance testing tool designed to assess and analyze the performance of hardware systems. It offers a wide range of benchmarks that cover various aspects of system performance, including CPU, GPU, memory, storage, network, file system and many more. -Although the Phoronix Test Suite is available as a module on Cheaha, we need to install or load the missing dependencies required by individual benchmarks. To streamline this process, we are containerizing the Phoronix Test Suite along with the required benchmarks and dependencies. This approach allows us to run the benchmarks directly on both CPU and GPU for comprehensive evaluation. The containerized version of the Phoronix Test Suite is currently available in the Gitlab registry for testing. +Although the Phoronix Test Suite is available as a module on Cheaha, we need to install or load the missing dependencies required by individual benchmarks. To streamline this process, we are containerizing the Phoronix Test Suite along with the required benchmarks and dependencies. This approach allows us to run the benchmarks directly on both CPU and GPU for comprehensive evaluation. The containerized version of the Phoronix Test Suite is currently available in the [Gitlab registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry) for testing. You can find the Phoronix Test Suite repository [here](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking). ## CPU Performance Testing From c0920df899af38a38187349642d4eba062407896 Mon Sep 17 00:00:00 2001 From: Premas Date: Tue, 29 Jul 2025 17:32:04 -0500 Subject: [PATCH 03/12] cpu testing --- docs/cheaha/system_testing.md | 140 +++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 4 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 6f80d98..2b979c9 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -1,11 +1,143 @@ # System Performance Testing with Phoronix Test Suite Benchmarks -The Phoronix Test Suite is an open-source benchmarking and comprehensive performance testing tool designed to assess and analyze the performance of hardware systems. It offers a wide range of benchmarks that cover various aspects of system performance, including CPU, GPU, memory, storage, network, file system and many more. +The [Phoronix Test Suite](https://openbenchmarking.org/tests) is an open-source benchmarking and comprehensive performance testing tool designed to assess and analyze the performance of hardware systems. It offers a wide range of benchmarks that cover various aspects of system performance, including CPU, GPU, memory, storage, network, file system and many more. It provides benchmark-specific results such as simulation speed (e.g., ns/day), execution time, or throughput, depending on the test. -Although the Phoronix Test Suite is available as a module on Cheaha, we need to install or load the missing dependencies required by individual benchmarks. To streamline this process, we are containerizing the Phoronix Test Suite along with the required benchmarks and dependencies. This approach allows us to run the benchmarks directly on both CPU and GPU for comprehensive evaluation. The containerized version of the Phoronix Test Suite is currently available in the [Gitlab registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry) for testing. You can find the Phoronix Test Suite repository [here](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking). + +Although the Phoronix Test Suite is available as a module on Cheaha, many individual benchmarks require additional dependency installations. To improve the reusability of CPU and GPU benchmarking by the UAB Research Computing (RC) team, the suite has been containerized with all necessary benchmarks and dependencies included. This approach streamlines the testing process, enabling more efficient and automated performance evaluation of the Cheaha system. The containerized version of the Phoronix Test Suite is currently available in the [Gitlab registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry) for testing. You can find the Phoronix Test Suite repository [here](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking). ## CPU Performance Testing -We have used Gromacs software for testing the performance of multi-core and multi-node CPU. +[GROMACS](https://www.gromacs.org/) is a software package utilized for evaluating the performance of CPU systems. The following steps demonstrates how to test a node using Phoronix and GROMACS. Note that testing requires access to the entire node. + + 1. To perform system testing, request for an exclusive compute node using `srun`. + + ```bash + $srun --nodes=1 --ntasks-per-node=24 --mem=80GB --time=10:00:00 --partition=intel-dcb --pty /bin/bash + ``` + + 1. Pull the Phoronix Test Suite using Singularity by obtaining the correct path from this [registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry). For this example, you can name the image file `phoronix-latest.sif`. + + ```bash + $singularity pull phoronix-latest.sif docker://gitlab.rc.uab.edu:4567/rc-data-science/community-containers/phoronix-test-suite-benchmarking:latest + ``` + + 1. Run the Singularity image `phoronix-latest.sif` using the `phoronix-test-suite` executable with the `batch-setup` option for initial configuration: + + ```bash + $singularity run phoronix-latest.sif phoronix-test-suite batch-setup + ``` + + Follow the prompts to complete the setup: + + (i) For saving test results in batch mode, enter n (no) + + ```bash + Save test results when in batch mode (Y/n): n + ``` + + (ii) To run all test options, enter y (yes) + + ```bash + Run all test options (Y/n): y + Batch settings saved. + ``` + + 1. Run the benchmark using the batch-benchmark option with GROMACS version 1.9.0. + + ```bash + $singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 + ``` + +The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources. The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. + +### Performance Results + +```bash +   2.375, 2.348, 2.351 +``` + +The performance of each run is measured in nanoseconds per day (Ns/day). This metric indicates how many nanoseconds of simulation time can be computed in one day of real time. The average performance of the GROMACS simulation across the three runs is 2.358 Ns/day. The deviation of 0.63% indicates that the three runs produced very similar results, with only a small variation in performance. A low deviation suggests that the test results are consistent and reliable. Note that this metric can be useful for comparing the performance of different hardware setups or GROMACS configurations. The average performance reported is 2.358 nanoseconds per day (Ns/day). This means that, on average, your GROMACS simulation can compute 2.358 nanoseconds of simulation time in one day of real-world time. + +This shows that the system is performing consistently, with an average speed of 2.358 Ns/day, and only a small variation across runs. This means your setup is likely stable and efficient for this particular GROMACS simulation. + +```bash +$ srun --nodes=1 --ntasks-per-node=24 --mem=120GB --time=10:00:00 --partition=intel-dcb --pty /bin/bash +``` + +```bash +========== +== CUDA == +========== +CUDA Version 12.2.2 + +Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + +This container image and its contents are governed by the NVIDIA Deep Learning Container License. +By pulling and using the container, you accept the terms and conditions of this license: +https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license +A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. + +WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available. +   Use the NVIDIA Container Toolkit to start this container with GPU support; see +   https://docs.nvidia.com/datacenter/cloud-native/ . + +    Evaluating External Test Dependencies .............................................................................................................................................................. + +Phoronix Test Suite v10.8.4 +    Installed:     pts/gromacs-1.9.0 + +System Information + +  PROCESSOR:            2 x Intel Xeon Gold 6126 @ 3.70GHz +  Core Count:           24                                                   +  Extensions:           SSE 4.2 + AVX512CD + AVX2 + AVX + RDRAND + FSGSBASE  +  Cache Size:           38.5 MB                                              +  Microcode:            0x2007006                                            +  Core Family:          Cascade Lake                                         +  Scaling Driver:       intel_pstate performance                             +  GRAPHICS:             mgadrmfb + Screen:               1024x768          +  MOTHERBOARD:          Dell 0H28RR +  BIOS Version:         2.23.0            +  MEMORY:           768GB +  DISK:             1000GB PERC H740P Mini +  File-System:          gpfs              +  Disk Scheduler:       DEADLINE          +  OPERATING SYSTEM:     Ubuntu 20.04 +  Kernel:               3.10.0-1160.24.1.el7.x86_64 (x86_64)  +  Compiler:             GCC 11.4.0 + CUDA 12.2                +  System Layer:         docker                                + +GROMACS 2024: + +    pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] +    Test 1 of 1 +    Estimated Trial Run Count:    3                      +    Estimated Time To Completion: 6 Minutes [10:42 CDT]  +        Started Run 1 @ 10:37:24 +        Started Run 2 @ 10:39:06 +        Started Run 3 @ 10:40:54 +    Implementation: MPI CPU - Input: water_GMX50_bare: +        2.375 +        2.348 +        2.351 +    Average: 2.358 Ns Per Day +    Deviation: 0.63% +``` + +Higher is Better: The larger the number, the faster your simulation is running. For instance, a simulation with 2.358 Ns/day will progress 2.281 nanoseconds in the simulated system for every day that passes in real time. -## GPU Benchmark Testing +```bash +GROMACS 2024: + pts/gromacs-1.8.0 [Implementation: MPI CPU - Input: water_GMX50_bare] + Test 1 of 1 + Estimated Trial Run Count: 3 + Estimated Time To Completion: 5 Minutes [11:34 CDT] + Started Run 1 @ 11:30:08 + The test quit with a non-zero exit status. + Started Run 2 @ 11:30:14 + The test quit with a non-zero exit status. + Started Run 3 @ 11:30:18 + The test quit with a non-zero exit status. + E: There are not enough slots available in the system to satisfy the 128 +``` From 206db1406c40b1d5b47111df3b880c5b1b792a77 Mon Sep 17 00:00:00 2001 From: Premas Date: Tue, 29 Jul 2025 18:12:17 -0500 Subject: [PATCH 04/12] gpu perf testing --- docs/cheaha/system_testing.md | 82 +++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 2b979c9..0a70caa 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -141,3 +141,85 @@ GROMACS 2024: The test quit with a non-zero exit status. E: There are not enough slots available in the system to satisfy the 128 ``` + +## GPU Performance Testing + +```bash +$ srun --ntasks=12 --gres=gpu:2 --mem=100GB--time=10:00:00 --partition=amperenodes --pty /bin/bash +$ export CUDA_VISIBLE_DEVICES=0 +``` + +```bash +========== +== CUDA == +========== + +CUDA Version 12.2.2 + +Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + +This container image and its contents are governed by the NVIDIA Deep Learning Container License. +By pulling and using the container, you accept the terms and conditions of this license: +https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license + +A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. + + Evaluating External Test Dependencies .................................. + +Phoronix Test Suite v10.8.4 + Installed: pts/gromacs-1.9.0 + +GROMACS 2024: + pts/gromacs-1.9.0 + System Test Configuration + 1: MPI CPU + 2: NVIDIA CUDA GPU + 3: Test All Options + ** Multiple items can be selected, delimit by a comma. ** + Implementation: 2 + +System Information + PROCESSOR: 2 x AMD EPYC 7763 64-Core + Core Count: 128 + Extensions: SSE 4.2 + AVX2 + AVX + RDRAND + FSGSBASE + Cache Size: 512 MB + Microcode: 0xa0011d3 + Core Family: Zen 3 + + GRAPHICS: NVIDIA A100 80GB PCIe + BAR1 / Visible vRAM: 131072 MiB + Display Driver: NVIDIA + Screen: 1024x768 + + MOTHERBOARD: Dell 03WYW4 + BIOS Version: 2.14.1 + + MEMORY: 512GB + + DISK: 2 x 3201GB Dell Ent NVMe CM6 MU 3.2TB + 2 x 480GB SK hynix HFS480G32FEH-BA1 + File-System: gpfs + Disk Scheduler: NONE + + OPERATING SYSTEM: Ubuntu 20.04 + Kernel: 3.10.0-1160.24.1.el7.x86_64 (x86_64) + Desktop: Xfce + Compiler: GCC 11.4.0 + CUDA 12.2 + System Layer: docker + +GROMACS 2024: + pts/gromacs-1.9.0 [Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare] + Test 1 of 1 + Estimated Trial Run Count: 3 + Estimated Time To Completion: 5 Minutes [09:01 CDT] + Started Run 1 @ 08:57:06 + Started Run 2 @ 08:57:51 + Started Run 3 @ 08:58:35 + + Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare: + 23.93 + 23.816 + 23.791 + + Average: 23.846 Ns Per Day + Deviation: 0.31% +``` \ No newline at end of file From d0fb4c2d67dc1e012d14b2afcaa941924b5879df Mon Sep 17 00:00:00 2001 From: Premas Date: Tue, 29 Jul 2025 18:16:35 -0500 Subject: [PATCH 05/12] nvidia-smi --- docs/cheaha/system_testing.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 0a70caa..7ec6d82 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -222,4 +222,32 @@ GROMACS 2024: Average: 23.846 Ns Per Day Deviation: 0.31% +``` + +```bash +$ nvidia-smi + ++-----------------------------------------------------------------------------------------+ +| NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | +|-----------------------------------------+------------------------+----------------------+ +| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | +| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | +| | | MIG M. | +|=========================================+========================+======================| +| 0 NVIDIA A100 80GB PCIe On | 00000000:25:00.0 Off | 0 | +| N/A 32C P0 60W / 300W | 501MiB / 81920MiB | 0% Default | +| | | Disabled | ++-----------------------------------------+------------------------+----------------------+ +| 1 NVIDIA A100 80GB PCIe On | 00000000:81:00.0 Off | 0 | +| N/A 30C P0 43W / 300W | 1MiB / 81920MiB | 0% Default | +| | | Disabled | ++-----------------------------------------+------------------------+----------------------+ + ++-----------------------------------------------------------------------------------------+ +| Processes: | +| GPU GI CI PID Type Process name GPU Memory | +| ID ID Usage | +|=========================================================================================| +| 0 N/A N/A 18877 C ...s/gromacs-1.9.0//cuda-build/bin/gmx 500MiB | ++-----------------------------------------------------------------------------------------+ ``` \ No newline at end of file From ea5bf6aea1efd991e823462cda9a0ba32fd77c2e Mon Sep 17 00:00:00 2001 From: Premas Date: Thu, 31 Jul 2025 09:55:59 -0500 Subject: [PATCH 06/12] cpu writeup --- .../images/system_testing_container_image.png | Bin 0 -> 104414 bytes docs/cheaha/system_testing.md | 91 +++++++++++------- 2 files changed, 57 insertions(+), 34 deletions(-) create mode 100644 docs/cheaha/images/system_testing_container_image.png diff --git a/docs/cheaha/images/system_testing_container_image.png b/docs/cheaha/images/system_testing_container_image.png new file mode 100644 index 0000000000000000000000000000000000000000..86d4f1d4564225121bc5cc994f1288ace01c5776 GIT binary patch literal 104414 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%0DSp#lCvP%-edHg_vnLKcx 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 OeDHRzwl|L+Px>e6rz^(* literal 0 HcmV?d00001 diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 7ec6d82..26b0e31 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -7,48 +7,65 @@ Although the Phoronix Test Suite is available as a module on Cheaha, many indivi ## CPU Performance Testing -[GROMACS](https://www.gromacs.org/) is a software package utilized for evaluating the performance of CPU systems. The following steps demonstrates how to test a node using Phoronix and GROMACS. Note that testing requires access to the entire node. +[GROMACS](https://openbenchmarking.org/test/pts/gromacs) is a software package commonly used to evaluate the performance of High Performance Computing (HPC) systems. The GROMACS benchmark is available through the [OpenBenchmarking](https://openbenchmarking.org/) repository and can be accessed using the Phoronix Test Suite. The following steps demonstrate how to test a CPU node using Phoronix and GROMACS. - 1. To perform system testing, request for an exclusive compute node using `srun`. + - To perform system testing, request for an exclusive compute node using `srun`. ```bash - $srun --nodes=1 --ntasks-per-node=24 --mem=80GB --time=10:00:00 --partition=intel-dcb --pty /bin/bash + $srun --nodes=1 --ntasks-per-node=24 --mem=80GB \ + --time=10:00:00 --partition=intel-dcb --pty /bin/bash ``` - 1. Pull the Phoronix Test Suite using Singularity by obtaining the correct path from this [registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry). For this example, you can name the image file `phoronix-latest.sif`. + +!!! note + Testing requires access to the entire node to ensure accurate performance measurement. This is also necessary because the benchmark utilizes all physical cores in the node, and partial allocations may lead to slot contention or failures due to insufficient available resources — a known issue reported [here](#known-issues). + - ```bash - $singularity pull phoronix-latest.sif docker://gitlab.rc.uab.edu:4567/rc-data-science/community-containers/phoronix-test-suite-benchmarking:latest - ``` - - 1. Run the Singularity image `phoronix-latest.sif` using the `phoronix-test-suite` executable with the `batch-setup` option for initial configuration: - - ```bash - $singularity run phoronix-latest.sif phoronix-test-suite batch-setup - ``` - Follow the prompts to complete the setup: + - Pull the Phoronix Test Suite using Singularity by copying the correct image path from this [container registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry). - (i) For saving test results in batch mode, enter n (no) - - ```bash - Save test results when in batch mode (Y/n): n - ``` + ![!System Testing Container Image](images/system_testing_container_image.png) + + For this example, you can name the image file as `phoronix-latest.sif`. + + ```bash + $singularity pull phoronix-latest.sif \ + docker://gitlab.rc.uab.edu:4567/rc-data-science/community-containers/phoronix-test-suite-benchmarking:latest + ``` + + - After pulling the container image, you can run the Phoronix Test Suite using the Singularity image `phoronix-latest.sif`. To begin, use the `batch-setup` option to configure automated test runs non-interactively. + + ```bash + $singularity run phoronix-latest.sif phoronix-test-suite batch-setup + ``` + This command launches the test suite inside the container and initiates the batch configuration process, allowing you to specify test preferences, logging, and result handling before execution. + + You can follow the prompts to complete the setup: + + (i) For saving test results in batch mode, enter n (no) + + ```bash + Save test results when in batch mode (Y/n): n + ``` + + (ii) To run all test options, enter y (yes) + + ```bash + Run all test options (Y/n): n + Batch settings saved. + ``` + + !!! important + You can choose to save the test results in batch mode (Y) if you wish to retain them for future analysis. Additionally, when you run the benchmark later, you will be prompted to name the test result file. This name will be used to store the results and logs for that run. + + + - Run the benchmark using the batch-benchmark option with GROMACS version 1.9.0. - (ii) To run all test options, enter y (yes) + ```bash + $singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 + ``` - ```bash - Run all test options (Y/n): y - Batch settings saved. - ``` - - 1. Run the benchmark using the batch-benchmark option with GROMACS version 1.9.0. - - ```bash - $singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 - ``` - -The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources. The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. + The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources. The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. ### Performance Results @@ -125,7 +142,8 @@ GROMACS 2024:     Deviation: 0.63% ``` -Higher is Better: The larger the number, the faster your simulation is running. For instance, a simulation with 2.358 Ns/day will progress 2.281 nanoseconds in the simulated system for every day that passes in real time. +Higher is B +etter: The larger the number, the faster your simulation is running. For instance, a simulation with 2.358 Ns/day will progress 2.281 nanoseconds in the simulated system for every day that passes in real time. ```bash GROMACS 2024: @@ -250,4 +268,9 @@ $ nvidia-smi |=========================================================================================| | 0 N/A N/A 18877 C ...s/gromacs-1.9.0//cuda-build/bin/gmx 500MiB | +-----------------------------------------------------------------------------------------+ -``` \ No newline at end of file +``` + +### Performance Results + + +### Known Issues From 9ccaeae7031bb577db277045287e482a0496ab89 Mon Sep 17 00:00:00 2001 From: Premas Date: Fri, 1 Aug 2025 11:02:25 -0500 Subject: [PATCH 07/12] cpu perf test --- docs/cheaha/system_testing.md | 143 +++++++++++++++++----------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 26b0e31..82345ee 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -48,7 +48,7 @@ Although the Phoronix Test Suite is available as a module on Cheaha, many indivi Save test results when in batch mode (Y/n): n ``` - (ii) To run all test options, enter y (yes) + (ii) To avoid running all test options, enter n (no). This is recommended because the gromacs-1.9.0 benchmark includes both CPU and GPU tests. To ensure you're testing the correct environment, manually select the specific option (CPU or GPU) you want to run. ```bash Run all test options (Y/n): n @@ -65,86 +65,88 @@ Although the Phoronix Test Suite is available as a module on Cheaha, many indivi $singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 ``` - The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources. The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. + The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources (CPU). The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. -### Performance Results + + !!! note + When running on CPU-only nodes, the testing options will not be prompted. By default, the benchmark will automatically perform CPU-based testing in this case. + -```bash -   2.375, 2.348, 2.351 -``` + ```bash + ========== + == CUDA == + ========== + CUDA Version 12.2.2 + + Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + This container image and its contents are governed by the NVIDIA Deep Learning Container License. + By pulling and using the container, you accept the terms and conditions of this license: + https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license + A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. + + WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available. +    Use the NVIDIA Container Toolkit to start this container with GPU support; see +    https://docs.nvidia.com/datacenter/cloud-native/ . + +     Evaluating External Test Dependencies .............................................................................................................................................................. + + Phoronix Test Suite v10.8.4 +     Installed:     pts/gromacs-1.9.0 + + System Information + +   PROCESSOR:            2 x Intel Xeon Gold 6126 @ 3.70GHz +   Core Count:           24                                                   +   Extensions:           SSE 4.2 + AVX512CD + AVX2 + AVX + RDRAND + FSGSBASE  +   Cache Size:           38.5 MB                                              +   Microcode:            0x2007006                                            +   Core Family:          Cascade Lake                                         +   Scaling Driver:       intel_pstate performance                             +   GRAPHICS:             mgadrmfb + Screen:               1024x768          +   MOTHERBOARD:          Dell 0H28RR +   BIOS Version:         2.23.0            +   MEMORY:           768GB +   DISK:             1000GB PERC H740P Mini +   File-System:          gpfs              +   Disk Scheduler:       DEADLINE          +   OPERATING SYSTEM:     Ubuntu 20.04 +   Kernel:               3.10.0-1160.24.1.el7.x86_64 (x86_64)  +   Compiler:             GCC 11.4.0 + CUDA 12.2                +   System Layer:         docker                                + + GROMACS 2024: + +     pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] +     Test 1 of 1 +     Estimated Trial Run Count:    3                      +     Estimated Time To Completion: 6 Minutes [10:42 CDT]  +         Started Run 1 @ 10:37:24 +         Started Run 2 @ 10:39:06 +         Started Run 3 @ 10:40:54 +     Implementation: MPI CPU - Input: water_GMX50_bare: +         2.375 +         2.348 +         2.351 +     Average: 2.358 Ns Per Day +     Deviation: 0.63% + ``` -The performance of each run is measured in nanoseconds per day (Ns/day). This metric indicates how many nanoseconds of simulation time can be computed in one day of real time. The average performance of the GROMACS simulation across the three runs is 2.358 Ns/day. The deviation of 0.63% indicates that the three runs produced very similar results, with only a small variation in performance. A low deviation suggests that the test results are consistent and reliable. Note that this metric can be useful for comparing the performance of different hardware setups or GROMACS configurations. The average performance reported is 2.358 nanoseconds per day (Ns/day). This means that, on average, your GROMACS simulation can compute 2.358 nanoseconds of simulation time in one day of real-world time. +### Results of CPU-Based Performance Testing -This shows that the system is performing consistently, with an average speed of 2.358 Ns/day, and only a small variation across runs. This means your setup is likely stable and efficient for this particular GROMACS simulation. +The performance of each run is measured in nanoseconds per day (Ns/day). This metric indicates how many nanoseconds of simulation time can be computed in one day of real time. The average performance of the GROMACS simulation across the three runs is 2.358 Ns/day. The deviation of 0.63% indicates that the three runs produced very similar results, with only a small variation in performance. A low deviation suggests that the test results are consistent and reliable. Note that this metric can be useful for comparing the performance of different hardware setups or GROMACS configurations. The average performance reported is 2.358 nanoseconds per day (Ns/day). This means that, on average, your GROMACS simulation can compute 2.358 nanoseconds of simulation time in one day of real-world time. ```bash -$ srun --nodes=1 --ntasks-per-node=24 --mem=120GB --time=10:00:00 --partition=intel-dcb --pty /bin/bash +   2.375, 2.348, 2.351 ``` -```bash -========== -== CUDA == -========== -CUDA Version 12.2.2 - -Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - -This container image and its contents are governed by the NVIDIA Deep Learning Container License. -By pulling and using the container, you accept the terms and conditions of this license: -https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license -A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. - -WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available. -   Use the NVIDIA Container Toolkit to start this container with GPU support; see -   https://docs.nvidia.com/datacenter/cloud-native/ . - -    Evaluating External Test Dependencies .............................................................................................................................................................. - -Phoronix Test Suite v10.8.4 -    Installed:     pts/gromacs-1.9.0 - -System Information - -  PROCESSOR:            2 x Intel Xeon Gold 6126 @ 3.70GHz -  Core Count:           24                                                   -  Extensions:           SSE 4.2 + AVX512CD + AVX2 + AVX + RDRAND + FSGSBASE  -  Cache Size:           38.5 MB                                              -  Microcode:            0x2007006                                            -  Core Family:          Cascade Lake                                         -  Scaling Driver:       intel_pstate performance                             -  GRAPHICS:             mgadrmfb - Screen:               1024x768          -  MOTHERBOARD:          Dell 0H28RR -  BIOS Version:         2.23.0            -  MEMORY:           768GB -  DISK:             1000GB PERC H740P Mini -  File-System:          gpfs              -  Disk Scheduler:       DEADLINE          -  OPERATING SYSTEM:     Ubuntu 20.04 -  Kernel:               3.10.0-1160.24.1.el7.x86_64 (x86_64)  -  Compiler:             GCC 11.4.0 + CUDA 12.2                -  System Layer:         docker                                - -GROMACS 2024: - -    pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] -    Test 1 of 1 -    Estimated Trial Run Count:    3                      -    Estimated Time To Completion: 6 Minutes [10:42 CDT]  -        Started Run 1 @ 10:37:24 -        Started Run 2 @ 10:39:06 -        Started Run 3 @ 10:40:54 -    Implementation: MPI CPU - Input: water_GMX50_bare: -        2.375 -        2.348 -        2.351 -    Average: 2.358 Ns Per Day -    Deviation: 0.63% -``` +This shows that the system is performing consistently, with an average speed of 2.358 Ns/day, and only a small variation across runs. This means your setup is likely stable and efficient for this particular GROMACS simulation. Higher is B etter: The larger the number, the faster your simulation is running. For instance, a simulation with 2.358 Ns/day will progress 2.281 nanoseconds in the simulated system for every day that passes in real time. +### Known Issues ```bash GROMACS 2024: pts/gromacs-1.8.0 [Implementation: MPI CPU - Input: water_GMX50_bare] @@ -270,7 +272,6 @@ $ nvidia-smi +-----------------------------------------------------------------------------------------+ ``` -### Performance Results +### Results of GPU-Based Performance Testing -### Known Issues From eb47f3495448854d8a6e52a2e52f4a349b26508c Mon Sep 17 00:00:00 2001 From: Premas Date: Sat, 2 Aug 2025 19:12:20 -0500 Subject: [PATCH 08/12] csv file added --- docs/cheaha/res/cpu_perf_test.csv | 7 +++++ docs/cheaha/res/gpu_perf_test.csv | 6 +++++ docs/cheaha/system_testing.md | 44 ++++++++++++++++++++----------- 3 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 docs/cheaha/res/cpu_perf_test.csv create mode 100644 docs/cheaha/res/gpu_perf_test.csv diff --git a/docs/cheaha/res/cpu_perf_test.csv b/docs/cheaha/res/cpu_perf_test.csv new file mode 100644 index 0000000..d6c5ce4 --- /dev/null +++ b/docs/cheaha/res/cpu_perf_test.csv @@ -0,0 +1,7 @@ +Metrics,Run 1,Run 2,Run 3,Description +Core Time (s),874.88,885.073,883.798,"Total compute time summed across all cores" +Wall Time (s),36.458,36.878,36.826,"Actual elapsed time" +Parallel Efficiency (%),2399.7,2400.0,2399.9,"Calculated as Core Time ÷ Wall Time. Higher values indicate more efficient CPU core usage." +Simulation Speed (ns/day),2.375,2.348,2.351,"Real simulation time (in nanoseconds) performed per day" +Simulation Time per Nanosecond (hr/ns),10.107,10.224,10.209,"Time it takes to simulate 1 ns of your system in real-world hours. Lower is better performnace." +Avg. Load Imbalance (%),0.9,1.4,1.1,"Measures how evenly computation is distributed across threads/cores. Lower is better performance." diff --git a/docs/cheaha/res/gpu_perf_test.csv b/docs/cheaha/res/gpu_perf_test.csv new file mode 100644 index 0000000..603ccba --- /dev/null +++ b/docs/cheaha/res/gpu_perf_test.csv @@ -0,0 +1,6 @@ +Metrics,Run 1,Run 2,Run 3,Description +Core Time (s),176.051,176.004,176.107,"Total compute time summed across all cores" +Wall Time (s),14.679,14.674,14.683,"Actual elapsed time" +Parallel Efficiency (%) (Core Time ÷ Wall Time),1199.4,1199.4,1199.4,"Calculated as Core Time ÷ Wall Time. Higher values mean better CPU core usage." +Simulation Speed (ns/day),23.556,23.563,23.549,"Real simulation time (in nanoseconds) performed per day" +Simulation Time per Nanosecond (hr/ns),1.019,1.019,1.019,"Time to simulate 1 ns of your system. Lower is better performance" diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 82345ee..c714f66 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -135,16 +135,27 @@ Although the Phoronix Test Suite is available as a module on Cheaha, many indivi ### Results of CPU-Based Performance Testing -The performance of each run is measured in nanoseconds per day (Ns/day). This metric indicates how many nanoseconds of simulation time can be computed in one day of real time. The average performance of the GROMACS simulation across the three runs is 2.358 Ns/day. The deviation of 0.63% indicates that the three runs produced very similar results, with only a small variation in performance. A low deviation suggests that the test results are consistent and reliable. Note that this metric can be useful for comparing the performance of different hardware setups or GROMACS configurations. The average performance reported is 2.358 nanoseconds per day (Ns/day). This means that, on average, your GROMACS simulation can compute 2.358 nanoseconds of simulation time in one day of real-world time. +Benchmarks for CPU-based testing were evaluated using the following key performance metrics: -```bash -   2.375, 2.348, 2.351 -``` +The performance of the GROMACS simulation is measured in nanoseconds per day (Ns/day)—a metric that indicates how many nanoseconds of simulation time can be computed in one day of real-world time. + +Across three runs, the average performance achieved was 2.358 Ns/day, with a low deviation of 0.63%, suggesting highly consistent and reliable results. This indicates that the system is performing steadily, and your current setup is both stable and efficient for this particular simulation. + +This metric is particularly useful for comparing performance across different hardware setups or GROMACS configurations. In general, a higher number of Ns/day means your simulation is running faster. For example, if your result is 2.3 Ns/day, it means the system can simulate 2.3 nanoseconds of molecular activity in one real-world day. So, the bigger the number, the less time it takes to run the simulation. + +{{ read_csv('cheaha/res/cpu_perf_test.csv', keep_default_na=False) }} + + +(i) Simulation Speed (ns/day) – Measures throughput and overall performance. + +(ii) Standard Deviation (%) – Assesses variability across runs. + +(iii) Wall-Clock Time (seconds) – Captures total execution time. -This shows that the system is performing consistently, with an average speed of 2.358 Ns/day, and only a small variation across runs. This means your setup is likely stable and efficient for this particular GROMACS simulation. +(iv) Parallel Efficiency (%) – Evaluates how effectively parallelism is utilized. -Higher is B -etter: The larger the number, the faster your simulation is running. For instance, a simulation with 2.358 Ns/day will progress 2.281 nanoseconds in the simulated system for every day that passes in real time. +These metrics provide a consistent basis for comparing node types and identifying potential bottlenecks in the +system performance. ### Known Issues ```bash @@ -230,18 +241,18 @@ GROMACS 2024: pts/gromacs-1.9.0 [Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare] Test 1 of 1 Estimated Trial Run Count: 3 - Estimated Time To Completion: 5 Minutes [09:01 CDT] - Started Run 1 @ 08:57:06 - Started Run 2 @ 08:57:51 - Started Run 3 @ 08:58:35 + Estimated Time To Completion: 4 Minutes [14:57 CDT] + Started Run 1 @ 14:54:12 + Started Run 2 @ 14:54:57 + Started Run 3 @ 14:55:42 Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare: - 23.93 - 23.816 - 23.791 + 23.556 + 23.563 + 23.549 - Average: 23.846 Ns Per Day - Deviation: 0.31% + Average: 23.556 Ns Per Day + Deviation: 0.03% ``` ```bash @@ -275,3 +286,4 @@ $ nvidia-smi ### Results of GPU-Based Performance Testing +{{ read_csv('cheaha/res/gpu_perf_test.csv', keep_default_na=False) }} \ No newline at end of file From 28bb3130597cd9729a8ed8b9e36d16a39a8babea Mon Sep 17 00:00:00 2001 From: Premas Date: Sun, 3 Aug 2025 00:34:48 -0500 Subject: [PATCH 09/12] add section container setup --- docs/cheaha/system_testing.md | 237 +++++++++++++++++----------------- 1 file changed, 120 insertions(+), 117 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index c714f66..a6945fd 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -3,145 +3,141 @@ The [Phoronix Test Suite](https://openbenchmarking.org/tests) is an open-source benchmarking and comprehensive performance testing tool designed to assess and analyze the performance of hardware systems. It offers a wide range of benchmarks that cover various aspects of system performance, including CPU, GPU, memory, storage, network, file system and many more. It provides benchmark-specific results such as simulation speed (e.g., ns/day), execution time, or throughput, depending on the test. -Although the Phoronix Test Suite is available as a module on Cheaha, many individual benchmarks require additional dependency installations. To improve the reusability of CPU and GPU benchmarking by the UAB Research Computing (RC) team, the suite has been containerized with all necessary benchmarks and dependencies included. This approach streamlines the testing process, enabling more efficient and automated performance evaluation of the Cheaha system. The containerized version of the Phoronix Test Suite is currently available in the [Gitlab registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry) for testing. You can find the Phoronix Test Suite repository [here](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking). +Although the Phoronix Test Suite is available as a module on Cheaha, many individual benchmarks require additional dependency installations. To improve the reusability of CPU and GPU benchmarking by the UAB Research Computing (RC) team, the suite has been containerized with all necessary benchmarks and dependencies included. This approach streamlines the testing process, enabling more efficient and automated performance evaluation of the Cheaha system. The containerized Phoronix Test Suite with GROMACS installation is now available for testing in the [Gitlab registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry) for testing. You can access the Phoronix Test Suite repository [here](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking). -## CPU Performance Testing +## GROMACS + +[GROMACS](https://openbenchmarking.org/test/pts/gromacs) is a software package commonly used to evaluate the performance of High Performance Computing (HPC) systems. The GROMACS benchmark is available through the [OpenBenchmarking](https://openbenchmarking.org/) repository and can be accessed using the Phoronix Test Suite. The following steps demonstrate how to test a CPU node using Phoronix and GROMACS. + +### Container Setup + +To begin, pull the Phoronix Test Suite using Singularity by copying the correct image path from this [container registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry). + +![!System Testing Container Image](images/system_testing_container_image.png) + +For this example, you can name the image file as `phoronix-latest.sif`. + +```bash +$singularity pull phoronix-latest.sif \ +docker://gitlab.rc.uab.edu:4567/rc-data-science/community-containers/phoronix-test-suite-benchmarking:latest +``` + +After pulling the container image, you can run the Phoronix Test Suite using the Singularity image, `phoronix-latest.sif` . First, you will need to run the `batch-setup` option to configure automated test runs non-interactively. -[GROMACS](https://openbenchmarking.org/test/pts/gromacs) is a software package commonly used to evaluate the performance of High Performance Computing (HPC) systems. The GROMACS benchmark is available through the [OpenBenchmarking](https://openbenchmarking.org/) repository and can be accessed using the Phoronix Test Suite. The following steps demonstrate how to test a CPU node using Phoronix and GROMACS. +```bash +$singularity run phoronix-latest.sif phoronix-test-suite batch-setup +``` +This command launches the test suite inside the container and initiates the batch configuration process, allowing you to specify test preferences, logging, and result handling before execution. - - To perform system testing, request for an exclusive compute node using `srun`. +You can follow the prompts to complete the setup: + + (i) For saving test results in batch mode, enter n (no) ```bash - $srun --nodes=1 --ntasks-per-node=24 --mem=80GB \ - --time=10:00:00 --partition=intel-dcb --pty /bin/bash + Save test results when in batch mode (Y/n): n + ``` + + (ii) To avoid running all test options, enter n (no). This is recommended because the gromacs-1.9.0 benchmark includes both CPU and GPU tests. To ensure you are testing the correct environment, manually select the specific option (CPU or GPU) you want to run. + + ```bash + Run all test options (Y/n): n + Batch settings saved. ``` - -!!! note - Testing requires access to the entire node to ensure accurate performance measurement. This is also necessary because the benchmark utilizes all physical cores in the node, and partial allocations may lead to slot contention or failures due to insufficient available resources — a known issue reported [here](#known-issues). +!!! important + You can choose to save the test results in batch mode (Y) if you wish to retain them for future analysis. Additionally, when you run the benchmark later, you will be prompted to name the test result file. This name will be used to store the results and logs for that run. +## CPU Performance Testing + +First, to perform CPU system testing, you will have to request for an exclusive compute node using `srun`. + +```bash +$srun --nodes=1 --ntasks-per-node=24 --mem=80GB \ +--time=10:00:00 --partition=intel-dcb --pty /bin/bash +``` - - Pull the Phoronix Test Suite using Singularity by copying the correct image path from this [container registry](https://gitlab.rc.uab.edu/rc-data-science/community-containers/phoronix-test-suite-benchmarking/container_registry). +Next, let us run the benchmark using the `batch-benchmark` option with GROMACS version 1.9.0 via Singularity: - ![!System Testing Container Image](images/system_testing_container_image.png) +```bash +$singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 +``` + +This command downloads the GROMACS 1.9.0 test suite along with the necessary sample input files, installs GROMACS 2024 inside the container, and runs the benchmark using available CPU resources. The test uses an MPI (Message Passing Interface) parallel implementation, leveraging multiple CPU processors simultaneously. + + +!!! note + (i) Testing requires access to the entire node to ensure accurate performance measurement. This is also necessary because the benchmark utilizes all physical cores in the node, and partial allocations may lead to slot contention or failures due to insufficient available resources — a known issue reported [here](#known-issues). - For this example, you can name the image file as `phoronix-latest.sif`. + (ii)When running on CPU-only nodes, the testing options will not be prompted. By default, the benchmark will automatically perform CPU-based testing in this case. + - ```bash - $singularity pull phoronix-latest.sif \ - docker://gitlab.rc.uab.edu:4567/rc-data-science/community-containers/phoronix-test-suite-benchmarking:latest - ``` +```bash +========== +== CUDA == +========== +CUDA Version 12.2.2 - - After pulling the container image, you can run the Phoronix Test Suite using the Singularity image `phoronix-latest.sif`. To begin, use the `batch-setup` option to configure automated test runs non-interactively. +Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - ```bash - $singularity run phoronix-latest.sif phoronix-test-suite batch-setup - ``` - This command launches the test suite inside the container and initiates the batch configuration process, allowing you to specify test preferences, logging, and result handling before execution. +This container image and its contents are governed by the NVIDIA Deep Learning Container License. +By pulling and using the container, you accept the terms and conditions of this license: +https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license +A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. - You can follow the prompts to complete the setup: - - (i) For saving test results in batch mode, enter n (no) +WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available. +   Use the NVIDIA Container Toolkit to start this container with GPU support; see +   https://docs.nvidia.com/datacenter/cloud-native/ . - ```bash - Save test results when in batch mode (Y/n): n - ``` - - (ii) To avoid running all test options, enter n (no). This is recommended because the gromacs-1.9.0 benchmark includes both CPU and GPU tests. To ensure you're testing the correct environment, manually select the specific option (CPU or GPU) you want to run. - - ```bash - Run all test options (Y/n): n - Batch settings saved. - ``` - - !!! important - You can choose to save the test results in batch mode (Y) if you wish to retain them for future analysis. Additionally, when you run the benchmark later, you will be prompted to name the test result file. This name will be used to store the results and logs for that run. - - - - Run the benchmark using the batch-benchmark option with GROMACS version 1.9.0. - - ```bash - $singularity run phoronix-latest.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 - ``` - - The above command downloads the gromacs-1.9.0 suite and the required sample test, install the Gromacs suite (GROMACS 2024), and begin to perform the testing on the available resources (CPU). The below result summarizes the Gromacs performance test. The test is running on an MPI (Message Passing Interface) CPU implementation, meaning it’s using multiple processors in parallel. The simulation is using `water_GMX50_bare` as input, which is a water molecular system. You can see the test is running 3 times to ensure consistency. - - - !!! note - When running on CPU-only nodes, the testing options will not be prompted. By default, the benchmark will automatically perform CPU-based testing in this case. - - - ```bash - ========== - == CUDA == - ========== - CUDA Version 12.2.2 - - Container image Copyright (c) 2016-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. - - This container image and its contents are governed by the NVIDIA Deep Learning Container License. - By pulling and using the container, you accept the terms and conditions of this license: - https://developer.nvidia.com/ngc/nvidia-deep-learning-container-license - A copy of this license is made available in this container at /NGC-DL-CONTAINER-LICENSE for your convenience. - - WARNING: The NVIDIA Driver was not detected.  GPU functionality will not be available. -    Use the NVIDIA Container Toolkit to start this container with GPU support; see -    https://docs.nvidia.com/datacenter/cloud-native/ . - -     Evaluating External Test Dependencies .............................................................................................................................................................. - - Phoronix Test Suite v10.8.4 -     Installed:     pts/gromacs-1.9.0 - - System Information - -   PROCESSOR:            2 x Intel Xeon Gold 6126 @ 3.70GHz -   Core Count:           24                                                   -   Extensions:           SSE 4.2 + AVX512CD + AVX2 + AVX + RDRAND + FSGSBASE  -   Cache Size:           38.5 MB                                              -   Microcode:            0x2007006                                            -   Core Family:          Cascade Lake                                         -   Scaling Driver:       intel_pstate performance                             -   GRAPHICS:             mgadrmfb - Screen:               1024x768          -   MOTHERBOARD:          Dell 0H28RR -   BIOS Version:         2.23.0            -   MEMORY:           768GB -   DISK:             1000GB PERC H740P Mini -   File-System:          gpfs              -   Disk Scheduler:       DEADLINE          -   OPERATING SYSTEM:     Ubuntu 20.04 -   Kernel:               3.10.0-1160.24.1.el7.x86_64 (x86_64)  -   Compiler:             GCC 11.4.0 + CUDA 12.2                -   System Layer:         docker                                - - GROMACS 2024: - -     pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] -     Test 1 of 1 -     Estimated Trial Run Count:    3                      -     Estimated Time To Completion: 6 Minutes [10:42 CDT]  -         Started Run 1 @ 10:37:24 -         Started Run 2 @ 10:39:06 -         Started Run 3 @ 10:40:54 -     Implementation: MPI CPU - Input: water_GMX50_bare: -         2.375 -         2.348 -         2.351 -     Average: 2.358 Ns Per Day -     Deviation: 0.63% - ``` +    Evaluating External Test Dependencies .............................................................................................................................................................. -### Results of CPU-Based Performance Testing +Phoronix Test Suite v10.8.4 +    Installed:     pts/gromacs-1.9.0 -Benchmarks for CPU-based testing were evaluated using the following key performance metrics: +System Information -The performance of the GROMACS simulation is measured in nanoseconds per day (Ns/day)—a metric that indicates how many nanoseconds of simulation time can be computed in one day of real-world time. +  PROCESSOR:            2 x Intel Xeon Gold 6126 @ 3.70GHz +  Core Count:           24                                                   +  Extensions:           SSE 4.2 + AVX512CD + AVX2 + AVX + RDRAND + FSGSBASE  +  Cache Size:           38.5 MB                                              +  Microcode:            0x2007006                                            +  Core Family:          Cascade Lake                                         +  Scaling Driver:       intel_pstate performance                             +  GRAPHICS:             mgadrmfb + Screen:               1024x768          +  MOTHERBOARD:          Dell 0H28RR +  BIOS Version:         2.23.0            +  MEMORY:           768GB +  DISK:             1000GB PERC H740P Mini +  File-System:          gpfs              +  Disk Scheduler:       DEADLINE          +  OPERATING SYSTEM:     Ubuntu 20.04 +  Kernel:               3.10.0-1160.24.1.el7.x86_64 (x86_64)  +  Compiler:             GCC 11.4.0 + CUDA 12.2                +  System Layer:         docker                                -Across three runs, the average performance achieved was 2.358 Ns/day, with a low deviation of 0.63%, suggesting highly consistent and reliable results. This indicates that the system is performing steadily, and your current setup is both stable and efficient for this particular simulation. +GROMACS 2024: -This metric is particularly useful for comparing performance across different hardware setups or GROMACS configurations. In general, a higher number of Ns/day means your simulation is running faster. For example, if your result is 2.3 Ns/day, it means the system can simulate 2.3 nanoseconds of molecular activity in one real-world day. So, the bigger the number, the less time it takes to run the simulation. +    pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] +    Test 1 of 1 +    Estimated Trial Run Count:    3                      +    Estimated Time To Completion: 6 Minutes [10:42 CDT]  +        Started Run 1 @ 10:37:24 +        Started Run 2 @ 10:39:06 +        Started Run 3 @ 10:40:54 +    Implementation: MPI CPU - Input: water_GMX50_bare: +        2.375 +        2.348 +        2.351 +    Average: 2.358 Ns Per Day +    Deviation: 0.63% +``` + +The benchmark was run on a system (intel-dcb partition) with 2 Intel Xeon Gold 6126 processors running at 3.70 GHz, totaling 24 CPU cores. The test utilized an MPI CPU implementation of GROMACS 2024 with the water_GMX50_bare as input, a water molecular system. The performance of the GROMACS simulation is measured in nanoseconds per day (Ns/day)—a metric that indicates how many nanoseconds of simulation time can be computed in one day of real-world time. Across three trial runs, the simulation achieved an average performance of 2.358 nanoseconds per day with very low variation (0.63% deviation), demonstrating consistent and efficient use of the available CPU cores. The following section provides a detailed breakdown of the metrics and results. + +### Results of CPU-Based Performance Testing + +Benchmarks for CPU-based testing were evaluated using the following key performance metrics: {{ read_csv('cheaha/res/cpu_perf_test.csv', keep_default_na=False) }} @@ -157,6 +153,9 @@ This metric is particularly useful for comparing performance across different ha These metrics provide a consistent basis for comparing node types and identifying potential bottlenecks in the system performance. + +This metric is particularly useful for comparing performance across different hardware setups or GROMACS configurations. In general, a higher number of Ns/day means your simulation is running faster. For example, if your result is 2.3 Ns/day, it means the system can simulate 2.3 nanoseconds of molecular activity in one real-world day. So, the bigger the number, the less time it takes to run the simulation. + ### Known Issues ```bash GROMACS 2024: @@ -177,7 +176,11 @@ GROMACS 2024: ```bash $ srun --ntasks=12 --gres=gpu:2 --mem=100GB--time=10:00:00 --partition=amperenodes --pty /bin/bash +``` + +``` $ export CUDA_VISIBLE_DEVICES=0 +$ singularity run --nv phoronix-gromacs.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 ``` ```bash From f9b08a9e611d701f76f2399d5095b2beaf5b6bbf Mon Sep 17 00:00:00 2001 From: Premas Date: Sun, 3 Aug 2025 01:02:35 -0500 Subject: [PATCH 10/12] cpu known issues --- docs/cheaha/system_testing.md | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index a6945fd..67ead50 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -137,29 +137,28 @@ The benchmark was run on a system (intel-dcb partition) with 2 Intel Xeon Gold 6 ### Results of CPU-Based Performance Testing -Benchmarks for CPU-based testing were evaluated using the following key performance metrics: +The GROMACS performance test was executed using MPI on a multi-core CPU setup, running three benchmark trials to ensure consistency. Benchmarks were evaluated using the following key performance metrics: {{ read_csv('cheaha/res/cpu_perf_test.csv', keep_default_na=False) }} +These metrics provide a reliable foundation for comparing node types, diagnosing bottlenecks, and assessing the scalability of the simulation environment. They are especially useful when evaluating different hardware configurations or GROMACS versions. -(i) Simulation Speed (ns/day) – Measures throughput and overall performance. +A crucial performance indicator is the Simulation Speed (ns/day), which reflects how fast the simulation progresses. For instance, a speed of 2.3 ns/day means the system can simulate 2.3 nanoseconds of molecular behavior in one real-world day. Therefore, higher values indicate faster simulation and better overall performance. -(ii) Standard Deviation (%) – Assesses variability across runs. +The results demonstrate highly efficient parallel performance, minimal load imbalance, and stable simulation speed all of which are strong indicators of an optimized CPU-based GROMACS environment. This confirms the environment is well-optimized for CPU-bound molecular dynamics simulations using GROMACS. -(iii) Wall-Clock Time (seconds) – Captures total execution time. +### Known Issues -(iv) Parallel Efficiency (%) – Evaluates how effectively parallelism is utilized. +(i) Slot Allocation Failure in GROMACS Benchmark -These metrics provide a consistent basis for comparing node types and identifying potential bottlenecks in the -system performance. +During CPU performance testing, the GROMACS benchmark fails with a `non-zero exit status` as shown below. This is because the benchmarking requests more CPU slots than were allocated. By default, it requires all physical cores of an entire node i.e., 128 MPI ranks in this case, but only 24 cores were requested on the `amd-hdr100` partition, causing the failure. +To resolve this, the recommended solution is to run the benchmark on a full node with 128 cores, matching the default MPI rank count. Alternatively, to run the benchmark on a smaller allocation or customize performance testing, the test profile can be modified to reduce the number of MPI ranks accordingly. -This metric is particularly useful for comparing performance across different hardware setups or GROMACS configurations. In general, a higher number of Ns/day means your simulation is running faster. For example, if your result is 2.3 Ns/day, it means the system can simulate 2.3 nanoseconds of molecular activity in one real-world day. So, the bigger the number, the less time it takes to run the simulation. -### Known Issues ```bash GROMACS 2024: - pts/gromacs-1.8.0 [Implementation: MPI CPU - Input: water_GMX50_bare] + pts/gromacs-1.9.0 [Implementation: MPI CPU - Input: water_GMX50_bare] Test 1 of 1 Estimated Trial Run Count: 3 Estimated Time To Completion: 5 Minutes [11:34 CDT] @@ -289,4 +288,7 @@ $ nvidia-smi ### Results of GPU-Based Performance Testing -{{ read_csv('cheaha/res/gpu_perf_test.csv', keep_default_na=False) }} \ No newline at end of file +{{ read_csv('cheaha/res/gpu_perf_test.csv', keep_default_na=False) }} + + +### Known Issues \ No newline at end of file From c372f2c51700e92ade7e37bc7de3c921c71191d4 Mon Sep 17 00:00:00 2001 From: Premas Date: Sun, 3 Aug 2025 03:34:08 -0500 Subject: [PATCH 11/12] gpu known issues --- docs/cheaha/system_testing.md | 59 +++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 67ead50..5a199d0 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -67,7 +67,7 @@ This command downloads the GROMACS 1.9.0 test suite along with the necessary sam !!! note - (i) Testing requires access to the entire node to ensure accurate performance measurement. This is also necessary because the benchmark utilizes all physical cores in the node, and partial allocations may lead to slot contention or failures due to insufficient available resources — a known issue reported [here](#known-issues). + (i) Testing requires access to the entire node to ensure accurate performance measurement. This is also necessary because the benchmark utilizes all physical cores in the node, and partial allocations may lead to slot contention or failures due to insufficient available resources — a known issue reported [here](#cpu-testing-known-issues). (ii)When running on CPU-only nodes, the testing options will not be prompted. By default, the benchmark will automatically perform CPU-based testing in this case. @@ -147,7 +147,7 @@ A crucial performance indicator is the Simulation Speed (ns/day), which reflects The results demonstrate highly efficient parallel performance, minimal load imbalance, and stable simulation speed all of which are strong indicators of an optimized CPU-based GROMACS environment. This confirms the environment is well-optimized for CPU-bound molecular dynamics simulations using GROMACS. -### Known Issues +### CPU Testing: Known Issues (i) Slot Allocation Failure in GROMACS Benchmark @@ -173,15 +173,28 @@ GROMACS 2024: ## GPU Performance Testing +To perform GPU system testing you will have to request for a compute node requesting 2 GPUs. ```bash -$ srun --ntasks=12 --gres=gpu:2 --mem=100GB--time=10:00:00 --partition=amperenodes --pty /bin/bash +$ srun --ntasks=12 --gres=gpu:2 --mem=100GB--time=10:00:00 \ +--partition=amperenodes --pty /bin/bash ``` -``` + +!!! important + (i) GPU testing has been successful on A100 nodes, ie., the `amperenodes` and `amperenodes-medium` partitions. For more details, see the known issue reported [here](#gpu-testing-known-issues). Until compatibility on Pascal nodes is confirmed, you can run GPU tests on `amperenodes` partitions. + (ii) Multi-GPU (>1GPU) runs currently fail due to PME (Particle Mesh Ewald) tuning conflicts at the reset step. As a workaround, run simulations on a single GPU for now. Refer to this [issue](#gpu-testing-known-issues) for more details. + + + +After acquiring the necessary GPU resources and completing the [batch setup](#container-setup) process, set the CUDA_VISIBLE_DEVICES environment variable and run the GROMACS benchmark using Singularity with GPU support enabled via the `--nv` flag. The `--nv` flag ensures that NVIDIA GPU libraries and drivers from the host are available inside the container at runtime. + +```bash $ export CUDA_VISIBLE_DEVICES=0 $ singularity run --nv phoronix-gromacs.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 ``` +The following showcase the results obtained from running the GROMACS 2024 GPU benchmark on an A100 node with CUDA 12.2.2. The system featured dual AMD EPYC 7763 processors with 128 cores. Across three trial runs, the benchmark achieved an average of 23.556 nanoseconds per day with minimal deviation (0.03%), indicating highly consistent and stable runs across trials. The high simulation speed shows that the A100 GPU was effectively used for computation, while the CPU efficiently handled data management and non-GPU tasks. Overall, the results demonstrate a well-balanced CPU-GPU configuration optimized for high-performance molecular dynamics workloads. + ```bash ========== == CUDA == @@ -257,9 +270,10 @@ GROMACS 2024: Deviation: 0.03% ``` +GPU usage and activity can be monitored with `nvidia-smi`, which shows real-time GPU memory use, utilization %, and running processes. If you see GPU utilization increasing during a GROMACS run, it means the GPU is actively working. The below `nvidia-smi` output indicates that the system has two NVIDIA A100 80GB GPUs. GPU 0 is actively running a GROMACS process (gmx), using approximately 1074 MiB of GPU memory and 94% GPU utilization. + ```bash $ nvidia-smi - +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ @@ -268,11 +282,11 @@ $ nvidia-smi | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA A100 80GB PCIe On | 00000000:25:00.0 Off | 0 | -| N/A 32C P0 60W / 300W | 501MiB / 81920MiB | 0% Default | +| N/A 39C P0 64W / 300W | 1083MiB / 81920MiB | 94% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA A100 80GB PCIe On | 00000000:81:00.0 Off | 0 | -| N/A 30C P0 43W / 300W | 1MiB / 81920MiB | 0% Default | +| N/A 31C P0 43W / 300W | 1MiB / 81920MiB | 0% Default | | | | Disabled | +-----------------------------------------+------------------------+----------------------+ @@ -281,14 +295,41 @@ $ nvidia-smi | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| -| 0 N/A N/A 18877 C ...s/gromacs-1.9.0//cuda-build/bin/gmx 500MiB | +| 0 N/A N/A 82610 C ...s/gromacs-1.9.0//cuda-build/bin/gmx 1074MiB | +-----------------------------------------------------------------------------------------+ ``` ### Results of GPU-Based Performance Testing +GPU-based GROMACS testing on A100 nodes showed consistently high simulation performance, achieving ~23.55 ns/day. The high parallel efficiency (~1199%) reflects the total core time accumulated across 12 CPU cores, compared to the actual elapsed wall time (~14.67 seconds). This indicates strong CPU utilization alongside efficient GPU acceleration. This setup offers a well-balanced configuration for fast, large-scale molecular dynamics simulations. {{ read_csv('cheaha/res/gpu_perf_test.csv', keep_default_na=False) }} -### Known Issues \ No newline at end of file +### GPU Testing: Known Issues + +(i) GROMACS GPU Benchmark Failure on Pascal Nodes + +When running the GROMACS 2024 GPU benchmark via the Phoronix Test Suite on Pascal-based GPU nodes (pascalnodes and pascalnodes-medium), the following error was encountered: + +```bash +[pts/gromacs-1.9.0 Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare] NVIDIA CUDA support is not available. +``` + +This indicates that the test could not detect or initialize CUDA GPU support. The likely reason for this failure is that GROMACS 2024 was compiled with CUDA 12.2.2, which requires a GPU with Compute Capability > 6.1. + +Pascal nodes have Compute Capability 6.0, which is no longer supported by CUDA 12.2 and newer. As a result, CUDA support is unavailable when running on Pascal-based GPUs. Refer to the official [CUDA support matrix](https://docs.nvidia.com/deeplearning/cudnn/backend/latest/reference/support-matrix.html) for more details. +To address this issue for now, please run GPU testing on one of the `amperenode` partitions until we develop and test a separate container using CUDA 12.0 or lesser to enable compatibility with Pascal nodes. + + +(ii) Running GROMACS on Multiple GPUs Failure + +When running GROMACS on multiple GPUs (2 GPUs), the program needs some time to adjust and optimize certain calculations i.e., PME (Particle Mesh Ewald) tuning. This tuning requires careful synchronization across all GPUs. The following error message means the program tried to restart its internal tracking too soon—before this tuning was finished—which caused it to crash. + +```bash +Fatal error: +PME tuning was still active when attempting to reset mdrun counters at step +2000. Try resetting counters later in the run, e.g. with gmx mdrun -resetstep. +``` + +To fix the issue, for now, it is recommended to run the simulation on a single GPU to monitor GPU system performance without causing the PME tuning error. If multi-GPU testing is essential, you may experiment with the `-resetstep` option in gmx mdrun to manually set the counter to a particular step and reset point after PME tuning completes. Further investigation and testing are needed to determine a stable multi-GPU configuration. From e8ca69550a603927b3b24c8576338023e447d3ed Mon Sep 17 00:00:00 2001 From: Premas Date: Sun, 3 Aug 2025 03:36:56 -0500 Subject: [PATCH 12/12] gpu perf --- docs/cheaha/system_testing.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/cheaha/system_testing.md b/docs/cheaha/system_testing.md index 5a199d0..e783804 100644 --- a/docs/cheaha/system_testing.md +++ b/docs/cheaha/system_testing.md @@ -189,8 +189,8 @@ $ srun --ntasks=12 --gres=gpu:2 --mem=100GB--time=10:00:00 \ After acquiring the necessary GPU resources and completing the [batch setup](#container-setup) process, set the CUDA_VISIBLE_DEVICES environment variable and run the GROMACS benchmark using Singularity with GPU support enabled via the `--nv` flag. The `--nv` flag ensures that NVIDIA GPU libraries and drivers from the host are available inside the container at runtime. ```bash -$ export CUDA_VISIBLE_DEVICES=0 -$ singularity run --nv phoronix-gromacs.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 +$export CUDA_VISIBLE_DEVICES=0 +$singularity run --nv phoronix-gromacs.sif phoronix-test-suite batch-benchmark gromacs-1.9.0 ``` The following showcase the results obtained from running the GROMACS 2024 GPU benchmark on an A100 node with CUDA 12.2.2. The system featured dual AMD EPYC 7763 processors with 128 cores. Across three trial runs, the benchmark achieved an average of 23.556 nanoseconds per day with minimal deviation (0.03%), indicating highly consistent and stable runs across trials. The high simulation speed shows that the A100 GPU was effectively used for computation, while the CPU efficiently handled data management and non-GPU tasks. Overall, the results demonstrate a well-balanced CPU-GPU configuration optimized for high-performance molecular dynamics workloads. @@ -313,7 +313,8 @@ GPU-based GROMACS testing on A100 nodes showed consistently high simulation perf When running the GROMACS 2024 GPU benchmark via the Phoronix Test Suite on Pascal-based GPU nodes (pascalnodes and pascalnodes-medium), the following error was encountered: ```bash -[pts/gromacs-1.9.0 Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare] NVIDIA CUDA support is not available. +[pts/gromacs-1.9.0 Implementation: NVIDIA CUDA GPU - Input: water_GMX50_bare] +NVIDIA CUDA support is not available. ``` This indicates that the test could not detect or initialize CUDA GPU support. The likely reason for this failure is that GROMACS 2024 was compiled with CUDA 12.2.2, which requires a GPU with Compute Capability > 6.1. @@ -322,7 +323,7 @@ Pascal nodes have Compute Capability 6.0, which is no longer supported by CUDA 1 To address this issue for now, please run GPU testing on one of the `amperenode` partitions until we develop and test a separate container using CUDA 12.0 or lesser to enable compatibility with Pascal nodes. -(ii) Running GROMACS on Multiple GPUs Failure +(ii) Running GROMACS on Multi-GPU Failure When running GROMACS on multiple GPUs (2 GPUs), the program needs some time to adjust and optimize certain calculations i.e., PME (Particle Mesh Ewald) tuning. This tuning requires careful synchronization across all GPUs. The following error message means the program tried to restart its internal tracking too soon—before this tuning was finished—which caused it to crash.