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