vtk-m/vtkm/cont/DeviceAdapterTag.h
Kenneth Moreland 5b8c282e9f Continue transfer of Users' Guide text
These changes complete the using part of the guide.
2023-11-21 10:33:45 -07:00

200 lines
9.1 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_DeviceAdapterTag_h
#define vtk_m_cont_DeviceAdapterTag_h
#include <vtkm/StaticAssert.h>
#include <vtkm/Types.h>
#include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <string>
#ifdef VTKM_DEVICE_ADAPTER
// Rather than use defines to specify the default device adapter
// VTK-m now builds for all device adapters and uses runtime controls
// to determine where execution occurs
#error The VTKM_DEVICE_ADAPTER define is no longer obeyed and needs to be removed
#endif
#ifdef VTKM_DEFAULT_DEVICE_ADAPTER_TAG
// Rather than use device adapter tag that had no shared parent
// VTK-m now uses a runtime device adapter implementation that
// allows for runtime execution selection of what device to execute on
#error The VTKM_DEFAULT_DEVICE_ADAPTER_TAG define is no longer required and needs to be removed
#endif
#define VTKM_DEVICE_ADAPTER_UNDEFINED -1
#define VTKM_DEVICE_ADAPTER_SERIAL 1
#define VTKM_DEVICE_ADAPTER_CUDA 2
#define VTKM_DEVICE_ADAPTER_TBB 3
#define VTKM_DEVICE_ADAPTER_OPENMP 4
#define VTKM_DEVICE_ADAPTER_KOKKOS 5
//VTKM_DEVICE_ADAPTER_TestAlgorithmGeneral 7
#define VTKM_MAX_DEVICE_ADAPTER_ID 8
#define VTKM_DEVICE_ADAPTER_ANY 127
namespace vtkm
{
namespace cont
{
using DeviceAdapterNameType = std::string;
/// @brief An object used to specify a device.
///
/// `vtkm::cont::DeviceAdapterId` can be used to specify a device to use when
/// executing some code. Each `DeviceAdapterTag` object inherits from
/// `vtkm::cont::DeviceAdapterId`. Functions can accept a `vtkm::cont::DeviceAdapterId`
/// object rather than a templated tag to select a device adapter at runtime.
struct DeviceAdapterId
{
constexpr bool operator==(DeviceAdapterId other) const { return this->Value == other.Value; }
constexpr bool operator!=(DeviceAdapterId other) const { return this->Value != other.Value; }
constexpr bool operator<(DeviceAdapterId other) const { return this->Value < other.Value; }
/// @brief Return whether this object represents a valid type of device.
///
/// This method will return true if the id represents a specific, valid device.
/// It will return true even if the device is disabled in by the runtime tracker
/// or if the device is not supported by the VTK-m build configuration.
///
/// It should be noted that this method return false for tags that are not specific
/// devices. This includes `vtkm::cont::DeviceAdapterTagAny` and
/// `vtkm::cont::DeviceAdapterTagUndefined`.
constexpr bool IsValueValid() const
{
return this->Value > 0 && this->Value < VTKM_MAX_DEVICE_ADAPTER_ID;
}
/// @brief Returns the numeric value of the index.
constexpr vtkm::Int8 GetValue() const { return this->Value; }
/// @brief Return a name representing the device.
///
/// The string returned from this method is stored in a type named
/// `vtkm::cont::DeviceAdapterNameType`, which is currently aliased to
/// `std::string`. The device adapter name is useful for printing information
/// about a device being used.
VTKM_CONT_EXPORT
DeviceAdapterNameType GetName() const;
protected:
friend DeviceAdapterId make_DeviceAdapterId(vtkm::Int8 id);
constexpr explicit DeviceAdapterId(vtkm::Int8 id)
: Value(id)
{
}
private:
vtkm::Int8 Value;
};
/// Construct a device adapter id from a runtime string
/// The string is case-insensitive. So CUDA will be selected with 'cuda', 'Cuda', or 'CUDA'.
VTKM_CONT_EXPORT
DeviceAdapterId make_DeviceAdapterId(const DeviceAdapterNameType& name);
/// Construct a device adapter id a vtkm::Int8.
/// The mapping of integer value to devices are:
///
/// DeviceAdapterTagSerial == 1
/// DeviceAdapterTagCuda == 2
/// DeviceAdapterTagTBB == 3
/// DeviceAdapterTagOpenMP == 4
/// DeviceAdapterTagKokkos == 5
///
inline DeviceAdapterId make_DeviceAdapterId(vtkm::Int8 id)
{
return DeviceAdapterId(id);
}
template <typename DeviceAdapter>
struct DeviceAdapterTraits;
}
}
/// Creates a tag named vtkm::cont::DeviceAdapterTagName and associated MPL
/// structures to use this tag. Always use this macro (in the base namespace)
/// when creating a device adapter.
#define VTKM_VALID_DEVICE_ADAPTER(Name, Id) \
namespace vtkm \
{ \
namespace cont \
{ \
struct VTKM_ALWAYS_EXPORT DeviceAdapterTag##Name : DeviceAdapterId \
{ \
constexpr DeviceAdapterTag##Name() \
: DeviceAdapterId(Id) \
{ \
} \
static constexpr bool IsEnabled = true; \
}; \
template <> \
struct DeviceAdapterTraits<vtkm::cont::DeviceAdapterTag##Name> \
{ \
static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
}; \
} \
}
/// Marks the tag named vtkm::cont::DeviceAdapterTagName and associated
/// structures as invalid to use. Always use this macro (in the base namespace)
/// when creating a device adapter.
#define VTKM_INVALID_DEVICE_ADAPTER(Name, Id) \
namespace vtkm \
{ \
namespace cont \
{ \
struct VTKM_ALWAYS_EXPORT DeviceAdapterTag##Name : DeviceAdapterId \
{ \
constexpr DeviceAdapterTag##Name() \
: DeviceAdapterId(Id) \
{ \
} \
static constexpr bool IsEnabled = false; \
}; \
template <> \
struct DeviceAdapterTraits<vtkm::cont::DeviceAdapterTag##Name> \
{ \
static DeviceAdapterNameType GetName() { return DeviceAdapterNameType(#Name); } \
}; \
} \
}
/// @struct vtkm::cont::DeviceAdapterTagAny
/// @brief Tag for a device adapter used to specify that any device may be used
/// for an operation.
///
/// In practice this is limited to devices that are currently available.
VTKM_VALID_DEVICE_ADAPTER(Any, VTKM_DEVICE_ADAPTER_ANY)
/// @struct vtkm::cont::DeviceAdapterTagUndefined
/// @brief Tag for a device adapter used to avoid specifying a device.
///
/// Useful as a placeholder when a device can be specified but none is given.
VTKM_INVALID_DEVICE_ADAPTER(Undefined, VTKM_DEVICE_ADAPTER_UNDEFINED)
/// Checks that the argument is a proper device adapter tag. This is a handy
/// concept check for functions and classes to make sure that a template
/// argument is actually a device adapter tag. (You can get weird errors
/// elsewhere in the code when a mistake is made.)
///
#define VTKM_IS_DEVICE_ADAPTER_TAG(tag) \
static_assert(std::is_base_of<vtkm::cont::DeviceAdapterId, tag>::value && \
!std::is_same<vtkm::cont::DeviceAdapterId, tag>::value, \
"Provided type is not a valid VTK-m device adapter tag.")
#endif //vtk_m_cont_DeviceAdapterTag_h