Skip to content

Commit

Permalink
Merge pull request #70 from constracktor/hpx_start
Browse files Browse the repository at this point in the history
Adding HPX backend (train,predict and tests) based on hpx::for_each and hpx::experimental::for_loop
  • Loading branch information
breyerml authored Nov 28, 2024
2 parents 66c17a4 + c5c7dab commit 385b9b4
Show file tree
Hide file tree
Showing 53 changed files with 2,653 additions and 53 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"plssvm/'
Priority: 1
- Regex: '^"(cuda|hip|CL|sycl|omp)'
- Regex: '^"(cuda|hip|CL|sycl|omp|hpx)'
Priority: 2
- Regex: '^"(tests|bindings)/'
Priority: 3
Expand Down
14 changes: 13 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Authors: Alexander Van Craen, Marcel Breyer
## Authors: Alexander Van Craen, Marcel Breyer, Alexander Strack
## Copyright (C): 2018-today The PLSSVM project - All Rights Reserved
## License: This file is part of the PLSSVM project which is released under the MIT license.
## See the LICENSE.md file in the project root for full license information.
Expand Down Expand Up @@ -376,6 +376,13 @@ if (PLSSVM_ENABLE_STDPAR_BACKEND MATCHES "AUTO" OR PLSSVM_ENABLE_STDPAR_BACKEND)
add_subdirectory(src/plssvm/backends/stdpar)
endif ()

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

