1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright (c) 2016 Thomas Heller 3 // Copyright (c) 2016 Hartmut Kaiser 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 /////////////////////////////////////////////////////////////////////////////// 8 9 #ifndef HPX_COMPUTE_CUDA_TARGET_HPP 10 #define HPX_COMPUTE_CUDA_TARGET_HPP 11 12 #include <hpx/config.hpp> 13 14 #if defined(HPX_HAVE_CUDA) 15 #include <hpx/compute/cuda/get_targets.hpp> 16 #include <hpx/lcos/future.hpp> 17 #include <hpx/lcos/local/spinlock.hpp> 18 #include <hpx/runtime/find_here.hpp> 19 #include <hpx/runtime/runtime_fwd.hpp> 20 21 #include <hpx/runtime/serialization/serialization_fwd.hpp> 22 23 #include <cuda_runtime.h> 24 25 #include <cstddef> 26 #include <mutex> 27 #include <string> 28 #include <utility> 29 #include <vector> 30 31 #include <hpx/config/warnings_prefix.hpp> 32 33 namespace hpx { namespace compute { namespace cuda 34 { 35 /////////////////////////////////////////////////////////////////////////// 36 struct target 37 { 38 public: 39 struct HPX_EXPORT native_handle_type 40 { 41 typedef hpx::lcos::local::spinlock mutex_type; 42 43 HPX_HOST_DEVICE native_handle_type(int device = 0); 44 45 HPX_HOST_DEVICE ~native_handle_type(); 46 47 HPX_HOST_DEVICE native_handle_type( 48 native_handle_type const& rhs) noexcept; 49 HPX_HOST_DEVICE native_handle_type( 50 native_handle_type && rhs) noexcept; 51 52 HPX_HOST_DEVICE native_handle_type& 53 operator=(native_handle_type const& rhs) noexcept; 54 HPX_HOST_DEVICE native_handle_type& 55 operator=(native_handle_type && rhs) noexcept; 56 57 HPX_HOST_DEVICE cudaStream_t get_stream() const; 58 get_devicehpx::compute::cuda::target::native_handle_type59 HPX_HOST_DEVICE int get_device() const noexcept 60 { 61 return device_; 62 } 63 processing_unitshpx::compute::cuda::target::native_handle_type64 HPX_HOST_DEVICE std::size_t processing_units() const 65 { 66 return processing_units_; 67 } 68 processor_familyhpx::compute::cuda::target::native_handle_type69 HPX_HOST_DEVICE std::size_t processor_family() const 70 { 71 return processor_family_; 72 } 73 processor_namehpx::compute::cuda::target::native_handle_type74 HPX_HOST_DEVICE std::string processor_name() const 75 { 76 return processor_name_; 77 } 78 79 void reset() noexcept; 80 81 private: 82 void init_processing_units(); 83 friend struct target; 84 85 mutable mutex_type mtx_; 86 int device_; 87 std::size_t processing_units_; 88 std::size_t processor_family_; 89 std::string processor_name_; 90 mutable cudaStream_t stream_; 91 }; 92 93 // Constructs default target targethpx::compute::cuda::target94 HPX_HOST_DEVICE target() 95 : handle_() 96 #if !defined(HPX_COMPUTE_DEVICE_CODE) 97 , locality_(hpx::find_here()) 98 #endif 99 {} 100 101 // Constructs target from a given device ID targethpx::compute::cuda::target102 explicit HPX_HOST_DEVICE target(int device) 103 : handle_(device) 104 #if !defined(HPX_COMPUTE_DEVICE_CODE) 105 , locality_(hpx::find_here()) 106 #endif 107 {} 108 targethpx::compute::cuda::target109 HPX_HOST_DEVICE target(hpx::id_type const& locality, int device) 110 : handle_(device) 111 #if !defined(HPX_COMPUTE_DEVICE_CODE) 112 , locality_(locality) 113 #endif 114 {} 115 targethpx::compute::cuda::target116 HPX_HOST_DEVICE target(target const& rhs) noexcept 117 : handle_(rhs.handle_) 118 #if !defined(HPX_COMPUTE_DEVICE_CODE) 119 , locality_(rhs.locality_) 120 #endif 121 {} 122 targethpx::compute::cuda::target123 HPX_HOST_DEVICE target(target && rhs) noexcept 124 : handle_(std::move(rhs.handle_)) 125 #if !defined(HPX_COMPUTE_DEVICE_CODE) 126 , locality_(std::move(rhs.locality_)) 127 #endif 128 {} 129 operator =hpx::compute::cuda::target130 HPX_HOST_DEVICE target& operator=(target const& rhs) noexcept 131 { 132 if (&rhs != this) 133 { 134 handle_ = rhs.handle_; 135 #if !defined(HPX_COMPUTE_DEVICE_CODE) 136 locality_ = rhs.locality_; 137 #endif 138 } 139 return *this; 140 } 141 operator =hpx::compute::cuda::target142 HPX_HOST_DEVICE target& operator=(target && rhs) noexcept 143 { 144 if (&rhs != this) 145 { 146 handle_ = std::move(rhs.handle_); 147 #if !defined(HPX_COMPUTE_DEVICE_CODE) 148 locality_ = std::move(rhs.locality_); 149 #endif 150 } 151 return *this; 152 } 153 154 HPX_HOST_DEVICE native_handlehpx::compute::cuda::target155 native_handle_type& native_handle() noexcept 156 { 157 return handle_; 158 } 159 HPX_HOST_DEVICE native_handlehpx::compute::cuda::target160 native_handle_type const& native_handle() const noexcept 161 { 162 return handle_; 163 } 164 165 HPX_HOST_DEVICE void synchronize() const; 166 get_localityhpx::compute::cuda::target167 HPX_HOST_DEVICE hpx::id_type const& get_locality() const noexcept 168 { 169 return locality_; 170 } 171 172 hpx::future<void> get_future() const; 173 get_local_targetshpx::compute::cuda::target174 static std::vector<target> get_local_targets() 175 { 176 return cuda::get_local_targets(); 177 } 178 static hpx::future<std::vector<target> > get_targetshpx::compute::cuda::target179 get_targets(hpx::id_type const& locality) 180 { 181 return cuda::get_targets(locality); 182 } 183 operator ==(target const & lhs,target const & rhs)184 friend bool operator==(target const& lhs, target const& rhs) 185 { 186 return lhs.handle_.get_device() == rhs.handle_.get_device() && 187 lhs.locality_ == rhs.locality_; 188 } 189 190 private: 191 #if !defined(HPX_COMPUTE_DEVICE_CODE) 192 friend class hpx::serialization::access; 193 194 void serialize(serialization::input_archive& ar, const unsigned int); 195 void serialize(serialization::output_archive& ar, const unsigned int); 196 #endif 197 198 native_handle_type handle_; 199 hpx::id_type locality_; 200 }; 201 202 HPX_API_EXPORT target& get_default_target(); 203 }}} 204 205 #include <hpx/config/warnings_suffix.hpp> 206 207 #endif 208 #endif 209