mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 21:33:55 +00:00
Simplify creating metadata in Buffer objects
Previously you had to create a special virtual object to place in the `Buffer`'s metadata. This added a lot of difficulty that is probably unnecessary. Instead, just have `Buffer` hold an arbitrary object and some simple functions to copy and delete it. There may be issues with type safety across translation units, but we'll deal with that when/if we run into it.
This commit is contained in:
parent
132a07225d
commit
2f04dc3aef
@ -99,12 +99,13 @@ public:
|
||||
vtkm::cont::GetSizeString(static_cast<vtkm::UInt64>(numBytes)).c_str());
|
||||
|
||||
buffers[0].SetNumberOfBytes(numBytes, preserve, token);
|
||||
vtkm::cont::detail::GetBitFieldMetaData(buffers[0])->NumberOfBits = numberOfBits;
|
||||
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits = numberOfBits;
|
||||
}
|
||||
|
||||
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
|
||||
{
|
||||
vtkm::Id numberOfBits = vtkm::cont::detail::GetBitFieldMetaData(buffers[0])->NumberOfBits;
|
||||
vtkm::Id numberOfBits =
|
||||
buffers[0].GetMetaData<vtkm::cont::internal::BitFieldMetaData>().NumberOfBits;
|
||||
VTKM_ASSERT((buffers[0].GetNumberOfBytes() * CHAR_BIT) >= numberOfBits);
|
||||
return numberOfBits;
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayHandleDiscard.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
BufferMetaDataDiscard::~BufferMetaDataDiscard() = default;
|
||||
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData> BufferMetaDataDiscard::DeepCopy() const
|
||||
{
|
||||
return std::unique_ptr<vtkm::cont::internal::BufferMetaData>(new BufferMetaDataDiscard(*this));
|
||||
}
|
||||
|
||||
vtkm::cont::internal::BufferMetaDataDiscard* GetDiscardMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaData* generalMetadata = buffer.GetMetaData();
|
||||
if (generalMetadata == nullptr)
|
||||
{
|
||||
buffer.SetMetaData(vtkm::cont::internal::BufferMetaDataDiscard{});
|
||||
generalMetadata = buffer.GetMetaData();
|
||||
}
|
||||
|
||||
vtkm::cont::internal::BufferMetaDataDiscard* metadata =
|
||||
dynamic_cast<vtkm::cont::internal::BufferMetaDataDiscard*>(buffer.GetMetaData());
|
||||
VTKM_ASSERT(metadata && "Buffer for discard array does not have correct metadata.");
|
||||
return metadata;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
@ -88,18 +88,11 @@ struct VTKM_ALWAYS_EXPORT StorageTagDiscard
|
||||
{
|
||||
};
|
||||
|
||||
struct VTKM_CONT_EXPORT BufferMetaDataDiscard : vtkm::cont::internal::BufferMetaData
|
||||
struct VTKM_ALWAYS_EXPORT DiscardMetaData
|
||||
{
|
||||
vtkm::Id NumberOfValues = 0;
|
||||
|
||||
VTKM_CONT ~BufferMetaDataDiscard() override;
|
||||
|
||||
VTKM_CONT std::unique_ptr<vtkm::cont::internal::BufferMetaData> DeepCopy() const override;
|
||||
};
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::internal::BufferMetaDataDiscard* GetDiscardMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer);
|
||||
|
||||
template <typename ValueType>
|
||||
class Storage<ValueType, StorageTagDiscard>
|
||||
{
|
||||
@ -118,12 +111,12 @@ public:
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
VTKM_ASSERT(numValues >= 0);
|
||||
vtkm::cont::internal::GetDiscardMetaData(buffers[0])->NumberOfValues = numValues;
|
||||
buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues = numValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
|
||||
{
|
||||
return vtkm::cont::internal::GetDiscardMetaData(buffers[0])->NumberOfValues;
|
||||
return buffers[0].GetMetaData<DiscardMetaData>().NumberOfValues;
|
||||
}
|
||||
|
||||
VTKM_CONT static ReadPortalType CreateReadPortal(const vtkm::cont::internal::Buffer*,
|
||||
|
@ -1,75 +0,0 @@
|
||||
//============================================================================
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayHandleImplicit.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
BufferMetaDataImplicit::BufferMetaDataImplicit(const BufferMetaDataImplicit& src)
|
||||
: Deleter(src.Deleter)
|
||||
, Copier(src.Copier)
|
||||
{
|
||||
if (src.Portal)
|
||||
{
|
||||
VTKM_ASSERT(src.Deleter);
|
||||
VTKM_ASSERT(src.Copier);
|
||||
|
||||
this->Portal = src.Copier(src.Portal);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->Portal = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BufferMetaDataImplicit::~BufferMetaDataImplicit()
|
||||
{
|
||||
if (this->Portal)
|
||||
{
|
||||
VTKM_ASSERT(this->Deleter);
|
||||
this->Deleter(this->Portal);
|
||||
this->Portal = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData> BufferMetaDataImplicit::DeepCopy() const
|
||||
{
|
||||
return std::unique_ptr<vtkm::cont::internal::BufferMetaData>(new BufferMetaDataImplicit(*this));
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
vtkm::cont::internal::BufferMetaDataImplicit* GetImplicitMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaDataImplicit* metadata =
|
||||
dynamic_cast<vtkm::cont::internal::BufferMetaDataImplicit*>(buffer.GetMetaData());
|
||||
VTKM_ASSERT(metadata && "Buffer for implicit array does not have correct metadata.");
|
||||
return metadata;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
}
|
||||
} // namespace vtkm::cont::detail
|
@ -91,41 +91,6 @@ struct VTKM_ALWAYS_EXPORT StorageTagImplicit
|
||||
namespace internal
|
||||
{
|
||||
|
||||
struct VTKM_CONT_EXPORT BufferMetaDataImplicit : vtkm::cont::internal::BufferMetaData
|
||||
{
|
||||
void* Portal;
|
||||
|
||||
using DeleterType = void(void*);
|
||||
DeleterType* Deleter;
|
||||
|
||||
using CopierType = void*(void*);
|
||||
CopierType* Copier;
|
||||
|
||||
template <typename PortalType>
|
||||
BufferMetaDataImplicit(const PortalType& portal)
|
||||
: Portal(new PortalType(portal))
|
||||
, Deleter([](void* p) { delete reinterpret_cast<PortalType*>(p); })
|
||||
, Copier([](void* p) -> void* { return new PortalType(*reinterpret_cast<PortalType*>(p)); })
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT BufferMetaDataImplicit(const BufferMetaDataImplicit& src);
|
||||
|
||||
BufferMetaDataImplicit& operator=(const BufferMetaDataImplicit&) = delete;
|
||||
|
||||
VTKM_CONT ~BufferMetaDataImplicit() override;
|
||||
|
||||
VTKM_CONT std::unique_ptr<vtkm::cont::internal::BufferMetaData> DeepCopy() const override;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::internal::BufferMetaDataImplicit* GetImplicitMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class ArrayPortalType>
|
||||
struct VTKM_ALWAYS_EXPORT
|
||||
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
|
||||
@ -144,10 +109,7 @@ struct VTKM_ALWAYS_EXPORT
|
||||
|
||||
VTKM_CONT static vtkm::Id GetNumberOfValues(const vtkm::cont::internal::Buffer* buffers)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaDataImplicit* metadata =
|
||||
detail::GetImplicitMetaData(buffers[0]);
|
||||
VTKM_ASSERT(metadata->Portal);
|
||||
return reinterpret_cast<ArrayPortalType*>(metadata->Portal)->GetNumberOfValues();
|
||||
return buffers[0].GetMetaData<ArrayPortalType>().GetNumberOfValues();
|
||||
}
|
||||
|
||||
VTKM_CONT static void ResizeBuffers(vtkm::Id numValues,
|
||||
@ -170,10 +132,7 @@ struct VTKM_ALWAYS_EXPORT
|
||||
vtkm::cont::DeviceAdapterId,
|
||||
vtkm::cont::Token&)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaDataImplicit* metadata =
|
||||
detail::GetImplicitMetaData(buffers[0]);
|
||||
VTKM_ASSERT(metadata->Portal);
|
||||
return *reinterpret_cast<ReadPortalType*>(metadata->Portal);
|
||||
return buffers[0].GetMetaData<ArrayPortalType>();
|
||||
}
|
||||
|
||||
VTKM_CONT static WritePortalType CreateWritePortal(const vtkm::cont::internal::Buffer*,
|
||||
@ -191,8 +150,7 @@ VTKM_CONT inline std::vector<vtkm::cont::internal::Buffer> PortalToArrayHandleIm
|
||||
const PortalType& portal)
|
||||
{
|
||||
std::vector<vtkm::cont::internal::Buffer> buffers(1);
|
||||
buffers[0].SetMetaData(std::unique_ptr<vtkm::cont::internal::BufferMetaData>(
|
||||
new vtkm::cont::internal::BufferMetaDataImplicit(portal)));
|
||||
buffers[0].SetMetaData(portal);
|
||||
return buffers;
|
||||
}
|
||||
|
||||
|
@ -41,62 +41,16 @@ namespace cont
|
||||
namespace detail
|
||||
{
|
||||
|
||||
vtkm::cont::internal::BufferMetaDataBitField* GetBitFieldMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaData* generalMetaData = buffer.GetMetaData();
|
||||
if (generalMetaData == nullptr)
|
||||
{
|
||||
VTKM_LOG_F(vtkm::cont::LogLevel::Warn, "BitField has buffer with no metadata. Setting.");
|
||||
const_cast<vtkm::cont::internal::Buffer&>(buffer).SetMetaData(
|
||||
vtkm::cont::internal::BufferMetaDataBitField{});
|
||||
generalMetaData = buffer.GetMetaData();
|
||||
VTKM_ASSERT(generalMetaData != nullptr);
|
||||
}
|
||||
|
||||
vtkm::cont::internal::BufferMetaDataBitField* metadata =
|
||||
dynamic_cast<vtkm::cont::internal::BufferMetaDataBitField*>(generalMetaData);
|
||||
if (metadata == nullptr)
|
||||
{
|
||||
VTKM_LOG_F(vtkm::cont::LogLevel::Error,
|
||||
"BitField has a buffer with metadata of the wrong type. "
|
||||
"Replacing, but this will likely cause problems.");
|
||||
const_cast<vtkm::cont::internal::Buffer&>(buffer).SetMetaData(
|
||||
vtkm::cont::internal::BufferMetaDataBitField{});
|
||||
generalMetaData = buffer.GetMetaData();
|
||||
metadata = dynamic_cast<vtkm::cont::internal::BufferMetaDataBitField*>(generalMetaData);
|
||||
VTKM_ASSERT(metadata != nullptr);
|
||||
}
|
||||
|
||||
// Check to make sure that the buffer is at least as larger as needed for buffer size.
|
||||
VTKM_ASSERT(buffer.GetNumberOfBytes() * CHAR_BIT >= metadata->NumberOfBits);
|
||||
|
||||
return metadata;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
BufferMetaDataBitField::~BufferMetaDataBitField() {}
|
||||
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData> BufferMetaDataBitField::DeepCopy() const
|
||||
{
|
||||
return std::unique_ptr<vtkm::cont::internal::BufferMetaData>(new BufferMetaDataBitField(*this));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
BitField::BitField()
|
||||
{
|
||||
this->Buffer.SetMetaData(internal::BufferMetaDataBitField{});
|
||||
this->Buffer.SetMetaData(internal::BitFieldMetaData{});
|
||||
}
|
||||
|
||||
vtkm::Id BitField::GetNumberOfBits() const
|
||||
{
|
||||
auto metadata = detail::GetBitFieldMetaData(this->Buffer);
|
||||
return metadata->NumberOfBits;
|
||||
return this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits;
|
||||
}
|
||||
|
||||
void BitField::Allocate(vtkm::Id numberOfBits,
|
||||
@ -113,7 +67,7 @@ void BitField::Allocate(vtkm::Id numberOfBits,
|
||||
vtkm::cont::GetSizeString(static_cast<vtkm::UInt64>(numBytes)).c_str());
|
||||
|
||||
this->Buffer.SetNumberOfBytes(numBytes, preserve, token);
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits = numberOfBits;
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits = numberOfBits;
|
||||
}
|
||||
|
||||
void BitField::ReleaseResourcesExecution()
|
||||
@ -125,7 +79,7 @@ void BitField::ReleaseResources()
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
this->Buffer.SetNumberOfBytes(0, vtkm::CopyFlag::Off, token);
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits = 0;
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits = 0;
|
||||
}
|
||||
|
||||
void BitField::SyncControlArray() const
|
||||
@ -150,21 +104,21 @@ BitField::WritePortalType BitField::WritePortal() const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
return WritePortalType(this->Buffer.WritePointerHost(token),
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits);
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits);
|
||||
}
|
||||
|
||||
BitField::ReadPortalType BitField::ReadPortal() const
|
||||
{
|
||||
vtkm::cont::Token token;
|
||||
return ReadPortalType(this->Buffer.ReadPointerHost(token),
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits);
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits);
|
||||
}
|
||||
|
||||
BitField::ReadPortalType BitField::PrepareForInput(vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
return ReadPortalType(this->Buffer.ReadPointerDevice(device, token),
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits);
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits);
|
||||
}
|
||||
|
||||
BitField::WritePortalType BitField::PrepareForOutput(vtkm::Id numBits,
|
||||
@ -173,14 +127,14 @@ BitField::WritePortalType BitField::PrepareForOutput(vtkm::Id numBits,
|
||||
{
|
||||
this->Allocate(numBits, vtkm::CopyFlag::Off, token);
|
||||
return WritePortalType(this->Buffer.WritePointerDevice(device, token),
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits);
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits);
|
||||
}
|
||||
|
||||
BitField::WritePortalType BitField::PrepareForInPlace(vtkm::cont::DeviceAdapterId device,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
return WritePortalType(this->Buffer.WritePointerDevice(device, token),
|
||||
detail::GetBitFieldMetaData(this->Buffer)->NumberOfBits);
|
||||
this->Buffer.GetMetaData<internal::BitFieldMetaData>().NumberOfBits);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,13 +36,9 @@ namespace internal
|
||||
|
||||
struct StorageTagBitField;
|
||||
|
||||
struct VTKM_CONT_EXPORT BufferMetaDataBitField : vtkm::cont::internal::BufferMetaData
|
||||
struct VTKM_ALWAYS_EXPORT BitFieldMetaData
|
||||
{
|
||||
vtkm::Id NumberOfBits = 0;
|
||||
|
||||
VTKM_CONT ~BufferMetaDataBitField() override;
|
||||
|
||||
VTKM_CONT std::unique_ptr<vtkm::cont::internal::BufferMetaData> DeepCopy() const override;
|
||||
};
|
||||
|
||||
}
|
||||
@ -99,9 +95,6 @@ struct BitCoordinate
|
||||
vtkm::Int32 BitOffset; // [0, bitsInWord)
|
||||
};
|
||||
|
||||
VTKM_CONT_EXPORT vtkm::cont::internal::BufferMetaDataBitField* GetBitFieldMetaData(
|
||||
const vtkm::cont::internal::Buffer& buffer);
|
||||
|
||||
/// Portal for performing bit or word operations on a BitField.
|
||||
///
|
||||
/// This is the implementation used by BitPortal and BitPortalConst.
|
||||
|
@ -135,8 +135,6 @@ set(template_sources
|
||||
set(sources
|
||||
ArrayHandle.cxx
|
||||
ArrayHandleBasic.cxx
|
||||
ArrayHandleDiscard.cxx
|
||||
ArrayHandleImplicit.cxx
|
||||
ArrayHandleSOA.cxx
|
||||
BitField.cxx
|
||||
ColorTablePresets.cxx
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include <vtkm/cont/ErrorBadAllocation.h>
|
||||
#include <vtkm/cont/ErrorBadDevice.h>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
||||
|
||||
#include <vtkm/cont/internal/Buffer.h>
|
||||
@ -100,6 +101,71 @@ struct BufferState
|
||||
}
|
||||
};
|
||||
|
||||
struct MetaDataManager
|
||||
{
|
||||
void* Data = nullptr;
|
||||
std::string Type;
|
||||
vtkm::cont::internal::detail::DeleterType* Deleter = nullptr;
|
||||
vtkm::cont::internal::detail::CopierType* Copier = nullptr;
|
||||
|
||||
MetaDataManager() = default;
|
||||
|
||||
MetaDataManager(void* data,
|
||||
const std::string& type,
|
||||
vtkm::cont::internal::detail::DeleterType* deleter,
|
||||
vtkm::cont::internal::detail::CopierType* copier)
|
||||
: Data(data)
|
||||
, Type(type)
|
||||
, Deleter(deleter)
|
||||
, Copier(copier)
|
||||
{
|
||||
}
|
||||
|
||||
~MetaDataManager()
|
||||
{
|
||||
if (this->Data != nullptr)
|
||||
{
|
||||
VTKM_ASSERT(this->Deleter != nullptr);
|
||||
this->Deleter(this->Data);
|
||||
this->Data = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
MetaDataManager(const MetaDataManager& src)
|
||||
{
|
||||
if (src.Data != nullptr)
|
||||
{
|
||||
VTKM_ASSERT(src.Copier);
|
||||
VTKM_ASSERT(src.Deleter);
|
||||
this->Data = src.Copier(src.Data);
|
||||
this->Type = src.Type;
|
||||
this->Deleter = src.Deleter;
|
||||
this->Copier = src.Copier;
|
||||
}
|
||||
}
|
||||
|
||||
MetaDataManager& operator=(const MetaDataManager& src)
|
||||
{
|
||||
if (this->Data != nullptr)
|
||||
{
|
||||
VTKM_ASSERT(this->Deleter != nullptr);
|
||||
this->Deleter(this->Data);
|
||||
this->Data = nullptr;
|
||||
this->Type = "";
|
||||
}
|
||||
if (src.Data != nullptr)
|
||||
{
|
||||
VTKM_ASSERT(src.Copier);
|
||||
VTKM_ASSERT(src.Deleter);
|
||||
this->Data = src.Copier(src.Data);
|
||||
this->Type = src.Type;
|
||||
this->Deleter = src.Deleter;
|
||||
this->Copier = src.Copier;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace vtkm
|
||||
@ -109,8 +175,6 @@ namespace cont
|
||||
namespace internal
|
||||
{
|
||||
|
||||
BufferMetaData::~BufferMetaData() {}
|
||||
|
||||
class Buffer::InternalsStruct
|
||||
{
|
||||
public:
|
||||
@ -138,7 +202,7 @@ public:
|
||||
std::mutex Mutex;
|
||||
std::condition_variable ConditionVariable;
|
||||
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData> MetaData;
|
||||
MetaDataManager MetaData;
|
||||
|
||||
LockType GetLock() { return LockType(this->Mutex); }
|
||||
|
||||
@ -535,10 +599,7 @@ struct VTKM_NEVER_EXPORT BufferHelper
|
||||
srcInternals->GetHostBuffer(srcLock).GetPointer(),
|
||||
static_cast<std::size_t>(size));
|
||||
|
||||
if (srcInternals->MetaData)
|
||||
{
|
||||
destInternals->MetaData = srcInternals->MetaData->DeepCopy();
|
||||
}
|
||||
destInternals->MetaData = srcInternals->MetaData;
|
||||
}
|
||||
|
||||
static void CopyOnDevice(
|
||||
@ -580,10 +641,7 @@ struct VTKM_NEVER_EXPORT BufferHelper
|
||||
|
||||
destInternals->SetNumberOfBytes(destLock, srcInternals->GetNumberOfBytes(srcLock));
|
||||
|
||||
if (srcInternals->MetaData)
|
||||
{
|
||||
destInternals->MetaData = srcInternals->MetaData->DeepCopy();
|
||||
}
|
||||
destInternals->MetaData = srcInternals->MetaData;
|
||||
}
|
||||
};
|
||||
|
||||
@ -637,14 +695,31 @@ void Buffer::SetNumberOfBytes(vtkm::BufferSizeType numberOfBytes,
|
||||
detail::BufferHelper::SetNumberOfBytes(this->Internals, lock, numberOfBytes, preserve, token);
|
||||
}
|
||||
|
||||
vtkm::cont::internal::BufferMetaData* Buffer::GetMetaData() const
|
||||
bool Buffer::HasMetaData() const
|
||||
{
|
||||
return this->Internals->MetaData.get();
|
||||
return (this->Internals->MetaData.Data != nullptr);
|
||||
}
|
||||
|
||||
void Buffer::SetMetaData(std::unique_ptr<vtkm::cont::internal::BufferMetaData>&& metadata) const
|
||||
bool Buffer::MetaDataIsType(const std::string& type) const
|
||||
{
|
||||
this->Internals->MetaData = std::move(metadata);
|
||||
return this->HasMetaData() && (this->Internals->MetaData.Type == type);
|
||||
}
|
||||
|
||||
void Buffer::SetMetaData(void* data,
|
||||
const std::string& type,
|
||||
detail::DeleterType* deleter,
|
||||
detail::CopierType* copier) const
|
||||
{
|
||||
this->Internals->MetaData = MetaDataManager(data, type, deleter, copier);
|
||||
}
|
||||
|
||||
void* Buffer::GetMetaData(const std::string& type) const
|
||||
{
|
||||
if (type != this->Internals->MetaData.Type)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType("Requesting Buffer meta data that is the wrong type.");
|
||||
}
|
||||
return this->Internals->MetaData.Data;
|
||||
}
|
||||
|
||||
bool Buffer::IsAllocatedOnHost() const
|
||||
@ -806,10 +881,7 @@ void Buffer::DeepCopyFrom(const vtkm::cont::internal::Buffer& src) const
|
||||
src.Internals->GetNumberOfBytes(srcLock),
|
||||
vtkm::CopyFlag::Off,
|
||||
token);
|
||||
if (src.Internals->MetaData)
|
||||
{
|
||||
dest.Internals->MetaData = src.Internals->MetaData->DeepCopy();
|
||||
}
|
||||
dest.Internals->MetaData = src.Internals->MetaData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/Serialization.h>
|
||||
#include <vtkm/cont/Token.h>
|
||||
|
||||
@ -59,29 +60,23 @@ namespace detail
|
||||
|
||||
struct BufferHelper;
|
||||
|
||||
} // namespace detail
|
||||
using DeleterType = void(void*);
|
||||
|
||||
/// \brief An object to hold metadata for a `Buffer` object.
|
||||
///
|
||||
/// A `Buffer` object can optionally hold a `BufferMetaData` object. The metadata object
|
||||
/// allows the buffer to hold state for the buffer that is not directly related to the
|
||||
/// memory allocated and its size. This allows you to completely encapsulate the state
|
||||
/// in the `Buffer` object and then pass the `Buffer` object to different object that
|
||||
/// provide different interfaces to the array.
|
||||
///
|
||||
/// To use `BufferMetaData`, create a subclass, and then provide that subclass as the
|
||||
/// metadata. The `Buffer` object will only remember it as the generic base class. You
|
||||
/// can then get the metadata and perform a `dynamic_cast` to check that the metadata
|
||||
/// is as expected and to get to the meta information
|
||||
///
|
||||
struct VTKM_CONT_EXPORT BufferMetaData
|
||||
template <typename T>
|
||||
void BasicDeleter(void* mem)
|
||||
{
|
||||
virtual ~BufferMetaData();
|
||||
T* obj = reinterpret_cast<T*>(mem);
|
||||
delete obj;
|
||||
}
|
||||
|
||||
/// Subclasses must provide a way to deep copy metadata.
|
||||
///
|
||||
virtual std::unique_ptr<BufferMetaData> DeepCopy() const = 0;
|
||||
};
|
||||
using CopierType = void*(const void*);
|
||||
template <typename T>
|
||||
void* BasicCopier(const void* mem)
|
||||
{
|
||||
return new T(*reinterpret_cast<const T*>(mem));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Manages a buffer data among the host and various devices.
|
||||
///
|
||||
@ -130,34 +125,65 @@ public:
|
||||
vtkm::CopyFlag preserve,
|
||||
vtkm::cont::Token& token);
|
||||
|
||||
/// \brief Gets the metadata for the buffer.
|
||||
private:
|
||||
VTKM_CONT bool MetaDataIsType(const std::string& type) const;
|
||||
VTKM_CONT void SetMetaData(void* data,
|
||||
const std::string& type,
|
||||
detail::DeleterType* deleter,
|
||||
detail::CopierType copier) const;
|
||||
VTKM_CONT void* GetMetaData(const std::string& type) const;
|
||||
|
||||
public:
|
||||
/// \brief Returns whether this `Buffer` holds metadata.
|
||||
///
|
||||
/// Holding metadata in a `Buffer` is optional. The metadata is held in a subclass of
|
||||
/// `BufferMetaData`, and you will have to safely downcast the object to retrieve the
|
||||
/// actual information.
|
||||
VTKM_CONT bool HasMetaData() const;
|
||||
|
||||
/// \brief Determines if the metadata for the buffer is set to the given type.
|
||||
///
|
||||
/// The metadata could be a `nullptr` if the metadata was never set.
|
||||
///
|
||||
VTKM_CONT vtkm::cont::internal::BufferMetaData* GetMetaData() const;
|
||||
template <typename MetaDataType>
|
||||
VTKM_CONT bool MetaDataIsType() const
|
||||
{
|
||||
return this->MetaDataIsType(vtkm::cont::TypeToString<MetaDataType>());
|
||||
}
|
||||
|
||||
/// \brief Sets the metadata for the buffer.
|
||||
///
|
||||
/// This form of SetMetaData takes an rvalue to a unique_ptr holding the metadata to
|
||||
/// ensure that the object is properly managed.
|
||||
/// Takes an arbitrary object and copies it to the metadata of this buffer. Any existing
|
||||
/// metadata is deleted. Any object can be set as the metadata as long as the object has
|
||||
/// a default constructor and is copyable.
|
||||
///
|
||||
VTKM_CONT void SetMetaData(
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData>&& metadata) const;
|
||||
|
||||
/// \brief Sets the metadata for the buffer.
|
||||
///
|
||||
/// This form of SetMetaData takes the metadata object value. The metadata object
|
||||
/// must be a subclass of BufferMetaData or you will get a compile error.
|
||||
/// Holding metadata in a `Buffer` is optional, but helpful for storing additional
|
||||
/// information or objects that cannot be implied by the buffer itself.
|
||||
///
|
||||
template <typename MetaDataType>
|
||||
VTKM_CONT void SetMetaData(const MetaDataType& metadata) const
|
||||
{
|
||||
this->SetMetaData(
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData>(new MetaDataType(metadata)));
|
||||
MetaDataType* metadataCopy = new MetaDataType(metadata);
|
||||
this->SetMetaData(metadataCopy,
|
||||
vtkm::cont::TypeToString(metadata),
|
||||
detail::BasicDeleter<MetaDataType>,
|
||||
detail::BasicCopier<MetaDataType>);
|
||||
}
|
||||
|
||||
/// \brief Gets the metadata for the buffer.
|
||||
///
|
||||
/// When you call this method, you have to specify a template parameter for the type
|
||||
/// of the metadata. If the metadata has not yet been set in this buffer, a new metadata
|
||||
/// object is created, set to this buffer, and returned. If metadata of a different type
|
||||
/// has already been set, then an exception is thrown.
|
||||
///
|
||||
/// The returned value is a reference that can be manipulated to alter the metadata of
|
||||
/// this buffer.
|
||||
///
|
||||
template <typename MetaDataType>
|
||||
VTKM_CONT MetaDataType& GetMetaData() const
|
||||
{
|
||||
if (!this->HasMetaData())
|
||||
{
|
||||
this->SetMetaData(MetaDataType{});
|
||||
}
|
||||
return *reinterpret_cast<MetaDataType*>(
|
||||
this->GetMetaData(vtkm::cont::TypeToString<MetaDataType>()));
|
||||
}
|
||||
|
||||
/// \brief Returns `true` if the buffer is allocated on the host.
|
||||
|
@ -23,32 +23,16 @@ constexpr vtkm::Id ARRAY_SIZE = 20;
|
||||
using PortalType = vtkm::cont::internal::ArrayPortalFromIterators<T*>;
|
||||
using PortalTypeConst = vtkm::cont::internal::ArrayPortalFromIterators<const T*>;
|
||||
|
||||
struct BufferMetaDataTest : vtkm::cont::internal::BufferMetaData
|
||||
struct TestMetaData
|
||||
{
|
||||
vtkm::Id Value;
|
||||
|
||||
std::unique_ptr<vtkm::cont::internal::BufferMetaData> DeepCopy() const override
|
||||
{
|
||||
return std::unique_ptr<vtkm::cont::internal::BufferMetaData>(new BufferMetaDataTest(*this));
|
||||
}
|
||||
};
|
||||
|
||||
constexpr vtkm::Id METADATA_VALUE = 42;
|
||||
|
||||
bool CheckMetaData(const vtkm::cont::internal::Buffer& buffer)
|
||||
{
|
||||
vtkm::cont::internal::BufferMetaData* generalMetaData = buffer.GetMetaData();
|
||||
if (!generalMetaData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
BufferMetaDataTest* metadata = dynamic_cast<BufferMetaDataTest*>(generalMetaData);
|
||||
if (!metadata)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return metadata->Value == METADATA_VALUE;
|
||||
return buffer.GetMetaData<TestMetaData>().Value == METADATA_VALUE;
|
||||
}
|
||||
|
||||
PortalType MakePortal(void* buffer, vtkm::Id numValues)
|
||||
@ -110,7 +94,7 @@ void DoTest()
|
||||
vtkm::cont::internal::Buffer buffer;
|
||||
|
||||
{
|
||||
BufferMetaDataTest metadata;
|
||||
TestMetaData metadata;
|
||||
metadata.Value = METADATA_VALUE;
|
||||
buffer.SetMetaData(metadata);
|
||||
VTKM_TEST_ASSERT(CheckMetaData(buffer));
|
||||
|
Loading…
Reference in New Issue
Block a user