1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 // This software is distributed WITHOUT ANY WARRANTY; without even
6 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 // PURPOSE. See the above copyright notice for more information.
8 //
9 // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 // Copyright 2014 UT-Battelle, LLC.
11 // Copyright 2014 Los Alamos National Security.
12 //
13 // Under the terms of Contract DE-NA0003525 with NTESS,
14 // the U.S. Government retains certain rights in this software.
15 //
16 // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 // Laboratory (LANL), the U.S. Government retains certain rights in
18 // this software.
19 //============================================================================
20 #ifndef vtk_m_cont_internal_DeviceAdapterTag_h
21 #define vtk_m_cont_internal_DeviceAdapterTag_h
22
23 #include <vtkm/StaticAssert.h>
24 #include <vtkm/Types.h>
25 #include <vtkm/internal/Configure.h>
26 #include <vtkm/internal/ExportMacros.h>
27
28 #include <vtkm/cont/vtkm_cont_export.h>
29
30 #include <string>
31
32 #define VTKM_DEVICE_ADAPTER_ERROR -2
33 #define VTKM_DEVICE_ADAPTER_UNDEFINED -1
34 #define VTKM_DEVICE_ADAPTER_SERIAL 1
35 #define VTKM_DEVICE_ADAPTER_CUDA 2
36 #define VTKM_DEVICE_ADAPTER_TBB 3
37 #define VTKM_DEVICE_ADAPTER_OPENMP 4
38 //VTKM_DEVICE_ADAPTER_TestAlgorithmGeneral 7
39 #define VTKM_MAX_DEVICE_ADAPTER_ID 8
40 #define VTKM_DEVICE_ADAPTER_ANY 127
41
42 namespace vtkm
43 {
44 namespace cont
45 {
46
47 using DeviceAdapterNameType = std::string;
48
49 struct DeviceAdapterId
50 {
51 constexpr bool operator==(DeviceAdapterId other) const { return this->Value == other.Value; }
52 constexpr bool operator!=(DeviceAdapterId other) const { return this->Value != other.Value; }
53 constexpr bool operator<(DeviceAdapterId other) const { return this->Value < other.Value; }
54
IsValueValidDeviceAdapterId55 constexpr bool IsValueValid() const
56 {
57 return this->Value > 0 && this->Value < VTKM_MAX_DEVICE_ADAPTER_ID;
58 }
59
GetValueDeviceAdapterId60 constexpr vtkm::Int8 GetValue() const { return this->Value; }
61
62 VTKM_CONT_EXPORT
63 DeviceAdapterNameType GetName() const;
64
65 protected:
66 friend DeviceAdapterId make_DeviceAdapterId(vtkm::Int8 id);
67
DeviceAdapterIdDeviceAdapterId68 constexpr explicit DeviceAdapterId(vtkm::Int8 id)
69 : Value(id)
70 {
71 }
72
73 private:
74 vtkm::Int8 Value;
75 };
76
make_DeviceAdapterId(vtkm::Int8 id)77 inline DeviceAdapterId make_DeviceAdapterId(vtkm::Int8 id)
78 {
79 return DeviceAdapterId(id);
80 }
81
82 template <typename DeviceAdapter>
83 struct DeviceAdapterTraits;
84 }
85 }
86
87 /// Creates a tag named vtkm::cont::DeviceAdapterTagName and associated MPL
88 /// structures to use this tag. Always use this macro (in the base namespace)
89 /// when creating a device adapter.
90 #define VTKM_VALID_DEVICE_ADAPTER(Name, Id) \
91 namespace vtkm \
92 { \
93 namespace cont \
94 { \
95 struct VTKM_ALWAYS_EXPORT DeviceAdapterTag##Name : DeviceAdapterId \
96 { \
97 constexpr DeviceAdapterTag##Name() \
98 : DeviceAdapterId(Id) \
99 { \
100 } \
101 static constexpr bool IsEnabled = true; \
102 }; \
103 template <> \
104 struct DeviceAdapterTraits<vtkm::cont::DeviceAdapterTag##Name> \
105 { \
106 static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
107 }; \
108 } \
109 }
110
111 /// Marks the tag named vtkm::cont::DeviceAdapterTagName and associated
112 /// structures as invalid to use. Always use this macro (in the base namespace)
113 /// when creating a device adapter.
114 #define VTKM_INVALID_DEVICE_ADAPTER(Name, Id) \
115 namespace vtkm \
116 { \
117 namespace cont \
118 { \
119 struct VTKM_ALWAYS_EXPORT DeviceAdapterTag##Name : DeviceAdapterId \
120 { \
121 constexpr DeviceAdapterTag##Name() \
122 : DeviceAdapterId(Id) \
123 { \
124 } \
125 static constexpr bool IsEnabled = false; \
126 }; \
127 template <> \
128 struct DeviceAdapterTraits<vtkm::cont::DeviceAdapterTag##Name> \
129 { \
130 static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
131 }; \
132 } \
133 }
134
135 // Represents when using TryExecute that the functor
136 // can be executed on any device instead of a specific
137 // one
138 VTKM_VALID_DEVICE_ADAPTER(Any, VTKM_DEVICE_ADAPTER_ANY)
139
140 VTKM_INVALID_DEVICE_ADAPTER(Undefined, VTKM_DEVICE_ADAPTER_UNDEFINED)
141
142 /// Checks that the argument is a proper device adapter tag. This is a handy
143 /// concept check for functions and classes to make sure that a template
144 /// argument is actually a device adapter tag. (You can get weird errors
145 /// elsewhere in the code when a mistake is made.)
146 ///
147 #define VTKM_IS_DEVICE_ADAPTER_TAG(tag) \
148 static_assert(std::is_base_of<vtkm::cont::DeviceAdapterId, tag>::value && \
149 !std::is_same<vtkm::cont::DeviceAdapterId, tag>::value, \
150 "Provided type is not a valid VTK-m device adapter tag.")
151
152 #endif //vtk_m_cont_internal_DeviceAdapterTag_h
153