Full GPU support for axom::Array#695
Conversation
agcapps
left a comment
There was a problem hiding this comment.
This is very good, Josh. I had a few questions, one of which (mismatch of memory space template parameter with constructor-specified allocator) may need more documentation or testing. I think I'm ready to approve once you've clarified those things.
src/axom/core/ArrayBase.hpp
Outdated
| * This abstraction is not implemented using Umpire's MemoryResourceType enum | ||
| * in order to also include a "Dynamic" option as a default template parameter | ||
| * for Array-like types |
|
And thank you for the link to the branch's docs on readthedocs. That is very helpful when reviewing documentation. |
Co-authored-by: Arlie Capps <48997041+agcapps@users.noreply.github.com>
| * \brief Exchanges the contents of this Array with the other. | ||
| */ | ||
| void swap(Array<T, DIM>& other); | ||
| void swap(Array<T, DIM, SPACE>& other); |
There was a problem hiding this comment.
Can this be extended to accept Array other from other memory spaces as well?
There was a problem hiding this comment.
I can add a swap function between memory spaces but I'd be curious to hear what some use cases might be for this - in the general case you'd have to copy both sets of data between memory spaces, so I think the only thing you'd really be swapping are the housekeeping/metadata variables.
There was a problem hiding this comment.
It might be useful for memory spaces that are compatible.
E.g. a Dynamic space that happens to be device memory (via umpire) and a Device space ?
| : ArrayBase<T, DIM, Array<T, DIM, SPACE>>( | ||
| static_cast<const ArrayBase<T, DIM, Array<T, DIM, SPACE>>&>(other)) | ||
| , m_allocator_id(SPACE == MemorySpace::Dynamic | ||
| ? allocator_id |
There was a problem hiding this comment.
What if allocator_id is from the correct memory space, but a different pool?
There was a problem hiding this comment.
I'm not an Umpire expert by any means but I believe in this case we'd have to do some introspection on the allocator to try to track down its "parent allocator"?
kennyweiss
left a comment
There was a problem hiding this comment.
Thanks @joshessman-llnl -- this is really nice and highly anticipated!
Please see my comments for some minor suggestions/corrections.
| #ifdef AXOM_USE_UMPIRE | ||
| // If we have Umpire, we can try and see what space the pointer is allocated in | ||
| // Probably not worth checking this if SPACE != Dynamic, we *could* error out | ||
| // if e.g., the user gives a host pointer to ArrayView<T, DIM, Device>, but even | ||
| // Thrust doesn't guard against this. | ||
|
|
||
| // FIXME: Is it worth trying to get rid of this at compile time? | ||
| // (using a workaround since we don't have "if constexpr") | ||
| if(SPACE == MemorySpace::Dynamic) | ||
| { | ||
| auto& rm = umpire::ResourceManager::getInstance(); | ||
| if(rm.hasAllocator(data)) | ||
| { | ||
| auto alloc = rm.getAllocator(data); | ||
| m_allocator_id = alloc.getId(); | ||
| } | ||
| } | ||
| #endif |
There was a problem hiding this comment.
Possible suggestion: Would it make sense to fold this into the getAllocatorID function for <SPACE == Dynamic> ?
There was a problem hiding this comment.
I'm probably missing something but I'm not clear on how getAllocatorID comes into play here - were you envisioning an overload getAllocatorID(T* ptr) that encapsulates the pointer introspection?
| // _iteration_end | ||
| } | ||
|
|
||
| #ifdef __CUDACC__ |
There was a problem hiding this comment.
Heads-up @bmhan12 -- we'll want to extend this example to support hip
src/axom/core/ArrayBase.hpp
Outdated
| /// \brief Translates between the MemorySpace enum and Umpire allocator IDs | ||
| template <MemorySpace SPACE> | ||
| inline int getAllocatorID(); | ||
|
|
There was a problem hiding this comment.
Minor (optional): It might be useful to have a utility function of the form:
bool areSpacesCompatible(MemorySpace space1, MemorySpace space2);And possibly also:
#ifdef AXOM_USE_UMPIRE
bool areSpacesCompatible(MemorySpace SPACE, int allocatorID);
#endifThere was a problem hiding this comment.
I can understand the utility of the second function (in particular, relating to @kanye-quest's comment about pooled allocators and also converting/swapping from Dynamic -> another space) but I'm not sure where/how the first one would be used.
| blt_add_executable( | ||
| NAME ${exe_name}_cuda_on_ex | ||
| blt_add_executable( | ||
| NAME core_acceleration_cuda_on_ex |
21c5f45 to
37f6409
Compare
Summary
Arrayand in particularArrayViewto run on the GPUMemorySpaceparameter to allow users to optionally lock down the memory space of anArrayat compile-timeRemaining tasks (non-exhaustive):
New docs:
https://axom.readthedocs.io/en/feature-essman-gpu_array/axom/core/docs/sphinx/core_containers.html#using-arrays-in-gpu-code