Hedgehog  3.1.0
A library to generate hybrid pipeline workflow systems
Loading...
Searching...
No Matches
abstract_cuda_task.h
Go to the documentation of this file.
1
2// NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the
3// software in any medium, provided that you keep intact this entire notice. You may improve, modify and create
4// derivative works of the software or any portion of the software, and you may copy and distribute such modifications
5// or works. Modified works should carry a notice stating that you changed the software and should note the date and
6// nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the
7// source of the software. NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND,
8// EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
9// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR
10// WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE
11// CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS
12// THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. You
13// are solely responsible for determining the appropriateness of using and distributing the software and you assume
14// all risks associated with its use, including but not limited to the risks and costs of program errors, compliance
15// with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of
16// operation. This software is not intended to be used in any situation where a failure could cause risk of injury or
17// damage to property. The software developed by NIST employees is not subject to copyright protection within the
18// United States.
19
20#ifndef HEDGEHOG_ABSTRACT_CUDA_TASK_H
21#define HEDGEHOG_ABSTRACT_CUDA_TASK_H
22#ifdef HH_USE_CUDA
23
24#include <cuda_runtime.h>
25#include <unordered_set>
26
27#include "abstract_task.h"
28#include "../../tools/cuda_debugging.h"
29
31namespace hh {
32
45template<size_t Separator, class ...AllTypes>
46class AbstractCUDATask : public AbstractTask<Separator, AllTypes...> {
47 private:
48 bool enablePeerAccess_ = false;
49 std::unordered_set<int> peerDeviceIds_ = {};
50 cudaStream_t stream_ = {};
51
52 public:
58 AbstractCUDATask(std::string const &name, size_t numberThreads, bool enablePeerAccess, bool automaticStart = false)
59 : AbstractTask<Separator, AllTypes...>(name, numberThreads, automaticStart),
61 this->coreTask()->printOptions().background({0x76, 0xb9, 0x00, 0xff});
62 this->coreTask()->printOptions().font({0xff, 0xff, 0xff, 0xff});
63 }
64
68 explicit AbstractCUDATask(std::string const name = "CudaTask", size_t numberThreads = 1) :
69 AbstractCUDATask<Separator, AllTypes...>(name, numberThreads, false, false) {};
70
75 : AbstractTask<Separator, AllTypes...>(std::shared_ptr<hh::core::CoreTask<Separator, AllTypes...>>(coreTask)),
77 this->coreTask()->printOptions().background({0x76, 0xb9, 0x00, 0xff});
78 this->coreTask()->printOptions().font({0xff, 0xff, 0xff, 0xff});
79 }
80
82 ~AbstractCUDATask() override {
83 if (this->memoryManager() != nullptr) {
84 checkCudaErrors(cudaSetDevice(this->memoryManager()->deviceId()));
85 }
86 }
87
90 void initialize() final {
91 int numGpus = 0;
92 int canAccess = 0;
93 checkCudaErrors(cudaGetDeviceCount(&numGpus));
94 assert(this->deviceId() < numGpus);
95 checkCudaErrors(cudaSetDevice(this->deviceId()));
96 checkCudaErrors(cudaStreamCreate(&stream_));
97
99 for (int i = 0; i < numGpus; ++i) {
100 if (i != this->deviceId()) {
101 checkCudaErrors(cudaDeviceCanAccessPeer(&canAccess, this->deviceId(), i));
102
103 if (canAccess) {
104 auto ret = cudaDeviceEnablePeerAccess(i, 0);
105 if (ret != cudaErrorPeerAccessAlreadyEnabled) {
106 checkCudaErrors(ret);
107 }
108 peerDeviceIds_.insert(i);
109 }
110 }
111 }
112 }
113 auto ret = cudaGetLastError();
114 if (ret != cudaErrorPeerAccessAlreadyEnabled) {
115 checkCudaErrors(ret);
116 }
117 this->initializeCuda();
118 }
119
123 void shutdown() final {
124 this->shutdownCuda();
125 checkCudaErrors(cudaStreamDestroy(stream_));
126 }
127
129 virtual void initializeCuda() {}
130
132 virtual void shutdownCuda() {}
133
136 bool enablePeerAccess() const { return enablePeerAccess_; }
137
140 cudaStream_t stream() const { return stream_; }
141
145 bool hasPeerAccess(int peerDeviceId) { return peerDeviceIds_.find(peerDeviceId) != peerDeviceIds_.end(); }
146
147};
148
149}
150#endif //HH_USE_CUDA
151#endif //HEDGEHOG_ABSTRACT_CUDA_TASK_H
#define checkCudaErrors(err)
Hedgehog main namespace.
Abstract Task specialized for CUDA computation.
AbstractCUDATask(std::string const &name, size_t numberThreads, bool enablePeerAccess, bool automaticStart=false)
AbstractCUDATask full constructor.
cudaStream_t stream_
CUDA stream linked to the task.
virtual void initializeCuda()
Virtual initialization step, where user defined data structure can be initialized.
bool enablePeerAccess_
Enable CUDA Peer Access through all CUDA devices available.
AbstractCUDATask(std::shared_ptr< hh::core::CoreTask< Separator, AllTypes... > > coreTask, bool enablePeerAccess)
Custom core task constructor.
cudaStream_t stream() const
Getter for CUDA task's stream.
~AbstractCUDATask() override
Default destructor.
virtual void shutdownCuda()
Virtual shutdown step, where user defined data structure can be destroyed.
bool hasPeerAccess(int peerDeviceId)
Accessor for peer access enabled for a specific device id.
void initialize() final
Initialize an AbstractCUDATask to bind it to a CUDA device, and do the peer access if enabled....
AbstractCUDATask(std::string const name="CudaTask", size_t numberThreads=1)
Main constructor for a AbstractCUDATask.
void shutdown() final
Shutdown an AbstractCUDATask to destroy the task's CUDA stream created during AbstractCUDATask::initi...
std::unordered_set< int > peerDeviceIds_
Sparse matrix of linked CUDA devices.
bool enablePeerAccess() const
Accessor for peer access choice.
Base node for computation.
std::shared_ptr< hh::core::CoreTask< Separator, AllTypes... > > const & coreTask() const
Accessor to the core task.
int deviceId()
Accessor to device id linked to the task (default 0 for CPU task)
size_t numberThreads() const
Number of threads accessor.
Definition: copyable.h:51
std::string name() const
Node's name accessor.
Definition: node.h:53
std::shared_ptr< hh::core::abstraction::NodeAbstraction > const & core() const
Core accessor.
Definition: node.h:49
std::shared_ptr< AbstractMemoryManager > const & memoryManager() const
Memory manager accessor.
Definition: task_node.h:53
Task core.
Definition: core_task.h:71