Viskores  1.0
RuntimeDeviceConfigurationKokkos.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
19 #define viskores_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
20 
22 #include <viskores/cont/Logging.h>
25 
27 #include <Kokkos_Core.hpp>
29 
30 #include <cstring>
31 #include <vector>
32 
33 namespace viskores
34 {
35 namespace cont
36 {
37 namespace internal
38 {
39 
40 namespace
41 {
43 RuntimeDeviceConfigReturnCode GetArgFromList(const std::vector<std::string>& argList,
44  const std::string& argName,
45  viskores::Id& value)
46 {
47  size_t pos;
48  try
49  {
50  for (auto argItr = argList.rbegin(); argItr != argList.rend(); argItr++)
51  {
52  if (argItr->rfind(argName, 0) == 0)
53  {
54  if (argItr->size() == argName.size())
55  {
56  value = std::stoi(*(--argItr), &pos, 10);
57  return RuntimeDeviceConfigReturnCode::SUCCESS;
58  }
59  else
60  {
61  value = std::stoi(argItr->substr(argName.size() + 1), &pos, 10);
62  return RuntimeDeviceConfigReturnCode::SUCCESS;
63  }
64  }
65  }
66  }
67  catch (const std::invalid_argument&)
68  {
71  "Unable to get arg " + argName +
72  "from kokkos argList, invalid argument thrown... This shouldn't have happened");
73  return RuntimeDeviceConfigReturnCode::INVALID_VALUE;
74  }
75  catch (const std::out_of_range&)
76  {
78  "Unable to get arg " + argName +
79  "from kokkos argList, out of range thrown... This shouldn't have happened");
80  return RuntimeDeviceConfigReturnCode::INVALID_VALUE;
81  }
82  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
83 }
84 
85 } // namespace anonymous
86 
87 template <>
88 class RuntimeDeviceConfiguration<viskores::cont::DeviceAdapterTagKokkos>
89  : public viskores::cont::internal::RuntimeDeviceConfigurationBase
90 {
91 public:
92  VISKORES_CONT viskores::cont::DeviceAdapterId GetDevice() const override final
93  {
95  }
96 
97  VISKORES_CONT virtual RuntimeDeviceConfigReturnCode SetThreads(
98  const viskores::Id& value) override final
99  {
100  if (Kokkos::is_initialized())
101  {
104  "SetThreads was called but Kokkos was already initailized! Updates will not be applied.");
105  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
106  }
107  this->KokkosArguments.insert(this->KokkosArguments.begin(),
108  "--kokkos-num-threads=" + std::to_string(value));
109  return RuntimeDeviceConfigReturnCode::SUCCESS;
110  }
111 
112  VISKORES_CONT virtual RuntimeDeviceConfigReturnCode SetDeviceInstance(
113  const viskores::Id& value) override final
114  {
115  if (Kokkos::is_initialized())
116  {
119  "SetDeviceInstance was called but Kokkos was already initailized! Updates will "
120  "not be applied.");
121  return RuntimeDeviceConfigReturnCode::NOT_APPLIED;
122  }
123  this->KokkosArguments.insert(this->KokkosArguments.begin(),
124  "--kokkos-device-id=" + std::to_string(value));
125  return RuntimeDeviceConfigReturnCode::SUCCESS;
126  }
127 
128  VISKORES_CONT virtual RuntimeDeviceConfigReturnCode GetThreads(
129  viskores::Id& value) const override final
130  {
131  return GetArgFromList(this->KokkosArguments, "--kokkos-num-threads", value);
132  }
133 
134  VISKORES_CONT virtual RuntimeDeviceConfigReturnCode GetDeviceInstance(
135  viskores::Id& value) const override final
136  {
137  return GetArgFromList(this->KokkosArguments, "--kokkos-device-id", value);
138  }
139 
140 protected:
144  VISKORES_CONT virtual void ParseExtraArguments(int& argc, char* argv[]) override final
145  {
146  if (argc > 0 && argv)
147  {
148  this->KokkosArguments.insert(this->KokkosArguments.end(), argv, argv + argc);
149  }
150  }
151 
162  VISKORES_CONT virtual void InitializeSubsystem() override final
163  {
164  if (!Kokkos::is_initialized())
165  {
166  std::vector<char*> argv;
167  for (auto& arg : this->KokkosArguments)
168  {
169  argv.push_back(&arg[0]);
170  }
171  int size = argv.size();
172  Kokkos::initialize(size, argv.data());
173  std::atexit(Kokkos::finalize);
174  }
175  else
176  {
179  "Attempted to Re-initialize Kokkos! The Kokkos subsystem can only be initialized once");
180  }
181  }
182 
183 private:
184  std::vector<std::string> KokkosArguments;
185 };
186 
187 } // namespace viskores::cont::internal
188 } // namespace viskores::cont
189 } // namespace viskores
190 
191 #endif //viskores_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h
viskores::cont::LogLevel::Error
@ Error
Important but non-fatal errors, such as device fail-over.
viskores::cont::LogLevel::Warn
@ Warn
Less important user errors, such as out-of-bounds parameters.
VISKORES_THIRDPARTY_POST_INCLUDE
#define VISKORES_THIRDPARTY_POST_INCLUDE
Definition: Configure.h:200
DeviceAdapterTagKokkos.h
viskores::cont::DeviceAdapterTagKokkos
Tag for a device adapter that uses the Kokkos library to run algorithms in parallel.
Definition: DeviceAdapterTagKokkos.h:39
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
RuntimeDeviceConfiguration.h
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
VISKORES_LOG_S
#define VISKORES_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:216
ErrorInternal.h
Logging.h
Logging utilities.
VISKORES_THIRDPARTY_PRE_INCLUDE
#define VISKORES_THIRDPARTY_PRE_INCLUDE
Definition: Configure.h:199