alpaka
repository·develop·Indexed 19 days ago
https://github.com/alpaka-group/alpakaA header-only C++20 abstraction library for parallel kernel acceleration. It provides performance portability across CPUs and GPUs (NVIDIA, AMD, Intel) using backends such as CUDA, HIP, SYCL, and OpenMP. The library utilizes a domain decomposition strategy based on a grid-blocks-threads model to allow a single kernel implementation to run on various hardware accelerators.
What's inside alpaka
- alpaka is a header-only C++20 abstraction library designed for accelerator development. Its primary goal is to provide performance portability across different hardware accelerators by providing an abstraction of the underlying levels of parallelism, rather than hiding them. This allows developers to write code that can run on various back-ends while maintaining performance.
Key features of Catch2
developCatch2 provides several features that differentiate it from other C++ testing frameworks:
- Self-registering tests: Write test cases as functions or methods that register themselves.
- Sections: Divide test cases into sections that run in isolation, which eliminates the need for traditional test fixtures.
- BDD Support: Use Given-When-Then style sections alongside traditional unit tests.
- Expression Decomposition: Use a single core assertion macro for comparisons. It uses standard C/C++ operators (like
==,!=, etc.) but decomposes the full expression to log both the left-hand side (lhs) and right-hand side (rhs) values upon failure. - Free-form naming: Test names are defined using free-form strings rather than being restricted to legal C++ identifiers.
Advanced features in Catch2
developBeyond basic testing, Catch2 includes several advanced capabilities:
- Test Tagging: Tag tests to run specific ad-hoc groups.
- Debugging: Optionally break into the debugger on failure (supported on common platforms).
- Modular Reporting: Output results via modular reporter objects. Includes basic textual, XML, and JUnit XML reporters (the latter is useful for CI server integration).
- Customizable Entry Point: A default
main()is provided, but you can supply your own for integration with custom test runners or GUIs. A command line parser is still available even if you provide your ownmain(). - Floating Point Comparison: Provides
Catch::Approxand a full set of matchers for floating point testing. - Data-Driven Testing: Includes data generators for testing multiple data sets.
- Matchers: Supports Hamcrest-style Matchers for testing complex properties.
- Microbenchmarking: Built-in support for microbenchmarking code segments.
Supported back-ends and scope of alpaka
developSupported Back-ends
alpakaprovides back-ends for several major technologies, including:- CUDA
- OpenMP
- HIP
- SYCL
- And other technologies via user-defined extensions.
Scope and Limitations
- Shared Memory Focus:
alpakais designed for parallelization within shared memory (within a node). It is not a distributed computing library. For parallelization across nodes in a cluster, you should combinealpakawith a library like MPI (Message Passing Interface). - No Automatic Optimization: The library does not automatically provide optimal kernel-to-platform mappings or optimize concurrent data access/memory layouts. Optimal execution depends on the user's selection of data structures.
- Arithmetic and Determinism:
alpakadoes not handle differences in arithmetic operations (like rounding) and does not guarantee deterministic results. Reordering or repartitioning threads can lead to non-deterministic results due to the non-associativity of floating-point operations.
Understand the Alpaka reduction example
developThe
example/reducedirectory contains a demonstration of a reduction operation designed to work across both CPU and GPU accelerators using the Alpaka library. This example showcases how to implement and execute parallel reduction kernels that are portable across different hardware back-ends.Key components of the example include:
alpakaConfig.hpp: Manages configurations and settings specific to individual accelerators.iterator.hpp: Provides both CPU and GPU iterator implementations used to traverse data.kernel.hpp: Contains the optimized Alpaka reduction kernel implementation.reduce.cpp: The main entry point that orchestrates the reduction process.
What is the alpaka library and its core model
developThe
alpakalibrary (Abstraction Library for Parallel Kernel Acceleration) implements an abstract interface for the hierarchical redundant parallelism model.This model allows you to write a single version of an algorithm or kernel that can be executed across heterogeneous parallel systems (CPUs, GPUs, and other accelerators) by simply selecting the target device. It exploits task-parallelism, data-parallelism, and memory hierarchies at all levels of modern multi-core architectures.
Key benefits include:
- Performance Portability: Achieve performance across various accelerators by utilizing only the supported levels of the hierarchy.
- Maintainability: Avoid "copy and paste" kernels for different APIs; all accelerator-dependent details are hidden within the library.
- Testability: Easily switch back-ends (e.g., run CUDA kernels on a CPU) for testing without special hardware.
- Extensibility: Users can define new devices, queues, buffer types, or even entire accelerator back-ends using the trait-based C++ template interface.
Mapping CUDA functionality to alpaka
developWhen using the CUDA back-end in alpaka, most CUDA functionality maps directly to alpaka function calls. However, there are key differences in indexing and dimensionality:
- Indexing Order: While CUDA uses
(x, y, z)order for block and grid sizes, alpaka uses the mathematical C/C++ array indexing scheme[z][y][x]. In both systems,xis the innermost/fastest running index. - Dimensionality: alpaka supports arbitrary dimensionality via templates, though the current CUDA implementation is restricted to a maximum of 3 dimensions.
- Device State: Be aware that the alpaka CUDA back-end can change the current CUDA device and will not automatically restore the previous device after an alpaka function invocation.
- Indexing Order: While CUDA uses
Preventing optimizer interference in benchmarks
developCompilers may optimize away code if the result is not used. Catch2 provides a built-in way to prevent this: return the value from the benchmark block.
Any value returned by the user code in a
BENCHMARKormeter.measureblock is guaranteed to be evaluated and treated as an observable effect, preventing it from being optimized out. While you can still usevolatileor output to stdout, returning the value is the preferred, idiomatic way.// BAD: may be optimized away BENCHMARK("no return"){ long_calculation(); }; // GOOD: result is guaranteed to be computed BENCHMARK("with return"){ return long_calculation(); };Handle CUDA Errors in alpaka
developUnlike raw CUDA where you must manually checkcudaGetLastErrororcudaGetErrorString, Alpaka handles error detection internally. When an error occurs, the details are captured and made available within the exception message thrown by the library. You do not need to call explicit error-checking functions in your application code.Choose an SYCL Accelerator
developThe SYCL back-end provides three main accelerators. These can be used to port existing alpaka code to SYCL-capable hardware:
alpaka::AccCpuSycl: Targets Intel and AMD CPUs using Intel's OpenCL implementation.alpaka::AccFpgaSyclIntel: Targets Intel FPGAs.alpaka::AccGpuSyclIntel: Targets Intel GPUs.
Important Restrictions:
- FPGA Isolation:
alpaka::AccFpgaSyclIntelcannot be used in the same project as the CPU or GPU back-ends due to different compilation requirements. - Dimensions: Like CUDA and HIP, the SYCL back-end supports a maximum of three kernel dimensions.
- FPGA Atomics: The FPGA back-end does not support atomics.
- GPU Double Precision: Some Intel GPUs do not support
double. You can enable software emulation via environment variables:export IGC_EnableDPEmulation=1 export OverrideDefaultFP64Settings=1
Perform Data and Type driven tests
developCatch2 supports advanced testing patterns where test cases are driven by:
- Types: Running the same test logic against different data types (Type-parametrized tests).
- Input Data: Running the same test logic against a variety of input values (Data generators).
How SKIP interacts with Sections and Generators
developThe
SKIPmacro can be used withinSECTIONblocks or when usingGENERATEto skip specific branches of a test case without failing the entire test suite.Behavioral Rules:
- Granularity: Individual sections or specific outputs from a generator can be skipped while the rest of the test continues to execute.
- Reporting: If any single section is skipped, the entire
TEST_CASEis reported as skipped (unless a failing assertion occurred elsewhere in the test, in which case it is reported as failed). - Generators: You can use
SKIPinside a generator's constructor to handle cases where the generator is empty without triggering a test failure.
TEST_CASE("complex test case") { int value = GENERATE(2, 4, 6); SECTION("a") { SECTION("a1") { CHECK(value < 8); } SECTION("a2") { if (value == 4) { SKIP(); } CHECK(value % 2 == 0); } } }