Commit fdb7abe7 authored by Kenneth Moreland's avatar Kenneth Moreland Committed by Kitware Robot
Browse files

Merge topic 'all-execobj-trivially-copyable'

294a30fd Check that all execution objects are trivially copyable
bd5b84fa Have VTKM_IS_TRIVIAL* macros show types better
3813fb51

 Make ArrayPortalRecombineVec trivially copyable
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Li-Ta Lo's avatarLi-Ta Lo <ollie@lanl.gov>
Merge-request: !2416
parents 33f6f0be 294a30fd
......@@ -294,24 +294,29 @@ namespace internal
template <typename SourcePortalType>
class ArrayPortalRecombineVec
{
vtkm::VecCConst<SourcePortalType> Portals;
// Note that this ArrayPortal has a pointer to a C array of other portals. We need to
// make sure that the pointer is valid on the device we are using it on. See the
// CreateReadPortal and CreateWritePortal in the Storage below to see how that is
// managed.
const SourcePortalType* Portals;
vtkm::IdComponent NumberOfComponents;
public:
using ValueType = vtkm::internal::RecombineVec<SourcePortalType>;
ArrayPortalRecombineVec() = default;
ArrayPortalRecombineVec(const vtkm::VecCConst<SourcePortalType>& portals)
: Portals(portals)
{
}
ArrayPortalRecombineVec(const SourcePortalType* portals, vtkm::IdComponent numComponents)
: Portals(portals, numComponents)
: Portals(portals)
, NumberOfComponents(numComponents)
{
}
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->Portals[0].GetNumberOfValues(); }
VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const { return ValueType(this->Portals, index); }
VTKM_EXEC_CONT ValueType Get(vtkm::Id index) const
{
return ValueType({ this->Portals, this->NumberOfComponents }, index);
}
VTKM_EXEC_CONT void Set(vtkm::Id index, const ValueType& value) const
{
......@@ -324,8 +329,8 @@ public:
VTKM_EXEC_CONT void Set(vtkm::Id index, const T& value) const
{
using Traits = vtkm::VecTraits<T>;
VTKM_ASSERT(Traits::GetNumberOfComponents(value) == this->Portals.GetNumberOfComponents());
for (vtkm::IdComponent cIndex = 0; cIndex < this->Portals.GetNumberOfComponents(); ++cIndex)
VTKM_ASSERT(Traits::GetNumberOfComponents(value) == this->NumberOfComponents);
for (vtkm::IdComponent cIndex = 0; cIndex < this->NumberOfComponents; ++cIndex)
{
this->Portals[cIndex].Set(index, Traits::GetComponent(value, cIndex));
}
......@@ -441,7 +446,6 @@ public:
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
ReadPortalType portal;
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
// The array portal needs a runtime-allocated array of portals for each component.
......@@ -479,7 +483,6 @@ public:
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
WritePortalType portal;
vtkm::IdComponent numComponents = NumberOfComponents(buffers);
// The array portal needs a runtime-allocated array of portals for each component.
......
......@@ -32,6 +32,8 @@
#include <vtkm/worklet/internal/WorkletBase.h>
#include <vtkmstd/is_trivial.h>
#include <sstream>
namespace vtkm
......@@ -316,6 +318,14 @@ struct DispatcherBaseTransportFunctor
using T = vtkm::internal::remove_pointer_and_decay<ControlParameter>;
using TransportType = typename vtkm::cont::arg::Transport<TransportTag, T, Device>;
using type = typename std::decay<typename TransportType::ExecObjectType>::type;
// If you get a compile error here, it means that an execution object type is not
// trivially copyable. This is strictly disallowed. All execution objects must be
// trivially copyable so that the can be memcpy-ed between host and devices.
// Note that it is still legal for execution objects to have pointers or other
// references to resources on a particular device. It is up to the generating code
// to ensure that all referenced resources are valid on the target device.
VTKM_IS_TRIVIALLY_COPYABLE(type);
};
template <typename ControlParameter, vtkm::IdComponent Index>
......
......@@ -55,10 +55,10 @@ struct is_trivial : std::false_type
// `VTKM_IS_TRIVIALLY_COPYABLE`, which will always pass on compilers that don't
// support is_trivially_copyable, but will do the correct check on compilers that
// do support it.
#define VTKM_IS_TRIVIALLY_COPYABLE(type) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIALLY_COPYABLE(...) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIALLY_CONSTRUCTIBLE(...) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIALLY_DESTRUCTIBLE(...) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIAL(type) VTKM_STATIC_ASSERT(true)
#define VTKM_IS_TRIVIAL(...) VTKM_STATIC_ASSERT(true)
} // namespace vtkmstd
......@@ -71,18 +71,54 @@ using std::is_trivially_constructible;
using std::is_trivially_copyable;
using std::is_trivially_destructible;
#define VTKM_IS_TRIVIALLY_COPYABLE(type) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_copyable<type>::value, \
"Type must be trivially copyable to be used here.")
#define VTKM_IS_TRIVIALLY_CONSTRUCTIBLE(...) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_constructible<__VA_ARGS__>::value, \
"Type must be trivially constructible to be used here.")
#define VTKM_IS_TRIVIALLY_DESTRUCTIBLE(...) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_destructible<__VA_ARGS__>::value, \
"Type must be trivially constructible to be used here.")
#define VTKM_IS_TRIVIAL(type) \
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivial<type>::value, \
"Type must be trivial to be used here.")
namespace detail
{
// Note: the reason why we redirect the trivial checks to these classes is so when the checks
// fail it is easier to read from the error messages exactly which type was being checked. If
// you just do a static assert in a macro, the error message is likely to give you either
// macro argument names or unresolved types in the error message, which is unhelpful.
template <typename T>
struct CheckTriviallyCopyable
{
VTKM_STATIC_ASSERT_MSG(vtkmstd::is_trivially_copyable<T>::value,
"Type must be trivially copyable to be used here.");
static constexpr bool value = true;
};
template <typename T>
struct CheckTriviallyConstructible
{
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_constructible<T>::value,
"Type must be trivially constructible to be used here.");
static constexpr bool value = true;
};
template <typename T>
struct CheckTriviallyDestructible
{
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivially_destructible<T>::value,
"Type must be trivially destructible to be used here.");
static constexpr bool value = true;
};
template <typename T>
struct CheckTrivial
{
VTKM_STATIC_ASSERT_MSG(::vtkmstd::is_trivial<T>::value, "Type must be trivial to be used here.");
static constexpr bool value = true;
};
} // namespace detail
#define VTKM_IS_TRIVIALLY_COPYABLE(...) \
VTKM_STATIC_ASSERT(::vtkmstd::detail::CheckTriviallyCopyable<__VA_ARGS__>::value)
#define VTKM_IS_TRIVIALLY_CONSTRUCTIBLE(...) \
VTKM_STATIC_ASSERT(::vtkmstd::detail::CheckTriviallyConstructible<__VA_ARGS__>::value)
#define VTKM_IS_TRIVIALLY_DESTRUCTIBLE(...) \
VTKM_STATIC_ASSERT(::vtkmstd::detail::CheckTriviallyDestructible<__VA_ARGS__>::value)
#define VTKM_IS_TRIVIAL(...) VTKM_STATIC_ASSERT(::vtkmstd::detail::CheckTrivial<__VA_ARGS__>::value)
} // namespace vtkmstd
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment