Skip to content

Commit

Permalink
Merge pull request arcaneframework#1282 from arcaneframework/dev/gg-a…
Browse files Browse the repository at this point in the history
…dd-null-runqueue

Add support for null RunQueue
  • Loading branch information
grospelliergilles authored Mar 20, 2024
2 parents 1b241a3 + deb8b7f commit 7317f0d
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 26 deletions.
60 changes: 52 additions & 8 deletions arcane/src/arcane/accelerator/core/RunQueue.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

#include "arcane/accelerator/core/internal/AcceleratorCoreGlobalInternal.h"
#include "arcane/accelerator/core/RunQueue.h"

#include "arcane/utils/FatalErrorException.h"

#include "arcane/accelerator/core/Runner.h"
#include "arcane/accelerator/core/internal/IRunnerRuntime.h"
#include "arcane/accelerator/core/IRunQueueStream.h"
Expand All @@ -31,6 +34,14 @@ namespace Arcane::Accelerator
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

RunQueue::
RunQueue()
{
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

RunQueue::
RunQueue(Runner& runner)
: m_p(impl::RunQueueImpl::create(runner._impl()))
Expand Down Expand Up @@ -99,10 +110,21 @@ RunQueue::
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

void RunQueue::
_checkNotNull() const
{
if (!m_p.get())
ARCANE_FATAL("Invalid operation on null RunQueue");
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/

void RunQueue::
barrier() const
{
m_p->_internalBarrier();
if (m_p)
m_p->_internalBarrier();
}

/*---------------------------------------------------------------------------*/
Expand All @@ -111,7 +133,9 @@ barrier() const
eExecutionPolicy RunQueue::
executionPolicy() const
{
return m_p->executionPolicy();
if (m_p)
return m_p->executionPolicy();
return eExecutionPolicy::None;
}

/*---------------------------------------------------------------------------*/
Expand All @@ -120,6 +144,7 @@ executionPolicy() const
impl::IRunnerRuntime* RunQueue::
_internalRuntime() const
{
_checkNotNull();
return m_p->_internalRuntime();
}

Expand All @@ -129,6 +154,7 @@ _internalRuntime() const
impl::IRunQueueStream* RunQueue::
_internalStream() const
{
_checkNotNull();
return m_p->_internalStream();
}

Expand All @@ -138,6 +164,7 @@ _internalStream() const
impl::RunCommandImpl* RunQueue::
_getCommandImpl() const
{
_checkNotNull();
return m_p->_internalCreateOrGetRunCommandImpl();
}

Expand All @@ -147,7 +174,9 @@ _getCommandImpl() const
void* RunQueue::
platformStream()
{
return m_p->_internalStream()->_internalImpl();
if (m_p)
return m_p->_internalStream()->_internalImpl();
return nullptr;
}

/*---------------------------------------------------------------------------*/
Expand All @@ -156,6 +185,7 @@ platformStream()
void RunQueue::
copyMemory(const MemoryCopyArgs& args) const
{
_checkNotNull();
_internalStream()->copyMemory(args);
}

Expand All @@ -165,6 +195,7 @@ copyMemory(const MemoryCopyArgs& args) const
void RunQueue::
prefetchMemory(const MemoryPrefetchArgs& args) const
{
_checkNotNull();
_internalStream()->prefetchMemory(args);
}

Expand All @@ -174,6 +205,7 @@ prefetchMemory(const MemoryPrefetchArgs& args) const
void RunQueue::
waitEvent(RunQueueEvent& event)
{
_checkNotNull();
auto* p = event._internalEventImpl();
return p->waitForEvent(_internalStream());
}
Expand All @@ -184,6 +216,7 @@ waitEvent(RunQueueEvent& event)
void RunQueue::
waitEvent(Ref<RunQueueEvent>& event)
{
_checkNotNull();
waitEvent(*event.get());
}

Expand All @@ -193,6 +226,7 @@ waitEvent(Ref<RunQueueEvent>& event)
void RunQueue::
recordEvent(RunQueueEvent& event)
{
_checkNotNull();
auto* p = event._internalEventImpl();
return p->recordQueue(_internalStream());
}
Expand All @@ -203,6 +237,7 @@ recordEvent(RunQueueEvent& event)
void RunQueue::
recordEvent(Ref<RunQueueEvent>& event)
{
_checkNotNull();
recordEvent(*event.get());
}

Expand All @@ -212,6 +247,7 @@ recordEvent(Ref<RunQueueEvent>& event)
void RunQueue::
setAsync(bool v)
{
_checkNotNull();
m_p->m_is_async = v;
}

Expand All @@ -221,7 +257,9 @@ setAsync(bool v)
bool RunQueue::
isAsync() const
{
return m_p->m_is_async;
if (m_p)
return m_p->m_is_async;
return false;
}

/*---------------------------------------------------------------------------*/
Expand All @@ -230,6 +268,7 @@ isAsync() const
bool RunQueue::
_isAutoPrefetchCommand() const
{
_checkNotNull();
return m_p->m_runner_impl->isAutoPrefetchCommand();
}

Expand All @@ -248,7 +287,9 @@ isAcceleratorPolicy() const
MemoryAllocationOptions RunQueue::
allocationOptions() const
{
return m_p->allocationOptions();
if (m_p)
return m_p->allocationOptions();
return {};
}

/*---------------------------------------------------------------------------*/
Expand All @@ -257,6 +298,7 @@ allocationOptions() const
void RunQueue::
setMemoryRessource(eMemoryRessource mem)
{
_checkNotNull();
m_p->m_memory_ressource = mem;
}

Expand All @@ -266,7 +308,9 @@ setMemoryRessource(eMemoryRessource mem)
eMemoryRessource RunQueue::
memoryRessource() const
{
return m_p->m_memory_ressource;
if (m_p)
return m_p->m_memory_ressource;
return eMemoryRessource::Unknown;
}

/*---------------------------------------------------------------------------*/
Expand All @@ -275,7 +319,7 @@ memoryRessource() const
extern "C++" ePointerAccessibility
getPointerAccessibility(RunQueue* queue, const void* ptr, PointerAttribute* ptr_attr)
{
if (!queue)
if (!queue || queue->isNull())
return ePointerAccessibility::Unknown;
return impl::RuntimeStaticInfo::getPointerAccessibility(queue->executionPolicy(), ptr, ptr_attr);
}
Expand All @@ -284,7 +328,7 @@ extern "C++" void impl::
arcaneCheckPointerIsAcccessible(RunQueue* queue, const void* ptr,
const char* name, const TraceInfo& ti)
{
if (!queue)
if (!queue || queue->isNull())
return;
return impl::RuntimeStaticInfo::checkPointerIsAcccessible(queue->executionPolicy(), ptr, name, ti);
}
Expand Down
67 changes: 49 additions & 18 deletions arcane/src/arcane/accelerator/core/RunQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,31 @@ namespace Arcane::Accelerator
/*!
* \brief File d'exécution pour un accélérateur.
*
* Cette classe a une sémantique par référence. La file d'exécution est
* Cette classe utilise une sémantique par référence. La file d'exécution est
* détruite lorsque la dernière référence dessus est détruite.
*
* Une file est attachée à une politique d'exécution et permet d'exécuter
* des commandes (RunCommand) sur un accélérateur ou sur le CPU.
* Une file est attachée à une instance de Runner et permet d'exécuter
* des commandes (RunCommand) sur un accélérateur ou sur le CPU. La méthode
* executionPolicy() permet de savoir où s'exécutera les commandes issues
* de la file.
*
* Les instances de cette classe sont créés par l'appel à makeQueue(Runner).
* Les instances de cette classe sont créées par l'appel à makeQueue(Runner).
* On peut ensuite créer des noyaux de calcul (RunCommand) via l'appel
* à makeCommand().
*
* Le constructeur par défaut construit Une file nulle qui ne peut pas être
* utilisée pour lancer des commandes. Les seules opérations autorisées sur
* la file nulle sont isNull(), executionPolicy(), isAcceleratorPolicy(),
* barrier(), allocationOptions() et memoryRessource().
*
* Les méthodes de cette classe ne sont pas thread-safe pour une même instance.
*/
class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
{
friend class RunCommand;
friend class impl::RunCommandLaunchInfo;
friend RunCommand makeCommand(const RunQueue& run_queue);
friend RunCommand makeCommand(const RunQueue* run_queue);

public:

Expand Down Expand Up @@ -75,6 +86,8 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue

public:

//! Créé une file nulle.
RunQueue();
//! Créé une file associée à \a runner avec les paramètres par défaut
explicit RunQueue(Runner& runner);
//! Créé une file associée à \a runner avec les paramètres \a bi
Expand All @@ -90,19 +103,27 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue

public:

//! Indique si la RunQueue est nulle
bool isNull() const { return !m_p; }

//! Politique d'exécution de la file.
eExecutionPolicy executionPolicy() const;
//! Indique si l'instance est associée à un accélérateur
bool isAcceleratorPolicy() const;

/*!
* \brief Positionne l'asynchronisme de l'instance.
*
* Si l'instance est asynchrone, il faut appeler explicitement barrier()
* Si l'instance est asynchrone, les différentes commandes
* associées ne sont pas bloquantes et il faut appeler explicitement barrier()
* pour attendre la fin de l'exécution des commandes.
*
* \pre !isNull()
*/
void setAsync(bool v);
//! Indique si la file d'exécution est asynchrone.
bool isAsync() const;

//! Bloque tant que toutes les commandes associées à la file ne sont pas terminées.
void barrier() const;

Expand All @@ -111,6 +132,11 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
//! Effectue un préfetching de la mémoire
void prefetchMemory(const MemoryPrefetchArgs& args) const;

/*!
* \name Gestion des évènements
* \pre !isNull()
*/
//!@{
//! Enregistre l'état de l'instance dans \a event.
void recordEvent(RunQueueEvent& event);
//! Enregistre l'état de l'instance dans \a event.
Expand All @@ -119,8 +145,10 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
void waitEvent(RunQueueEvent& event);
//! Bloque l'exécution sur l'instance tant que les jobs enregistrés dans \a event ne sont pas terminés
void waitEvent(Ref<RunQueueEvent>& event);
//!@}

//@{ \brief Gestion mémoire
//! \name Gestion mémoire
//!@{
/*!
* \brief Options d'allocation associée à cette file.
*
Expand All @@ -137,33 +165,34 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
*
* \sa memoryRessource()
* \sa allocationOptions()
*
* \pre !isNull()
*/
void setMemoryRessource(eMemoryRessource mem);

/*!
* \brief Ressource mémoire utilisée pour les allocations avec cette instance.
*/
//! Ressource mémoire utilisée pour les allocations avec cette instance.
eMemoryRessource memoryRessource() const;
//@}
//!@}

public:

/*!
* \brief Pointeur sur la structure interne dépendante de l'implémentation.
*
* Cette méthode est réservée à un usage avancée.
* La file retournée ne doit pas être conservée au delà de la vie de l'instance.
*
* Avec CUDA, le pointeur retourné est un 'cudaStream_t*'. Avec HIP, il
* s'agit d'un 'hipStream_t*'.
*/
* \brief Pointeur sur la structure interne dépendante de l'implémentation.
*
* Cette méthode est réservée à un usage avancée.
* La file retournée ne doit pas être conservée au delà de la vie de l'instance.
*
* Avec CUDA, le pointeur retourné est un 'cudaStream_t*'. Avec HIP, il
* s'agit d'un 'hipStream_t*'.
*/
void* platformStream();

private:

impl::IRunnerRuntime* _internalRuntime() const;
impl::IRunQueueStream* _internalStream() const;
impl::RunCommandImpl* _getCommandImpl() const;
void _checkNotNull() const;

// Pour VariableViewBase
friend class VariableViewBase;
Expand All @@ -185,6 +214,7 @@ class ARCANE_ACCELERATOR_CORE_EXPORT RunQueue
inline RunCommand
makeCommand(const RunQueue& run_queue)
{
run_queue._checkNotNull();
return RunCommand(run_queue);
}

Expand All @@ -195,6 +225,7 @@ inline RunCommand
makeCommand(const RunQueue* run_queue)
{
ARCANE_CHECK_POINTER(run_queue);
run_queue->_checkNotNull();
return RunCommand(*run_queue);
}

Expand Down
Loading

0 comments on commit 7317f0d

Please sign in to comment.