//============================================================================ // 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_ArrayHandleBasic_h #define vtk_m_cont_ArrayHandleBasic_h #include #include #include #include #include #include #include namespace vtkm { namespace cont { namespace internal { template class VTKM_ALWAYS_EXPORT Storage { public: using ReadPortalType = vtkm::internal::ArrayPortalBasicRead; using WritePortalType = vtkm::internal::ArrayPortalBasicWrite; VTKM_CONT constexpr static vtkm::IdComponent GetNumberOfBuffers() { return 1; } VTKM_CONT static void ResizeBuffers(vtkm::Id numValues, vtkm::cont::internal::Buffer* buffers, vtkm::CopyFlag preserve, vtkm::cont::Token& token) { buffers[0].SetNumberOfBytes( vtkm::internal::NumberOfValuesToNumberOfBytes(numValues), preserve, token); } VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers) { return static_cast(buffers->GetNumberOfBytes() / static_cast(sizeof(T))); } VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return ReadPortalType(reinterpret_cast(buffers[0].ReadPointerDevice(device, token)), GetNumberOfValues(buffers)); } VTKM_CONT static WritePortalType CreateWritePortal(vtkm::cont::internal::Buffer* buffers, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) { return WritePortalType(reinterpret_cast(buffers[0].WritePointerDevice(device, token)), GetNumberOfValues(buffers)); } }; } // namespace internal template class VTKM_ALWAYS_EXPORT ArrayHandleBasic : public ArrayHandle { public: VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleBasic, (ArrayHandleBasic), (ArrayHandle)); ArrayHandleBasic( T* array, vtkm::Id numberOfValues, vtkm::cont::internal::BufferInfo::Deleter deleter, vtkm::cont::internal::BufferInfo::Reallocater reallocater = internal::InvalidRealloc) : Superclass(std::vector{ vtkm::cont::internal::MakeBuffer( vtkm::cont::DeviceAdapterTagUndefined{}, array, array, vtkm::internal::NumberOfValuesToNumberOfBytes(numberOfValues), deleter, reallocater) }) { } ArrayHandleBasic( T* array, vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId device, vtkm::cont::internal::BufferInfo::Deleter deleter, vtkm::cont::internal::BufferInfo::Reallocater reallocater = internal::InvalidRealloc) : Superclass(std::vector{ vtkm::cont::internal::MakeBuffer( device, array, array, vtkm::internal::NumberOfValuesToNumberOfBytes(numberOfValues), deleter, reallocater) }) { } ArrayHandleBasic( T* array, void* container, vtkm::Id numberOfValues, vtkm::cont::internal::BufferInfo::Deleter deleter, vtkm::cont::internal::BufferInfo::Reallocater reallocater = internal::InvalidRealloc) : Superclass(std::vector{ vtkm::cont::internal::MakeBuffer( vtkm::cont::DeviceAdapterTagUndefined{}, array, container, vtkm::internal::NumberOfValuesToNumberOfBytes(numberOfValues), deleter, reallocater) }) { } ArrayHandleBasic( T* array, void* container, vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId device, vtkm::cont::internal::BufferInfo::Deleter deleter, vtkm::cont::internal::BufferInfo::Reallocater reallocater = internal::InvalidRealloc) : Superclass(std::vector{ vtkm::cont::internal::MakeBuffer( device, array, container, vtkm::internal::NumberOfValuesToNumberOfBytes(numberOfValues), deleter, reallocater) }) { } /// @{ /// \brief Gets raw access to the `ArrayHandle`'s data. /// /// Note that the returned array may become invalidated by other operations on the ArryHandle /// unless you provide a token. /// const T* GetReadPointer(vtkm::cont::Token& token) const { return reinterpret_cast(this->GetBuffers()[0].ReadPointerHost(token)); } const T* GetReadPointer() const { vtkm::cont::Token token; return this->GetReadPointer(token); } T* GetWritePointer(vtkm::cont::Token& token) const { return reinterpret_cast(this->GetBuffers()[0].WritePointerHost(token)); } T* GetWritePointer() const { vtkm::cont::Token token; return this->GetWritePointer(token); } const T* GetReadPointer(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { return reinterpret_cast(this->GetBuffers()[0].ReadPointerDevice(device, token)); } const T* GetReadPointer(vtkm::cont::DeviceAdapterId device) const { vtkm::cont::Token token; return this->GetReadPointer(device, token); } T* GetWritePointer(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const { return reinterpret_cast(this->GetBuffers()[0].WritePointerDevice(device, token)); } T* GetWritePointer(vtkm::cont::DeviceAdapterId device) const { vtkm::cont::Token token; return this->GetWritePointer(device, token); } /// @} }; /// A convenience function for creating an ArrayHandle from a standard C array. /// template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(const T* array, vtkm::Id numberOfValues, vtkm::CopyFlag copy) { if (copy == vtkm::CopyFlag::On) { vtkm::cont::ArrayHandleBasic handle; handle.Allocate(numberOfValues); std::copy( array, array + numberOfValues, vtkm::cont::ArrayPortalToIteratorBegin(handle.WritePortal())); return handle; } else { return vtkm::cont::ArrayHandleBasic(const_cast(array), numberOfValues, [](void*) {}); } } template VTKM_DEPRECATED(1.6, "Specify a vtkm::CopyFlag or use a move version of make_ArrayHandle.") VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(const T* array, vtkm::Id numberOfValues) { return make_ArrayHandle(array, numberOfValues, vtkm::CopyFlag::Off); } /// A convenience function to move a user-allocated array into an `ArrayHandle`. /// The provided array pointer will be reset to `nullptr`. /// If the array was not allocated with the `new[]` operator, then deleter and reallocater /// functions must be provided. /// template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandleMove( T*& array, vtkm::Id numberOfValues, vtkm::cont::internal::BufferInfo::Deleter deleter = internal::SimpleArrayDeleter, vtkm::cont::internal::BufferInfo::Reallocater reallocater = internal::SimpleArrayReallocater) { vtkm::cont::ArrayHandleBasic arrayHandle(array, numberOfValues, deleter, reallocater); array = nullptr; return arrayHandle; } /// A convenience function for creating an ArrayHandle from an std::vector. /// template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(const std::vector& array, vtkm::CopyFlag copy) { if (!array.empty()) { return make_ArrayHandle(array.data(), static_cast(array.size()), copy); } else { // Vector empty. Just return an empty array handle. return vtkm::cont::ArrayHandle(); } } template VTKM_DEPRECATED(1.6, "Specify a vtkm::CopyFlag or use a move version of make_ArrayHandle.") VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(const std::vector& array) { return make_ArrayHandle(array, vtkm::CopyFlag::Off); } /// Move an std::vector into an ArrayHandle. /// template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandleMove(std::vector&& array) { using vector_type = std::vector; vector_type* container = new vector_type(std::move(array)); return vtkm::cont::ArrayHandleBasic(container->data(), container, static_cast(container->size()), internal::StdVectorDeleter, internal::StdVectorReallocater); } template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(std::vector&& array, vtkm::CopyFlag vtkmNotUsed(copy)) { return make_ArrayHandleMove(array); } /// Create an ArrayHandle directly from an initializer list of values. /// template VTKM_CONT vtkm::cont::ArrayHandleBasic make_ArrayHandle(std::initializer_list&& values) { return make_ArrayHandle(values.begin(), static_cast(values.size()), vtkm::CopyFlag::On); } } } // namespace vtkm::cont //============================================================================= // Specializations of serialization related classes /// @cond SERIALIZATION namespace vtkm { namespace cont { template struct SerializableTypeString> { static VTKM_CONT const std::string& Get() { static std::string name = "AH<" + SerializableTypeString::Get() + ">"; return name; } }; template struct SerializableTypeString> : SerializableTypeString> { }; } } // vtkm::cont namespace mangled_diy_namespace { template struct Serialization> { static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::ArrayHandle& obj) { vtkmdiy::save(bb, obj.GetBuffers()[0]); } static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::ArrayHandle& obj) { vtkm::cont::internal::Buffer buffer; vtkmdiy::load(bb, buffer); obj = vtkm::cont::ArrayHandle(&buffer); } }; template struct Serialization> : Serialization> { }; } // diy /// @endcond SERIALIZATION #ifndef vtk_m_cont_ArrayHandleBasic_cxx namespace vtkm { namespace cont { namespace internal { /// \cond /// Make doxygen ignore this section #define VTKM_STORAGE_EXPORT(Type) \ extern template class VTKM_CONT_TEMPLATE_EXPORT Storage; \ extern template class VTKM_CONT_TEMPLATE_EXPORT Storage, StorageTagBasic>; \ extern template class VTKM_CONT_TEMPLATE_EXPORT Storage, StorageTagBasic>; \ extern template class VTKM_CONT_TEMPLATE_EXPORT Storage, StorageTagBasic>; VTKM_STORAGE_EXPORT(char) VTKM_STORAGE_EXPORT(vtkm::Int8) VTKM_STORAGE_EXPORT(vtkm::UInt8) VTKM_STORAGE_EXPORT(vtkm::Int16) VTKM_STORAGE_EXPORT(vtkm::UInt16) VTKM_STORAGE_EXPORT(vtkm::Int32) VTKM_STORAGE_EXPORT(vtkm::UInt32) VTKM_STORAGE_EXPORT(vtkm::Int64) VTKM_STORAGE_EXPORT(vtkm::UInt64) VTKM_STORAGE_EXPORT(vtkm::Float32) VTKM_STORAGE_EXPORT(vtkm::Float64) #undef VTKM_STORAGE_EXPORT /// \endcond } // namespace internal #define VTKM_ARRAYHANDLE_EXPORT(Type) \ extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle; \ extern template class VTKM_CONT_TEMPLATE_EXPORT \ ArrayHandle, StorageTagBasic>; \ extern template class VTKM_CONT_TEMPLATE_EXPORT \ ArrayHandle, StorageTagBasic>; \ extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle, StorageTagBasic>; VTKM_ARRAYHANDLE_EXPORT(char) VTKM_ARRAYHANDLE_EXPORT(vtkm::Int8) VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt8) VTKM_ARRAYHANDLE_EXPORT(vtkm::Int16) VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt16) VTKM_ARRAYHANDLE_EXPORT(vtkm::Int32) VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt32) VTKM_ARRAYHANDLE_EXPORT(vtkm::Int64) VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt64) VTKM_ARRAYHANDLE_EXPORT(vtkm::Float32) VTKM_ARRAYHANDLE_EXPORT(vtkm::Float64) #undef VTKM_ARRAYHANDLE_EXPORT } } // end vtkm::cont #endif // !vtk_m_cont_ArrayHandleBasic_cxx #endif //vtk_m_cont_ArrayHandleBasic_h