Skip to content

Commit

Permalink
Merge pull request #72 from SC-SGS/Kokkos
Browse files Browse the repository at this point in the history
Add new Kokkos backend
  • Loading branch information
vancraar authored Dec 4, 2024
2 parents b563c6f + cd6d31c commit ace2d49
Show file tree
Hide file tree
Showing 91 changed files with 7,409 additions and 364 deletions.
5 changes: 4 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---
Language: Json
DisableFormat: true
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
Expand Down Expand Up @@ -79,7 +82,7 @@ IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"plssvm/'
Priority: 1
- Regex: '^"(cuda|hip|CL|sycl|omp|hpx)'
- Regex: '^"(cuda|hip|CL|sycl|omp|hpx|Kokkos)'
Priority: 2
- Regex: '^"(tests|bindings)/'
Priority: 3
Expand Down
27 changes: 25 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ endif ()
########################################################################################################################
## set base sources
set(PLSSVM_BASE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/plssvm/backends/Kokkos/execution_space.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/plssvm/backends/SYCL/implementation_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/plssvm/backends/SYCL/kernel_invocation_types.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/plssvm/backends/stdpar/implementation_types.cpp
Expand Down Expand Up @@ -411,6 +412,13 @@ if (PLSSVM_ENABLE_SYCL_BACKEND MATCHES "AUTO" OR PLSSVM_ENABLE_SYCL_BACKEND)
add_subdirectory(src/plssvm/backends/SYCL)
endif ()

## check for Kokkos backend
set(PLSSVM_ENABLE_KOKKOS_BACKEND AUTO CACHE STRING "Enable SYCL Backend")
set_property(CACHE PLSSVM_ENABLE_KOKKOS_BACKEND PROPERTY STRINGS AUTO ON OFF)
if (PLSSVM_ENABLE_KOKKOS_BACKEND MATCHES "AUTO" OR PLSSVM_ENABLE_KOKKOS_BACKEND)
add_subdirectory(src/plssvm/backends/Kokkos)
endif ()

## check if ANY backend is available/has been enabled
get_target_property(PLSSVM_LINKED_BACKENDS ${PLSSVM_ALL_LIBRARY_NAME} INTERFACE_LINK_LIBRARIES)
if (NOT PLSSVM_LINKED_BACKENDS)
Expand Down Expand Up @@ -642,7 +650,7 @@ if (PLSSVM_ENABLE_FORMATTING)
list(APPEND CMAKE_MESSAGE_INDENT "Formatting: ")

## install library to add a clang-format target
set(PLSSVM_format_VERSION 7021abbf066e2e577926731c3fa4141f456c5024)
set(PLSSVM_format_VERSION d22c36043bea6ef85f3eb68b823f50703bd1cc21)
find_package(format QUIET)
if (format_FOUND)
message(STATUS "Found package format.")
Expand Down Expand Up @@ -734,6 +742,10 @@ if (TARGET ${PLSSVM_SYCL_BACKEND_LIBRARY_NAME})
endforeach ()
list(APPEND PLSSVM_BACKEND_NAME_LIST "sycl")
endif ()
if (TARGET ${PLSSVM_KOKKOS_BACKEND_LIBRARY_NAME})
message(STATUS "${PLSSVM_KOKKOS_BACKEND_SUMMARY_STRING}")
list(APPEND PLSSVM_BACKEND_NAME_LIST "kokkos")
endif ()
message(STATUS "")

########################################################################################################################
Expand All @@ -758,8 +770,8 @@ message(STATUS "Generating manpage files.")
string(TIMESTAMP PLSSVM_CURRENT_BUILD_TIME "%d. %B %Y")
string(REPLACE ";" "|" PLSSVM_PLATFORM_NAME_LIST "${PLSSVM_PLATFORM_NAME_LIST}")
string(REPLACE ";" "|" PLSSVM_BACKEND_NAME_LIST "${PLSSVM_BACKEND_NAME_LIST}")
string(REPLACE ";" "|" PLSSVM_SYCL_BACKEND_NAME_LIST "${PLSSVM_SYCL_BACKEND_NAME_LIST}")
if (TARGET ${PLSSVM_SYCL_BACKEND_LIBRARY_NAME})
string(REPLACE ";" "|" PLSSVM_SYCL_BACKEND_NAME_LIST "${PLSSVM_SYCL_BACKEND_NAME_LIST}")
set(PLSSVM_SYCL_IMPLEMENTATION_TYPE_MANPAGE_ENTRY "
.TP
.B --sycl_implementation_type
Expand All @@ -772,6 +784,15 @@ choose the kernel invocation type when using SYCL as backend: automatic|nd_range
")
endif ()
set(PLSSVM_SYCL_MANPAGE_ENTRY "${PLSSVM_SYCL_KERNEL_INVOCATION_TYPE_MANPAGE_ENTRY}${PLSSVM_SYCL_IMPLEMENTATION_TYPE_MANPAGE_ENTRY}")
## assemble the Kokkos manpage entry
if (TARGET ${PLSSVM_KOKKOS_BACKEND_LIBRARY_NAME})
string(REPLACE ";" "|" PLSSVM_KOKKOS_BACKEND_AVAILABLE_EXECUTION_SPACES "${PLSSVM_KOKKOS_BACKEND_AVAILABLE_EXECUTION_SPACES}")
set(PLSSVM_KOKKOS_MANPAGE_ENTRY "
.TP
.B --kokkos_execution_space
choose the Kokkos execution space to be used in the Kokkos backend: automatic|${PLSSVM_KOKKOS_BACKEND_AVAILABLE_EXECUTION_SPACES} (default: automatic)
")
endif ()
## assemble the performance tracker manpage entry
if (PLSSVM_ENABLE_PERFORMANCE_TRACKING)
set(PLSSVM_PERFORMANCE_TRACKER_MANPAGE_ENTRY "
Expand All @@ -787,6 +808,7 @@ configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/docs/plssvm-train.1
@ONLY
)
# update manpage entry since plssvm-predict can't recognize the SYCL kernel invocation type
set(PLSSVM_SYCL_MANPAGE_ENTRY "${PLSSVM_SYCL_IMPLEMENTATION_TYPE_MANPAGE_ENTRY}")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/docs/plssvm-predict.1.in
Expand Down Expand Up @@ -866,6 +888,7 @@ install(FILES
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmHPXTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmAdaptiveCppTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmDPCPPTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmKokkosTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmstdparTargets.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/plssvm/cmake
)
1 change: 1 addition & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"cmake/presets/opencl.json",
"cmake/presets/acpp.json",
"cmake/presets/dpcpp.json",
"cmake/presets/kokkos.json",
"cmake/presets/all.json"
]
}
79 changes: 52 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ The main highlights of our SVM implementations are:
- [HIP](https://github.com/ROCm-Developer-Tools/HIP)
- [OpenCL](https://www.khronos.org/opencl/)
- [SYCL](https://www.khronos.org/sycl/) (supported implementations are [DPC++](https://github.com/intel/llvm) and [AdaptiveCpp](https://github.com/AdaptiveCpp/AdaptiveCpp) (formerly known as hipSYCL); specifically the versions [sycl-nightly/20231201](https://github.com/intel/llvm/tree/sycl-nightly/20230110) and AdaptiveCpp release [v24.06.0](https://github.com/AdaptiveCpp/AdaptiveCpp/releases/tag/v23.10.0))
- [Kokkos](https://github.com/kokkos/kokkos) (all execution spaces supported except `OpenMPTarget` and `OpenACC`); specifically the version [4.5.00](https://github.com/kokkos/kokkos/releases/tag/4.5.00)
3. Six different kernel functions to be able to classify a large variety of different problems:
- linear: $\vec{u}^T$ $\cdot$ $\vec{v}$
- polynomial: $(\gamma$ $\cdot$ $\vec{u}^T$ $\cdot$ $\vec{v}$ $+$ $coef0)^{d}$
Expand Down Expand Up @@ -128,6 +129,10 @@ Additional dependencies for the SYCL backend:

- the code must be compiled with a SYCL capable compiler; currently supported are [DPC++](https://github.com/intel/llvm) and [AdaptiveCpp](https://github.com/AdaptiveCpp/AdaptiveCpp)

Additional dependencies for the Kokkos backend:

- a Kokkos installation with the respective execution spaces enabled; currently all execution spaces are supported except `OpenMPTarget` and `OpenACC`

Additional dependencies for the stdpar backend:

- the code must be compiled with a stdpar capable compiler; currently supported are [nvc++](https://developer.nvidia.com/hpc-sdk), [roc-stdpar](https://github.com/ROCm/roc-stdpar), [icpx](https://www.intel.com/content/www/us/en/developer/tools/oneapi/dpc-compiler.html), [AdaptiveCpp](https://github.com/AdaptiveCpp/AdaptiveCpp), and [GNU GCC](https://gcc.gnu.org/))
Expand Down Expand Up @@ -243,6 +248,11 @@ The `[optional_options]` can be one or multiple of:
- `AUTO`: check for the OpenMP backend but **do not** fail if not available
- `OFF`: do not check for the OpenMP backend

- `PLSSVM_ENABLE_HPX_BACKEND=ON|OFF|AUTO` (default: `AUTO`):
- `ON`: check for the HPX backend and fail if not available
- `AUTO`: check for the HPX backend but **do not** fail if not available
- `OFF`: do not check for the HPX backend

- `PLSSVM_ENABLE_STDPAR_BACKEND=ON|OFF|AUTO` (default: `AUTO`):
- `ON`: check for the stdpar backend and fail if not available
- `AUTO`: check for the stdpar backend but **do not** fail if not available
Expand All @@ -268,6 +278,11 @@ The `[optional_options]` can be one or multiple of:
- `AUTO`: check for the SYCL backend but **do not** fail if not available
- `OFF`: do not check for the SYCL backend

- `PLSSVM_ENABLE_KOKKOS_BACKEND=ON|OFF|AUTO` (default: `AUTO`):
- `ON`: check for the Kokkos backend and fail if not available
- `AUTO`: check for the Kokkos backend but **do not** fail if not available
- `OFF`: do not check for the Kokkos backend

**Attention:** at least one backend must be enabled and available!

- `PLSSVM_ENABLE_FAST_MATH=ON|OFF` (default depending on `CMAKE_BUILD_TYPE`: `ON` for Release or RelWithDebInfo, `OFF` otherwise): enable `fast-math` compiler flags for all backends
Expand Down Expand Up @@ -344,6 +359,10 @@ If more than one SYCL implementation is available the environment variables `PLS

- `PLSSVM_SYCL_BACKEND_PREFERRED_IMPLEMENTATION` (`dpcpp`|`adaptivecpp`): specify the preferred SYCL implementation if the `sycl_implementation_type` option is set to `automatic`; additional the specified SYCL implementation is used in the `plssvm::sycl` namespace, the other implementations are available in the `plssvm::dpcpp` and `plssvm::adaptivecpp` namespace respectively

If the Kokkos backend is available the following additional option is available (**note**: this option takes only effect if the Kokkos SYCL execution space is available):

- `PLSSVM_KOKKOS_BACKEND_INTEL_LLVM_ENABLE_AOT` (default: `ON`): enable Ahead-of-Time (AOT) compilation for the specified target platforms

If the stdpar backend is available, an additional options can be set.

- `PLSSVM_STDPAR_BACKEND_IMPLEMENTATION` (default: `AUTO`): explicitly specify the used stdpar implementation; must be one of: `AUTO`, `NVHPC`, `roc-stdpar`, `IntelLLVM`, `ACPP`, `GNU_TBB`.
Expand All @@ -363,24 +382,6 @@ Available configure presets:
"hpx" - HPX backend
"hpx_python" - HPX backend + Python bindings
"hpx_test" - HPX backend tests
"cuda" - CUDA backend
"cuda_python" - CUDA backend + Python bindings
"cuda_test" - CUDA backend tests
"hip" - HIP backend
"hip_python" - HIP backend + Python bindings
"hip_test" - HIP backend tests
"opencl" - OpenCL backend
"opencl_python" - OpenCL backend + Python bindings
"opencl_test" - OpenCL backend tests
"acpp" - AdaptiveCpp SYCL backend
"acpp_python" - AdaptiveCpp SYCL backend + Python bindings
"acpp_test" - AdaptiveCpp SYCL backend tests
"dpcpp" - DPC++/icpx SYCL backend
"dpcpp_python" - DPC++/icpx backend + Python bindings
"dpcpp_test" - DPC++/icpx backend tests
"all" - All available backends
"all_python" - All available backends + Python bindings
"all_test" - All available backends tests
"stdpar" - stdpar backend
"stdpar_python" - stdpar backend + Python bindings
"stdpar_test" - stdpar backend tests
Expand All @@ -399,6 +400,27 @@ Available configure presets:
"stdpar_intelllvm" - stdpar IntelLLVM (icpx) backend
"stdpar_intelllvm_python" - stdpar IntelLLVM (icpx) backend + Python bindings
"stdpar_intelllvm_test" - stdpar IntelLLVM (icpx) backend tests
"cuda" - CUDA backend
"cuda_python" - CUDA backend + Python bindings
"cuda_test" - CUDA backend tests
"hip" - HIP backend
"hip_python" - HIP backend + Python bindings
"hip_test" - HIP backend tests
"opencl" - OpenCL backend
"opencl_python" - OpenCL backend + Python bindings
"opencl_test" - OpenCL backend tests
"acpp" - AdaptiveCpp SYCL backend
"acpp_python" - AdaptiveCpp SYCL backend + Python bindings
"acpp_test" - AdaptiveCpp SYCL backend tests
"dpcpp" - DPC++/icpx SYCL backend
"dpcpp_python" - DPC++/icpx backend + Python bindings
"dpcpp_test" - DPC++/icpx backend tests
"kokkos" - Kokkos backend
"kokkos_python" - Kokkos backend + Python bindings
"kokkos_test" - Kokkos backend tests
"all" - All available backends
"all_python" - All available backends + Python bindings
"all_test" - All available backends tests
```

With these presets, building and testing, e.g., our CUDA backend is as simple as typing (in the PLSSVM root directory):
Expand Down Expand Up @@ -553,12 +575,14 @@ Usage:
-i, --max_iter arg set the maximum number of CG iterations (default: num_features)
-l, --solver arg choose the solver: automatic|cg_explicit|cg_implicit (default: automatic)
-a, --classification arg the classification strategy to use for multi-class classification: oaa|oao (default: oaa)
-b, --backend arg choose the backend: automatic|openmp|hpx|cuda|hip|opencl|sycl|stdpar (default: automatic)
-b, --backend arg choose the backend: automatic|openmp|hpx|cuda|hip|opencl|sycl|kokkos|stdpar (default: automatic)
-p, --target_platform arg choose the target platform: automatic|cpu|gpu_nvidia|gpu_amd|gpu_intel (default: automatic)
--sycl_kernel_invocation_type arg
choose the kernel invocation type when using SYCL as backend: automatic|nd_range (default: automatic)
--sycl_implementation_type arg
choose the SYCL implementation to be used in the SYCL backend: automatic|dpcpp|adaptivecpp (default: automatic)
--kokkos_execution_space arg
choose the Kokkos execution space to be used in the Kokkos backend: automatic|Cuda|OpenMP|Serial (default: automatic)
--performance_tracking arg
the output YAML file where the performance tracking results are written to; if not provided, the results are dumped to stderr
--use_strings_as_labels use strings as labels instead of plane numbers
Expand Down Expand Up @@ -594,10 +618,10 @@ Another example targeting NVIDIA GPUs using the SYCL backend looks like:

The `--backend=automatic` option works as follows:

- if the `gpu_nvidia` target is available, check for existing backends in order `cuda` 🠦 `hip` 🠦 `opencl` 🠦 `sycl` 🠦 `stdpar`
- otherwise, if the `gpu_amd` target is available, check for existing backends in order `hip` 🠦 `opencl` 🠦 `sycl` 🠦 `stdpar`
- otherwise, if the `gpu_intel` target is available, check for existing backends in order `sycl` 🠦 `opencl` 🠦 `stdpar`
- otherwise, if the `cpu` target is available, check for existing backends in order `sycl` 🠦 `opencl` 🠦 `openmp` 🠦 `hpx` 🠦 `stdpar`
- if the `gpu_nvidia` target is available, check for existing backends in order `cuda` 🠦 `hip` 🠦 `opencl` 🠦 `sycl` 🠦 `kokkos` 🠦 `stdpar`
- otherwise, if the `gpu_amd` target is available, check for existing backends in order `hip` 🠦 `opencl` 🠦 `sycl` 🠦 `kokkos` 🠦 `stdpar`
- otherwise, if the `gpu_intel` target is available, check for existing backends in order `sycl` 🠦 `opencl` 🠦 `kokkos` 🠦 `stdpar`
- otherwise, if the `cpu` target is available, check for existing backends in order `sycl` 🠦 `kokkos` 🠦 `opencl` 🠦 `openmp` 🠦 `hpx` 🠦 `stdpar`

Note that during CMake configuration it is guaranteed that at least one of the above combinations does exist.

Expand All @@ -609,11 +633,13 @@ The `--target_platform=automatic` option works for the different backends as fol
- `HIP`: always selects an AMD GPU (if no AMD GPU is available, throws an exception)
- `OpenCL`: tries to find available devices in the following order: NVIDIA GPUs 🠦 AMD GPUs 🠦 Intel GPUs 🠦 CPU
- `SYCL`: tries to find available devices in the following order: NVIDIA GPUs 🠦 AMD GPUs 🠦 Intel GPUs 🠦 CPU
- `Kokkos`: checks which execution spaces are available and which target platforms they support and then tries to find available devices in the following order: NVIDIA GPUs 🠦 AMD GPUs 🠦 Intel GPUs 🠦 CPU
- `stdpar`: target device must be selected at compile time (using `PLSSVM_TARGET_PLATFORMS`) or using environment variables at runtime

The `--sycl_kernel_invocation_type` and `--sycl_implementation_type` flags are only used if the `--backend` is `sycl`, otherwise a warning is emitted on `stderr`.
If the `--sycl_kernel_invocation_type` is `automatic`, the `nd_range` invocation type is currently always used.
If the `--sycl_implementation_type` is `automatic`, the used SYCL implementation is determined by the `PLSSVM_SYCL_BACKEND_PREFERRED_IMPLEMENTATION` CMake flag.
If the `--kokkos_execution_space` is `automatic`, uses the best fitting execution space based on the provided and/or available target platforms.

### Predicting using `plssvm-predict`

Expand All @@ -628,10 +654,12 @@ LS-SVM with multiple (GPU-)backends
Usage:
./plssvm-predict [OPTION...] test_file model_file [output_file]
-b, --backend arg choose the backend: automatic|openmp|cuda|hip|opencl|sycl|stdpar (default: automatic)
-b, --backend arg choose the backend: automatic|openmp|hpx|cuda|hip|opencl|sycl|kokkos|stdpar (default: automatic)
-p, --target_platform arg choose the target platform: automatic|cpu|gpu_nvidia|gpu_amd|gpu_intel (default: automatic)
--sycl_implementation_type arg
choose the SYCL implementation to be used in the SYCL backend: automatic|dpcpp|adaptivecpp (default: automatic)
--kokkos_execution_space arg
choose the Kokkos execution space to be used in the Kokkos backend: automatic|Cuda|OpenMP|Serial (default: automatic)
--performance_tracking arg
the output YAML file where the performance tracking results are written to; if not provided, the results are dumped to stderr
--use_strings_as_labels use strings as labels instead of plane numbers
Expand Down Expand Up @@ -777,9 +805,6 @@ Roughly the same can be achieved using our Python bindings with the following Py
import plssvm
from sklearn.metrics import classification_report

# correctly initialize and finalize environments
environment_guard = plssvm.environment.ScopeGuard()

try:
# create a new C-SVM parameter set, explicitly overriding the default kernel function
params = plssvm.Parameter(kernel_type=plssvm.KernelFunctionType.POLYNOMIAL)
Expand Down
4 changes: 3 additions & 1 deletion bindings/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ set(PLSSVM_PYTHON_BINDINGS_SOURCES
${CMAKE_CURRENT_LIST_DIR}/classification_types.cpp
${CMAKE_CURRENT_LIST_DIR}/csvm.cpp
${CMAKE_CURRENT_LIST_DIR}/data_set.cpp
${CMAKE_CURRENT_LIST_DIR}/environment.cpp
${CMAKE_CURRENT_LIST_DIR}/file_format_types.cpp
${CMAKE_CURRENT_LIST_DIR}/gamma.cpp
${CMAKE_CURRENT_LIST_DIR}/kernel_function_types.cpp
Expand Down Expand Up @@ -98,6 +97,9 @@ endif ()
if (TARGET ${PLSSVM_SYCL_BACKEND_DPCPP_LIBRARY_NAME})
list(APPEND PLSSVM_PYTHON_BINDINGS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/backends/dpcpp_csvm.cpp)
endif ()
if (TARGET ${PLSSVM_KOKKOS_BACKEND_LIBRARY_NAME})
list(APPEND PLSSVM_PYTHON_BINDINGS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/backends/kokkos_csvm.cpp)
endif ()

# create pybind11 module
set(PLSSVM_PYTHON_BINDINGS_LIBRARY_NAME plssvm)
Expand Down
Loading

0 comments on commit ace2d49

Please sign in to comment.