2014-02-10 19:53:03 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2014-02-10 19:53:03 +00:00
|
|
|
// 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.
|
|
|
|
//============================================================================
|
2014-06-23 23:33:04 +00:00
|
|
|
#ifndef vtk_m_cont_StorageBasic_h
|
|
|
|
#define vtk_m_cont_StorageBasic_h
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
#include <vtkm/Assert.h>
|
2019-05-01 13:42:57 +00:00
|
|
|
#include <vtkm/Pair.h>
|
2014-02-10 19:53:03 +00:00
|
|
|
#include <vtkm/Types.h>
|
2017-01-09 21:15:32 +00:00
|
|
|
#include <vtkm/cont/ErrorBadAllocation.h>
|
2017-05-18 14:51:24 +00:00
|
|
|
#include <vtkm/cont/ErrorBadValue.h>
|
2014-06-23 23:33:04 +00:00
|
|
|
#include <vtkm/cont/Storage.h>
|
|
|
|
|
2014-02-10 19:53:03 +00:00
|
|
|
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2014-06-23 23:33:04 +00:00
|
|
|
/// A tag for the basic implementation of a Storage object.
|
2017-05-18 14:29:41 +00:00
|
|
|
struct VTKM_ALWAYS_EXPORT StorageTagBasic
|
|
|
|
{
|
|
|
|
};
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace internal
|
|
|
|
{
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2018-04-04 15:27:57 +00:00
|
|
|
/// Function that does all of VTK-m de-allocations for storage basic.
|
|
|
|
/// This is exists so that stolen arrays can call the correct free
|
|
|
|
/// function ( _aligned_malloc / cuda_free ).
|
|
|
|
VTKM_CONT_EXPORT void free_memory(void* ptr);
|
|
|
|
|
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
/// Class that does all of VTK-m allocations
|
|
|
|
/// for storage basic. This is exists so that
|
|
|
|
/// stolen arrays can call the correct free
|
|
|
|
/// function ( _aligned_malloc ) on windows
|
|
|
|
struct VTKM_CONT_EXPORT StorageBasicAllocator
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-02-09 21:17:39 +00:00
|
|
|
void* allocate(size_t size, size_t align);
|
2015-08-04 21:56:33 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
template <typename T>
|
2018-04-04 15:27:57 +00:00
|
|
|
inline void deallocate(T* p)
|
2017-09-21 14:33:17 +00:00
|
|
|
{
|
2018-04-04 15:27:57 +00:00
|
|
|
internal::free_memory(static_cast<void*>(p));
|
2017-09-21 14:33:17 +00:00
|
|
|
}
|
2015-08-04 21:56:33 +00:00
|
|
|
};
|
2018-04-04 15:27:57 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
/// Base class for basic storage classes. This allow us to implement
|
|
|
|
/// vtkm::cont::Storage<T, StorageTagBasic > for any T type with no overhead
|
|
|
|
/// as all heavy logic is provide by a type-agnostic API including allocations, etc.
|
2017-06-23 13:33:28 +00:00
|
|
|
class VTKM_CONT_EXPORT StorageBasicBase
|
|
|
|
{
|
|
|
|
public:
|
2018-02-09 21:17:39 +00:00
|
|
|
using AllocatorType = StorageBasicAllocator;
|
|
|
|
VTKM_CONT StorageBasicBase();
|
2018-04-04 15:27:57 +00:00
|
|
|
|
|
|
|
/// A non owning view of already allocated memory
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT StorageBasicBase(const void* array, vtkm::Id size, vtkm::UInt64 sizeOfValue);
|
2018-04-04 15:27:57 +00:00
|
|
|
|
|
|
|
/// Transfer the ownership of already allocated memory to VTK-m
|
|
|
|
VTKM_CONT StorageBasicBase(const void* array,
|
|
|
|
vtkm::Id size,
|
|
|
|
vtkm::UInt64 sizeOfValue,
|
|
|
|
void (*deleteFunction)(void*));
|
|
|
|
|
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT ~StorageBasicBase();
|
|
|
|
|
2018-10-23 21:03:20 +00:00
|
|
|
VTKM_CONT StorageBasicBase(StorageBasicBase&& src) noexcept;
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT StorageBasicBase(const StorageBasicBase& src);
|
2018-10-23 21:03:20 +00:00
|
|
|
VTKM_CONT StorageBasicBase& operator=(StorageBasicBase&& src) noexcept;
|
|
|
|
VTKM_CONT StorageBasicBase& operator=(const StorageBasicBase& src);
|
2017-06-23 13:33:28 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
/// \brief Return the number of bytes allocated for this storage object(Capacity).
|
|
|
|
///
|
|
|
|
///
|
|
|
|
VTKM_CONT vtkm::UInt64 GetNumberOfBytes() const { return this->AllocatedByteSize; }
|
2017-06-23 13:33:28 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
/// \brief Return the number of 'T' values allocated by this storage
|
|
|
|
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
|
|
|
|
|
|
|
|
/// \brief Allocates an array with the specified number of elements.
|
2017-06-23 13:33:28 +00:00
|
|
|
///
|
|
|
|
/// The allocation may be done on an already existing array, but can wipe out
|
|
|
|
/// any data already in the array. This method can throw
|
|
|
|
/// ErrorBadAllocation if the array cannot be allocated or
|
|
|
|
/// ErrorBadValue if the allocation is not feasible (for example, the
|
|
|
|
/// array storage is read-only).
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void AllocateValues(vtkm::Id numberOfValues, vtkm::UInt64 sizeOfValue);
|
2017-06-23 13:33:28 +00:00
|
|
|
|
|
|
|
/// \brief Reduces the size of the array without changing its values.
|
|
|
|
///
|
|
|
|
/// This method allows you to resize the array without reallocating it. The
|
2018-02-09 21:17:39 +00:00
|
|
|
/// size of the array is changed so that it can hold \c numberOfValues values.
|
|
|
|
/// The data in the reallocated array stays the same, but \c numberOfValues must be
|
2017-06-23 13:33:28 +00:00
|
|
|
/// equal or less than the preexisting size. That is, this method can only be
|
|
|
|
/// used to shorten the array, not lengthen.
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void Shrink(vtkm::Id numberOfValues);
|
2017-06-23 13:33:28 +00:00
|
|
|
|
|
|
|
/// \brief Frees any resources (i.e. memory) stored in this array.
|
|
|
|
///
|
|
|
|
/// After calling this method GetNumberOfBytes() will return 0. The
|
|
|
|
/// resources should also be released when the Storage class is
|
|
|
|
/// destroyed.
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void ReleaseResources();
|
|
|
|
|
|
|
|
/// \brief Returns if vtkm will deallocate this memory. VTK-m StorageBasic
|
|
|
|
/// is designed that VTK-m will not deallocate user passed memory, or
|
|
|
|
/// instances that have been stolen (\c StealArray)
|
2018-04-04 15:27:57 +00:00
|
|
|
VTKM_CONT bool WillDeallocate() const { return this->DeleteFunction != nullptr; }
|
|
|
|
|
|
|
|
/// \brief Change the Change the pointer that this class is using. Should only be used
|
|
|
|
/// by ExecutionArrayInterface sublcasses.
|
|
|
|
/// Note: This will release any previous allocated memory!
|
|
|
|
VTKM_CONT void SetBasePointer(const void* ptr,
|
|
|
|
vtkm::Id numberOfValues,
|
|
|
|
vtkm::UInt64 sizeOfValue,
|
|
|
|
void (*deleteFunction)(void*));
|
2017-06-23 13:33:28 +00:00
|
|
|
|
|
|
|
/// Return the memory location of the first element of the array data.
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void* GetBasePointer() const;
|
2017-06-23 13:33:28 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void* GetEndPointer(vtkm::Id numberOfValues, vtkm::UInt64 sizeOfValue) const;
|
2017-06-23 13:33:28 +00:00
|
|
|
|
|
|
|
/// Return the memory location of the first element past the end of the
|
|
|
|
/// array's allocated memory buffer.
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void* GetCapacityPointer() const;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void* Array;
|
|
|
|
vtkm::UInt64 AllocatedByteSize;
|
|
|
|
vtkm::Id NumberOfValues;
|
2018-04-04 15:27:57 +00:00
|
|
|
void (*DeleteFunction)(void*);
|
2017-06-23 13:33:28 +00:00
|
|
|
};
|
|
|
|
|
2014-06-23 23:33:04 +00:00
|
|
|
/// A basic implementation of an Storage object.
|
2014-02-10 19:53:03 +00:00
|
|
|
///
|
2014-06-23 23:33:04 +00:00
|
|
|
/// \todo This storage does \em not construct the values within the array.
|
2014-02-10 19:53:03 +00:00
|
|
|
/// Thus, it is important to not use this class with any type that will fail if
|
|
|
|
/// not constructed. These are things like basic types (int, float, etc.) and
|
|
|
|
/// the VTKm Tuple classes. In the future it would be nice to have a compile
|
|
|
|
/// time check to enforce this.
|
|
|
|
///
|
|
|
|
template <typename ValueT>
|
2017-06-23 13:33:28 +00:00
|
|
|
class VTKM_ALWAYS_EXPORT Storage<ValueT, vtkm::cont::StorageTagBasic> : public StorageBasicBase
|
2014-02-10 19:53:03 +00:00
|
|
|
{
|
|
|
|
public:
|
2018-02-09 21:17:39 +00:00
|
|
|
using AllocatorType = vtkm::cont::internal::StorageBasicAllocator;
|
2017-06-23 18:50:34 +00:00
|
|
|
using ValueType = ValueT;
|
|
|
|
using PortalType = vtkm::cont::internal::ArrayPortalFromIterators<ValueType*>;
|
|
|
|
using PortalConstType = vtkm::cont::internal::ArrayPortalFromIterators<const ValueType*>;
|
2014-02-10 19:53:03 +00:00
|
|
|
|
|
|
|
public:
|
2017-08-17 12:43:39 +00:00
|
|
|
/// \brief construct storage that VTK-m is responsible for
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT Storage();
|
2018-10-23 21:03:20 +00:00
|
|
|
VTKM_CONT Storage(const Storage<ValueT, vtkm::cont::StorageTagBasic>& src);
|
|
|
|
VTKM_CONT Storage(Storage<ValueT, vtkm::cont::StorageTagBasic>&& src) noexcept;
|
2017-08-17 12:43:39 +00:00
|
|
|
|
|
|
|
/// \brief construct storage that VTK-m is not responsible for
|
2018-04-04 15:27:57 +00:00
|
|
|
VTKM_CONT Storage(const ValueType* array, vtkm::Id numberOfValues);
|
|
|
|
|
|
|
|
/// \brief construct storage that was previously allocated and now VTK-m is
|
|
|
|
/// responsible for
|
|
|
|
VTKM_CONT Storage(const ValueType* array, vtkm::Id numberOfValues, void (*deleteFunction)(void*));
|
2015-04-28 00:01:05 +00:00
|
|
|
|
2018-10-23 21:03:20 +00:00
|
|
|
VTKM_CONT Storage& operator=(const Storage<ValueT, vtkm::cont::StorageTagBasic>& src);
|
|
|
|
VTKM_CONT Storage& operator=(Storage<ValueT, vtkm::cont::StorageTagBasic>&& src);
|
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT void Allocate(vtkm::Id numberOfValues);
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT PortalType GetPortal();
|
2017-06-23 13:33:28 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT PortalConstType GetPortalConst() const;
|
2014-02-10 19:53:03 +00:00
|
|
|
|
2016-08-02 17:02:11 +00:00
|
|
|
/// \brief Get a pointer to the underlying data structure.
|
|
|
|
///
|
|
|
|
/// This method returns the pointer to the array held by this array. The
|
|
|
|
/// memory associated with this array still belongs to the Storage (i.e.
|
|
|
|
/// Storage will eventually deallocate the array).
|
|
|
|
///
|
2018-02-09 21:17:39 +00:00
|
|
|
VTKM_CONT ValueType* GetArray();
|
|
|
|
|
|
|
|
VTKM_CONT const ValueType* GetArray() const;
|
2016-08-02 17:02:11 +00:00
|
|
|
|
2019-05-01 13:42:57 +00:00
|
|
|
/// \brief Transfer ownership of the underlying away from this object.
|
2014-02-10 19:53:03 +00:00
|
|
|
///
|
2019-05-01 13:42:57 +00:00
|
|
|
/// This method returns the pointer and free function to the array held
|
|
|
|
/// by this array. It then clears the internal ownership flags, thereby ensuring
|
|
|
|
/// that the Storage will never deallocate the array or be able to reallocate it.
|
|
|
|
/// This is helpful for taking a reference for an array created internally by
|
2017-08-17 12:43:39 +00:00
|
|
|
/// VTK-m and not having to keep a VTK-m object around. Obviously the caller
|
2019-05-01 13:42:57 +00:00
|
|
|
/// becomes responsible for destroying the memory, and should use the provided
|
|
|
|
/// delete function.
|
2014-02-10 19:53:03 +00:00
|
|
|
///
|
2019-05-01 13:42:57 +00:00
|
|
|
VTKM_CONT vtkm::Pair<ValueType*, void (*)(void*)> StealArray();
|
2014-02-10 19:53:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont
|
|
|
|
|
2016-12-19 13:58:12 +00:00
|
|
|
#ifndef vtkm_cont_StorageBasic_cxx
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
namespace internal
|
|
|
|
{
|
2016-12-19 13:58:12 +00:00
|
|
|
|
2017-09-21 23:14:55 +00:00
|
|
|
/// \cond
|
|
|
|
/// Make doxygen ignore this section
|
2019-02-28 20:08:08 +00:00
|
|
|
#define VTKM_STORAGE_EXPORT(Type) \
|
2018-02-13 15:39:10 +00:00
|
|
|
extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<Type, StorageTagBasic>; \
|
|
|
|
extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Vec<Type, 2>, StorageTagBasic>; \
|
|
|
|
extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Vec<Type, 3>, StorageTagBasic>; \
|
|
|
|
extern template class VTKM_CONT_TEMPLATE_EXPORT Storage<vtkm::Vec<Type, 4>, StorageTagBasic>;
|
|
|
|
|
2019-02-28 20:08:08 +00:00
|
|
|
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
|
2017-09-21 23:14:55 +00:00
|
|
|
/// \endcond
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <vtkm/cont/StorageBasic.hxx>
|
|
|
|
|
2014-06-23 23:33:04 +00:00
|
|
|
#endif //vtk_m_cont_StorageBasic_h
|