14#include "arcane/accelerator/sycl/SyclAccelerator.h"
15#include "arcane/accelerator/sycl/internal/SyclAcceleratorInternal.h"
17#include "arcane/utils/PlatformUtils.h"
18#include "arcane/utils/NotSupportedException.h"
19#include "arcane/utils/NotImplementedException.h"
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/IMemoryRessourceMng.h"
22#include "arcane/utils/internal/MemoryUtilsInternal.h"
23#include "arcane/utils/internal/IMemoryRessourceMngInternal.h"
25#include "arcane/accelerator/core/RunQueueBuildInfo.h"
26#include "arcane/accelerator/core/Memory.h"
27#include "arcane/accelerator/core/DeviceInfoList.h"
28#include "arcane/accelerator/core/RunQueue.h"
29#include "arcane/accelerator/core/DeviceMemoryInfo.h"
30#include "arcane/accelerator/core/NativeStream.h"
31#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
32#include "arcane/accelerator/core/internal/RegisterRuntimeInfo.h"
33#include "arcane/accelerator/core/internal/IRunQueueStream.h"
34#include "arcane/accelerator/core/internal/IRunQueueEventImpl.h"
38namespace Arcane::Accelerator::Sycl
41using namespace Arccore;
43#define ARCANE_SYCL_FUNC_NOT_HANDLED \
44 std::cout << "WARNING: SYCL: function not handled " << A_FUNCINFO << "\n"
51class SyclRunQueueStream
57 ~SyclRunQueueStream()
override
65 return m_runtime->notifyBeginLaunchKernel();
69 return m_runtime->notifyEndLaunchKernel();
73 m_sycl_stream->wait_and_throw();
77 m_sycl_stream->wait();
82 auto source_bytes = args.source().
bytes();
83 m_sycl_stream->memcpy(args.destination().
data(), source_bytes.data(),
90 auto source_bytes = args.source().bytes();
91 Int64 nb_byte = source_bytes.size();
94 m_sycl_stream->prefetch(source_bytes.data(), nb_byte);
105 sycl::event last_event;
107 last_event = *(
reinterpret_cast<sycl::event*
>(sycl_event_ptr));
108 m_last_command_event = last_event;
113 static sycl::async_handler _getAsyncHandler()
115 auto err_handler = [](
const sycl::exception_list& exceptions) {
116 std::ostringstream ostr;
117 ostr <<
"Error in SYCL runtime\n";
118 for (
const std::exception_ptr& e : exceptions) {
120 std::rethrow_exception(e);
122 catch (
const sycl::exception& e) {
123 ostr <<
"SYCL exception: " << e.what() <<
"\n";
136 sycl::queue& trueStream()
const
138 return *m_sycl_stream;
144 std::unique_ptr<sycl::queue> m_sycl_stream;
145 sycl::event m_last_command_event;
151class SyclRunQueueEvent
156 explicit SyclRunQueueEvent([[maybe_unused]]
bool has_timer)
159 ~SyclRunQueueEvent()
override
171#if defined(__ADAPTIVECPP__)
172 m_recorded_stream = stream;
174#elif defined(__INTEL_LLVM_COMPILER)
190#if defined(__ADAPTIVECPP__)
192 m_sycl_event.wait(rq->trueStream().get_wait_list());
193#elif defined(__INTEL_LLVM_COMPILER)
194 std::vector<sycl::event> events;
195 events.push_back(m_sycl_event);
197 rq->trueStream().ext_oneapi_submit_barrier(events);
203 Int64 elapsedTime([[maybe_unused]] IRunQueueEventImpl* start_event)
final
208 sycl::event
event = (
static_cast<SyclRunQueueEvent*
>(start_event))->m_sycl_event;
210 if (event==sycl::event())
213 bool is_submitted =
event.get_info<sycl::info::event::command_execution_status>() == sycl::info::event_command_status::complete;
216 Int64 start =
event.get_profiling_info<sycl::info::event_profiling::command_start>();
217 Int64 end =
event.get_profiling_info<sycl::info::event_profiling::command_end>();
218 return (end - start);
221 bool hasPendingWork()
final
228 sycl::event m_sycl_event;
238 friend class SyclRunQueueStream;
242 void notifyBeginLaunchKernel()
override
245 void notifyEndLaunchKernel()
override
248 void barrier()
override
252 m_default_queue->wait();
260 return new SyclRunQueueStream(
this, bi);
271 [[maybe_unused]]
DeviceId device_id)
override
279 void setCurrentDevice([[maybe_unused]]
DeviceId device_id)
final
281 ARCANE_SYCL_FUNC_NOT_HANDLED;
283 const IDeviceInfoList* deviceInfoList()
override {
return &m_device_info_list; }
285 void getPointerAttribute(
PointerAttribute& attribute,
const void* ptr)
override
287 sycl::usm::alloc sycl_mem_type = sycl::get_pointer_type(ptr, *m_default_context);
289 const void* host_ptr =
nullptr;
290 const void* device_ptr =
nullptr;
291 if (sycl_mem_type == sycl::usm::alloc::host) {
294 mem_type = ePointerMemoryType::Host;
299 else if (sycl_mem_type == sycl::usm::alloc::device) {
300 mem_type = ePointerMemoryType::Device;
303 else if (sycl_mem_type == sycl::usm::alloc::shared) {
304 mem_type = ePointerMemoryType::Managed;
312 _fillPointerAttribute(attribute, mem_type, device_id, ptr, device_ptr, host_ptr);
320 void fillDevicesAndSetDefaultQueue(
bool is_verbose);
321 sycl::queue& defaultQueue()
const {
return *m_default_queue; }
322 sycl::device& defaultDevice()
const {
return *m_default_device; }
327 std::unique_ptr<sycl::device> m_default_device;
328 std::unique_ptr<sycl::context> m_default_context;
329 std::unique_ptr<sycl::queue> m_default_queue;
333 void _init(sycl::device& device)
335 m_default_device = std::make_unique<sycl::device>(device);
336 m_default_queue = std::make_unique<sycl::queue>(device);
337 m_default_context = std::make_unique<sycl::context>(device);
348 sycl::device& d = runtime->defaultDevice();
351 auto queue_property = sycl::property::queue::in_order();
353 auto profiling_property = sycl::property::queue::enable_profiling();
354 sycl::property_list queue_properties(queue_property, profiling_property);
357 sycl::async_handler err_handler;
358 err_handler = _getAsyncHandler();
360 m_sycl_stream = std::make_unique<sycl::queue>(d, err_handler, queue_properties);
362 ARCANE_SYCL_FUNC_NOT_HANDLED;
363 m_sycl_stream = std::make_unique<sycl::queue>(d, err_handler, queue_properties);
370void SyclRunnerRuntime::
371fillDevicesAndSetDefaultQueue(
bool is_verbose)
374 for (
auto platform : sycl::platform::get_platforms()) {
375 std::cout <<
"Platform: "
376 <<
platform.get_info<sycl::info::platform::name>()
381 sycl::device device{ sycl::gpu_selector_v };
383 std::cout <<
"\nDevice: " << device.get_info<sycl::info::device::name>()
384 <<
"\nVersion=" << device.get_info<sycl::info::device::version>()
390 DeviceInfo device_info;
391 device_info.setDescription(
"No description info");
392 device_info.setDeviceId(DeviceId(0));
393 device_info.setName(device.get_info<sycl::info::device::name>());
394 m_device_info_list.addDevice(device_info);
422namespace Arcane::Accelerator::Sycl
428void SyclMemoryCopier::
437 sycl::queue& q = global_sycl_runtime.defaultQueue();
448extern "C" ARCANE_EXPORT
void
452 using namespace Arcane::Accelerator::Sycl;
453 Arcane::Accelerator::impl::setUsingSYCLRuntime(
true);
454 Arcane::Accelerator::impl::setSYCLRunQueueRuntime(&global_sycl_runtime);
462 mrm->
setCopier(&global_sycl_memory_copier);
463 global_sycl_runtime.fillDevicesAndSetDefaultQueue(init_info.isVerbose());
464 setSyclMemoryQueue(global_sycl_runtime.defaultQueue());
#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_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Identifiant d'un composant du système.
Information mémoire d'un accélérateur.
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.
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.
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.
impl::NativeStream nativeStream() override
Pointeur sur la structure interne dépendante de l'implémentation.
void barrier() override
Bloque jusqu'à ce que toutes les actions associées à cette file soient terminées.
sycl::event lastCommandEvent()
Évènement correspondant à la dernière commande.
void prefetchMemory(const MemoryPrefetchArgs &args) override
Effectue un pré-chargement d'une zone mémoire.
void copyMemory(const MemoryCopyArgs &args) override
Effectue une copie entre deux zones mémoire.
bool _barrierNoException() override
Barrière sans exception. Retourne true en cas d'erreur.
void _setSyclLastCommandEvent(void *sycl_event_ptr) override
Pour SYCL, positionne l'évènement associé à la dernière commande exécutée.
void notifyEndLaunchKernel(impl::RunCommandImpl &) override
Notification de fin de lancement de la commande.
void notifyBeginLaunchKernel(impl::RunCommandImpl &c) override
Notification avant le lancement de la commande.
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.
Type opaque pour encapsuler une 'stream' native.
Implémentation d'une commande pour accélérateur.
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.
Interface pour les copies mémoire avec support des accélérateurs.
virtual IMemoryRessourceMngInternal * _internal()=0
Interface interne.
Partie interne à Arcane de 'IMemoryRessourceMng'.
virtual void setAllocator(eMemoryRessource r, IMemoryAllocator *allocator)=0
Positionne l'allocateur pour la ressource r.
virtual void setCopier(IMemoryCopier *copier)=0
Positionne l'instance gérant les copies.
virtual void setIsAccelerator(bool v)=0
Indique si un accélérateur est disponible.
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.
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
constexpr __host__ __device__ SizeType size() const noexcept
Retourne la taille du tableau.
eMemoryAdvice
Conseils pour la gestion mémoire.
ePointerMemoryType
Type de mémoire pour un pointeur.
eExecutionPolicy
Politique d'exécution pour un Runner.
@ SYCL
Politique d'exécution utilisant l'environnement SYCL.
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 -*-
@ HostPinned
Alloue sur l'hôte.
@ UnifiedMemory
Alloue en utilisant la mémoire unifiée.
@ Device
Alloue sur le device.
Arcane::eMemoryResource eMemoryRessource
Typedef pour la version Arcane historique (avec 2's')