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/IMemoryRessourceMngInternal.h"
24#include "arcane/accelerator/core/RunQueueBuildInfo.h"
25#include "arcane/accelerator/core/Memory.h"
26#include "arcane/accelerator/core/DeviceInfoList.h"
27#include "arcane/accelerator/core/RunQueue.h"
28#include "arcane/accelerator/core/DeviceMemoryInfo.h"
29#include "arcane/accelerator/core/NativeStream.h"
30#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
31#include "arcane/accelerator/core/internal/RegisterRuntimeInfo.h"
32#include "arcane/accelerator/core/internal/IRunQueueStream.h"
33#include "arcane/accelerator/core/internal/IRunQueueEventImpl.h"
37namespace Arcane::Accelerator::Sycl
40using namespace Arccore;
42#define ARCANE_SYCL_FUNC_NOT_HANDLED \
43 std::cout << "WARNING: SYCL: function not handled " << A_FUNCINFO << "\n"
50class SyclRunQueueStream
56 ~SyclRunQueueStream()
override
64 return m_runtime->notifyBeginLaunchKernel();
68 return m_runtime->notifyEndLaunchKernel();
72 m_sycl_stream->wait_and_throw();
76 m_sycl_stream->wait();
81 auto source_bytes = args.source().bytes();
82 m_sycl_stream->memcpy(args.destination().data(), source_bytes.data(),
89 auto source_bytes = args.source().bytes();
90 Int64 nb_byte = source_bytes.size();
93 m_sycl_stream->prefetch(source_bytes.data(), nb_byte);
104 sycl::event last_event;
106 last_event = *(
reinterpret_cast<sycl::event*
>(sycl_event_ptr));
107 m_last_command_event = last_event;
112 static sycl::async_handler _getAsyncHandler()
114 auto err_handler = [](
const sycl::exception_list& exceptions) {
115 std::ostringstream ostr;
116 ostr <<
"Error in SYCL runtime\n";
117 for (
const std::exception_ptr& e : exceptions) {
119 std::rethrow_exception(e);
121 catch (
const sycl::exception& e) {
122 ostr <<
"SYCL exception: " << e.what() <<
"\n";
135 sycl::queue& trueStream()
const
137 return *m_sycl_stream;
143 std::unique_ptr<sycl::queue> m_sycl_stream;
144 sycl::event m_last_command_event;
150class SyclRunQueueEvent
155 explicit SyclRunQueueEvent([[maybe_unused]]
bool has_timer)
158 ~SyclRunQueueEvent()
override
170#if defined(__ADAPTIVECPP__)
171 m_recorded_stream = stream;
173#elif defined(__INTEL_LLVM_COMPILER)
189#if defined(__ADAPTIVECPP__)
191 m_sycl_event.wait(rq->trueStream().get_wait_list());
192#elif defined(__INTEL_LLVM_COMPILER)
193 std::vector<sycl::event> events;
194 events.push_back(m_sycl_event);
196 rq->trueStream().ext_oneapi_submit_barrier(events);
202 Int64 elapsedTime([[maybe_unused]] IRunQueueEventImpl* start_event)
final
207 sycl::event
event = (
static_cast<SyclRunQueueEvent*
>(start_event))->m_sycl_event;
209 if (event==sycl::event())
212 bool is_submitted =
event.get_info<sycl::info::event::command_execution_status>() == sycl::info::event_command_status::complete;
215 Int64 start =
event.get_profiling_info<sycl::info::event_profiling::command_start>();
216 Int64 end =
event.get_profiling_info<sycl::info::event_profiling::command_end>();
217 return (end - start);
220 bool hasPendingWork()
final
227 sycl::event m_sycl_event;
237 friend class SyclRunQueueStream;
241 void notifyBeginLaunchKernel()
override
244 void notifyEndLaunchKernel()
override
247 void barrier()
override
251 m_default_queue->wait();
259 return new SyclRunQueueStream(
this, bi);
269 void setMemoryAdvice([[maybe_unused]] ConstMemoryView buffer, [[maybe_unused]]
eMemoryAdvice advice,
270 [[maybe_unused]]
DeviceId device_id)
override
273 void unsetMemoryAdvice([[maybe_unused]] ConstMemoryView buffer,
278 void setCurrentDevice([[maybe_unused]]
DeviceId device_id)
final
280 ARCANE_SYCL_FUNC_NOT_HANDLED;
282 const IDeviceInfoList* deviceInfoList()
override {
return &m_device_info_list; }
284 void getPointerAttribute(
PointerAttribute& attribute,
const void* ptr)
override
286 sycl::usm::alloc sycl_mem_type = sycl::get_pointer_type(ptr, *m_default_context);
288 const void* host_ptr =
nullptr;
289 const void* device_ptr =
nullptr;
290 if (sycl_mem_type == sycl::usm::alloc::host) {
293 mem_type = ePointerMemoryType::Host;
298 else if (sycl_mem_type == sycl::usm::alloc::device) {
299 mem_type = ePointerMemoryType::Device;
302 else if (sycl_mem_type == sycl::usm::alloc::shared) {
303 mem_type = ePointerMemoryType::Managed;
311 _fillPointerAttribute(attribute, mem_type, device_id, ptr, device_ptr, host_ptr);
319 void fillDevicesAndSetDefaultQueue(
bool is_verbose);
320 sycl::queue& defaultQueue()
const {
return *m_default_queue; }
321 sycl::device& defaultDevice()
const {
return *m_default_device; }
326 std::unique_ptr<sycl::device> m_default_device;
327 std::unique_ptr<sycl::context> m_default_context;
328 std::unique_ptr<sycl::queue> m_default_queue;
332 void _init(sycl::device& device)
334 m_default_device = std::make_unique<sycl::device>(device);
335 m_default_queue = std::make_unique<sycl::queue>(device);
336 m_default_context = std::make_unique<sycl::context>(device);
347 sycl::device& d = runtime->defaultDevice();
350 auto queue_property = sycl::property::queue::in_order();
352 auto profiling_property = sycl::property::queue::enable_profiling();
353 sycl::property_list queue_properties(queue_property, profiling_property);
356 sycl::async_handler err_handler;
357 err_handler = _getAsyncHandler();
359 m_sycl_stream = std::make_unique<sycl::queue>(d, err_handler, queue_properties);
361 ARCANE_SYCL_FUNC_NOT_HANDLED;
362 m_sycl_stream = std::make_unique<sycl::queue>(d, err_handler, queue_properties);
369void SyclRunnerRuntime::
370fillDevicesAndSetDefaultQueue(
bool is_verbose)
373 for (
auto platform : sycl::platform::get_platforms()) {
374 std::cout <<
"Platform: "
375 <<
platform.get_info<sycl::info::platform::name>()
380 sycl::device device{ sycl::gpu_selector_v };
382 std::cout <<
"\nDevice: " << device.get_info<sycl::info::device::name>()
383 <<
"\nVersion=" << device.get_info<sycl::info::device::version>()
389 DeviceInfo device_info;
390 device_info.setDescription(
"No description info");
391 device_info.setDeviceId(DeviceId(0));
392 device_info.setName(device.get_info<sycl::info::device::name>());
393 m_device_info_list.addDevice(device_info);
421namespace Arcane::Accelerator::Sycl
427void SyclMemoryCopier::
436 sycl::queue& q = global_sycl_runtime.defaultQueue();
437 q.memcpy(to.data(), from.data(), from.bytes().size()).wait();
447extern "C" ARCANE_EXPORT
void
451 using namespace Arcane::Accelerator::Sycl;
452 Arcane::Accelerator::impl::setUsingSYCLRuntime(
true);
453 Arcane::Accelerator::impl::setSYCLRunQueueRuntime(&global_sycl_runtime);
460 mrm->
setCopier(&global_sycl_memory_copier);
461 global_sycl_runtime.fillDevicesAndSetDefaultQueue(init_info.isVerbose());
462 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.
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.
Exception lorsqu'une fonction n'est pas implémentée.
Exception lorsqu'une opération n'est pas supportée.
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.
-*- 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')