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 )
62 #if defined(LVARRAY_USE_HIP) 63 if( space == MemorySpace::hip )
67 LVARRAY_ERROR(
"Unrecognized memory space " << static_cast< int >( space ) );
78 if( space == chai::NONE )
79 return MemorySpace::undefined;
80 if( space == chai::CPU )
81 return MemorySpace::host;
82 #if defined(LVARRAY_USE_CUDA) 83 if( space == chai::GPU )
84 return MemorySpace::cuda;
86 #if defined(LVARRAY_USE_HIP) 87 if( space == chai::GPU )
88 return MemorySpace::hip;
91 LVARRAY_ERROR(
"Unrecognized execution space " << static_cast< int >( space ) );
93 return MemorySpace::undefined;
111 template<
typename T >
120 constexpr
static bool hasShallowCopy =
true;
132 m_pointer( nullptr ),
134 m_pointerRecord( nullptr )
145 m_pointer( nullptr ),
147 #if !defined(LVARRAY_DEVICE_COMPILE)
148 , m_pointerRecord( new chai::PointerRecord{} )
150 , m_pointerRecord(
nullptr )
153 #if defined(LVARRAY_DEVICE_COMPILE) 154 LVARRAY_ERROR(
"Creating a new ChaiBuffer on device is not supported. This is often the result of capturing an array on device instead of a view." );
156 m_pointerRecord->m_size = 0;
159 for(
int space = chai::CPU; space < chai::NUM_EXECUTION_SPACES; ++space )
161 m_pointerRecord->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space ) );
174 ChaiBuffer( std::initializer_list< MemorySpace >
const & spaces,
175 std::initializer_list< umpire::Allocator >
const & allocators ):
176 m_pointer( nullptr ),
178 #if !defined(LVARRAY_DEVICE_COMPILE)
179 , m_pointerRecord( new chai::PointerRecord{} )
181 , m_pointerRecord(
nullptr )
184 #if defined(LVARRAY_DEVICE_COMPILE) 185 LVARRAY_ERROR(
"Creating a new ChaiBuffer on device is not supported." );
189 m_pointerRecord->m_size = 0;
194 for(
int space = chai::CPU; space < chai::NUM_EXECUTION_SPACES; ++space )
196 m_pointerRecord->m_allocators[ space ] = internal::getArrayManager().getAllocatorId( chai::ExecutionSpace( space ) );
199 for( std::size_t i = 0; i < spaces.size(); ++i )
201 m_pointerRecord->m_allocators[ internal::toChaiExecutionSpace( spaces.begin()[ i ] ) ] = allocators.begin()[ i ].getId();
214 m_pointer( src.m_pointer ),
215 m_capacity( src.m_capacity ),
216 m_pointerRecord( src.m_pointerRecord )
218 #if defined(LVARRAY_USE_DEVICE) && !defined(LVARRAY_DEVICE_COMPILE) 219 move( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ),
true );
232 m_pointer( src.m_pointer ),
233 m_capacity( src.m_capacity ),
234 m_pointerRecord( src.m_pointerRecord )
236 #if defined(LVARRAY_USE_DEVICE) && !defined(LVARRAY_DEVICE_COMPILE) 237 moveNested( internal::toMemorySpace( internal::getArrayManager().getExecutionSpace() ), size,
true );
249 m_pointer( src.m_pointer ),
250 m_capacity( src.m_capacity ),
251 m_pointerRecord( src.m_pointerRecord )
254 src.m_pointer =
nullptr;
255 src.m_pointerRecord =
nullptr;
263 template<
typename U >
266 m_pointer( reinterpret_cast< T * >( src.data() ) ),
267 m_capacity( typeManipulation::
convertSize< T, U >( src.capacity() ) ),
268 m_pointerRecord( &src.pointerRecord() )
294 m_pointer = src.m_pointer;
295 m_pointerRecord = src.m_pointerRecord;
298 src.m_pointer =
nullptr;
299 src.m_pointerRecord =
nullptr;
315 std::ptrdiff_t
const newCapacity )
317 #if defined(LVARRAY_DEVICE_COMPILE) 324 chai::PointerRecord *
const newRecord =
new chai::PointerRecord{};
325 newRecord->m_size = newCapacity *
sizeof( T );
326 newRecord->m_user_callback = m_pointerRecord->m_user_callback;
328 for(
int s = chai::CPU; s < chai::NUM_EXECUTION_SPACES; ++s )
330 newRecord->m_allocators[ s ] = m_pointerRecord->m_allocators[ s ];
333 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
335 internal::chaiLock.lock();
336 internal::getArrayManager().allocate( newRecord, chaiSpace );
337 internal::chaiLock.unlock();
339 T *
const newPointer =
static_cast< T *
>( newRecord->m_pointers[ chaiSpace ] );
343 LVARRAY_ERROR_IF_NE_MSG( space, MemorySpace::host,
"Calling reallocate with a non-zero current size is not yet supporeted for the GPU." );
344 std::ptrdiff_t
const overlapAmount =
std::min( newCapacity, size );
350 m_capacity = newCapacity;
351 m_pointer = newPointer;
352 m_pointerRecord = newRecord;
353 registerTouch( space );
365 #if defined(LVARRAY_DEVICE_COMPILE) 366 LVARRAY_ERROR(
"Deallocation from device is not supported." );
368 std::lock_guard< std::mutex > lock( internal::chaiLock );
369 internal::getArrayManager().free( m_pointerRecord );
372 m_pointerRecord =
nullptr;
381 {
return m_capacity; }
388 {
return m_pointer; }
396 {
return *m_pointerRecord; }
404 template<
typename INDEX_TYPE >
407 {
return m_pointer[ i ]; }
419 #if defined(LVARRAY_USE_CUDA) || defined(LVARRAY_USE_HIP ) 420 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
421 if( m_pointerRecord ==
nullptr ||
423 chaiSpace == chai::NONE )
return;
425 chai::ExecutionSpace
const prevSpace = m_pointerRecord->m_last_space;
427 if( prevSpace == chai::CPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch );
429 move( space, touch );
431 if( prevSpace == chai::GPU && prevSpace != chaiSpace ) moveInnerData( space, size, touch );
447 #if defined(LVARRAY_USE_CUDA) || defined(LVARRAY_USE_HIP) 448 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
449 if( m_pointerRecord ==
nullptr ||
451 chaiSpace == chai::NONE )
return;
453 auto & am = internal::getArrayManager();
454 const_cast< T * &
>( m_pointer ) =
455 static_cast< T * >( am.move( const_cast< T_non_const * >( m_pointer ), m_pointerRecord, chaiSpace ) );
457 if( !std::is_const< T >::value && touch ) m_pointerRecord->m_touched[ chaiSpace ] =
true;
458 m_pointerRecord->m_last_space = chaiSpace;
469 {
return internal::toMemorySpace( m_pointerRecord->m_last_space ); }
478 chai::ExecutionSpace
const chaiSpace = internal::toChaiExecutionSpace( space );
479 m_pointerRecord->m_touched[ chaiSpace ] =
true;
480 m_pointerRecord->m_last_space = chaiSpace;
488 template<
typename U=ChaiBuffer< T > >
491 std::string
const typeString = system::demangleType< U >();
492 m_pointerRecord->m_user_callback =
493 [name, typeString]( chai::PointerRecord
const *
const record, chai::Action
const act, chai::ExecutionSpace
const s )
495 if( act == chai::ACTION_MOVE )
498 std::string
const paddedSize = std::string( 9 - size.size(),
' ' ) + size;
499 char const *
const spaceStr = ( s == chai::CPU ) ?
"HOST " :
"DEVICE";
500 LVARRAY_LOG(
"Moved " << paddedSize <<
" to the " << spaceStr <<
": " << typeString <<
" " << name );
516 template<
typename U=T_non_const >
517 std::enable_if_t< bufferManipulation::HasMemberFunction_move< U > >
520 if( space == MemorySpace::undefined )
return;
522 for( std::ptrdiff_t i = 0; i < size; ++i )
524 const_cast< T_non_const *
>( m_pointer )[ i ].move( space, touch );
534 template<
typename U=T_non_const >
535 std::enable_if_t< !bufferManipulation::HasMemberFunction_move< U > >
540 T * LVARRAY_RESTRICT m_pointer =
nullptr;
543 std::ptrdiff_t m_capacity = 0;
546 chai::PointerRecord * m_pointerRecord =
nullptr;
#define LVARRAY_UNUSED_VARIABLE(X)
Mark X as an unused variable, used to silence compiler warnings.
Definition: Macros.hpp:79
LVARRAY_HOST_DEVICE 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:313
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:489
MemorySpace getPreviousSpace() const
Definition: ChaiBuffer.hpp:468
T value_type
Alias for T used used in the bufferManipulation functions.
Definition: ChaiBuffer.hpp:117
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:417
LVARRAY_HOST_DEVICE void free()
Free the data in the buffer but does not destroy any values.
Definition: ChaiBuffer.hpp:363
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:231
std::ptrdiff_t m_capacity
The size of the allocation.
Definition: ChaiBuffer.hpp:543
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
LVARRAY_HOST_DEVICE LVARRAY_FORCE_INLINE constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > min(T const a, T const b)
Definition: math.hpp:362
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:344
chai::ExecutionSpace toChaiExecutionSpace(MemorySpace const space)
Definition: ChaiBuffer.hpp:52
Implements the Buffer interface using CHAI.
Definition: ChaiBuffer.hpp:112
LVARRAY_HOST_DEVICE LVARRAY_INTEL_CONSTEXPR ChaiBuffer & operator=(ChaiBuffer const &src)
Copy assignment operator.
Definition: ChaiBuffer.hpp:277
#define LVARRAY_LOG(...)
Print the expression.
Definition: Macros.hpp:105
T *LVARRAY_RESTRICT m_pointer
A pointer to the data.
Definition: ChaiBuffer.hpp:540
void move(MemorySpace const space, bool const touch) const
Move the buffer to the given execution space, optionally touching it.
Definition: ChaiBuffer.hpp:445
LVARRAY_HOST_DEVICE ChaiBuffer(ChaiBuffer const &src)
Copy constructor.
Definition: ChaiBuffer.hpp:213
MemorySpace toMemorySpace(chai::ExecutionSpace const space)
Definition: ChaiBuffer.hpp:76
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:546
Contains functions for manipulating buffers.
#define LVARRAY_ERROR(MSG)
Abort execution.
Definition: Macros.hpp:176
LVARRAY_HOST_DEVICE constexpr T & operator[](INDEX_TYPE const i) const
Definition: ChaiBuffer.hpp:406
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.
LVARRAY_HOST_DEVICE 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:174
The top level namespace.
Definition: Array.hpp:24
LVARRAY_HOST_DEVICE constexpr std::ptrdiff_t capacity() const
Definition: ChaiBuffer.hpp:380
std::remove_const_t< T > T_non_const
An alias for the non const version of T.
Definition: ChaiBuffer.hpp:123
Contains a bunch of macro definitions.
LVARRAY_HOST_DEVICE constexpr ChaiBuffer()
Default constructor, creates an uninitialized ChaiBuffer.
Definition: ChaiBuffer.hpp:131
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:291
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:518
#define LVARRAY_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:360
LVARRAY_HOST_DEVICE constexpr ChaiBuffer(ChaiBuffer< U > const &src)
Create a shallow copy of src but with a different type.
Definition: ChaiBuffer.hpp:265
LVARRAY_HOST_DEVICE ChaiBuffer(bool)
Constructor for creating an empty Buffer.
Definition: ChaiBuffer.hpp:144
LVARRAY_HOST_DEVICE constexpr ChaiBuffer(ChaiBuffer &&src)
Move constructor.
Definition: ChaiBuffer.hpp:248
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:536
LVARRAY_HOST_DEVICE constexpr T * data() const
Definition: ChaiBuffer.hpp:387
constexpr void registerTouch(MemorySpace const space) const
Touch the buffer in the given space.
Definition: ChaiBuffer.hpp:476
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:600
LVARRAY_HOST_DEVICE constexpr chai::PointerRecord & pointerRecord() const
Return a reference to the associated CHAI PointerRecord.
Definition: ChaiBuffer.hpp:395