2016-12-19 13:58:12 +00:00
|
|
|
//============================================================================
|
|
|
|
// 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.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
2016-12-19 13:58:12 +00:00
|
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
|
|
// Copyright 2014 Los Alamos National Security.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
2016-12-19 13:58:12 +00:00
|
|
|
// the U.S. Government retains certain rights in this software.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
|
|
// this software.
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
#define vtkm_cont_StorageBasic_cxx
|
|
|
|
#include <vtkm/cont/StorageBasic.h>
|
2018-02-09 21:17:39 +00:00
|
|
|
#include <vtkm/internal/Configure.h>
|
2016-12-19 13:58:12 +00:00
|
|
|
|
|
|
|
#if defined(VTKM_POSIX)
|
|
|
|
#define VTKM_MEMALIGN_POSIX
|
|
|
|
#elif defined(_WIN32)
|
|
|
|
#define VTKM_MEMALIGN_WIN
|
|
|
|
#elif defined(__SSE__)
|
|
|
|
#define VTKM_MEMALIGN_SSE
|
|
|
|
#else
|
|
|
|
#define VTKM_MEMALIGN_NONE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(VTKM_MEMALIGN_POSIX)
|
|
|
|
#include <stdlib.h>
|
|
|
|
#elif defined(VTKM_MEMALIGN_WIN)
|
|
|
|
#include <malloc.h>
|
|
|
|
#elif defined(VTKM_MEMALIGN_SSE)
|
|
|
|
#include <xmmintrin.h>
|
|
|
|
#else
|
|
|
|
#include <malloc.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdlib>
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
namespace internal
|
|
|
|
{
|
2016-12-19 13:58:12 +00:00
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
void* StorageBasicAllocator::allocate(size_t size, size_t align)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
#if defined(VTKM_MEMALIGN_POSIX)
|
2017-05-18 14:29:41 +00:00
|
|
|
void* mem = nullptr;
|
2016-12-19 13:58:12 +00:00
|
|
|
if (posix_memalign(&mem, align, size) != 0)
|
|
|
|
{
|
|
|
|
mem = nullptr;
|
|
|
|
}
|
|
|
|
#elif defined(VTKM_MEMALIGN_WIN)
|
2017-05-18 14:29:41 +00:00
|
|
|
void* mem = _aligned_malloc(size, align);
|
2016-12-19 13:58:12 +00:00
|
|
|
#elif defined(VTKM_MEMALIGN_SSE)
|
2017-05-18 14:29:41 +00:00
|
|
|
void* mem = _mm_malloc(size, align);
|
2016-12-19 13:58:12 +00:00
|
|
|
#else
|
2017-05-18 14:29:41 +00:00
|
|
|
void* mem = malloc(size);
|
2016-12-19 13:58:12 +00:00
|
|
|
#endif
|
|
|
|
return mem;
|
|
|
|
}
|
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
void StorageBasicAllocator::free_memory(void* mem)
|
2016-12-19 13:58:12 +00:00
|
|
|
{
|
|
|
|
#if defined(VTKM_MEMALIGN_POSIX)
|
|
|
|
free(mem);
|
|
|
|
#elif defined(VTKM_MEMALIGN_WIN)
|
|
|
|
_aligned_free(mem);
|
|
|
|
#elif defined(VTKM_MEMALIGN_SSE)
|
|
|
|
_mm_free(mem);
|
|
|
|
#else
|
|
|
|
free(mem);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2018-02-09 21:17:39 +00:00
|
|
|
|
|
|
|
StorageBasicBase::StorageBasicBase()
|
|
|
|
: Array(nullptr)
|
|
|
|
, AllocatedByteSize(0)
|
|
|
|
, NumberOfValues(0)
|
|
|
|
, DeallocateOnRelease(true)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageBasicBase::StorageBasicBase(const void* array,
|
|
|
|
vtkm::Id numberOfValues,
|
|
|
|
vtkm::UInt64 sizeOfValue)
|
|
|
|
: Array(const_cast<void*>(array))
|
|
|
|
, AllocatedByteSize(static_cast<vtkm::UInt64>(numberOfValues) * sizeOfValue)
|
|
|
|
, NumberOfValues(numberOfValues)
|
|
|
|
, DeallocateOnRelease(array == nullptr ? true : false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageBasicBase::~StorageBasicBase()
|
|
|
|
{
|
|
|
|
this->ReleaseResources();
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageBasicBase::StorageBasicBase(const StorageBasicBase& src)
|
|
|
|
: Array(src.Array)
|
|
|
|
, AllocatedByteSize(src.AllocatedByteSize)
|
|
|
|
, NumberOfValues(src.NumberOfValues)
|
|
|
|
, DeallocateOnRelease(src.DeallocateOnRelease)
|
|
|
|
|
|
|
|
{
|
|
|
|
if (src.DeallocateOnRelease)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue(
|
|
|
|
"Attempted to copy a storage array that needs deallocation. "
|
|
|
|
"This is disallowed to prevent complications with deallocation.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
StorageBasicBase StorageBasicBase::operator=(const StorageBasicBase& src)
|
|
|
|
{
|
|
|
|
if (src.DeallocateOnRelease)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue(
|
|
|
|
"Attempted to copy a storage array that needs deallocation. "
|
|
|
|
"This is disallowed to prevent complications with deallocation.");
|
|
|
|
}
|
|
|
|
|
|
|
|
this->ReleaseResources();
|
|
|
|
this->Array = src.Array;
|
|
|
|
this->AllocatedByteSize = src.AllocatedByteSize;
|
|
|
|
this->NumberOfValues = src.NumberOfValues;
|
|
|
|
this->DeallocateOnRelease = src.DeallocateOnRelease;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StorageBasicBase::ReleaseResources()
|
|
|
|
{
|
|
|
|
if (this->AllocatedByteSize > 0)
|
|
|
|
{
|
|
|
|
VTKM_ASSERT(this->Array != nullptr);
|
|
|
|
if (this->DeallocateOnRelease)
|
|
|
|
{
|
|
|
|
AllocatorType{}.free_memory(this->Array);
|
|
|
|
}
|
|
|
|
this->Array = nullptr;
|
|
|
|
this->AllocatedByteSize = 0;
|
|
|
|
this->NumberOfValues = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
VTKM_ASSERT(this->Array == nullptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void StorageBasicBase::AllocateValues(vtkm::Id numberOfValues, vtkm::UInt64 sizeOfValue)
|
|
|
|
{
|
|
|
|
if (numberOfValues < 0)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadAllocation("Cannot allocate an array with negative size.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that the number of bytes won't be more than a size_t can hold.
|
|
|
|
const size_t maxNumValues = std::numeric_limits<size_t>::max() / sizeOfValue;
|
|
|
|
if (static_cast<vtkm::UInt64>(numberOfValues) > maxNumValues)
|
|
|
|
{
|
|
|
|
throw ErrorBadAllocation("Requested allocation exceeds size_t capacity.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we are allocating less data, just shrink the array.
|
|
|
|
// (If allocation empty, drop down so we can deallocate memory.)
|
|
|
|
vtkm::UInt64 allocsize = static_cast<vtkm::UInt64>(numberOfValues) * sizeOfValue;
|
|
|
|
if ((allocsize <= this->AllocatedByteSize) && (numberOfValues > 0))
|
|
|
|
{
|
|
|
|
this->NumberOfValues = numberOfValues;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this->DeallocateOnRelease)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue("User allocated arrays cannot be reallocated.");
|
|
|
|
}
|
|
|
|
|
|
|
|
this->ReleaseResources();
|
|
|
|
|
|
|
|
if (numberOfValues > 0)
|
|
|
|
{
|
|
|
|
this->Array = AllocatorType{}.allocate(allocsize, VTKM_ALLOCATION_ALIGNMENT);
|
|
|
|
this->AllocatedByteSize = allocsize;
|
|
|
|
this->NumberOfValues = numberOfValues;
|
|
|
|
if (this->Array == nullptr)
|
|
|
|
{
|
|
|
|
// Make sureour state is OK.
|
|
|
|
this->AllocatedByteSize = 0;
|
|
|
|
this->NumberOfValues = 0;
|
|
|
|
throw vtkm::cont::ErrorBadAllocation("Could not allocate basic control array.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ReleaseResources should have already set NumberOfValues to 0.
|
|
|
|
VTKM_ASSERT(this->NumberOfValues == 0);
|
|
|
|
VTKM_ASSERT(this->AllocatedByteSize == 0);
|
|
|
|
}
|
|
|
|
this->DeallocateOnRelease = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void StorageBasicBase::Shrink(vtkm::Id numberOfValues)
|
|
|
|
{
|
|
|
|
if (numberOfValues > this->NumberOfValues)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue("Shrink method cannot be used to grow array.");
|
|
|
|
}
|
|
|
|
|
|
|
|
this->NumberOfValues = numberOfValues;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* StorageBasicBase::GetBasePointer() const
|
|
|
|
{
|
|
|
|
return this->Array;
|
|
|
|
}
|
|
|
|
|
|
|
|
void* StorageBasicBase::GetEndPointer(vtkm::Id numberOfValues, vtkm::UInt64 sizeOfValue) const
|
|
|
|
{
|
|
|
|
VTKM_ASSERT(this->NumberOfValues == numberOfValues);
|
|
|
|
if (!this->Array)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto p = static_cast<vtkm::UInt8*>(this->Array);
|
|
|
|
auto offset = static_cast<vtkm::UInt64>(this->NumberOfValues) * sizeOfValue;
|
|
|
|
return static_cast<void*>(p + offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* StorageBasicBase::GetCapacityPointer() const
|
|
|
|
{
|
|
|
|
if (!this->Array)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
auto v = static_cast<vtkm::UInt8*>(this->Array) + AllocatedByteSize;
|
|
|
|
return static_cast<void*>(v);
|
|
|
|
}
|
|
|
|
|
2016-12-19 13:58:12 +00:00
|
|
|
template class VTKM_CONT_EXPORT Storage<char, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Int8, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::UInt8, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Int16, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::UInt16, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Int32, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::UInt32, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Int64, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::UInt64, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Float32, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Float64, StorageTagBasic>;
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Int64, 2>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Int32, 2>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float32, 2>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float64, 2>, StorageTagBasic>;
|
2016-12-19 13:58:12 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Int64, 3>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Int32, 3>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float32, 3>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float64, 3>, StorageTagBasic>;
|
2016-12-19 13:58:12 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<char, 4>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<Int8, 4>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<UInt8, 4>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float32, 4>, StorageTagBasic>;
|
|
|
|
template class VTKM_CONT_EXPORT Storage<vtkm::Vec<vtkm::Float64, 4>, StorageTagBasic>;
|
2016-12-19 13:58:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont::internal
|