14#include "arcane/accelerator/cuda/CudaAccelerator.h"
16#include "arcane/utils/PlatformUtils.h"
17#include "arcane/utils/Array.h"
18#include "arcane/utils/TraceInfo.h"
19#include "arcane/utils/NotSupportedException.h"
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/NotImplementedException.h"
22#include "arcane/utils/IMemoryRessourceMng.h"
23#include "arcane/utils/MemoryView.h"
24#include "arcane/utils/OStringStream.h"
25#include "arcane/utils/ValueConvert.h"
26#include "arcane/utils/internal/IMemoryRessourceMngInternal.h"
28#include "arcane/accelerator/core/RunQueueBuildInfo.h"
29#include "arcane/accelerator/core/Memory.h"
30#include "arcane/accelerator/core/DeviceInfoList.h"
32#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
33#include "arcane/accelerator/core/internal/RegisterRuntimeInfo.h"
34#include "arcane/accelerator/core/internal/RunCommandImpl.h"
35#include "arcane/accelerator/core/internal/IRunQueueStream.h"
36#include "arcane/accelerator/core/internal/IRunQueueEventImpl.h"
37#include "arcane/accelerator/core/PointerAttribute.h"
38#include "arcane/accelerator/core/RunQueue.h"
39#include "arcane/accelerator/cuda/runtime/internal/Cupti.h"
45#ifdef ARCANE_HAS_CUDA_NVTOOLSEXT
46#include <nvtx3/nvToolsExt.h>
51namespace Arcane::Accelerator::Cuda
55 Int32 global_cupti_flush = 0;
56 CuptiInfo global_cupti_info;
62void arcaneCheckCudaErrors(
const TraceInfo& ti, CUresult e)
64 if (e == CUDA_SUCCESS)
66 const char* error_name =
nullptr;
67 CUresult e2 = cuGetErrorName(e, &error_name);
68 if (e2 != CUDA_SUCCESS)
69 error_name =
"Unknown";
71 const char* error_message =
nullptr;
72 CUresult e3 = cuGetErrorString(e, &error_message);
73 if (e3 != CUDA_SUCCESS)
74 error_message =
"Unknown";
76 ARCANE_FATAL(
"CUDA Error trace={0} e={1} name={2} message={3}",
77 ti, e, error_name, error_message);
83void _printUUID(std::ostream& o,
char bytes[16])
85 static const char hexa_chars[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f' };
87 for (
int i = 0; i < 16; ++i) {
88 o << hexa_chars[(bytes[i] >> 4) & 0xf];
89 o << hexa_chars[bytes[i] & 0xf];
90 if (i == 4 || i == 6 || i == 8 || i == 10)
109 int priority =
bi.priority();
122#ifdef ARCANE_HAS_CUDA_NVTOOLSEXT
123 auto kname =
c.kernelName();
129 return m_runtime->notifyBeginLaunchKernel();
133#ifdef ARCANE_HAS_CUDA_NVTOOLSEXT
136 return m_runtime->notifyEndLaunchKernel();
153 ARCANE_CHECK_CUDA(
r);
159 auto src = args.source().bytes();
168 ARCANE_CHECK_CUDA(
r);
174 return &m_cuda_stream;
181 return m_cuda_stream;
263 void notifyBeginLaunchKernel()
override
265 ++m_nb_kernel_launched;
267 std::cout <<
"BEGIN CUDA KERNEL!\n";
269 void notifyEndLaunchKernel()
override
273 std::cout <<
"END CUDA KERNEL!\n";
275 void barrier()
override
297 auto v = buffer.bytes();
298 const void*
ptr = v.data();
299 size_t count = v.size();
324 auto v = buffer.bytes();
325 const void*
ptr = v.data();
326 size_t count = v.size();
353 ARCANE_FATAL(
"Device {0} is not an accelerator device",
id);
357 const IDeviceInfoList* deviceInfoList()
final {
return &m_device_info_list; }
359 void startProfiling()
override
364 void stopProfiling()
override
369 bool isProfilingActive()
override
382 ptr,
ca.devicePointer,
ca.hostPointer);
387#ifdef ARCANE_HAS_CUDA_NVTOOLSEXT
405 void popProfilerRange()
override
407#ifdef ARCANE_HAS_CUDA_NVTOOLSEXT
414 finalizeCudaMemoryAllocators(
tm);
419 void fillDevices(
bool is_verbose);
423 Int64 m_nb_kernel_launched = 0;
424 bool m_is_verbose =
false;
431void CudaRunnerRuntime::
432fillDevices(
bool is_verbose)
436 std::ostream&
omain = std::cout;
438 omain <<
"ArcaneCUDA: Initialize Arcane CUDA runtime nb_available_device=" <<
nb_device <<
"\n";
443 std::ostream& o =
ostr.stream();
444 o <<
"Device " << i <<
" name=" <<
dp.name <<
"\n";
445 o <<
" computeCapability = " <<
dp.major <<
"." <<
dp.minor <<
"\n";
446 o <<
" totalGlobalMem = " <<
dp.totalGlobalMem <<
"\n";
447 o <<
" sharedMemPerBlock = " <<
dp.sharedMemPerBlock <<
"\n";
448 o <<
" regsPerBlock = " <<
dp.regsPerBlock <<
"\n";
449 o <<
" warpSize = " <<
dp.warpSize <<
"\n";
450 o <<
" memPitch = " <<
dp.memPitch <<
"\n";
451 o <<
" maxThreadsPerBlock = " <<
dp.maxThreadsPerBlock <<
"\n";
452 o <<
" totalConstMem = " <<
dp.totalConstMem <<
"\n";
453 o <<
" clockRate = " <<
dp.clockRate <<
"\n";
454 o <<
" deviceOverlap = " <<
dp.deviceOverlap <<
"\n";
455 o <<
" multiProcessorCount = " <<
dp.multiProcessorCount <<
"\n";
456 o <<
" kernelExecTimeoutEnabled = " <<
dp.kernelExecTimeoutEnabled <<
"\n";
457 o <<
" integrated = " <<
dp.integrated <<
"\n";
458 o <<
" canMapHostMemory = " <<
dp.canMapHostMemory <<
"\n";
459 o <<
" computeMode = " <<
dp.computeMode <<
"\n";
460 o <<
" maxThreadsDim = " <<
dp.maxThreadsDim[0] <<
" " <<
dp.maxThreadsDim[1]
461 <<
" " <<
dp.maxThreadsDim[2] <<
"\n";
462 o <<
" maxGridSize = " <<
dp.maxGridSize[0] <<
" " <<
dp.maxGridSize[1]
463 <<
" " <<
dp.maxGridSize[2] <<
"\n";
481 omain << description;
490 Int32 global_cupti_level = 0;
493 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_CUPTI_LEVEL",
true))
494 global_cupti_level = v.value();
495 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_CUPTI_FLUSH",
true))
496 global_cupti_flush = v.value();
497 bool do_print_cupti =
true;
498 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_CUPTI_PRINT",
true))
499 do_print_cupti = (v.value() != 0);
501 if (global_cupti_level > 0) {
502#ifndef ARCANE_HAS_CUDA_CUPTI
503 ARCANE_FATAL(
"Trying to enable CUPTI but Arcane is not compiled with cupti support");
505 global_cupti_info.init(global_cupti_level, do_print_cupti);
506 global_cupti_info.start();
547extern "C" ARCANE_EXPORT
void
551 using namespace Arcane::Accelerator::Cuda;
552 Arcane::Accelerator::impl::setUsingCUDARuntime(
true);
554 initializeCudaMemoryAllocators();
557 mrm->setIsAccelerator(
true);
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
void copy(ConstMemoryView from, eMemoryRessource from_mem, MutableMemoryView to, eMemoryRessource to_mem, const RunQueue *queue) override
Copie les données de from vers to avec la queue queue.
void notifyBeginLaunchKernel(impl::RunCommandImpl &c) override
Notification avant le lancement de la commande.
void barrier() override
Bloque jusqu'à ce que toutes les actions associées à cette file soient terminées.
bool _barrierNoException() override
Barrière sans exception. Retourne true en cas d'erreur.
void prefetchMemory(const MemoryPrefetchArgs &args) override
Effectue un pré-chargement d'une zone mémoire.
void * _internalImpl() override
Pointeur sur la structure interne dépendante de l'implémentation.
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.
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.
Information sur un device.
Interface d'une liste de devices.
Arguments pour la copie mémoire.
Arguments pour le préfetching mémoire.
Informations sur une adresse mémoire.
Informations pour initialiser le runtime accélérateur.
Informations pour créer une RunQueue.
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.
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é à une RunQueue.
Implémentation d'une commande pour accélérateur.
Interface pour les copies mémoire avec support des accélérateurs.
Partie interne à Arcane de 'IMemoryRessourceMng'.
virtual IMemoryRessourceMngInternal * _internal()=0
Interface interne.
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Flot de sortie lié à une String.
Interface du gestionnaire de traces.
Chaîne de caractères unicode.
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.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
eMemoryRessource
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.
Espace de nom de Arccore.
std::int64_t Int64
Type entier signé sur 64 bits.
std::int32_t Int32
Type entier signé sur 32 bits.