-
Notifications
You must be signed in to change notification settings - Fork 59
Add a Resource Aware Pool #901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
153 commits
Select commit
Hold shift + click to select a range
e099fbc
initial changes for resource aware pool
kab163 04ade92
initial changes for resource aware pool
kab163 ced4817
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 5e6f904
making fixes because i know how to do stuff
kab163 cda63bf
silencing warnings
kab163 e9a13f2
rap updates
kab163 a1b852f
changes to make it almost work
kab163 1f38604
changes to make resource first, trying to integrate allocate_resource
kab163 309475d
fixing errors in example and adding work-around for rm.move deallocate
kab163 2ffa9b6
updates so far
kab163 86d28e5
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 1b3c4d5
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 9c9a85d
adding changes to make things work with hip
kab163 da06bf6
updating RAP, still WIP
kab163 96462a6
maybe this works...added more event tracking in deallocate
kab163 2f58838
getting rid of my_test and extra comments
kab163 3235865
adding new do_deallocate, adding resource to coalesce, etc
kab163 4c0c5dd
adding a way to reuse pending blocks if appliable
kab163 b6a7e58
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 11cb6c2
random fixes and changed map names
kab163 cbb6e76
fixing indentations, updating pending vector in release and deallocate
kab163 4dd75d3
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 9cd4321
updating how pending, free, and used states are updated and used
kab163 381d601
adding call to do_dealloc from allocate
kab163 a75c3ed
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 46f6c46
updates to RAP, trying to add helper functions
kab163 311f2b5
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 3aa2ce1
fixing bug in getResource
kab163 5a09235
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 cc7e0eb
updating test example
kab163 8f97b3e
updating checks, adding todo notes
kab163 39ea9ac
Apply style updates
d288eea
adding doc page
kab163 b107c82
edits to docs page
kab163 fcd2833
name update
kab163 9ee8716
adding resource check in deallocate and fixing hip errors
kab163 0443888
Apply style updates
67c432d
updating the way we handle calling deallocate with no resource
kab163 830388c
update to docs
kab163 95d24e6
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 12114e3
Apply style updates
b8ce172
adding a to_string method for resources for debugging and logging info
kab163 be50f1c
fixing merge
kab163 ed1e6e0
Apply style updates
cb28ba4
adding test
kab163 8f30b00
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 3ebb0c2
Apply style updates
d69413c
updating test and fixing a few bugs
kab163 d6053b2
fixing merge
kab163 0a65307
Apply style updates
3f5a021
removing cuda dependency not needed
kab163 bc4972d
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 238da8a
adding test to make test
kab163 7efd602
fixing bugs in rap test
kab163 c128a18
Apply style updates
b56d2df
updates to example
kab163 8500d8c
updating merge
kab163 e50d947
hackathon updates
kab163 17c2e71
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 67969a3
fixing merge
kab163 55721ac
making example simpler and fixing cmake
kab163 0955ad7
Apply style updates
3a6f2ee
updating docs
kab163 cd159b8
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 0a74bfd
updates to getResource, RAP header, and commenting out events still
kab163 262e5a5
Apply style updates
1f28000
Merge branch 'develop' of https://github.com/LLNL/Umpire into task/ka…
kab163 8c0a53c
updates to cmake
kab163 3ddd233
trying to get CI to pass
kab163 a1d379b
adding docs, fixing ci errors
kab163 60f8f52
more fixes to pass CI
kab163 380d29e
Apply style updates
edf478a
fixing docs
kab163 30c90da
Merge branch 'task/kab163/resource-aware-pool' of https://github.com/…
kab163 6ed786b
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 4acbadb
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 267780a
not using sycl with RAP yet
kab163 a3a8e26
fixing hip errors
kab163 b3d2138
fixing mem leak
kab163 857cf35
trying to resolve hip error
kab163 f8230f2
trying to resolve clock issue
kab163 776d7bb
trying to resolve mem leak
kab163 69a600e
Apply style updates
912a5c0
Merge branch 'develop' of github.com:LLNL/Umpire into task/kab163/res…
kab163 bac0c83
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 50816bd
Merge branch 'develop' of https://github.com/LLNL/Umpire into task/ka…
kab163 0f0b700
trying to fix mem leak in test
kab163 6582279
Apply style updates
110a7f3
temp commit to do debugging
kab163 96214c5
Merge branch 'develop' of https://github.com/LLNL/Umpire into task/ka…
kab163 e034448
Merge branch 'task/kab163/resource-aware-pool' of https://github.com/…
kab163 7e5c173
Apply style updates
b71e970
moving location of setting chunk->free
kab163 c8d7aff
Merge branch 'task/kab163/resource-aware-pool' of https://github.com/…
kab163 812f2d4
trying to resolve mem leaks
kab163 d01df3a
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 d2c58d1
fixing mem leak
kab163 a372ac6
Apply style updates
6b1cfbf
merging with develop
kab163 d96e150
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 244bee4
updates to RAP
kab163 15168d1
tester benchmark
kab163 f0cc90e
Apply style updates
37ad840
updating temp benchmark
kab163 09cb0cb
temp debug statements
kab163 7c33d96
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 d432427
Apply style updates
afb809f
merging with develop
kab163 426753d
Merge branch 'task/kab163/resource-aware-pool' of https://github.com/…
kab163 c1fae83
updates to RAP class
kab163 0824050
merging with myself
kab163 d28220f
Apply style updates
1bb28aa
fixing bug in pending status tracking
kab163 5e9b122
Apply style updates
6ede374
fixing another bug
kab163 1956af8
Apply style updates
c79b088
fixing benchmark and final fixes to rap class
kab163 3f4792e
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 dd88e46
in progress trying to add events for allocate and deallocate with res…
kab163 7601037
Apply style updates
9ee6b00
fixing events
kab163 9643dd8
fixing sqlite events
kab163 226984f
making sure name for shared memory allocator is string so example com…
kab163 8748e69
Merge branch 'task/kab163/resource-aware-pool' of https://github.com/…
kab163 feb758d
Update docs/sphinx/cookbook/resource_aware_pool.rst
kab163 ac71b4e
Update docs/sphinx/cookbook/resource_aware_pool.rst
kab163 b52e54f
Fixing another docs typo
kab163 a028234
Update resource_aware_pool.rst
kab163 ee56eea
implementing changes from review
kab163 9141211
Apply style updates
3c4e4d0
renaming example and cleaning up
kab163 64939d0
making getResource and getNumPending private
kab163 4be2f36
Apply style updates
b47e0c3
adding aligned_size and aligned_highwatermark_size stuff
kab163 d6798e4
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 8ae1cbe
making benchmark work for both cuda and hip
kab163 347fc2d
fixing test and adding to docs
kab163 98bbbbb
changing m_pending to a list and adding Release test
kab163 0024944
cleaning up pending list check in allocate
kab163 7fa13e8
revisions from review
kab163 e47f80a
Apply style updates
88558e0
more changes from review
kab163 eaf2d2a
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 6aea1fe
changing order of allocate and deallocate functions so resource is last
kab163 7d4d668
Apply style updates
8345094
adding default resource when not specified
kab163 e9eccf5
Apply style updates
afd4cfd
fixing test
kab163 262308c
update docs
kab163 04095da
adding Host as the default resource, adding to docs, release only rel…
kab163 cc1c824
Apply style updates
b7dbac4
moving do_deallocate call for finished pending chunks to coalesce
kab163 ca4c55f
Merge branch 'task/kab163/resource-aware-pool' of github.com:LLNL/Ump…
kab163 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,178 @@ | ||
| #include <stdio.h> | ||
| #include <math.h> | ||
| #include <iostream> | ||
|
|
||
| #include "camp/camp.hpp" | ||
| #include "umpire/ResourceManager.hpp" | ||
| #include "umpire/Umpire.hpp" | ||
| #include "umpire/strategy/QuickPool.hpp" | ||
| #include "umpire/strategy/ResourceAwarePool.hpp" | ||
|
|
||
| using namespace camp::resources; | ||
|
|
||
| #if defined(UMPIRE_ENABLE_CUDA) | ||
| using resource_type = Cuda; | ||
| #elif defined(UMPIRE_ENABLE_HIP) | ||
| using resource_type = Hip; | ||
| #endif | ||
|
|
||
| constexpr int ITER = 5; | ||
| constexpr int NUM = 2048; | ||
| const int NUM_PER_BLOCK = 256; | ||
| const int NUM_BLOCKS = NUM/NUM_PER_BLOCK; | ||
|
|
||
| using clock_value_t = long long; | ||
|
|
||
| __device__ clock_value_t my_clock() | ||
| { | ||
| return clock64(); | ||
| } | ||
|
|
||
| __device__ void sleep(clock_value_t sleep_cycles) | ||
| { | ||
| clock_value_t start = my_clock(); | ||
| clock_value_t cycles_elapsed; | ||
| do { | ||
| cycles_elapsed = my_clock() - start; | ||
| } while (cycles_elapsed < sleep_cycles); | ||
| } | ||
|
|
||
| __global__ void do_sleep() | ||
| { | ||
| // Sleep in kernel in order to replicate data race | ||
| sleep(100000000); | ||
| } | ||
|
|
||
| __global__ void touch_data(double* data) | ||
| { | ||
| int id = blockIdx.x * blockDim.x + threadIdx.x; | ||
|
|
||
| if (id < NUM) { | ||
| data[id] = id; | ||
| } | ||
| } | ||
|
|
||
| __global__ void check_data(double* data) | ||
| { | ||
| int id = blockIdx.x * blockDim.x + threadIdx.x; | ||
|
|
||
| //Then error check that data[id] still == id | ||
| if (id < NUM) { | ||
| if (data[id] != id) | ||
| data[id] = -1; | ||
| } | ||
| } | ||
|
|
||
| __global__ void touch_data_again(double* data) | ||
| { | ||
| int id = blockIdx.x * blockDim.x + threadIdx.x; | ||
|
|
||
| if (id < NUM) { | ||
| data[id] = 8.76543210; | ||
| } | ||
| } | ||
|
|
||
| void QuickPool_check(umpire::Allocator quick_pool) | ||
| { | ||
| auto& rm = umpire::ResourceManager::getInstance(); | ||
| bool error{false}; | ||
|
|
||
| // Create hip streams | ||
| auto s1 = resource_type().get_stream(); | ||
| auto s2 = resource_type().get_stream(); | ||
|
|
||
| double* a = static_cast<double*>(quick_pool.allocate(NUM * sizeof(double))); | ||
|
|
||
| touch_data<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, s1>>>(a); | ||
| do_sleep<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, s1>>>(); | ||
| check_data<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, s1>>>(a); | ||
|
|
||
| quick_pool.deallocate(a); | ||
| a = static_cast<double*>(quick_pool.allocate(NUM * sizeof(double))); | ||
|
|
||
| touch_data_again<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, s2>>>(a); | ||
|
|
||
| double* b = static_cast<double*>(quick_pool.allocate(NUM * sizeof(double))); | ||
| resource_type().get_event().wait(); | ||
| rm.copy(b, a); | ||
kab163 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| b = static_cast<double*>(rm.move(b, rm.getAllocator("HOST"))); | ||
kab163 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| for (int i = 0; i < NUM; i++) { | ||
| if(b[i] == (-1)) { | ||
| error = true; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (error) { | ||
| std::cout << "Errors Found!" << std::endl; | ||
kab163 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } else { | ||
| std::cout << "Kernel succeeded! Expected result returned" << std::endl; | ||
| } | ||
|
|
||
| quick_pool.deallocate(a); | ||
| rm.deallocate(b); | ||
| } | ||
|
|
||
| void ResourceAwarePool_check(umpire::Allocator rap_pool) | ||
| { | ||
| // Create hip resources | ||
| resource_type d1, d2; | ||
| Resource r1{d1}, r2{d2}; | ||
|
|
||
| // ResourceAwarePool checks | ||
| auto& rm = umpire::ResourceManager::getInstance(); | ||
| bool error{false}; | ||
|
|
||
| for(int i = 0; i < ITER; i++) { | ||
| double* a = static_cast<double*>(rap_pool.allocate(NUM * sizeof(double), r1)); | ||
|
|
||
| touch_data<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, d1.get_stream()>>>(a); | ||
| do_sleep<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, d1.get_stream()>>>(); | ||
| check_data<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, d1.get_stream()>>>(a); | ||
|
|
||
| rap_pool.deallocate(a, r1); | ||
| a = static_cast<double*>(rap_pool.allocate(NUM * sizeof(double), r2)); | ||
|
|
||
| touch_data_again<<<NUM_BLOCKS, NUM_PER_BLOCK, 0, d2.get_stream()>>>(a); | ||
|
|
||
| double* b = static_cast<double*>(rap_pool.allocate(NUM * sizeof(double), r2)); | ||
| r2.get_event().wait(); | ||
| rm.copy(b, a); | ||
kab163 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| b = static_cast<double*>(rm.move(b, rm.getAllocator("HOST"))); | ||
|
|
||
| for (int i = 0; i < NUM; i++) { | ||
| if(b[i] == (-1)) { | ||
| error = true; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (error) { | ||
| std::cout << "Errors Found!" << std::endl; | ||
| } else { | ||
| std::cout << "Kernel succeeded! Expected result returned" << std::endl; | ||
| } | ||
|
|
||
| rap_pool.deallocate(a, r2); | ||
| rm.deallocate(b); | ||
| error = false; // reset to find any new errors in next iter | ||
| } | ||
| } | ||
|
|
||
| int main(int, char**) | ||
| { | ||
| auto& rm = umpire::ResourceManager::getInstance(); | ||
| auto quick_pool = rm.makeAllocator<umpire::strategy::QuickPool>("quick-pool", rm.getAllocator("UM")); | ||
| auto rap_pool = rm.makeAllocator<umpire::strategy::ResourceAwarePool>("rap-pool", rm.getAllocator("UM")); | ||
|
|
||
| std::cout<<"Checking QuickPool ...."<<std::endl; | ||
| QuickPool_check(quick_pool); | ||
|
|
||
| std::cout<<"Checking ResourceAwarePool ...."<<std::endl; | ||
| ResourceAwarePool_check(rap_pool); | ||
|
|
||
| std::cout<<"Done!"<<std::endl; | ||
| return 0; | ||
| } | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| .. _resource_aware_pool: | ||
|
|
||
| ============================= | ||
| Creating a Resource Aware Pool | ||
| ============================= | ||
|
|
||
| This recipe describes how to create and use an Umpire ``ResourceAwarePool``. This pool is somewhat advanced | ||
| so we also provide a bit of background on Camp resources which are used to track resources and events. | ||
|
|
||
| Camp Resources | ||
| -------------- | ||
|
|
||
| Umpire uses `Camp <https://github.com/LLNL/camp>`_ resources to keep track of "streams of execution". A single "stream of execution" | ||
| on the device corresponds to a single Camp device resource (e.g. a single cuda stream). | ||
| Similarly, when we are executing on the host, this | ||
| corresponds to a separate "stream of execution" and therefore a separate Camp host resource. | ||
|
|
||
| Typically, we deal with multiple Camp resources. This includes a single resource for the host and | ||
| one or more for the device, depending on how many (cuda, hip, etc.) streams we have in use. | ||
| While we can have multiple camp resources for the device (e.g. multiple cuda streams), | ||
| we can only have one resource for the host because the host only has one stream of execution. | ||
| Since we are dealing with Camp resources, we call this pool strategy the ``ResourceAwarePool``. | ||
|
|
||
| Generic vs. Specific Camp Resources | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Camp has two different types of Resources: generic and specific. A specific resource is created with: | ||
|
|
||
| .. code-block:: bash | ||
| camp::resources::Cuda c1; | ||
|
|
||
| This will create a Cuda (specific) resource. With ``c1`` we can call different methods like ``get_platform()`` | ||
| or ``get_stream()``. Parts of Umpire such as the Operations use these camp methods under the hood. On the | ||
| other hand, a generic resource is created with: | ||
|
|
||
| .. code-block:: bash | ||
| camp::resources::Resource r{c1}; | ||
|
|
||
| This way of creating a generic resource uses the specific resource created above, ``c1``, to constuct it. | ||
| We can also create a generic resource with: | ||
|
|
||
| .. code-blcok:: bash | ||
| camp::resources::Resource r{camp::resources::Cuda()}; | ||
|
|
||
| The ``ResourceAwarePool`` stores a generic camp resource, but since the compiler can implicitly convert a | ||
| specific resource to a generic resource and vice versa, you can use either kind of resource | ||
| with the ``ResourceAwarePool`` methods. The catch is that only the specific resource (``c1``) has a | ||
| method like ``get_stream()`` which would be needed when launching kernels - so we will be using the | ||
| specific resource in the examples below. | ||
|
|
||
| Throughout the rest of this documentation page, we will use a "camp resource" to refer to a "stream of | ||
| execution". If the camp resource is on the device, then we are referring to a device stream such | ||
| as a cuda stream or hip stream. | ||
|
|
||
| Using a Single Resource | ||
| ----------------------- | ||
|
|
||
| Umpire's strategies such as ``QuickPool`` and ``DynamicPoolList`` work very well | ||
| on the device when we are dealing with a single camp device resource. In the figure below, we have | ||
| the host resource which allocates memory (a\ :sub:`1`\), uses the memory in a kernel (k\ :sub:`1`\), then schedules | ||
| a deallocate (d\ :sub:`2`\). Then, the host immidiately reuses that memory for a different kernel (k\ :sub:`2`\). | ||
|
|
||
| .. image:: ./single_mem.png | ||
|
|
||
| In this scenario, there is no potential for a data race, since we are dealing with just one cuda stream | ||
| and kernels on a single stream execute sequentially. In other words, this scenario deals with only | ||
| one Camp device resource. In this type of scenario, there is no need for a ``ResourceAwarePool`` because | ||
| it would behave the same as your typical ``QuickPool``. | ||
|
|
||
| .. note:: A ``ResourceAwarePool`` with only one resource will behave the same as a ``QuickPool`` strategy. | ||
| We don't advise using the ``ResourceAwarePool`` with only one resource since it will have the added | ||
| overhead of the pending state (explained below). Instead, just use ``QuickPool`` if possible. | ||
|
|
||
| Using Multiple Resources | ||
| ------------------------ | ||
|
|
||
| When dealing with multiple camp device resources, there is a possibility for a data race if we allocate, use, and | ||
| schedule a deallocation on one stream and then try to reuse that memory immediately on another stream. | ||
| The figure below depicts that scenario. Note that the overlap in the kernels corresponds to a potential | ||
| data race. | ||
|
|
||
| .. image:: ./multi-mem.png | ||
|
|
||
| Umpire's ``ResourceAwarePool`` is designed to avoid any potential data races by making the resources | ||
| "aware" of the memory used by another resource. If resource ``r2`` needs to allocate memory, but that | ||
| memory is potentially still being used by another resource, ``r1``, then ``r2`` will use different | ||
| memory instead. To do that, the ``ResourceAwarePool`` introduces a "pending" state. | ||
|
|
||
| As soon as ``r1`` schedules a deallocation, that memory is marked as ``_``pending``_`` and is only available | ||
| for use by ``r1``. When the deallocation is complete, the ``_``pending``_`` marker is cleared, making that memory | ||
| available for use by other resources. So when ``r2`` needs an allocation, it first checks to see if the memory | ||
| is still ``_``pending``_``. If it is NOT ``_``pending``_``, it will reuse that memory, otherwise it will use a | ||
| different piece of memory instead. | ||
|
|
||
| The figure below illustrates the 3 states of a ``ResourceAwarePool``: free, used, and pending. | ||
|
|
||
| .. image:: ./states.png | ||
|
|
||
| Using a ResourceAwarePool | ||
| ------------------------- | ||
|
|
||
| In this example, we will review how to use the :class:`umpire::strategy::ResourceAwarePool` | ||
| strategy. You can create a ``ResourceAwarePool`` with the following code: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| auto& rm = umpire::ResourceManager::getInstance(); | ||
| auto pool = rm.makeAllocator<umpire::strategy::ResourceAwarePool>("rap-pool", rm.getAllocator("UM")); | ||
|
|
||
| Next, you will want to create camp resources. We use these camp resources to track events | ||
| on the resource. Below is an example of creating a camp resource for two device streams and the host. | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| using namespace camp::resources; | ||
| ... | ||
| Cuda d1, d2; //create (specific) Cuda resources, d1 for stream1, d2 for stream2 | ||
| Host h1; //create a (specific) Host resource | ||
|
|
||
| Then, to allocate memory with your ``ResourceAwarePool`` you can do the following: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| double* a = static_cast<double*>(pool.allocate(NUM_THREADS * sizeof(double), d1)); | ||
|
|
||
| Note that there is an extra parameter when using the ``allocate`` function. The second parameter is | ||
| the resource (``d1``) we want the allocated memory to be associated with. In other words, ``d1`` is | ||
| the device stream we want to launch the kernel on which will use that memory. | ||
|
|
||
| .. note:: | ||
| If allocate is called with no resource, then it will use the default Camp Host resource. | ||
|
|
||
| Next, be sure to launch the kernel using the correct stream. | ||
| Since we are using Camp resources, we use ``d1`` that we created above. For example: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| my_kernel<<NUM_BLOCKS, BLOCK_SIZE, 0, d1.get_stream()>>>(a, NUM_THREADS); | ||
|
|
||
| The kernel launch specifies the stream from the Cuda resource we created above. | ||
| To deallocate, use the following code: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| pool.deallocate(a, d1); | ||
|
|
||
| .. note:: | ||
| It can be hard to keep track of which resource corresponds to which pointer. If it is not feasible to keep track | ||
| of that, you can call ``pool.deallocate(ptr)`` as usual. However, this method will call the private ``getResource(ptr)`` | ||
| method on the ``ResourceAwarePool`` instance and then call the deallocate method with the correct resource. | ||
| Because of this overhead, it is recommended to include a resource with the deallocate method if possible. | ||
|
|
||
| Assuming you need to reallocate memory on ``a`` with ``d2``, you could then launch a second kernel with the second stream. For example: | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| a = static_cast<double*>(pool.allocate(NUM_THREADS * sizeof(double), d2)); | ||
| ... | ||
| my_other_kernel<<NUM_BLOCKS, BLOCK_SIZE, 0, d2.get_stream()>>>(a, NUM_THREADS); | ||
|
|
||
| Since we are using the ``ResourceAwarePool``, we will not cause a data race from trying to reuse that memory. If the | ||
| memory is still being used by ``d1`` by the time ``d2`` is requesting it, it will be in a ``_``pending``_`` state and thus | ||
| not resued by ``d2``. Instead, ``d2`` will be given a different piece of memory. | ||
|
|
||
| The ``ResourceAwarePool`` will also be useful for avoiding data races in a situation where host and device | ||
| share a single memory space. In the case of a single memory space, just having two or more camp resources, | ||
| whether host or device, will give us the potential for data races since memory can be visible by both host and device. | ||
|
|
||
| A full example of using the ``ResourceAwarePool`` can be seen below: | ||
|
|
||
| .. literalinclude:: ../../../examples/rap_example.cpp |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.