Adding rocAL+rocJPEG decode performance harness#474
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a manual performance harness for measuring rocAL image decode throughput (rocJPEG vs TurboJPEG) in multi-GPU sharded workloads, and updates rocAL’s rocJPEG path to optionally split decode work across multiple dedicated rocJPEG decoder instances.
Changes:
- Add a new manual benchmark folder (
tests/cpp_api/rocjpeg_decode_perf/) with C++/Python runners and reporting scripts for repeatable on/off comparisons. - Enhance rocAL’s rocJPEG decode implementation to optionally shard a batch across up to 4 dedicated rocJPEG decoder instances using OpenMP.
- Update
dataloader_multithreadto support configurable CPU thread count and an “effective batch size” for rocJPEG split-path benchmarking.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/cpp_api/rocjpeg_decode_perf/run_tests_twice_solution_on_off.sh | Driver script to run C++/Python benchmarks with rocJPEG split on/off plus TurboJPEG baselines. |
| tests/cpp_api/rocjpeg_decode_perf/rocal_decode_call_bench.py | Python rocAL decode benchmark with optional multi-process shard execution and timing extraction. |
| tests/cpp_api/rocjpeg_decode_perf/reporting_test_results.sh | Parses rocAL C++/Python logs and summarizes per-shard decode times and computed speedups. |
| tests/cpp_api/rocjpeg_decode_perf/reporting_perf_sharded_results.sh | Parses sharded jpegdecodeperf logs and summarizes per-GPU decode results. |
| tests/cpp_api/rocjpeg_decode_perf/README.md | Documents benchmark purpose, required env, workflows, and log/report generation. |
| tests/cpp_api/rocjpeg_decode_perf/perf_sharded_launcher.cpp | C++ helper to shard a dataset via symlinks and launch jpegdecodeperf per GPU with logs. |
| tests/cpp_api/dataloader_multithread/dataloader_multithread.cpp | Adds CPU thread-count arg and adjusts effective batch sizing/output handling for rocJPEG split benchmarking. |
| rocAL/source/loaders/image/image_read_and_decode.cpp | Implements optional rocJPEG dedicated OpenMP split path with multiple decoder instances and per-shard decode. |
| rocAL/include/loaders/image/image_read_and_decode.h | Adds state for multiple rocJPEG decoders, sub-batch sizes, and split toggle flag. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Harden the sharded launcher work directory cleanup, make symlink names collision-resistant, validate dataloader CPU thread count, improve Python decoded image accounting, and use spawn for multi-shard benchmark workers.
Latest Code Change Test SummaryTest ConfigurationAMD-SMI 26.2.2+671d39a71e Dataset: ImageNet 5 Classes Decoded Image Count
C++ rocAL Sample Decode-Time Results
Python rocAL Benchmark Decode-Time Results
rocAL Patch Solution Enhancement
|
rrawther
left a comment
There was a problem hiding this comment.
please address review comments
The Added Test Script FilesThese files are not intended to be regular correctness/unit tests. They are a manual performance harness for validating the rocJPEG split-decoder change in rocAL. The rocAL code change affects how rocJPEG decode work is scheduled internally: instead of using one rocJPEG decoder instance for the full batch, the split path can use multiple dedicated rocJPEG decoder instances and divide the batch across them. To validate that type of change, we need more than a normal pass/fail test; we need a repeatable way to compare decode timing with the split path ON and OFF across C++ and Python rocAL entry points. The scripts are organized as follows:
This folder gives developers a reproducible workflow for answering:
This is why the folder is under |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #474 +/- ##
===========================================
- Coverage 75.68% 75.67% -0.01%
===========================================
Files 318 318
Lines 26289 26358 +69
===========================================
+ Hits 19895 19944 +49
- Misses 6394 6414 +20
🚀 New features to boost your workflow:
|
|
Verified the benchmark scripts in the PR with |
Addressed in this commit: e20b8d0 Updated as requested. I removed the |
|
Commit: e20b8d0 Validation Verified the changes/cleanup with: bash -n tests/cpp_api/rocjpeg_decode_perf/run_tests_twice_solution_on_off.sh
python3 -m py_compile tests/cpp_api/rocjpeg_decode_perf/rocal_decode_call_bench.py
cmake --build build --target rocal -j$(nproc)Also built the |
spolifroni-amd
left a comment
There was a problem hiding this comment.
This requires a changelog entry.
LakshmiKumar23
left a comment
There was a problem hiding this comment.
Does not effect the TurboJPEG workflow for trainings and improves only decoding time with rocJPEG.
The changelog file changes done in the latest commit. |
Changes are made on this request, the review is showing a way to resolve conversation.
Motivation
This PR adds a rocAL-focused performance harness for validating and measuring rocJPEG-backed image decode behavior, especially for multi-GPU sharded decode workloads.
The main goals are:
jpegdecodeperfacross GPU shards, making it easier to compare rocAL decode results against rocJPEG sample-level performance.dataloader_multithreadtest app so it can drive the new rocJPEG split-path benchmarking with configurable CPU thread count and effective batch sizing.Technical Details
This PR adds the main rocAL decode enhancement being measured by the new harness: rocJPEG decode work can now be split across multiple dedicated rocJPEG decoder instances instead of sending the whole batch through one shared rocJPEG decoder.
The rocJPEG dedicated OpenMP split path is enabled by default. With the default behavior, rocAL creates up to four rocJPEG decoder instances, bounded by the configured CPU thread count and batch size. The input batch is divided into per-decoder sub-batches, and OpenMP dispatches those sub-batches across the dedicated decoder workers. This allows the benchmark configuration of four CPU threads to use four rocJPEG decoder instances, reducing contention around one decoder and improving decode throughput for sharded/multi-GPU image loading workloads.
To compare against the previous behavior, set
ROCAL_ROCJPEG_DEDICATED_OMP_SPLIT=0. In that mode, rocAL keeps the previous single-decoder rocJPEG path, so the benchmark scripts can compare the old and new behavior directly.This PR adds
tests/cpp_api/rocjpeg_decode_perf/as a manual performance harness for the rocJPEG split-decoder change. These scripts are not regular CTest unit tests; they are intended for explicit developer/reviewer runs on systems with a suitable dataset and GPU configuration.The harness is needed because the change is performance-sensitive. A correctness-only test would not show whether splitting rocJPEG work across multiple decoder instances improves decode time or whether ON/OFF behavior remains comparable.
The harness provides:
dataloader_multithread.fn.readers.fileandfn.decoders.image.ROCAL_ROCJPEG_DEDICATED_OMP_SPLIT=0and=1.jpegdecodeperflauncher for rocJPEG sample-level comparison.This PR adds a new manual benchmark/support folder:
New files:
The new
README.mddocuments the benchmark purpose, required environment variables, common workflow, log locations, and example commands for PR reviewers or developers running the tests manually.run_tests_twice_solution_on_off.shis the main rocAL comparison driver. It runs six benchmark cases:The script uses:
to toggle the dedicated split path for rocJPEG runs. It writes logs under configurable
LOG_DIR, defaulting to:The script requires only the machine-specific inputs to be exported:
and supports optional:
reporting_test_results.shparses the logs produced byrun_tests_twice_solution_on_off.sh. It summarizes:rocal_decode_call_bench.pyis a Python rocAL decode benchmark. It builds a simplereaders.file+decoders.imagepipeline and supports:pipe.timing_info()perf_sharded_launcher.cppis a standalone helper launcher for rocJPEGjpegdecodeperf. It:.jpgand.jpegfilesjpegdecodeperfprocess per GPUjpegdecodeperf_gpu<N>.logreporting_perf_sharded_results.shparses the logs produced byperf_sharded_launcher.cpp. It reports:Changes in:
include:
_use_rocjpeg_dedicated_omp_split, controlled byROCAL_ROCJPEG_DEDICATED_OMP_SPLIT.This PR also updates:
to support this benchmark path by:
cpu_thread_countargumentcpu_thread_countintorocalCreateROCAL_ROCJPEG_DEDICATED_OMP_SPLITTest Plan
Lightweight validation was run after applying the changes:
Manual benchmark workflow documented in the README:
Standalone
jpegdecodeperfworkflow documented in the README:Test Result
The following local checks passed:
reporting_perf_sharded_results.shreporting_test_results.shrun_tests_twice_solution_on_off.shperf_sharded_launcher.cppcompiled successfully withg++ -std=c++17 -Wall -Wextra -pedantic.rocal_decode_call_bench.pypassed Python bytecode compilation withpython3 -m py_compile.The benchmark harness was added specifically to report the effect of this change by comparing:
against:
for both C++ and Python rocAL decode paths.
No full hardware benchmark results are included in this PR note because the added harness is intended to support manual performance validation on systems with the target ROCm/rocAL/rocJPEG installation, dataset, and GPU configuration.