16 #include "LvArrayConfig.hpp" 24 #include <chai/ArrayManager.hpp> 41 static chai::ArrayManager & arrayManager = *chai::ArrayManager::getInstance();
54 if( space == MemorySpace::undefined )
56 if( space == MemorySpace::host )
58 #if defined(LVARRAY_USE_CUDA) 59 if( space == MemorySpace::cuda || space == MemorySpace::hip )
63 LVARRAY_ERROR(
"Unrecognized memory space " << static_cast< int >( space ) );
74 if( space == chai::NONE )
75 return MemorySpace::undefined;
76 if( space == chai::CPU )
77 return MemorySpace::host;
78 #if defined(LVARRAY_USE_CUDA) 79 if( space == chai::GPU )
80 return MemorySpace::cuda;
83 LVARRAY_ERROR(
"Unrecognized execution space " << static_cast< int >( space ) );
85 return MemorySpace::undefined;
103 template<
typename T >
112 constexpr
static bool hasShallowCopy =
true;
124 m_pointer( nullptr ),
126 m_pointerRecord( nullptr )
135 m_pointer( nullptr ),
137 m_pointerRecord( new chai::PointerRecord{} )
139 m_pointerRecord->m_size = 0;
142 for(
int space = chai::CPU; space < chai::NUM_EXECUTION_SPACES; ++space )
144 m_pointerRecord->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space ) );
154 ChaiBuffer( std::initializer_list< MemorySpace >
const & spaces,
155 std::initializer_list< umpire::Allocator >
const & allocators ):
156 m_pointer( nullptr ),
158 m_pointerRecord( new chai::PointerRecord{} )
160 m_pointerRecord->m_size = 0;
165 for(
int space = chai::CPU; space < chai::NUM_EXECUTION_SPACES; ++space )
167 m_pointerRecord->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space ) );
170 for( std::size_t i = 0; i < spaces.size(); ++i )
172 m_pointerRecord->m_allocators[ internal::toChaiExecutionSpace( spaces.begin()[ i ] ) ] = allocators.begin()[ i ].getId();
184 m_pointer( src.m_pointer ),
185 m_capacity( src.m_capacity ),
186 m_pointerRecord( src.m_pointerRecord )
188 #if defined(LVARRAY_USE_CUDA) && !defined(__CUDA_ARCH__) 189 move( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ),
true );
202 m_pointer( src.m_pointer ),
203 m_capacity( src.m_capacity ),
204 m_pointerRecord( src.m_pointerRecord )
206 #if defined(LVARRAY_USE_CUDA) && !defined(__CUDA_ARCH__) 207 moveNested( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ), size,
true );
219 m_pointer( src.m_pointer ),
220 m_capacity( src.m_capacity ),
221 m_pointerRecord( src.m_pointerRecord )
224 src.m_pointer =
nullptr;
225 src.m_pointerRecord =
nullptr;
233 template<
typename U >
236 m_pointer( reinterpret_cast< T * >( src.data() ) ),
237 m_capacity( typeManipulation::
convertSize< T, U >( src.capacity() ) ),
238 m_pointerRecord( &src.pointerRecord() )
264 m_pointer = src.m_pointer;
265 m_pointerRecord = src.m_pointerRecord;
268 src.m_pointer =
nullptr;
269 src.m_pointerRecord =
nullptr;
284 chai::PointerRecord *
const newRecord =
new chai::PointerRecord{};
285 newRecord->m_size = newCapacity *
sizeof( T );
286 newRecord->m_user_callback = m_pointerRecord->m_user_callback;
288 for(
int s = chai::CPU; s < chai::NUM_EXECUTION_SPACES; ++s )
290 newRecord->m_allocators[ s ] = m_pointerRecord->m_allocators[ s ];
293 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
295 internal::chaiLock.lock();
296 internal::getArrayManager().allocate( newRecord, chaiSpace );
297 internal::chaiLock.unlock();
299 T *
const newPointer =
static_cast< T *
>( newRecord->m_pointers[ chaiSpace ] );
303 LVARRAY_ERROR_IF_NE_MSG( space, MemorySpace::host,
"Calling reallocate with a non-zero current size is not yet supporeted for the GPU." );
304 std::ptrdiff_t
const overlapAmount =
std::min( newCapacity, size );
310 m_capacity = newCapacity;
311 m_pointer = newPointer;
312 m_pointerRecord = newRecord;
313 registerTouch( space );
323 std::lock_guard< std::mutex > lock( internal::chaiLock );
324 internal::getArrayManager().free( m_pointerRecord );
327 m_pointerRecord =
nullptr;
335 {
return m_capacity; }
342 {
return m_pointer; }
350 {
return *m_pointerRecord; }
358 template<
typename INDEX_TYPE >
361 {
return m_pointer[ i ]; }
373 #if defined(LVARRAY_USE_CUDA) 374 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
375 if( m_pointerRecord ==
nullptr ||
377 chaiSpace == chai::NONE )
return;
379 chai::ExecutionSpace
const prevSpace = m_pointerRecord->m_last_space;
381 if( prevSpace == chai::CPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch );
383 move( space, touch );
385 if( prevSpace == chai::GPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch );
401 #if defined(LVARRAY_USE_CUDA) 402 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
403 if( m_pointerRecord ==
nullptr ||
405 chaiSpace == chai::NONE )
return;
407 const_cast< T * &
>( m_pointer ) =
408 static_cast< T * >( internal::getArrayManager().move( const_cast< T_non_const * >( m_pointer ),
412 if( !std::is_const< T >::value && touch ) m_pointerRecord->m_touched[ chaiSpace ] =
true;
413 m_pointerRecord->m_last_space = chaiSpace;
424 {
return internal::toMemorySpace( m_pointerRecord->m_last_space ); }
433 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
434 m_pointerRecord->m_touched[ chaiSpace ] =
true;
435 m_pointerRecord->m_last_space = chaiSpace;
443 template<
typename U=ChaiBuffer< T > >
446 std::string
const typeString = system::demangleType< U >();
447 m_pointerRecord->m_user_callback =
448 [name, typeString]( chai::PointerRecord
const *
const record, chai::Action
const act, chai::ExecutionSpace
const s )
450 if( act == chai::ACTION_MOVE )
453 std::string
const paddedSize = std::string( 9 - size.size(),
' ' ) + size;
454 char const *
const spaceStr = ( s == chai::CPU ) ?
"HOST " :
"DEVICE";
455 LVARRAY_LOG(
"Moved " << paddedSize <<
" to the " << spaceStr <<
": " << typeString <<
" " << name );
471 template<
typename U=T_non_const >
472 std::enable_if_t< bufferManipulation::HasMemberFunction_move< U > >
475 if( space == MemorySpace::undefined )
return;
477 for( std::ptrdiff_t i = 0; i < size; ++i )
479 const_cast< T_non_const *
>( m_pointer )[ i ].move( space, touch );
489 template<
typename U=T_non_const >
490 std::enable_if_t< !bufferManipulation::HasMemberFunction_move< U > >
495 T * LVARRAY_RESTRICT m_pointer =
nullptr;
498 std::ptrdiff_t m_capacity = 0;
501 chai::PointerRecord * m_pointerRecord =
nullptr;
#define LVARRAY_UNUSED_VARIABLE(X)
Mark X as an unused variable, used to silence compiler warnings.
Definition: Macros.hpp:51
void free()
Free the data in the buffer but does not destroy any values.
Definition: ChaiBuffer.hpp:321
ChaiBuffer(std::initializer_list< MemorySpace > const &spaces, std::initializer_list< umpire::Allocator > const &allocators)
Construct a ChaiBuffer which uses the specific allocator for each space.
Definition: ChaiBuffer.hpp:154
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void uninitializedMove(T *const LVARRAY_RESTRICT dst, std::ptrdiff_t const size, T *const LVARRAY_RESTRICT src)
Move construct values from the source to the destination.
Definition: arrayManipulation.hpp:201
void setName(std::string const &name)
Set the name associated with this buffer which is used in the chai callback.
Definition: ChaiBuffer.hpp:444
MemorySpace getPreviousSpace() const
Definition: ChaiBuffer.hpp:423
T value_type
Alias for T used used in the bufferManipulation functions.
Definition: ChaiBuffer.hpp:109
void moveNested(MemorySpace const space, std::ptrdiff_t const size, bool const touch) const
Move the buffer to the given execution space, optionally touching it.
Definition: ChaiBuffer.hpp:371
Contains functions that interact with the system or runtime environment.
static std::mutex chaiLock
chai is not threadsafe so we use a lock to serialize access.
Definition: ChaiBuffer.hpp:46
LVARRAY_HOST_DEVICE ChaiBuffer(ChaiBuffer const &src, std::ptrdiff_t const size)
Copy constructor.
Definition: ChaiBuffer.hpp:201
std::ptrdiff_t m_capacity
The size of the allocation.
Definition: ChaiBuffer.hpp:498
constexpr LVARRAY_HOST_DEVICE std::enable_if_t<(sizeof(T)<=sizeof(U)), INDEX_TYPE > convertSize(INDEX_TYPE const numU)
Convert a number of values of type U to a number of values of type T.
Definition: typeManipulation.hpp:476
Contains templates useful for type manipulation.
#define LVARRAY_ERROR_IF_NE_MSG(lhs, rhs, msg)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:305
chai::ExecutionSpace toChaiExecutionSpace(MemorySpace const space)
Definition: ChaiBuffer.hpp:52
Implements the Buffer interface using CHAI.
Definition: ChaiBuffer.hpp:104
LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR ChaiBuffer & operator=(ChaiBuffer const &src)
Copy assignment operator.
Definition: ChaiBuffer.hpp:247
LVARRAY_HOST_DEVICE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
Definition: math.hpp:358
#define LVARRAY_LOG(...)
Print the expression.
Definition: Macros.hpp:77
T *LVARRAY_RESTRICT m_pointer
A pointer to the data.
Definition: ChaiBuffer.hpp:495
void move(MemorySpace const space, bool const touch) const
Move the buffer to the given execution space, optionally touching it.
Definition: ChaiBuffer.hpp:399
LVARRAY_HOST_DEVICE ChaiBuffer(ChaiBuffer const &src)
Copy constructor.
Definition: ChaiBuffer.hpp:183
MemorySpace toMemorySpace(chai::ExecutionSpace const space)
Definition: ChaiBuffer.hpp:72
chai::ArrayManager & getArrayManager()
Definition: ChaiBuffer.hpp:39
chai::PointerRecord * m_pointerRecord
A pointer to the chai PointerRecord, keeps track of the memory space information. ...
Definition: ChaiBuffer.hpp:501
Contains functions for manipulating buffers.
void reallocate(std::ptrdiff_t const size, MemorySpace const space, std::ptrdiff_t const newCapacity)
Reallocate the buffer to the new capacity.
Definition: ChaiBuffer.hpp:281
#define LVARRAY_ERROR(MSG)
Abort execution.
Definition: Macros.hpp:143
LVARRAY_HOST_DEVICE constexpr T & operator[](INDEX_TYPE const i) const
Definition: ChaiBuffer.hpp:360
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void free(BUFFER &buf, std::ptrdiff_t const size)
Destroy the values in the buffer and free it's memory.
Definition: bufferManipulation.hpp:188
camp::resources::Platform MemorySpace
an alias for camp::resources::Platform.
Definition: bufferManipulation.hpp:31
Contains functions for manipulating a contiguous array of values.
ChaiBuffer(bool)
Constructor for creating an empty Buffer.
Definition: ChaiBuffer.hpp:134
The top level namespace.
Definition: Array.hpp:24
LVARRAY_HOST_DEVICE constexpr std::ptrdiff_t capacity() const
Definition: ChaiBuffer.hpp:334
std::remove_const_t< T > T_non_const
An alias for the non const version of T.
Definition: ChaiBuffer.hpp:115
Contains a bunch of macro definitions.
LVARRAY_HOST_DEVICE constexpr ChaiBuffer()
Default constructor, creates an uninitialized ChaiBuffer.
Definition: ChaiBuffer.hpp:123
DISABLE_HD_WARNING LVARRAY_HOST_DEVICE void destroy(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size)
Destory the values in the array.
Definition: arrayManipulation.hpp:152
LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR ChaiBuffer & operator=(ChaiBuffer &&src)
Move assignment operator.
Definition: ChaiBuffer.hpp:261
std::enable_if_t< bufferManipulation::HasMemberFunction_move< U > > moveInnerData(MemorySpace const space, std::ptrdiff_t const size, bool const touch) const
Move inner allocations to the memory space space.
Definition: ChaiBuffer.hpp:473
#define LVARRAY_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:321
LVARRAY_HOST_DEVICE constexpr ChaiBuffer(ChaiBuffer< U > const &src)
Create a shallow copy of src but with a different type.
Definition: ChaiBuffer.hpp:235
LVARRAY_HOST_DEVICE constexpr ChaiBuffer(ChaiBuffer &&src)
Move constructor.
Definition: ChaiBuffer.hpp:218
std::enable_if_t< !bufferManipulation::HasMemberFunction_move< U > > moveInnerData(MemorySpace const, std::ptrdiff_t const, bool const) const
Move inner allocations to the memory space space.
Definition: ChaiBuffer.hpp:491
LVARRAY_HOST_DEVICE constexpr T * data() const
Definition: ChaiBuffer.hpp:341
constexpr void registerTouch(MemorySpace const space) const
Touch the buffer in the given space.
Definition: ChaiBuffer.hpp:431
std::string calculateSize(size_t const bytes)
Definition: system.cpp:406
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:549
LVARRAY_HOST_DEVICE constexpr chai::PointerRecord & pointerRecord() const
Return a reference to the associated CHAI PointerRecord.
Definition: ChaiBuffer.hpp:349