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)
195 cudaGetDevice(&device_id);
196 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, _getMemoryLocation(device_id)));
197 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetAccessedBy, _getMemoryLocation(cudaCpuDeviceId)));
208 bool m_use_ats =
false;
223class UnifiedMemoryCudaMemoryAllocator
224:
public AcceleratorMemoryAllocatorBase
229 UnifiedMemoryCudaMemoryAllocator()
233 _setTraceLevel(v.value());
246 void* p = ptr.baseAddress();
247 Int64 s = ptr.capacity();
249 _applyHint(ptr.baseAddress(), ptr.size(), new_args);
262 cudaGetDevice(&device_id);
264 auto device_memory_location = _getMemoryLocation(device_id);
265 auto cpu_memory_location = _getMemoryLocation(cudaCpuDeviceId);
269 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, device_memory_location));
270 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetAccessedBy, cpu_memory_location));
273 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetPreferredLocation, cpu_memory_location));
277 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, new_size, cudaMemAdviseSetReadMostly, device_memory_location));
280 void _removeHint(
void* p,
size_t size, MemoryAllocationArgs args)
286 ARCCORE_CHECK_CUDA(cudaMemAdvise(p, size, cudaMemAdviseUnsetReadMostly, _getMemoryLocation(device_id)));
291 bool m_use_ats =
false;
302 cudaError_t _allocate(
void** ptr,
size_t new_size)
final
304 return ::cudaMallocHost(ptr, new_size);
306 cudaError_t _deallocate(
void* ptr)
final
308 return ::cudaFreeHost(ptr);
316class HostPinnedCudaMemoryAllocator
317:
public AcceleratorMemoryAllocatorBase
322 HostPinnedCudaMemoryAllocator()
338class DeviceConcreteAllocator
343 DeviceConcreteAllocator()
346 m_use_ats = v.value();
349 cudaError_t _allocate(
void** ptr,
size_t new_size)
final
353 *ptr = std::aligned_alloc(128, new_size);
356 return cudaErrorMemoryAllocation;
358 cudaError_t r = ::cudaMalloc(ptr, new_size);
362 cudaError_t _deallocate(
void* ptr)
final
369 return ::cudaFree(ptr);
376 bool m_use_ats =
false;
382class DeviceCudaMemoryAllocator
383:
public AcceleratorMemoryAllocatorBase
388 DeviceCudaMemoryAllocator()
414void initializeCudaMemoryAllocators()
416 unified_memory_cuda_memory_allocator.initialize();
417 device_cuda_memory_allocator.initialize();
418 host_pinned_cuda_memory_allocator.initialize();
421void finalizeCudaMemoryAllocators(
ITraceMng* tm)
423 unified_memory_cuda_memory_allocator.finalize(tm);
424 device_cuda_memory_allocator.finalize(tm);
425 host_pinned_cuda_memory_allocator.finalize(tm);
431void arcaneCheckCudaErrors(
const TraceInfo& ti, CUresult e)
433 if (e == CUDA_SUCCESS)
435 const char* error_name =
nullptr;
436 CUresult e2 = cuGetErrorName(e, &error_name);
437 if (e2 != CUDA_SUCCESS)
438 error_name =
"Unknown";
440 const char* error_message =
nullptr;
441 CUresult e3 = cuGetErrorString(e, &error_message);
442 if (e3 != CUDA_SUCCESS)
443 error_message =
"Unknown";
445 ARCCORE_FATAL(
"CUDA Error trace={0} e={1} name={2} message={3}",
446 ti, e, error_name, error_message);
464 Int32 getNbThreadPerBlock(
const void* kernel_ptr)
466 std::scoped_lock lock(m_mutex);
467 auto x = m_nb_thread_per_block_map.find(kernel_ptr);
468 if (x != m_nb_thread_per_block_map.end())
470 int min_grid_size = 0;
471 int computed_block_size = 0;
472 int wanted_shared_memory = 0;
473 cudaError_t r = cudaOccupancyMaxPotentialBlockSize(&min_grid_size, &computed_block_size, kernel_ptr, wanted_shared_memory);
474 if (r != cudaSuccess)
475 computed_block_size = 0;
477 cudaOccupancyMaxActiveBlocksPerMultiprocessor(&num_block_0, kernel_ptr, 256, wanted_shared_memory);
479 cudaOccupancyMaxActiveBlocksPerMultiprocessor(&num_block_1, kernel_ptr, 1024, wanted_shared_memory);
481 cudaFuncAttributes func_attr;
482 cudaFuncGetAttributes(&func_attr, kernel_ptr);
483 m_nb_thread_per_block_map[kernel_ptr] = computed_block_size;
484 std::cout <<
"ComputedBlockSize=" << computed_block_size <<
" n0=" << num_block_0 <<
" n1=" << num_block_1
485 <<
" min_grid_size=" << min_grid_size <<
" nb_reg=" << func_attr.numRegs;
487#if CUDART_VERSION >= 12040
489 const char* func_name =
nullptr;
490 cudaFuncGetName(&func_name, kernel_ptr);
491 std::cout <<
" name=" << func_name <<
"\n";
494 return computed_block_size;
499 std::unordered_map<const void*, Int32> m_nb_thread_per_block_map;
506class CudaRunQueueStream
515 ARCCORE_CHECK_CUDA(cudaStreamCreate(&m_cuda_stream));
517 int priority = bi.priority();
518 ARCCORE_CHECK_CUDA(cudaStreamCreateWithPriority(&m_cuda_stream, cudaStreamDefault, priority));
521 ~CudaRunQueueStream()
override
523 ARCCORE_CHECK_CUDA_NOTHROW(cudaStreamDestroy(m_cuda_stream));
530#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
531 auto kname = c.kernelName();
533 nvtxRangePush(c.traceInfo().name());
535 nvtxRangePush(kname.localstr());
537 return m_runtime->notifyBeginLaunchKernel();
541#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
544 return m_runtime->notifyEndLaunchKernel();
548 ARCCORE_CHECK_CUDA(cudaStreamSynchronize(m_cuda_stream));
549 if (global_cupti_flush > 0)
550 global_cupti_info.flush();
554 return (cudaStreamSynchronize(m_cuda_stream) != cudaSuccess);
558 auto source_bytes = args.source().
bytes();
559 auto r = cudaMemcpyAsync(args.destination().
data(), source_bytes.data(),
560 source_bytes.size(), cudaMemcpyDefault, m_cuda_stream);
561 ARCCORE_CHECK_CUDA(r);
567 auto src = args.source().
bytes();
571 int device = cudaCpuDeviceId;
576 auto mem_location = _getMemoryLocation(device);
577#if defined(ARCCORE_USING_CUDA13_OR_GREATER)
578 auto r = cudaMemPrefetchAsync(src.data(), src.size(), mem_location, 0, m_cuda_stream);
580 auto r = cudaMemPrefetchAsync(src.data(), src.size(), mem_location, m_cuda_stream);
582 ARCCORE_CHECK_CUDA(r);
593 cudaStream_t trueStream()
const
595 return m_cuda_stream;
601 cudaStream_t m_cuda_stream =
nullptr;
607class CudaRunQueueEvent
612 explicit CudaRunQueueEvent(
bool has_timer)
615 ARCCORE_CHECK_CUDA(cudaEventCreate(&m_cuda_event));
617 ARCCORE_CHECK_CUDA(cudaEventCreateWithFlags(&m_cuda_event, cudaEventDisableTiming));
619 ~CudaRunQueueEvent()
override
621 ARCCORE_CHECK_CUDA_NOTHROW(cudaEventDestroy(m_cuda_event));
630 ARCCORE_CHECK_CUDA(cudaEventRecord(m_cuda_event, rq->trueStream()));
635 ARCCORE_CHECK_CUDA(cudaEventSynchronize(m_cuda_event));
641 ARCCORE_CHECK_CUDA(cudaStreamWaitEvent(rq->trueStream(), m_cuda_event, cudaEventWaitDefault));
644 Int64 elapsedTime(IRunQueueEventImpl* start_event)
final
648 auto* true_start_event =
static_cast<CudaRunQueueEvent*
>(start_event);
649 float time_in_ms = 0.0;
654 ARCCORE_CHECK_CUDA(cudaEventElapsedTime(&time_in_ms, true_start_event->m_cuda_event, m_cuda_event));
655 double x = time_in_ms * 1.0e6;
660 bool hasPendingWork()
final
662 cudaError_t v = cudaEventQuery(m_cuda_event);
663 if (v == cudaErrorNotReady)
665 ARCCORE_CHECK_CUDA(v);
671 cudaEvent_t m_cuda_event;
686 void notifyBeginLaunchKernel()
override
688 ++m_nb_kernel_launched;
690 std::cout <<
"BEGIN CUDA KERNEL!\n";
692 void notifyEndLaunchKernel()
override
694 ARCCORE_CHECK_CUDA(cudaGetLastError());
696 std::cout <<
"END CUDA KERNEL!\n";
698 void barrier()
override
700 ARCCORE_CHECK_CUDA(cudaDeviceSynchronize());
720 auto v = buffer.
bytes();
721 const void* ptr = v.
data();
722 size_t count = v.size();
723 int device = device_id.
asInt32();
724 cudaMemoryAdvise cuda_advise;
727 cuda_advise = cudaMemAdviseSetReadMostly;
729 cuda_advise = cudaMemAdviseSetPreferredLocation;
731 cuda_advise = cudaMemAdviseSetAccessedBy;
733 cuda_advise = cudaMemAdviseSetPreferredLocation;
734 device = cudaCpuDeviceId;
737 cuda_advise = cudaMemAdviseSetAccessedBy;
738 device = cudaCpuDeviceId;
743 ARCCORE_CHECK_CUDA(cudaMemAdvise(ptr, count, cuda_advise, _getMemoryLocation(device)));
747 auto v = buffer.
bytes();
748 const void* ptr = v.
data();
749 size_t count = v.size();
750 int device = device_id.
asInt32();
751 cudaMemoryAdvise cuda_advise;
754 cuda_advise = cudaMemAdviseUnsetReadMostly;
756 cuda_advise = cudaMemAdviseUnsetPreferredLocation;
758 cuda_advise = cudaMemAdviseUnsetAccessedBy;
760 cuda_advise = cudaMemAdviseUnsetPreferredLocation;
761 device = cudaCpuDeviceId;
764 cuda_advise = cudaMemAdviseUnsetAccessedBy;
765 device = cudaCpuDeviceId;
769 ARCCORE_CHECK_CUDA(cudaMemAdvise(ptr, count, cuda_advise, _getMemoryLocation(device)));
772 void setCurrentDevice(
DeviceId device_id)
final
776 ARCCORE_FATAL(
"Device {0} is not an accelerator device",
id);
777 ARCCORE_CHECK_CUDA(cudaSetDevice(
id));
780 const IDeviceInfoList* deviceInfoList()
final {
return &m_device_info_list; }
782 void startProfiling()
override
784 global_cupti_info.start();
787 void stopProfiling()
override
789 global_cupti_info.stop();
792 bool isProfilingActive()
override
794 return global_cupti_info.isActive();
797 void getPointerAttribute(
PointerAttribute& attribute,
const void* ptr)
override
799 cudaPointerAttributes ca;
800 ARCCORE_CHECK_CUDA(cudaPointerGetAttributes(&ca, ptr));
804 _fillPointerAttribute(attribute, mem_type, ca.device,
805 ptr, ca.devicePointer, ca.hostPointer);
811 int wanted_d = device_id.
asInt32();
812 ARCCORE_CHECK_CUDA(cudaGetDevice(&d));
814 ARCCORE_CHECK_CUDA(cudaSetDevice(wanted_d));
816 size_t total_mem = 0;
817 ARCCORE_CHECK_CUDA(cudaMemGetInfo(&free_mem, &total_mem));
819 ARCCORE_CHECK_CUDA(cudaSetDevice(d));
821 dmi.setFreeMemory(free_mem);
822 dmi.setTotalMemory(total_mem);
826 void pushProfilerRange(
const String& name,
Int32 color_rgb)
override
828#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
829 if (color_rgb >= 0) {
832 nvtxEventAttributes_t eventAttrib;
833 std::memset(&eventAttrib, 0,
sizeof(nvtxEventAttributes_t));
834 eventAttrib.version = NVTX_VERSION;
835 eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
836 eventAttrib.colorType = NVTX_COLOR_ARGB;
837 eventAttrib.color = color_rgb;
838 eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
839 eventAttrib.message.ascii = name.
localstr();
840 nvtxRangePushEx(&eventAttrib);
846 void popProfilerRange()
override
848#ifdef ARCCORE_HAS_CUDA_NVTOOLSEXT
855 finalizeCudaMemoryAllocators(tm);
859 const void* kernel_ptr,
860 Int64 total_loop_size)
override
868 int nb_block_per_sm = 0;
869 ARCCORE_CHECK_CUDA(cudaOccupancyMaxActiveBlocksPerMultiprocessor(&nb_block_per_sm, kernel_ptr, nb_thread, shared_memory));
871 int max_block =
static_cast<int>((nb_block_per_sm * m_multi_processor_count) * m_cooperative_ratio);
872 max_block = std::max(max_block, 1);
873 if (nb_block > max_block) {
876 return modified_args;
881 if (!m_use_computed_occupancy)
883 if (shared_memory < 0)
886 if (shared_memory != 0)
888 Int32 computed_block_size = m_occupancy_map.getNbThreadPerBlock(kernel_ptr);
889 if (computed_block_size == 0)
895 Int64 big_b = (total_loop_size + computed_block_size - 1) / computed_block_size;
896 int blocks_per_grid = CheckedConvert::toInt32(big_b);
899 return modified_args;
904 void fillDevices(
bool is_verbose);
908 m_use_computed_occupancy = v.value();
911 x = std::clamp(x, 10, 100);
912 m_cooperative_ratio = x / 100.0;
918 Int64 m_nb_kernel_launched = 0;
919 bool m_is_verbose =
false;
920 bool m_use_computed_occupancy =
false;
921 Int32 m_multi_processor_count = 0;
922 double m_cooperative_ratio = 1.0;
930void CudaRunnerRuntime::
931fillDevices(
bool is_verbose)
934 ARCCORE_CHECK_CUDA(cudaGetDeviceCount(&nb_device));
935 std::ostream& omain = std::cout;
937 omain <<
"ArcaneCUDA: Initialize Arcane CUDA runtime nb_available_device=" << nb_device <<
"\n";
938 for (
int i = 0; i < nb_device; ++i) {
940 cudaGetDeviceProperties(&dp, i);
941 int runtime_version = 0;
942 cudaRuntimeGetVersion(&runtime_version);
943 int driver_version = 0;
944 cudaDriverGetVersion(&driver_version);
945 std::ostringstream ostr;
946 std::ostream& o = ostr;
947 o <<
"Device " << i <<
" name=" << dp.name <<
"\n";
948 o <<
" Driver version = " << (driver_version / 1000) <<
"." << (driver_version % 1000) <<
"\n";
949 o <<
" Runtime version = " << (runtime_version / 1000) <<
"." << (runtime_version % 1000) <<
"\n";
950 o <<
" computeCapability = " << dp.major <<
"." << dp.minor <<
"\n";
951 o <<
" totalGlobalMem = " << dp.totalGlobalMem <<
"\n";
952 o <<
" sharedMemPerBlock = " << dp.sharedMemPerBlock <<
"\n";
953 o <<
" sharedMemPerMultiprocessor = " << dp.sharedMemPerMultiprocessor <<
"\n";
954 o <<
" sharedMemPerBlockOptin = " << dp.sharedMemPerBlockOptin <<
"\n";
955 o <<
" regsPerBlock = " << dp.regsPerBlock <<
"\n";
956 o <<
" warpSize = " << dp.warpSize <<
"\n";
957 o <<
" memPitch = " << dp.memPitch <<
"\n";
958 o <<
" maxThreadsPerBlock = " << dp.maxThreadsPerBlock <<
"\n";
959 o <<
" maxBlocksPerMultiProcessor = " << dp.maxBlocksPerMultiProcessor <<
"\n";
960 o <<
" maxThreadsPerMultiProcessor = " << dp.maxThreadsPerMultiProcessor <<
"\n";
961 o <<
" totalConstMem = " << dp.totalConstMem <<
"\n";
962 o <<
" cooperativeLaunch = " << dp.cooperativeLaunch <<
"\n";
963 o <<
" multiProcessorCount = " << dp.multiProcessorCount <<
"\n";
964 o <<
" integrated = " << dp.integrated <<
"\n";
965 o <<
" canMapHostMemory = " << dp.canMapHostMemory <<
"\n";
966 o <<
" directManagedMemAccessFromHost = " << dp.directManagedMemAccessFromHost <<
"\n";
967 o <<
" hostNativeAtomicSupported = " << dp.hostNativeAtomicSupported <<
"\n";
968 o <<
" pageableMemoryAccess = " << dp.pageableMemoryAccess <<
"\n";
969 o <<
" concurrentManagedAccess = " << dp.concurrentManagedAccess <<
"\n";
970 o <<
" pageableMemoryAccessUsesHostPageTables = " << dp.pageableMemoryAccessUsesHostPageTables <<
"\n";
971 o <<
" hostNativeAtomicSupported = " << dp.hostNativeAtomicSupported <<
"\n";
972 o <<
" maxThreadsDim = " << dp.maxThreadsDim[0] <<
" " << dp.maxThreadsDim[1]
973 <<
" " << dp.maxThreadsDim[2] <<
"\n";
974 o <<
" maxGridSize = " << dp.maxGridSize[0] <<
" " << dp.maxGridSize[1]
975 <<
" " << dp.maxGridSize[2] <<
"\n";
976 o <<
" pciInfo = " << dp.pciDomainID <<
" " << dp.pciBusID <<
" " << dp.pciDeviceID <<
"\n";
977 o <<
" memoryBusWitdh = " << dp.memoryBusWidth <<
" bits\n";
980 ARCCORE_CHECK_CUDA(cudaDeviceGetAttribute(&clock_rate, cudaDevAttrClockRate, i));
981 o <<
" clockRate = " << (clock_rate / 1000) <<
" MHz\n";
983 int memory_clock_rate = 0;
984 ARCCORE_CHECK_CUDA(cudaDeviceGetAttribute(&memory_clock_rate, cudaDevAttrMemoryClockRate, i));
985 o <<
" memoryClockRate = " << (memory_clock_rate / 1000) <<
" MHz\n";
987 Real memory_bandwith = ((dp.memoryBusWidth * memory_clock_rate * 2.0) / 8.0) / 1.0e6;
988 o <<
" MemoryBandwith = " << memory_bandwith <<
" GB/s\n";
990#if !defined(ARCCORE_USING_CUDA13_OR_GREATER)
991 o <<
" deviceOverlap = " << dp.deviceOverlap <<
"\n";
992 o <<
" computeMode = " << dp.computeMode <<
"\n";
993 o <<
" kernelExecTimeoutEnabled = " << dp.kernelExecTimeoutEnabled <<
"\n";
999 m_multi_processor_count = dp.multiProcessorCount;
1003 int greatest_val = 0;
1004 ARCCORE_CHECK_CUDA(cudaDeviceGetStreamPriorityRange(&least_val, &greatest_val));
1005 o <<
" leastPriority = " << least_val <<
" greatestPriority = " << greatest_val <<
"\n";
1007 std::ostringstream device_uuid_ostr;
1010 ARCCORE_CHECK_CUDA(cuDeviceGet(&device, i));
1012 ARCCORE_CHECK_CUDA(cuDeviceGetUuid(&device_uuid, device));
1013 o <<
" deviceUuid=";
1014 Impl::printUUID(device_uuid_ostr, device_uuid.bytes);
1015 o << device_uuid_ostr.str();
1018 String description(ostr.str());
1020 omain << description;
1023 device_info.setDescription(description);
1024 device_info.setDeviceId(
DeviceId(i));
1025 device_info.setName(dp.name);
1026 device_info.setWarpSize(dp.warpSize);
1027 device_info.setUUIDAsString(device_uuid_ostr.str());
1028 device_info.setSharedMemoryPerBlock(
static_cast<Int32>(dp.sharedMemPerBlock));
1029 device_info.setSharedMemoryPerMultiprocessor(
static_cast<Int32>(dp.sharedMemPerMultiprocessor));
1030 device_info.setSharedMemoryPerBlockOptin(
static_cast<Int32>(dp.sharedMemPerBlockOptin));
1031 device_info.setTotalConstMemory(
static_cast<Int32>(dp.totalConstMem));
1032 device_info.setPCIDomainID(dp.pciDomainID);
1033 device_info.setPCIBusID(dp.pciBusID);
1034 device_info.setPCIDeviceID(dp.pciDeviceID);
1035 m_device_info_list.addDevice(device_info);
1038 Int32 global_cupti_level = 0;
1042 global_cupti_level = v.value();
1044 global_cupti_flush = v.value();
1045 bool do_print_cupti =
true;
1047 do_print_cupti = (v.value() != 0);
1049 if (global_cupti_level > 0) {
1050#ifndef ARCCORE_HAS_CUDA_CUPTI
1051 ARCCORE_FATAL(
"Trying to enable CUPTI but Arcane is not compiled with cupti support");
1053 global_cupti_info.init(global_cupti_level, do_print_cupti);
1054 global_cupti_info.start();
1075 ARCCORE_CHECK_CUDA(cudaMemcpy(to.
data(), from.
data(), from.
bytes().
size(), cudaMemcpyDefault));
1106extern "C" ARCCORE_EXPORT
void
1107arcaneRegisterAcceleratorRuntimecuda(Arcane::Accelerator::RegisterRuntimeInfo& init_info)
1109 using namespace Arcane::Accelerator::Cuda;
1110 global_cuda_runtime.build();
1111 Accelerator::Impl::setUsingCUDARuntime(
true);
1112 Accelerator::Impl::setCUDARunQueueRuntime(&global_cuda_runtime);
1113 initializeCudaMemoryAllocators();
1118 _setAllocator(&unified_memory_cuda_memory_allocator);
1119 _setAllocator(&host_pinned_cuda_memory_allocator);
1120 _setAllocator(&device_cuda_memory_allocator);
1121 mrm->
setCopier(&global_cuda_memory_copier);
1122 global_cuda_runtime.fillDevices(init_info.isVerbose());
#define ARCCORE_FATAL(...)
Macro envoyant une exception FatalErrorException.
#define ARCCORE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
Classe de base d'un allocateur spécifique pour accélérateur.
eMemoryResource memoryResource() const final
Ressource mémoire fournie par l'allocateur.
void _doInitializeDevice(bool default_use_memory_pool=false)
Initialisation pour la mémoire Device.
void _doInitializeHostPinned(bool default_use_memory_pool=false)
Initialisation pour la mémoire HostPinned.
void _doInitializeUVM(bool default_use_memory_pool=false)
Initialisation pour la mémoire UVM.
void copy(ConstMemoryView from, eMemoryResource from_mem, MutableMemoryView to, eMemoryResource to_mem, const RunQueue *queue) override
Copie les données de from vers to avec la queue queue.
void barrier() override
Bloque jusqu'à ce que toutes les actions associées à cette file soient terminées.
void notifyBeginLaunchKernel(Impl::RunCommandImpl &c) override
Notification avant le lancement de la commande.
bool _barrierNoException() override
Barrière sans exception. Retourne true en cas d'erreur.
Impl::NativeStream nativeStream() override
Pointeur sur la structure interne dépendante de l'implémentation.
void prefetchMemory(const MemoryPrefetchArgs &args) override
Effectue un pré-chargement d'une zone mémoire.
void notifyEndLaunchKernel(Impl::RunCommandImpl &) override
Notification de fin de lancement de la commande.
void copyMemory(const MemoryCopyArgs &args) override
Effectue une copie entre deux zones mémoire.
Classe singleton pour gérer CUPTI.
Map contenant l'occupation idéale pour un kernel donné.
void * allocateMemory(Int64 size) final
Alloue un bloc pour size octets.
void freeMemory(void *ptr, Int64 size) final
Libère le bloc situé à l'adresse address contenant size octets.
bool m_use_hint_as_mainly_device
Si vrai, par défaut on considère toutes les allocations comme eMemoryLocationHint::MainlyDevice.
Allocateur pour la mémoire unifiée.
void notifyMemoryArgsChanged(MemoryAllocationArgs old_args, MemoryAllocationArgs new_args, AllocatedMemoryInfo ptr) final
Notifie du changement des arguments spécifiques à l'instance.
Identifiant d'un composant du système.
bool isHost() const
Indique si l'instance est associée à l'hôte.
Int32 asInt32() const
Valeur numérique du device.
bool isAccelerator() const
Indique si l'instance est associée à un accélérateur.
Information sur un accélérateur.
Information mémoire d'un accélérateur.
Interface d'une liste de devices.
Interface d'une liste de devices.
Interface de l'implémentation d'un évènement.
Interface d'un flux d'exécution pour une RunQueue.
Interface du runtime associé à un accélérateur.
Arguments pour lancer un kernel.
bool isCooperative() const
Indique si on lance en mode coopératif (i.e. cudaLaunchCooperativeKernel).
Int32 nbBlockPerGrid() const
Nombre de blocs de la grille.
void setNbThreadPerBlock(Int32 v)
Nombre de threads par bloc.
void setNbBlockPerGrid(Int32 v)
Nombre de blocs de la grille.
Int32 nbThreadPerBlock() const
Nombre de threads par bloc.
Int32 sharedMemorySize() const
Mémoire partagée à allouer pour le noyau.
Type opaque pour encapsuler une 'stream' native.
Implémentation d'une commande pour accélérateur.
Arguments pour la copie mémoire.
Arguments pour le préfetching mémoire.
Informations sur une adresse mémoire.
Informations pour créer une RunQueue.
bool isDefault() const
Indique si l'instance a uniquement les valeurs par défaut.
File d'exécution pour un accélérateur.
bool isAsync() const
Indique si la file d'exécution est asynchrone.
void copyMemory(const MemoryCopyArgs &args) const
Copie des informations entre deux zones mémoires.
Informations sur une zone mémoire allouée.
Vue constante sur une zone mémoire contigue contenant des éléments de taille fixe.
constexpr SpanType bytes() const
Vue sous forme d'octets.
constexpr const std::byte * data() const
Pointeur sur la zone mémoire.
Classe template pour convertir un type.
Interface pour les copies mémoire avec support des accélérateurs.
Partie interne à Arcane de 'IMemoryRessourceMng'.
virtual void setAllocator(eMemoryResource r, IMemoryAllocator *allocator)=0
Positionne l'allocateur pour la ressource r.
virtual void setMemoryPool(eMemoryResource r, IMemoryPool *pool)=0
Positionne le pool mémoire pour la ressource r.
virtual void setIsAccelerator(bool v)=0
Indique si un accélérateur est disponible.
virtual void setCopier(IMemoryCopier *copier)=0
Positionne l'instance gérant les copies.
virtual IMemoryResourceMngInternal * _internal()=0
Interface interne.
Interface du gestionnaire de traces.
Classe contenant des informations pour spécialiser les allocations.
Vue modifiable sur une zone mémoire contigue contenant des éléments de taille fixe.
constexpr std::byte * data() const
Pointeur sur la zone mémoire.
constexpr SpanType bytes() const
Vue sous forme d'octets.
constexpr __host__ __device__ pointer data() const noexcept
Pointeur sur le début de la vue.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
Chaîne de caractères unicode.
const char * localstr() const
Retourne la conversion de l'instance dans l'encodage UTF-8.
eMemoryAdvice
Conseils pour la gestion mémoire.
@ AccessedByHost
Indique que la zone mémoire est accédée par l'hôte.
@ PreferredLocationDevice
Privilégié le positionnement de la mémoire sur l'accélérateur.
@ MostlyRead
Indique que la zone mémoire est principalement en lecture seule.
@ PreferredLocationHost
Privilégié le positionnement de la mémoire sur l'hôte.
@ AccessedByDevice
Indique que la zone mémoire est accédée par l'accélérateur.
ePointerMemoryType
Type de mémoire pour un pointeur.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ CUDA
Politique d'exécution utilisant l'environnement CUDA.
IMemoryRessourceMng * getDataMemoryResourceMng()
Gestionnaire de ressource mémoire pour les données.
IMemoryAllocator * setAcceleratorHostMemoryAllocator(IMemoryAllocator *a)
Positionne l'allocateur spécifique pour les accélérateurs.
void setDefaultDataMemoryResource(eMemoryResource mem_resource)
Positionne la ressource mémoire utilisée pour l'allocateur mémoire des données.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Type entier signé sur 64 bits.
eMemoryLocationHint
Indices sur la localisation mémoire attendue.
@ MainlyHost
Indique que la donnée sera plutôt utilisée sur CPU.
@ HostAndDeviceMostlyRead
Indique que la donnée sera utilisée à la fois sur accélérateur et sur CPU et qu'elle ne sera pas souv...
@ MainlyDevice
Indique que la donnée sera plutôt utilisée sur accélérateur.
double Real
Type représentant un réel.
eMemoryResource
Liste des ressources mémoire disponibles.
@ HostPinned
Alloue sur l'hôte.
@ UnifiedMemory
Alloue en utilisant la mémoire unifiée.
@ Device
Alloue sur le device.
std::int32_t Int32
Type entier signé sur 32 bits.