## check for CUDA backend
set(PLSSVM_ENABLE_CUDA_BACKEND AUTO CACHE STRING "Enable CUDA Backend")
set_property(CACHE PLSSVM_ENABLE_CUDA_BACKEND PROPERTY STRINGS AUTO ON OFF)
Expand Down Expand Up @@ -705,6 +712,10 @@ if (TARGET ${PLSSVM_STDPAR_BACKEND_LIBRARY_NAME})
message(STATUS "${PLSSVM_STDPAR_BACKEND_SUMMARY_STRING}")
list(APPEND PLSSVM_BACKEND_NAME_LIST "stdpar")
endif ()
if (TARGET ${PLSSVM_HPX_BACKEND_LIBRARY_NAME})
message(STATUS "${PLSSVM_HPX_BACKEND_SUMMARY_STRING}")
list(APPEND PLSSVM_BACKEND_NAME_LIST "hpx")
endif ()
if (TARGET ${PLSSVM_CUDA_BACKEND_LIBRARY_NAME})
message(STATUS "${PLSSVM_CUDA_BACKEND_SUMMARY_STRING}")
list(APPEND PLSSVM_BACKEND_NAME_LIST "cuda")
Expand Down Expand Up @@ -852,6 +863,7 @@ install(FILES
"${PROJECT_BINARY_DIR}/plssvmHIPTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmOpenCLTargets.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/plssvm/plssvmOpenMPTargets.cmake"
"${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/plssvmstdparTargets.cmake"
Expand Down
3 changes: 2 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"version": 6,
"include": [
"cmake/presets/openmp.json",
"cmake/presets/hpx.json",
"cmake/presets/stdpar.json",
"cmake/presets/stdpar_gcc.json",
"cmake/presets/stdpar_nvhpc.json",
Expand All @@ -15,4 +16,4 @@
"cmake/presets/dpcpp.json",
"cmake/presets/all.json"
]
}
}
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ The main highlights of our SVM implementations are:
1. Drop-in replacement for LIBSVM's `svm-train`, `svm-predict`, and `svm-scale` (some features currently not implemented).
2. Support of multiple different programming frameworks for parallelization (also called backends in our PLSSVM implementation) which allows us to target GPUs and CPUs from different vendors like NVIDIA, AMD, or Intel:
- [OpenMP](https://www.openmp.org/)
- [HPX](https://hpx.stellar-group.org/)
- [stdpar](https://en.cppreference.com/w/cpp/algorithm) (supported implementations are [nvc++](https://developer.nvidia.com/hpc-sdk) from NVIDIA's HPC SDK, [roc-stdpar](https://github.com/ROCm/roc-stdpar) as a patched LLVM, [icpx](https://www.intel.com/content/www/us/en/developer/tools/oneapi/dpc-compiler.html) as Intel's oneAPI compiler, [AdaptiveCpp](https://github.com/AdaptiveCpp/AdaptiveCpp), and [GNU GCC](https://gcc.gnu.org/) using TBB). <br>
**Note**: due to the nature of the used USM mechanics in the `stdpar` implementations, the `stdpar` backend **can't** be enabled together with **any** other backend! <br>
**Note**: since every translation units need to be compiled with the same flag, we currently globally set `CMAKE_CXX_FLAGS` although it's discouraged in favor of `target_compile_options`.
Expand Down Expand Up @@ -105,6 +106,10 @@ Additional dependencies for the stdpar backend:

- compiler with stdpar support

Additional dependencies for the HPX backend:

- [HPX ≥ v1.9.0](https://hpx.stellar-group.org/)

Additional dependencies for the CUDA backend:

- CUDA SDK
Expand Down Expand Up @@ -355,6 +360,9 @@ Available configure presets:
"openmp" - OpenMP backend
"openmp_python" - OpenMP backend + Python bindings
"openmp_test" - OpenMP backend tests
"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
Expand Down Expand Up @@ -545,7 +553,7 @@ 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|cuda|hip|opencl|sycl|stdpar (default: automatic)
-b, --backend arg choose the backend: automatic|openmp|hpx|cuda|hip|opencl|sycl|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)
Expand Down Expand Up @@ -589,13 +597,14 @@ 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` 🠦 `stdpar`
- otherwise, if the `cpu` target is available, check for existing backends in order `sycl` 🠦 `opencl` 🠦 `openmp` 🠦 `hpx` 🠦 `stdpar`

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

The `--target_platform=automatic` option works for the different backends as follows:

- `OpenMP`: always selects a CPU
- `HPX`: always selects a CPU
- `CUDA`: always selects an NVIDIA GPU (if no NVIDIA GPU is available, throws an exception)
- `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
Expand Down
7 changes: 5 additions & 2 deletions bindings/Python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Authors: Alexander Van Craen, Marcel Breyer
## Authors: Alexander Van Craen, Marcel Breyer, Alexander Strack
## Copyright (C): 2018-today The PLSSVM project - All Rights Reserved
## License: This file is part of the PLSSVM project which is released under the MIT license.
## See the LICENSE.md file in the project root for full license information.
Expand Down Expand Up @@ -68,6 +68,9 @@ endif ()
if (TARGET ${PLSSVM_OPENMP_BACKEND_LIBRARY_NAME})
list(APPEND PLSSVM_PYTHON_BINDINGS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/backends/openmp_csvm.cpp)
endif ()
if (TARGET ${PLSSVM_HPX_BACKEND_LIBRARY_NAME})
list(APPEND PLSSVM_PYTHON_BINDINGS_SOURCES ${CMAKE_CURRENT_LIST_DIR}/backends/hpx_csvm.cpp)
endif ()
if (TARGET ${PLSSVM_STDPAR_BACKEND_LIBRARY_NAME})

# AdaptiveCpp stdpar only support on the CPU when using our Python bindings
Expand Down Expand Up @@ -125,4 +128,4 @@ target_compile_options(${PLSSVM_BASE_LIBRARY_NAME} PUBLIC $<$<COMPILE_LANG_AND_I
target_compile_options(${PLSSVM_BASE_LIBRARY_NAME} PUBLIC -fPIC)

# append pybind11 bindings library to installed targets
append_local_and_parent(PLSSVM_TARGETS_TO_INSTALL ${PLSSVM_PYTHON_BINDINGS_LIBRARY_NAME})
append_local_and_parent(PLSSVM_TARGETS_TO_INSTALL ${PLSSVM_PYTHON_BINDINGS_LIBRARY_NAME})
12 changes: 8 additions & 4 deletions bindings/Python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
- [plssvm.Parameter](#plssvmparameter)
- [plssvm.DataSet](#plssvmdataset)
- [plssvm.CSVM](#plssvmcsvm)
- [plssvm.openmp.CSVM, plssvm.stdpar.CSVM, plssvm.cuda.CSVM, plssvm.hip.CSVM, plssvm.opencl.CSVM, plssvm.sycl.CSVM, plssvm.dpcpp.CSVM, plssvm.adaptivecpp.CSVM](#plssvmopenmpcsvm-plssvmcudacsvm-plssvmhipcsvm-plssvmopenclcsvm-plssvmsyclcsvm-plssvmdpcppcsvm-plssvmadaptivecppcsvm)
- [plssvm.openmp.CSVM, plssvm.hpx.CSVM, plssvm.stdpar.CSVM, plssvm.cuda.CSVM, plssvm.hip.CSVM, plssvm.opencl.CSVM, plssvm.sycl.CSVM, plssvm.dpcpp.CSVM, plssvm.adaptivecpp.CSVM](#plssvmopenmpcsvm-plssvmhpxcsvm-plssvmcudacsvm-plssvmhipcsvm-plssvmopenclcsvm-plssvmsyclcsvm-plssvmdpcppcsvm-plssvmadaptivecppcsvm)
- [plssvm.Model](#plssvmmodel)
- [plssvm.Version](#plssvmversion)
- [plssvm.environment.ScopeGuard](#plssvmenvironmentscopeguard)
Expand Down Expand Up @@ -196,7 +196,7 @@ The following table lists all PLSSVM enumerations exposed on the Python side:
| `FileFormatType` | `LIBSVM`, `ARFF` | The different supported file format types (default: `LIBSVM`). |
| `GammaCoefficientType` | `AUTOMATIC`, `SCALE` | The different modes for the dynamic gamma calculation (default: `AUTOMATIC`). |
| `ClassificationType` | `OAA`, `OAO` | The different supported multi-class classification strategies (default: `LIBSVM`). |
| `BackendType` | `AUTOMATIC`, `OPENMP`, `CUDA`, `HIP`, `OPENCL`, `SYCL` | The different supported backends (default: `AUTOMATIC`). If `AUTOMATIC` is provided, the selected backend depends on the used target platform. |
| `BackendType` | `AUTOMATIC`, `OPENMP`, `HPX`, `CUDA`, `HIP`, `OPENCL`, `SYCL` | The different supported backends (default: `AUTOMATIC`). If `AUTOMATIC` is provided, the selected backend depends on the used target platform. |
| `VerbosityLevel` | `QUIET`, `LIBSVM`, `TIMING`, `FULL` | The different supported log levels (default: `FULL`). `QUIET` means no output, `LIBSVM` output that is as conformant as possible with LIBSVM's output, `TIMING` all timing related outputs, and `FULL` everything. Can be combined via bit-wise operations. |
| `Status` | `UNINITIALIZED`, `INITIALIZED`, `FINALIZED`, `UNNECESSARY` | The different environment status values. **Note**: located in the `plssvm.environment` module. | |

Expand Down Expand Up @@ -337,6 +337,10 @@ If the most performant backend should be used, it is sufficient to use `plssvm.C
`sycl_implementation_type` to choose between DPC++ and AdaptiveCpp as SYCL implementations
and `sycl_kernel_invocation_type` to choose between the two different SYCL kernel invocation types.

**Note**: if the backend type is `plssvm.BackendType.HPX` it is necessary to initialize and finalize the HPX runtime.
The runtime can be manually managed using `plssvm.environment.initialize()` and `plssvm.environment.finalize()`.
We recommend utilizing `plssvm.environment.ScopeGuard()` to manage the lifetime of the HPX runtime automatically.

| methods | description |
|----------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `set_params(params)` | Replace the current `plssvm.Parameter` with the provided one. |
Expand All @@ -349,7 +353,7 @@ and `sycl_kernel_invocation_type` to choose between the two different SYCL kerne
| `score(model)` | Score the model with respect to itself returning its accuracy. |
| `score(model, data_set)` | Score the model given the provided data set returning its accuracy. |

#### `plssvm.openmp.CSVM`, `plssvm.stdpar.CSVM`, plssvm.cuda.CSVM`, `plssvm.hip.CSVM`, `plssvm.opencl.CSVM`, `plssvm.sycl.CSVM`, `plssvm.dpcpp.CSVM`, `plssvm.adaptivecpp.CSVM`
#### `plssvm.openmp.CSVM`, `plssvm.hpx.CSVM`, `plssvm.stdpar.CSVM`, plssvm.cuda.CSVM`, `plssvm.hip.CSVM`, `plssvm.opencl.CSVM`, `plssvm.sycl.CSVM`, `plssvm.dpcpp.CSVM`, `plssvm.adaptivecpp.CSVM`

These classes represent the backend specific CSVMs.
**Note**: they are only available if the respective backend has been enabled during PLSSVM's build step.
Expand Down Expand Up @@ -560,4 +564,4 @@ The PLSSVM Python3 bindings define a few new exception types:
| `ClassificationReportError` | If something in the classification report went wrong. **Note**: shouldn't occur in user code. |
| `EnvironmentError` | If something during environment initialization or finalization went wrong. |

Depending on the available backends, additional `BackendError`s are also available (e.g., `plssvm.cuda.BackendError`).
Depending on the available backends, additional `BackendError`s are also available (e.g., `plssvm.cuda.BackendError`).
2 changes: 2 additions & 0 deletions bindings/Python/backend_types.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* @author Alexander Van Craen
* @author Marcel Breyer
* @author Alexander Strack
* @copyright 2018-today The PLSSVM project - All Rights Reserved
* @license This file is part of the PLSSVM project which is released under the MIT license.
* See the LICENSE.md file in the project root for full license information.
Expand All @@ -20,6 +21,7 @@ void init_backend_types(py::module_ &m) {
py::enum_<plssvm::backend_type>(m, "BackendType")
.value("AUTOMATIC", plssvm::backend_type::automatic, "the default backend; depends on the specified target platform")
.value("OPENMP", plssvm::backend_type::openmp, "OpenMP to target CPUs only (currently no OpenMP target offloading support)")
.value("HPX", plssvm::backend_type::hpx, "HPX to target CPUs only (currently no GPU executor support)")
.value("STDPAR", plssvm::backend_type::stdpar, "C++ standard parallelism to target CPUs and GPUs from different vendors based on the used stdpar implementation; supported implementations are: nvhpc (nvc++), roc-stdpar, AdaptiveCpp, Intel LLVM (icpx), and GNU GCC + TBB")
.value("CUDA", plssvm::backend_type::cuda, "CUDA to target NVIDIA GPUs only")
.value("HIP", plssvm::backend_type::hip, "HIP to target AMD and NVIDIA GPUs")
Expand Down
Loading

0 comments on commit 385b9b4

Please sign in to comment.