15#if ALPAKA_LANG_CUDA || ALPAKA_LANG_HIP
25 namespace unifiedCudaHip
27 template<
typename T_ApiInterface, alpaka::concepts::DeviceKind T_DeviceKind>
28 struct Platform : std::enable_shared_from_this<Platform<T_ApiInterface, T_DeviceKind>>
30 using ApiInterface = T_ApiInterface;
35 Platform(Platform
const&) =
delete;
36 Platform& operator=(Platform
const&) =
delete;
38 Platform(Platform&&) =
delete;
39 Platform& operator=(Platform&&) =
delete;
44 static_assert(internal::concepts::Platform<Platform>);
47 std::vector<std::weak_ptr<unifiedCudaHip::Device<Platform>>> devices;
48 std::mutex deviceGuard;
50 std::shared_ptr<Platform> getSharedPtr()
52 return this->shared_from_this();
55 friend struct alpaka::internal::GetName;
59 return "unifiedCudaHip::Platform";
62 friend struct onHost::internal::GetDeviceCount;
64 uint32_t getDeviceCount()
67 constexpr bool isSupportedDev = trait::IsDeviceSupportedBy::
68 Op<T_DeviceKind, ALPAKA_TYPEOF(getApi(std::declval<Platform>()))>::value;
69 if constexpr(isSupportedDev)
72 typename ApiInterface::Error_t error = ApiInterface::getDeviceCount(&numDevices);
73 if(error != ApiInterface::success)
76 if(devices.size() <
static_cast<size_t>(numDevices))
78 std::lock_guard<std::mutex> lk{deviceGuard};
79 devices.resize(numDevices);
81 return static_cast<uint32_t
>(numDevices);
87 friend struct onHost::internal::MakeDevice;
89 Handle<unifiedCudaHip::Device<Platform>> makeDevice(uint32_t
const& idx)
92 uint32_t
const numDevices = getDeviceCount();
95 std::stringstream ssErr;
96 ssErr <<
"Unable to return device handle for GPU (" << T_DeviceKind{}.getName()
97 <<
") device with index " << idx <<
" because there are only " << numDevices <<
" devices!";
98 throw std::runtime_error(ssErr.str());
100 std::lock_guard<std::mutex> lk{deviceGuard};
102 if(
auto sharedPtr = devices[idx].lock())
106 auto thisHandle = getSharedPtr();
107 auto newDevice = std::make_shared<unifiedCudaHip::Device<Platform>>(std::move(thisHandle), idx);
108 devices[idx] = newDevice;
112 friend struct internal::GetDeviceProperties;
118 template<
typename T_ApiInterface, alpaka::concepts::DeviceKind T_DeviceKind>
119 struct GetDeviceProperties::Op<unifiedCudaHip::Platform<T_ApiInterface, T_DeviceKind>>
121 DeviceProperties operator()(
122 unifiedCudaHip::Platform<T_ApiInterface, T_DeviceKind>
const&,
123 uint32_t deviceIdx)
const
126 using ApiInterface =
typename unifiedCudaHip::Platform<T_ApiInterface, T_DeviceKind>::ApiInterface;
127 typename ApiInterface::DeviceProp_t devProp;
128 ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(ApiInterface, ApiInterface::getDeviceProperties(&devProp, deviceIdx));
130 std::size_t freeGlobalMemBytes(0u);
131 std::size_t globalMemCapacityBytes(0u);
132 ALPAKA_UNIFORM_CUDA_HIP_RT_CHECK(
134 ApiInterface::memGetInfo(&freeGlobalMemBytes, &globalMemCapacityBytes));
136 auto prop = DeviceProperties{};
137 prop.name = devProp.name;
138 prop.warpSize = devProp.warpSize;
139 prop.multiProcessorCount = devProp.multiProcessorCount;
140 prop.globalMemCapacityBytes = globalMemCapacityBytes;
141 prop.sharedMemPerBlockBytes = devProp.sharedMemPerBlock;
143 prop.maxThreadsPerBlock = devProp.maxThreadsPerBlock;
146 devProp.maxThreadsDim[0u],
147 devProp.maxThreadsDim[1u],
148 devProp.maxThreadsDim[2u]};
149 prop.fnMaxThreadsPerBlock = [maxThreadsPerBlock = prop.maxThreadsPerBlock,
150 cudaMaxThreadsPerBlock](uint32_t*
data, uint32_t numDims)
154 for(uint32_t d = 0u; d < numDims; ++d)
155 data[numDims - 1u - d] = cudaMaxThreadsPerBlock[d];
161 for(uint32_t d = 0u; d < numDims; ++d)
162 data[d] = maxThreadsPerBlock;
166 prop.maxBlocksPerGrid = std::numeric_limits<uint32_t>::max();
169 devProp.maxGridSize[0u],
170 devProp.maxGridSize[1u],
171 devProp.maxGridSize[2u]};
172 prop.fnMaxBlocksPerGrid =
173 [maxBlocksPerGrid = prop.maxBlocksPerGrid, cudaMaxBlocksPerGrid](uint32_t*
data, uint32_t numDims)
177 for(uint32_t d = 0u; d < numDims; ++d)
178 data[numDims - 1u - d] = cudaMaxBlocksPerGrid[d];
184 for(uint32_t d = 0u; d < numDims; ++d)
185 data[d] = maxBlocksPerGrid;
#define ALPAKA_LOG_FUNCTION(logLvl)
Log the entry and exit of a scope.
Functionality which is usable on the host CPU controller thread.
decltype(auto) data(auto &&any)
pointer to data of an object
std::convertible_to< std::string > auto getName(auto &&any)
Runtime name for a given object.
ALPAKA_FN_HOST_ACC Vec(T_1, T_Args...) -> Vec< T_1, uint32_t(sizeof...(T_Args)+1u), ArrayStorage< T_1, uint32_t(sizeof...(T_Args)+1u)> >