PLSSVM - Parallel Least Squares Support Vector Machine  2.0.0
A Least Squares Support Vector Machine implementation using different backends.
csvm_factory.hpp
Go to the documentation of this file.
1 
12 #ifndef PLSSVM_CSVM_FACTORY_HPP_
13 #define PLSSVM_CSVM_FACTORY_HPP_
14 #pragma once
15 
16 #include "plssvm/backend_types.hpp" // plssvm::backend, plssvm::csvm_to_backend_type_v
17 #include "plssvm/backends/SYCL/implementation_type.hpp" // plssvm::sycl::implementation_type
18 #include "plssvm/csvm.hpp" // plssvm::csvm, plssvm::csvm_backend_exists_v
19 #include "plssvm/detail/type_traits.hpp" // plssvm::detail::remove_cvref_t
20 #include "plssvm/exceptions/exceptions.hpp" // plssvm::unsupported_backend_exception
21 
22 #include "plssvm/backends/SYCL/detail/constants.hpp" // alias plssvm::sycl to the PLSSVM_SYCL_BACKEND_PREFERRED_IMPLEMENTATION
23  // or to plssvm::dpcpp if no SYCL backend is available
24 
25 // only include requested/available backends
26 #if defined(PLSSVM_HAS_OPENMP_BACKEND)
27  #include "plssvm/backends/OpenMP/csvm.hpp" // plssvm::openmp::csvm, plssvm::csvm_backend_exists_v
28 #endif
29 #if defined(PLSSVM_HAS_CUDA_BACKEND)
30  #include "plssvm/backends/CUDA/csvm.hpp" // plssvm::cuda::csvm, plssvm::csvm_backend_exists_v
31 #endif
32 #if defined(PLSSVM_HAS_HIP_BACKEND)
33  #include "plssvm/backends/HIP/csvm.hpp" // plssvm::hip::csvm, plssvm::csvm_backend_exists_v
34 #endif
35 #if defined(PLSSVM_HAS_OPENCL_BACKEND)
36  #include "plssvm/backends/OpenCL/csvm.hpp" // plssvm::opencl::csvm, plssvm::csvm_backend_exists_v
37 #endif
38 #if defined(PLSSVM_HAS_SYCL_BACKEND)
39  #if defined(PLSSVM_SYCL_BACKEND_HAS_DPCPP)
40  #include "plssvm/backends/SYCL/DPCPP/csvm.hpp" // plssvm::dpcpp::csvm, plssvm::csvm_backend_exists_v
41  #endif
42  #if defined(PLSSVM_SYCL_BACKEND_HAS_HIPSYCL)
43  #include "plssvm/backends/SYCL/hipSYCL/csvm.hpp" // plssvm::hipsycl::csvm, plssvm::csvm_backend_exists_v
44  #endif
45 #endif
46 
47 #include "fmt/core.h" // fmt::format
48 #include "igor/igor.hpp" // igor::parser, igor::has_unnamed_arguments
49 
50 #include <memory> // std::unique_ptr, std::make_unique
51 #include <type_traits> // std::is_same_v, std::is_constructible_v
52 #include <utility> // std::forward
53 
54 namespace plssvm {
55 
56 namespace detail {
57 
67 template <typename csvm_type, typename... Args>
68 [[nodiscard]] inline std::unique_ptr<csvm> make_csvm_default_impl([[maybe_unused]] Args &&...args) {
69  // test whether the backend is available
70  if constexpr (csvm_backend_exists_v<csvm_type>) {
71  // test whether the backend can be constructed with the provided parameter
72  if constexpr (std::is_constructible_v<csvm_type, Args...>) {
73  return std::make_unique<csvm_type>(std::forward<Args>(args)...);
74  } else {
75  throw unsupported_backend_exception{ fmt::format("Provided invalid (named) arguments for the {} backend!", csvm_to_backend_type_v<csvm_type>) };
76  }
77  } else {
78  throw unsupported_backend_exception{ fmt::format("No {} backend available!", csvm_to_backend_type_v<csvm_type>) };
79  }
80 }
81 
90 template <typename... Args>
91 [[nodiscard]] inline std::unique_ptr<csvm> make_csvm_sycl_impl([[maybe_unused]] Args &&...args) {
92  // check igor parameter
93  igor::parser parser{ args... };
94 
95  // get the SYCL implementation type to use
97  // check whether a specific SYCL implementation type has been requested
98  if constexpr (parser.has(sycl_implementation_type)) {
99  // compile time check: the value must have the correct type
100  static_assert(std::is_same_v<detail::remove_cvref_t<decltype(parser(sycl_implementation_type))>, sycl::implementation_type>, "Provided sycl_implementation_type must be convertible to a plssvm::sycl::implementation_type!");
101  impl_type = static_cast<sycl::implementation_type>(parser(sycl_implementation_type));
102  }
103 
104  switch (impl_type) {
106  return make_csvm_default_impl<sycl::csvm>(std::forward<Args>(args)...);
108  return make_csvm_default_impl<dpcpp::csvm>(std::forward<Args>(args)...);
110  return make_csvm_default_impl<hipsycl::csvm>(std::forward<Args>(args)...);
111  }
112  throw unsupported_backend_exception{ "No sycl backend available!" };
113 }
114 
123 template <typename... Args>
124 [[nodiscard]] inline std::unique_ptr<csvm> make_csvm_impl(const backend_type backend, Args &&...args) {
125  switch (backend) {
127  return make_csvm_impl(determine_default_backend(), std::forward<Args>(args)...);
129  return make_csvm_default_impl<openmp::csvm>(std::forward<Args>(args)...);
130  case backend_type::cuda:
131  return make_csvm_default_impl<cuda::csvm>(std::forward<Args>(args)...);
132  case backend_type::hip:
133  return make_csvm_default_impl<hip::csvm>(std::forward<Args>(args)...);
135  return make_csvm_default_impl<opencl::csvm>(std::forward<Args>(args)...);
136  case backend_type::sycl:
137  return make_csvm_sycl_impl(std::forward<Args>(args)...);
138  }
139  throw unsupported_backend_exception{ "Unrecognized backend provided!" };
140 }
141 
142 } // namespace detail
143 
157 template <typename... Args>
158 [[nodiscard]] inline std::unique_ptr<csvm> make_csvm(const backend_type backend, Args &&...args) {
159  return detail::make_csvm_impl(backend, std::forward<Args>(args)...);
160 }
168 template <typename... Args>
169 [[nodiscard]] inline std::unique_ptr<csvm> make_csvm(Args &&...args) {
170  return detail::make_csvm_impl(backend_type::automatic, std::forward<Args>(args)...);
171 }
172 
173 } // namespace plssvm
174 
175 #endif // PLSSVM_CSVM_FACTORY_HPP_
Defines an enumeration holding all possible backends. Can also include backends not available on the ...
Defines a C-SVM using the CUDA backend.
Defines a C-SVM using the HIP backend.
Defines a C-SVM using the OpenCL backend.
Defines a C-SVM using the OpenMP backend.
Defines a base C-SVM used for the different SYCL backends using DPC++ as SYCL implementation.
Global compile-time constants specific to the SYCL backend.
Defines a base C-SVM used for the different SYCL backends using hipSYCL as SYCL implementation.
Exception type thrown if the requested backend is not supported on the target machine.
Definition: exceptions.hpp:127
Defines the base class for all C-SVM backends and implements the functionality shared by all of them.
Implements custom exception classes derived from std::runtime_error including source location informa...
Defines an enumeration holding all possible SYCL implementations.
std::unique_ptr< csvm > make_csvm_impl(const backend_type backend, Args &&...args)
Create a new C-SVM using the backend type and the additional parameter args.
Definition: csvm_factory.hpp:124
std::remove_cv_t< std::remove_reference_t< T > > remove_cvref_t
Remove the topmost reference- and cv-qualifiers.
Definition: type_traits.hpp:46
std::unique_ptr< csvm > make_csvm_sycl_impl([[maybe_unused]] Args &&...args)
Construct a SYCL C-SVM using the parameters args.
Definition: csvm_factory.hpp:91
std::unique_ptr< csvm > make_csvm_default_impl([[maybe_unused]] Args &&...args)
Construct a C-SVM using the parameters args.
Definition: csvm_factory.hpp:68
implementation_type
Enum class for all possible SYCL implementation types.
Definition: implementation_type.hpp:24
The main namespace containing all public API functions.
Definition: backend_types.hpp:24
std::unique_ptr< csvm > make_csvm(const backend_type backend, Args &&...args)
Create a new C-SVM using the backend type and additional parameter args.
Definition: csvm_factory.hpp:158
backend_type
Enum class for all possible backend types.
Definition: backend_types.hpp:30
backend_type determine_default_backend(const std::vector< backend_type > &available_backends=list_available_backends(), const std::vector< target_platform > &available_target_platforms=list_available_target_platforms())
Returns the default backend (if plssvm::backend_type::automatic is used) given the backend and target...
Defines some generic type traits used in the PLSSVM library.