14#include "arccore/accelerator_native/CudaAccelerator.h"
16#include "arccore/base/CheckedConvert.h"
17#include "arccore/base/FatalErrorException.h"
19#include "arccore/common/internal/MemoryUtilsInternal.h"
20#include "arccore/common/internal/IMemoryResourceMngInternal.h"
22#include "arccore/common/accelerator/RunQueueBuildInfo.h"
23#include "arccore/common/accelerator/Memory.h"
24#include "arccore/common/accelerator/DeviceInfoList.h"
25#include "arccore/common/accelerator/KernelLaunchArgs.h"
26#include "arccore/common/accelerator/RunQueue.h"
27#include "arccore/common/accelerator/DeviceMemoryInfo.h"
28#include "arccore/common/accelerator/NativeStream.h"
29#include "arccore/common/accelerator/internal/IRunnerRuntime.h"
30#include "arccore/common/accelerator/internal/RegisterRuntimeInfo.h"
31#include "arccore/common/accelerator/internal/RunCommandImpl.h"
32#include "arccore/common/accelerator/internal/IRunQueueStream.h"
33#include "arccore/common/accelerator/internal/IRunQueueEventImpl.h"
34#include "arccore/common/accelerator/internal/AcceleratorMemoryAllocatorBase.h"
36#include "arccore/accelerator_native/runtime/Cupti.h"
39#include <unordered_map>
49#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
50#include <nvtx3/nvToolsExt.h>
53namespace Arcane::Accelerator::Cuda
55using Impl::KernelLaunchArgs;
59 Int32 global_cupti_flush = 0;
68#if defined(ARCCORE_USING_CUDA13_OR_GREATER)
70_getMemoryLocation(
int device_id)
72 cudaMemLocation mem_location;
73 mem_location.type = cudaMemLocationTypeDevice;
74 mem_location.id = device_id;
75 if (device_id == cudaCpuDeviceId)
76 mem_location.type = cudaMemLocationTypeHost;
78 mem_location.type = cudaMemLocationTypeDevice;
79 mem_location.id = device_id;
85_getMemoryLocation(
int device_id)
102 virtual cudaError_t _allocate(
void** ptr,
size_t new_size) = 0;
103 virtual cudaError_t _deallocate(
void* ptr) = 0;
109template <
typename ConcreteAllocatorType>
110class UnderlyingAllocator
115 UnderlyingAllocator() =
default;
122 ARCCORE_CHECK_CUDA(m_concrete_allocator._allocate(&out, size));
127 ARCCORE_CHECK_CUDA_NOTHROW(m_concrete_allocator._deallocate(ptr));
130 void doMemoryCopy(
void* destination,
const void* source,
Int64 size)
final
132 ARCCORE_CHECK_CUDA(cudaMemcpy(destination, source, size, cudaMemcpyDefault));
137 return m_concrete_allocator.memoryResource();
142 ConcreteAllocatorType m_concrete_allocator;
148class UnifiedMemoryConcreteAllocator
153 UnifiedMemoryConcreteAllocator()
156 m_use_ats = v.value();
161 cudaError_t _deallocate(
void* ptr)
final
168 return ::cudaFree(ptr);
171 cudaError_t _allocate(
void** ptr,
size_t new_size)
final
174 *ptr = ::aligned_alloc(128, new_size);
177 auto r = ::cudaMallocManaged(ptr, new_size, cudaMemAttachGlobal);
182 if (r != cudaSuccess)
196 cudaGetDevice(&device_id);
197 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, _getMemoryLocation(device_id)));
198 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetAccessedBy, _getMemoryLocation(cudaCpuDeviceId)));
209 bool m_use_ats =
false;
225class UnifiedMemoryCudaMemoryAllocator
226:
public AcceleratorMemoryAllocatorBase
231 UnifiedMemoryCudaMemoryAllocator()
235 _setTraceLevel(v.value());
248 void* p = ptr.baseAddress();
249 Int64 s = ptr.capacity();
251 _applyHint(ptr.baseAddress(), ptr.size(), new_args);
264 cudaGetDevice(&device_id);
266 auto device_memory_location = _getMemoryLocation(device_id);
267 auto cpu_memory_location = _getMemoryLocation(cudaCpuDeviceId);
271 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, device_memory_location));
272 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetAccessedBy, cpu_memory_location));
275 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, cpu_memory_location));
279 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetReadMostly, device_memory_location));
282 void _removeHint(
void* p,
size_t size, MemoryAllocationArgs args)
288 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, size, cudaMemAdviseUnsetReadMostly, _getMemoryLocation(device_id)));
293 bool m_use_ats =
false;
304 cudaError_t _allocate(
void** ptr,
size_t new_size)
final
306 return ::cudaMallocHost(ptr, new_size);
308 cudaError_t _deallocate(
void* ptr)
final
310 return ::cudaFreeHost(ptr);
318class HostPinnedCudaMemoryAllocator
319:
public AcceleratorMemoryAllocatorBase
324 HostPinnedCudaMemoryAllocator()
340class DeviceConcreteAllocator
345 DeviceConcreteAllocator()
348 m_use_ats = v.value();
351 cudaError_t _allocate(
void** ptr,
size_t new_size)
final
355 *ptr = std::aligned_alloc(128, new_size);
358 return cudaErrorMemoryAllocation;
360 cudaError_t r = ::cudaMalloc(ptr, new_size);
364 cudaError_t _deallocate(
void* ptr)
final
371 return ::cudaFree(ptr);
378 bool m_use_ats =
false;
384class DeviceCudaMemoryAllocator
385:
public AcceleratorMemoryAllocatorBase
390 DeviceCudaMemoryAllocator()
416void initializeCudaMemoryAllocators()
418 unified_memory_cuda_memory_allocator.initialize();
419 device_cuda_memory_allocator.initialize();
420 host_pinned_cuda_memory_allocator.initialize();
423void finalizeCudaMemoryAllocators(
ITraceMng* tm)
425 unified_memory_cuda_memory_allocator.finalize(tm);
426 device_cuda_memory_allocator.finalize(tm);
427 host_pinned_cuda_memory_allocator.finalize(tm);
433void arcaneCheckCudaErrors(
const TraceInfo& ti, CUresult e)
435 if (e == CUDA_SUCCESS)
437 const char* error_name =
nullptr;
438 CUresult e2 = cuGetErrorName(e, &error_name);
439 if (e2 != CUDA_SUCCESS)
440 error_name =
"Unknown";
442 const char* error_message =
nullptr;
443 CUresult e3 = cuGetErrorString(e, &error_message);
444 if (e3 != CUDA_SUCCESS)
445 error_message =
"Unknown";
447 ARCCORE_FATAL(
"CUDA Error trace={0} e={1} name={2} message={3}",
448 ti, e, error_name, error_message);
466 Int32 getNbThreadPerBlock(
const void* kernel_ptr)
468 std::scoped_lock lock(m_mutex);
469 auto x = m_nb_thread_per_block_map.find(kernel_ptr);
470 if (x != m_nb_thread_per_block_map.end())
472 int min_grid_size = 0;
473 int computed_block_size = 0;
474 int wanted_shared_memory = 0;
475 cudaError_t r = cudaOccupancyMaxPotentialBlockSize(&min_grid_size, &computed_block_size, kernel_ptr, wanted_shared_memory);
476 if (r != cudaSuccess)
477 computed_block_size = 0;
479 cudaOccupancyMaxActiveBlocksPerMultiprocessor(&num_block_0, kernel_ptr, 256, wanted_shared_memory);
481 cudaOccupancyMaxActiveBlocksPerMultiprocessor(&num_block_1, kernel_ptr, 1024, wanted_shared_memory);
483 cudaFuncAttributes func_attr;
484 cudaFuncGetAttributes(&func_attr, kernel_ptr);
485 m_nb_thread_per_block_map[kernel_ptr] = computed_block_size;
486 std::cout <<
"ComputedBlockSize=" << computed_block_size <<
" n0=" << num_block_0 <<
" n1=" << num_block_1
487 <<
" min_grid_size=" << min_grid_size <<
" nb_reg=" << func_attr.numRegs;
489#if CUDART_VERSION >= 12040
491 const char* func_name =
nullptr;
492 cudaFuncGetName(&func_name, kernel_ptr);
493 std::cout <<
" name=" << func_name <<
"\n";
496 return computed_block_size;
501 std::unordered_map<const void*, Int32> m_nb_thread_per_block_map;
508class CudaRunQueueStream
517 ARCCORE_CHECK_CUDA(cudaStreamCreate(&m_cuda_stream));
519 int priority = bi.priority();
520 ARCCORE_CHECK_CUDA(cudaStreamCreateWithPriority(&m_cuda_stream, cudaStreamDefault, priority));
523 ~CudaRunQueueStream()
override
525 ARCCORE_CHECK_CUDA_NOTHROW(cudaStreamDestroy(m_cuda_stream));
532#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
533 auto kname = c.kernelName();
535 nvtxRangePush(c.traceInfo().name());
537 nvtxRangePush(kname.localstr());
539 return m_runtime->notifyBeginLaunchKernel();
543#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
546 return m_runtime->notifyEndLaunchKernel();
550 ARCCORE_CHECK_CUDA(cudaStreamSynchronize(m_cuda_stream));
551 if (global_cupti_flush > 0)
552 global_cupti_info.flush();
556 return (cudaStreamSynchronize(m_cuda_stream) != cudaSuccess);
560 auto source_bytes = args.source().
bytes();
561 auto r = cudaMemcpyAsync(args.destination().
data(), source_bytes.data(),
562 source_bytes.size(), cudaMemcpyDefault, m_cuda_stream);
563 ARCCORE_CHECK_CUDA(r);
569 auto src = args.source().
bytes();
573 int device = cudaCpuDeviceId;
578 auto mem_location = _getMemoryLocation(device);
579#if defined(ARCCORE_USING_CUDA13_OR_GREATER)
580 auto r = cudaMemPrefetchAsync(src.data(), src.size(), mem_location, 0, m_cuda_stream);
582 auto r = cudaMemPrefetchAsync(src.data(), src.size(), mem_location, m_cuda_stream);
584 ARCCORE_CHECK_CUDA(r);
595 cudaStream_t trueStream()
const
597 return m_cuda_stream;
603 cudaStream_t m_cuda_stream =
nullptr;
609class CudaRunQueueEvent
614 explicit CudaRunQueueEvent(
bool has_timer)
617 ARCCORE_CHECK_CUDA(cudaEventCreate(&m_cuda_event));
619 ARCCORE_CHECK_CUDA(cudaEventCreateWithFlags(&m_cuda_event, cudaEventDisableTiming));
621 ~CudaRunQueueEvent()
override
623 ARCCORE_CHECK_CUDA_NOTHROW(cudaEventDestroy(m_cuda_event));
632 ARCCORE_CHECK_CUDA(cudaEventRecord(m_cuda_event, rq->trueStream()));
637 ARCCORE_CHECK_CUDA(cudaEventSynchronize(m_cuda_event));
643 ARCCORE_CHECK_CUDA(cudaStreamWaitEvent(rq->trueStream(), m_cuda_event, cudaEventWaitDefault));
646 Int64 elapsedTime(IRunQueueEventImpl* start_event)
final
650 auto* true_start_event =
static_cast<CudaRunQueueEvent*
>(start_event);
651 float time_in_ms = 0.0;
656 ARCCORE_CHECK_CUDA(cudaEventElapsedTime(&time_in_ms, true_start_event->m_cuda_event, m_cuda_event));
657 double x = time_in_ms * 1.0e6;
662 bool hasPendingWork()
final
664 cudaError_t v = cudaEventQuery(m_cuda_event);
665 if (v == cudaErrorNotReady)
667 ARCCORE_CHECK_CUDA(v);
673 cudaEvent_t m_cuda_event;
688 void notifyBeginLaunchKernel()
override
690 ++m_nb_kernel_launched;
692 std::cout <<
"BEGIN CUDA KERNEL!\n";
694 void notifyEndLaunchKernel()
override
696 ARCCORE_CHECK_CUDA(cudaGetLastError());
698 std::cout <<
"END CUDA KERNEL!\n";
700 void barrier()
override
702 ARCCORE_CHECK_CUDA(cudaDeviceSynchronize());
722 auto v = buffer.
bytes();
723 const void* ptr = v.
data();
724 size_t count = v.size();
725 int device = device_id.
asInt32();
726 cudaMemoryAdvise cuda_advise;
729 cuda_advise = cudaMemAdviseSetReadMostly;
731 cuda_advise = cudaMemAdviseSetPreferredLocation;
733 cuda_advise = cudaMemAdviseSetAccessedBy;
735 cuda_advise = cudaMemAdviseSetPreferredLocation;
736 device = cudaCpuDeviceId;
739 cuda_advise = cudaMemAdviseSetAccessedBy;
740 device = cudaCpuDeviceId;
745 ARCCORE_CHECK_CUDA(cudaMemAdvise(ptr, count, cuda_advise, _getMemoryLocation(device)));
749 auto v = buffer.
bytes();
750 const void* ptr = v.
data();
751 size_t count = v.size();
752 int device = device_id.
asInt32();
753 cudaMemoryAdvise cuda_advise;
756 cuda_advise = cudaMemAdviseUnsetReadMostly;
758 cuda_advise = cudaMemAdviseUnsetPreferredLocation;
760 cuda_advise = cudaMemAdviseUnsetAccessedBy;
762 cuda_advise = cudaMemAdviseUnsetPreferredLocation;
763 device = cudaCpuDeviceId;
766 cuda_advise = cudaMemAdviseUnsetAccessedBy;
767 device = cudaCpuDeviceId;
771 ARCCORE_CHECK_CUDA(cudaMemAdvise(ptr, count, cuda_advise, _getMemoryLocation(device)));
774 void setCurrentDevice(
DeviceId device_id)
final
778 ARCCORE_FATAL(
"Device {0} is not an accelerator device",
id);
779 ARCCORE_CHECK_CUDA(cudaSetDevice(
id));
782 const IDeviceInfoList* deviceInfoList()
final {
return &m_device_info_list; }
784 void startProfiling()
override
786 global_cupti_info.start();
789 void stopProfiling()
override
791 global_cupti_info.stop();
794 bool isProfilingActive()
override
796 return global_cupti_info.isActive();
799 void getPointerAttribute(
PointerAttribute& attribute,
const void* ptr)
override
801 cudaPointerAttributes ca;
802 ARCCORE_CHECK_CUDA(cudaPointerGetAttributes(&ca, ptr));
806 _fillPointerAttribute(attribute, mem_type, ca.device,
807 ptr, ca.devicePointer, ca.hostPointer);
813 int wanted_d = device_id.
asInt32();
814 ARCCORE_CHECK_CUDA(cudaGetDevice(&d));
816 ARCCORE_CHECK_CUDA(cudaSetDevice(wanted_d));
818 size_t total_mem = 0;
819 ARCCORE_CHECK_CUDA(cudaMemGetInfo(&free_mem, &total_mem));
821 ARCCORE_CHECK_CUDA(cudaSetDevice(d));
823 dmi.setFreeMemory(free_mem);
824 dmi.setTotalMemory(total_mem);
828 void pushProfilerRange(
const String& name,
Int32 color_rgb)
override
830#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
831 if (color_rgb >= 0) {
834 nvtxEventAttributes_t eventAttrib;
835 std::memset(&eventAttrib, 0,
sizeof(nvtxEventAttributes_t));
836 eventAttrib.version = NVTX_VERSION;
837 eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
838 eventAttrib.colorType = NVTX_COLOR_ARGB;
839 eventAttrib.color = color_rgb;
840 eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
841 eventAttrib.message.ascii = name.
localstr();
842 nvtxRangePushEx(&eventAttrib);
848 void popProfilerRange()
override
850#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
857 finalizeCudaMemoryAllocators(tm);
861 const void* kernel_ptr,
862 Int64 total_loop_size)
override
870 int nb_block_per_sm = 0;
871 ARCCORE_CHECK_CUDA(cudaOccupancyMaxActiveBlocksPerMultiprocessor(&nb_block_per_sm, kernel_ptr, nb_thread, shared_memory));
873 int max_block =
static_cast<int>((nb_block_per_sm * m_multi_processor_count) * m_cooperative_ratio);
874 max_block = std::max(max_block, 1);
875 if (nb_block > max_block) {
878 return modified_args;
883 if (!m_use_computed_occupancy)
885 if (shared_memory < 0)
888 if (shared_memory != 0)
890 Int32 computed_block_size = m_occupancy_map.getNbThreadPerBlock(kernel_ptr);
891 if (computed_block_size == 0)
897 Int64 big_b = (total_loop_size + computed_block_size - 1) / computed_block_size;
898 int blocks_per_grid = CheckedConvert::toInt32(big_b);
901 return modified_args;
906 void fillDevices(
bool is_verbose);
910 m_use_computed_occupancy = v.value();
913 x = std::clamp(x, 10, 100);
914 m_cooperative_ratio = x / 100.0;
920 Int64 m_nb_kernel_launched = 0;
921 bool m_is_verbose =
false;
922 bool m_use_computed_occupancy =
false;
923 Int32 m_multi_processor_count = 0;
924 double m_cooperative_ratio = 1.0;
932void CudaRunnerRuntime::
933fillDevices(
bool is_verbose)
936 ARCCORE_CHECK_CUDA(cudaGetDeviceCount(&nb_device));
937 std::ostream& omain = std::cout;
939 omain <<
"ArcaneCUDA: Initialize Arcane CUDA runtime nb_available_device=" << nb_device <<
"\n";
940 for (
int i = 0; i < nb_device; ++i) {
942 cudaGetDeviceProperties(&dp, i);
943 int runtime_version = 0;
944 cudaRuntimeGetVersion(&runtime_version);
945 int driver_version = 0;
946 cudaDriverGetVersion(&driver_version);
947 std::ostringstream ostr;
948 std::ostream& o = ostr;
949 o <<
"Device " << i <<
" name=" << dp.name <<
"\n";
950 o <<
" Driver version = " << (driver_version / 1000) <<
"." << (driver_version % 1000) <<
"\n";
951 o <<
" Runtime version = " << (runtime_version / 1000) <<
"." << (runtime_version % 1000) <<
"\n";
952 o <<
" computeCapability = " << dp.major <<
"." << dp.minor <<
"\n";
953 o <<
" totalGlobalMem = " << dp.totalGlobalMem <<
"\n";
954 o <<
" sharedMemPerBlock = " << dp.sharedMemPerBlock <<
"\n";
955 o <<
" sharedMemPerMultiprocessor = " << dp.sharedMemPerMultiprocessor <<
"\n";
956 o <<
" sharedMemPerBlockOptin = " << dp.sharedMemPerBlockOptin <<
"\n";
957 o <<
" regsPerBlock = " << dp.regsPerBlock <<
"\n";
958 o <<
" warpSize = " << dp.warpSize <<
"\n";
959 o <<
" memPitch = " << dp.memPitch <<
"\n";
960 o <<
" maxThreadsPerBlock = " << dp.maxThreadsPerBlock <<
"\n";
961 o <<
" maxBlocksPerMultiProcessor = " << dp.maxBlocksPerMultiProcessor <<
"\n";
962 o <<
" maxThreadsPerMultiProcessor = " << dp.maxThreadsPerMultiProcessor <<
"\n";
963 o <<
" totalConstMem = " << dp.totalConstMem <<
"\n";
964 o <<
" cooperativeLaunch = " << dp.cooperativeLaunch <<
"\n";
965 o <<
" multiProcessorCount = " << dp.multiProcessorCount <<
"\n";
966 o <<
" integrated = " << dp.integrated <<
"\n";
967 o <<
" canMapHostMemory = " << dp.canMapHostMemory <<
"\n";
968 o <<
" directManagedMemAccessFromHost = " << dp.directManagedMemAccessFromHost <<
"\n";
969 o <<
" hostNativeAtomicSupported = " << dp.hostNativeAtomicSupported <<
"\n";
970 o <<
" pageableMemoryAccess = " << dp.pageableMemoryAccess <<
"\n";
971 o <<
" concurrentManagedAccess = " << dp.concurrentManagedAccess <<
"\n";
972 o <<
" pageableMemoryAccessUsesHostPageTables = " << dp.pageableMemoryAccessUsesHostPageTables <<
"\n";
973 o <<
" hostNativeAtomicSupported = " << dp.hostNativeAtomicSupported <<
"\n";
974 o <<
" maxThreadsDim = " << dp.maxThreadsDim[0] <<
" " << dp.maxThreadsDim[1]
975 <<
" " << dp.maxThreadsDim[2] <<
"\n";
976 o <<
" maxGridSize = " << dp.maxGridSize[0] <<
" " << dp.maxGridSize[1]
977 <<
" " << dp.maxGridSize[2] <<
"\n";
978 o <<
" pciInfo = " << dp.pciDomainID <<
" " << dp.pciBusID <<
" " << dp.pciDeviceID <<
"\n";
979 o <<
" memoryBusWitdh = " << dp.memoryBusWidth <<
" bits\n";
982 ARCCORE_CHECK_CUDA(cudaDeviceGetAttribute(&clock_rate, cudaDevAttrClockRate, i));
983 o <<
" clockRate = " << (clock_rate / 1000) <<
" MHz\n";
985 int memory_clock_rate = 0;
986 ARCCORE_CHECK_CUDA(cudaDeviceGetAttribute(&memory_clock_rate, cudaDevAttrMemoryClockRate, i));
987 o <<
" memoryClockRate = " << (memory_clock_rate / 1000) <<
" MHz\n";
989 Real memory_bandwith = ((dp.memoryBusWidth * memory_clock_rate * 2.0) / 8.0) / 1.0e6;
990 o <<
" MemoryBandwith = " << memory_bandwith <<
" GB/s\n";
992#if !defined(ARCCORE_USING_CUDA13_OR_GREATER)
993 o <<
" deviceOverlap = " << dp.deviceOverlap <<
"\n";
994 o <<
" computeMode = " << dp.computeMode <<
"\n";
995 o <<
" kernelExecTimeoutEnabled = " << dp.kernelExecTimeoutEnabled <<
"\n";
1001 m_multi_processor_count = dp.multiProcessorCount;
1005 int greatest_val = 0;
1006 ARCCORE_CHECK_CUDA(cudaDeviceGetStreamPriorityRange(&least_val, &greatest_val));
1007 o <<
" leastPriority = " << least_val <<
" greatestPriority = " << greatest_val <<
"\n";
1009 std::ostringstream device_uuid_ostr;
1012 ARCCORE_CHECK_CUDA(cuDeviceGet(&device, i));
1014 ARCCORE_CHECK_CUDA(cuDeviceGetUuid(&device_uuid, device));
1015 o <<
" deviceUuid=";
1016 Impl::printUUID(device_uuid_ostr, device_uuid.bytes);
1017 o << device_uuid_ostr.str();
1020 String description(ostr.str());
1022 omain << description;
1025 device_info.setDescription(description);
1026 device_info.setDeviceId(
DeviceId(i));
1027 device_info.setName(dp.name);
1028 device_info.setWarpSize(dp.warpSize);
1029 device_info.setUUIDAsString(device_uuid_ostr.str());
1030 device_info.setSharedMemoryPerBlock(
static_cast<Int32>(dp.sharedMemPerBlock));
1031 device_info.setSharedMemoryPerMultiprocessor(
static_cast<Int32>(dp.sharedMemPerMultiprocessor));
1032 device_info.setSharedMemoryPerBlockOptin(
static_cast<Int32>(dp.sharedMemPerBlockOptin));
1033 device_info.setTotalConstMemory(
static_cast<Int32>(dp.totalConstMem));
1034 device_info.setPCIDomainID(dp.pciDomainID);
1035 device_info.setPCIBusID(dp.pciBusID);
1036 device_info.setPCIDeviceID(dp.pciDeviceID);
1037 m_device_info_list.addDevice(device_info);
1040 Int32 global_cupti_level = 0;
1044 global_cupti_level = v.value();
1046 global_cupti_flush = v.value();
1047 bool do_print_cupti =
true;
1049 do_print_cupti = (v.value() != 0);
1051 if (global_cupti_level > 0) {
1052#ifndef ARCCORE_HAS_CUDA_CUPTI
1053 ARCCORE_FATAL(
"Trying to enable CUPTI but Arcane is not compiled with cupti support");
1055 global_cupti_info.init(global_cupti_level, do_print_cupti);
1056 global_cupti_info.start();
1077 ARCCORE_CHECK_CUDA(cudaMemcpy(to.
data(), from.
data(), from.
bytes().
size(), cudaMemcpyDefault));
1108extern "C" ARCCORE_EXPORT
void
1109arcaneRegisterAcceleratorRuntimecuda(Arcane::Accelerator::RegisterRuntimeInfo& init_info)
1111 using namespace Arcane::Accelerator::Cuda;
1112 global_cuda_runtime.build();
1113 Accelerator::Impl::setUsingCUDARuntime(
true);
1114 Accelerator::Impl::setCUDARunQueueRuntime(&global_cuda_runtime);
1115 initializeCudaMemoryAllocators();
1120 _setAllocator(&unified_memory_cuda_memory_allocator);
1121 _setAllocator(&host_pinned_cuda_memory_allocator);
1122 _setAllocator(&device_cuda_memory_allocator);
1123 mrm->
setCopier(&global_cuda_memory_copier);
1124 global_cuda_runtime.fillDevices(init_info.isVerbose());
#define ARCCORE_FATAL(...)
Macro throwing a FatalErrorException.
#define ARCCORE_CHECK_POINTER(ptr)
Macro that returns the pointer ptr if it is not null or throws an exception if it is null.
Base class of a specific allocator for accelerator.
eMemoryResource memoryResource() const final
Memory resource provided by the allocator.
void _doInitializeDevice(bool default_use_memory_pool=false)
Initialization for Device memory.
void _doInitializeHostPinned(bool default_use_memory_pool=false)
Initialization for HostPinned memory.
void _doInitializeUVM(bool default_use_memory_pool=false)
Initialization for UVM memory.
void copy(ConstMemoryView from, eMemoryResource from_mem, MutableMemoryView to, eMemoryResource to_mem, const RunQueue *queue) override
Copies the data from from to to with the queue queue.
void barrier() override
Blocks until all actions associated with this queue are finished.
void notifyBeginLaunchKernel(Impl::RunCommandImpl &c) override
Notification before command launch.
bool _barrierNoException() override
Barrier without exception. Returns true in case of error.
Impl::NativeStream nativeStream() override
Pointer to the internal structure dependent on the implementation.
void prefetchMemory(const MemoryPrefetchArgs &args) override
Performs a prefetch of a memory region.
void notifyEndLaunchKernel(Impl::RunCommandImpl &) override
Notification of command launch completion.
void copyMemory(const MemoryCopyArgs &args) override
Performs a copy between two memory regions.
Singleton class to manage CUPTI.
Map containing the ideal occupancy for a given kernel.
void * allocateMemory(Int64 size) final
Allocates a block for size bytes.
void freeMemory(void *ptr, Int64 size) final
Frees the block located at address address containing size bytes.
bool m_use_hint_as_mainly_device
Allocator for unified memory.
void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) final
Notifies of a change in instance-specific arguments.
Identifier of a system component.
bool isHost() const
Indicates if the instance is associated with the host.
Int32 asInt32() const
Numerical value of the device.
bool isAccelerator() const
Indicates if the instance is associated with an accelerator.
Information about an accelerator.
Accelerator memory information.
Interface of a list of devices.
Interface for a list of devices.
Interface for event implementation.
Interface of an execution stream for a RunQueue.
Interface of the runtime associated with an accelerator.
Arguments for launching a kernel.
bool isCooperative() const
Indicates if running in cooperative mode (i.e. cudaLaunchCooperativeKernel).
Int32 nbBlockPerGrid() const
Number of grid blocks.
void setNbThreadPerBlock(Int32 v)
Number of threads per block.
void setNbBlockPerGrid(Int32 v)
Number of grid blocks.
Int32 nbThreadPerBlock() const
Number of threads per block.
Int32 sharedMemorySize() const
Shared memory to allocate for the kernel.
Opaque type to encapsulate a native 'stream'.
Implementation of a command for accelerator.
Memory prefetching arguments.
Information about a memory address.
Information to create a RunQueue.
bool isDefault() const
Indicates if the instance only has default values.
Execution queue for an accelerator.
bool isAsync() const
Indicates if the execution queue is asynchronous.
void copyMemory(const MemoryCopyArgs &args) const
Copies information between two memory regions.
Information about an allocated memory region.
Constant view on a contiguous memory region containing fixed-size elements.
constexpr SpanType bytes() const
View in byte form.
constexpr const std::byte * data() const
Pointer to the memory region.
Template class for converting a type.
Interface for memory copies with accelerator support.
Internal part of Arcane's 'IMemoryResourceMng'.
virtual void setAllocator(eMemoryResource r, IMemoryAllocator *allocator)=0
Sets the allocator for resource r.
virtual void setMemoryPool(eMemoryResource r, IMemoryPool *pool)=0
Sets the memory pool for resource r.
virtual void setIsAccelerator(bool v)=0
Indicates if an accelerator is available.
virtual void setCopier(IMemoryCopier *copier)=0
Sets the copying instance.
virtual IMemoryResourceMngInternal * _internal()=0
Internal interface.
Class containing information to specialize allocations.
Mutable view on a contiguous memory region containing fixed-size elements.
constexpr std::byte * data() const
Pointer to the memory region.
constexpr SpanType bytes() const
View in byte form.
constexpr __host__ __device__ pointer data() const noexcept
Pointer to the start of the view.
constexpr __host__ __device__ SizeType size() const noexcept
Returns the size of the array.
Unicode character string.
const char * localstr() const
Returns the conversion of the instance into UTF-8 encoding.
eMemoryAdvice
Memory management advice.
@ AccessedByHost
Indicates that the memory region is accessed by the host.
@ PreferredLocationDevice
Prefers memory placement on the accelerator.
@ MostlyRead
Indicates that the memory region is primarily read-only.
@ PreferredLocationHost
Prefers memory placement on the host.
@ AccessedByDevice
Indicates that the memory region is accessed by the device.
ePointerMemoryType
Memory type for a pointer.
eExecutionPolicy
Execution policy for a Runner.
@ CUDA
Execution policy using the CUDA environment.
IMemoryRessourceMng * getDataMemoryResourceMng()
Memory resource manager for data.
IMemoryAllocator * setAcceleratorHostMemoryAllocator(IMemoryAllocator *a)
Sets the specific allocator for accelerators.
void setDefaultDataMemoryResource(eMemoryResource mem_resource)
Sets the memory resource used for the data memory allocator.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
eMemoryLocationHint
Indices for expected memory location.
@ MainlyHost
Indicates that the data will primarily be used on the CPU.
@ HostAndDeviceMostlyRead
Indicates that the data will be used both on the accelerator and on the CPU and will not be frequentl...
@ MainlyDevice
Indicates that the data will primarily be used on the accelerator.
double Real
Type representing a real number.
eMemoryResource
List of available memory resources.
@ HostPinned
Allocates on the host.
@ UnifiedMemory
Allocates using unified memory.
@ Device
Allocates on the device.
std::int32_t Int32
Signed integer type of 32 bits.