VTK-m  2.2
RuntimeDeviceConfigurationKokkos.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
11 #define vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
12 
14 #include <vtkm/cont/Logging.h>
17 
19 #include <Kokkos_Core.hpp>
21 
22 #include <cstring>
23 #include <vector>
24 
25 namespace vtkm
26 {
27 namespace cont
28 {
29 namespace internal
30 {
31 
32 namespace
33 {
35 RuntimeDeviceConfigReturnCode GetArgFromList(const std::vector<std::string>& argList,
36  const std::string& argName,
37  vtkm::Id& value)
38 {
39  size_t pos;
40  try
41  {
42  for (auto argItr = argList.rbegin(); argItr != argList.rend(); argItr++)
43  {
44  if (argItr->rfind(argName, 0) == 0)
45  {
46  if (argItr->size() == argName.size())
47  {
48  value = std::stoi(*(--argItr), &pos, 10);
49  return RuntimeDeviceConfigReturnCode::SUCCESS;
50  }
51  else
52  {
53  value = std::stoi(argItr->substr(argName.size() + 1), &pos, 10);
54  return RuntimeDeviceConfigReturnCode::SUCCESS;
55  }
56  }
57  }
58  }
59  catch (const std::invalid_argument&)
60  {
62  "Unable to get arg " + argName +
63  "from kokkos argList, invalid argument thrown... This shouldn't have happened");
64  return RuntimeDeviceConfigReturnCode::INVALID_VALUE;
65  }
66  catch (const std::out_of_range&)
67  {
69  "Unable to get arg " + argName +
70  "from kokkos argList, out of range thrown... This shouldn't have happened");
71  return RuntimeDeviceConfigReturnCode::INVALID_VALUE;
72  }
73  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
74 }
75 
76 } // namespace anonymous
77 
78 template <>
79 class RuntimeDeviceConfiguration<vtkm::cont::DeviceAdapterTagKokkos>
80  : public vtkm::cont::internal::RuntimeDeviceConfigurationBase
81 {
82 public:
83  VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final
84  {
86  }
87 
88  VTKM_CONT virtual RuntimeDeviceConfigReturnCode SetThreads(const vtkm::Id& value) override final
89  {
90  if (Kokkos::is_initialized())
91  {
92  VTKM_LOG_S(
94  "SetThreads was called but Kokkos was already initailized! Updates will not be applied.");
95  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
96  }
97  this->KokkosArguments.insert(this->KokkosArguments.begin(),
98  "--kokkos-num-threads=" + std::to_string(value));
99  return RuntimeDeviceConfigReturnCode::SUCCESS;
100  }
101 
102  VTKM_CONT virtual RuntimeDeviceConfigReturnCode SetDeviceInstance(
103  const vtkm::Id& value) override final
104  {
105  if (Kokkos::is_initialized())
106  {
108  "SetDeviceInstance was called but Kokkos was already initailized! Updates will "
109  "not be applied.");
110  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
111  }
112  this->KokkosArguments.insert(this->KokkosArguments.begin(),
113  "--kokkos-device-id=" + std::to_string(value));
114  return RuntimeDeviceConfigReturnCode::SUCCESS;
115  }
116 
117  VTKM_CONT virtual RuntimeDeviceConfigReturnCode GetThreads(vtkm::Id& value) const override final
118  {
119  return GetArgFromList(this->KokkosArguments, "--kokkos-num-threads", value);
120  }
121 
122  VTKM_CONT virtual RuntimeDeviceConfigReturnCode GetDeviceInstance(
123  vtkm::Id& value) const override final
124  {
125  return GetArgFromList(this->KokkosArguments, "--kokkos-device-id", value);
126  }
127 
128 protected:
132  VTKM_CONT virtual void ParseExtraArguments(int& argc, char* argv[]) override final
133  {
134  if (argc > 0 && argv)
135  {
136  this->KokkosArguments.insert(this->KokkosArguments.end(), argv, argv + argc);
137  }
138  }
139 
150  VTKM_CONT virtual void InitializeSubsystem() override final
151  {
152  if (!Kokkos::is_initialized())
153  {
154  std::vector<char*> argv;
155  for (auto& arg : this->KokkosArguments)
156  {
157  argv.push_back(&arg[0]);
158  }
159  int size = argv.size();
160  Kokkos::initialize(size, argv.data());
161  std::atexit(Kokkos::finalize);
162  }
163  else
164  {
165  VTKM_LOG_S(
167  "Attempted to Re-initialize Kokkos! The Kokkos subsystem can only be initialized once");
168  }
169  }
170 
171 private:
172  std::vector<std::string> KokkosArguments;
173 };
174 
175 } // namespace vtkm::cont::internal
176 } // namespace vtkm::cont
177 } // namespace vtkm
178 
179 #endif //vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
VTKM_THIRDPARTY_POST_INCLUDE
#define VTKM_THIRDPARTY_POST_INCLUDE
Definition: Configure.h:192
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
DeviceAdapterTagKokkos.h
RuntimeDeviceConfiguration.h
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::cont::LogLevel::Error
@ Error
Important but non-fatal errors, such as device fail-over.
VTKM_LOG_S
#define VTKM_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:208
vtkm::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:58
VTKM_THIRDPARTY_PRE_INCLUDE
#define VTKM_THIRDPARTY_PRE_INCLUDE
Definition: Configure.h:191
ErrorInternal.h
Logging.h
Logging utilities.
vtkm::cont::DeviceAdapterTagKokkos
Tag for a device adapter that uses the Kokkos library to run algorithms in parallel.
Definition: DeviceAdapterTagKokkos.h:31