Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to change memory resource used for default data allocator #1808

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "arcane/utils/ITraceMng.h"
#include "arcane/utils/String.h"
#include "arcane/utils/Property.h"
#include "arcane/utils/MemoryUtils.h"

#include "arcane/accelerator/core/Runner.h"
#include "arcane/accelerator/core/DeviceId.h"
Expand Down Expand Up @@ -175,6 +176,7 @@ arcaneInitializeRunner(Accelerator::Runner& runner,ITraceMng* tm,
if (policy==eExecutionPolicy::None)
ARCANE_FATAL("Invalid policy eExecutionPolicy::None");
tm->info() << "AcceleratorRuntime=" << accelerator_runtime;
tm->info() << "DefaultDataAllocator MemoryResource=" << MemoryUtils::getDefaultDataMemoryResource();
if (impl::isAcceleratorPolicy(policy)){
tm->info() << "Using accelerator runtime=" << policy << " device=" << acc_info.deviceId();
runner.initialize(policy,acc_info.deviceId());
Expand Down
18 changes: 16 additions & 2 deletions arcane/src/arcane/impl/ArcaneMain.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
#include "arcane/utils/CommandLineArguments.h"
#include "arcane/utils/ApplicationInfo.h"
#include "arcane/utils/TestLogger.h"
#include "arcane/utils/MemoryUtils.h"
#include "arcane/utils/internal/MemoryUtilsInternal.h"

#include "arcane/core/ArcaneException.h"
#include "arcane/core/IMainFactory.h"
Expand Down Expand Up @@ -1113,7 +1115,7 @@
*
* \retval 0 si tout est OK
*
* \note Ne pas appeler directement cette méthode mais
* \note Il ne faut pas appeler directement cette méthode mais
* passer par ArcaneMainAutoDetectHelper.
*/
int ArcaneMain::
Expand All @@ -1130,7 +1132,7 @@
return 0;

try {
// Pour l'instant, seul les runtimes 'cuda' et 'hip' sont autorisés
// Pour l'instant, seul les runtimes 'cuda', 'hip' et 'sycl' sont autorisés
if (runtime_name != "cuda" && runtime_name != "hip" && runtime_name != "sycl")
ARCANE_FATAL("Invalid accelerator runtime '{0}'. Only 'cuda', 'hip' or 'sycl' is allowed", runtime_name);

Expand Down Expand Up @@ -1165,8 +1167,20 @@
if (!verbose_str.null())
runtime_info.setVerbose(true);

// Par défaut utilise la mémoire unifiée pour les données.
// Le runtime accélérateur pourra changer cela.
MemoryUtils::setDefaultDataMemoryResource(eMemoryResource::UnifiedMemory);

Check warning on line 1172 in arcane/src/arcane/impl/ArcaneMain.cc

View check run for this annotation

Codecov / codecov/patch

arcane/src/arcane/impl/ArcaneMain.cc#L1172

Added line #L1172 was not covered by tests

(*my_functor)(runtime_info);
has_accelerator = true;

// Permet de surcharger le choix de l'allocateur des données
String data_allocator_str = Arcane::platform::getEnvironmentVariable("ARCANE_DEFAULT_DATA_MEMORY_RESOURCE");

Check warning on line 1178 in arcane/src/arcane/impl/ArcaneMain.cc

View check run for this annotation

Codecov / codecov/patch

arcane/src/arcane/impl/ArcaneMain.cc#L1178

Added line #L1178 was not covered by tests
if (!data_allocator_str.null()){
eMemoryResource v = MemoryUtils::getMemoryResourceFromName(data_allocator_str);

Check warning on line 1180 in arcane/src/arcane/impl/ArcaneMain.cc

View check run for this annotation

Codecov / codecov/patch

arcane/src/arcane/impl/ArcaneMain.cc#L1180

Added line #L1180 was not covered by tests
if (v!=eMemoryResource::Unknown)
MemoryUtils::setDefaultDataMemoryResource(v);

Check warning on line 1182 in arcane/src/arcane/impl/ArcaneMain.cc

View check run for this annotation

Codecov / codecov/patch

arcane/src/arcane/impl/ArcaneMain.cc#L1182

Added line #L1182 was not covered by tests
}
}
catch (const Exception& ex) {
return arcanePrintArcaneException(ex, nullptr);
Expand Down
3 changes: 2 additions & 1 deletion arcane/src/arcane/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
set(TEST_DIRS . anyitem dof inout)
set(TEST_DIRS . anyitem dof inout)

set(TEST_LIBS ${ARCANE_ADDITIONNAL_TEST_LIBRARIES})
if(MPI_FOUND AND NOT WIN32)
Expand Down Expand Up @@ -365,6 +365,7 @@ if (ARCANE_HAS_ACCELERATOR_API)
arcane_add_test_sequential(standalone_accelerator_testsum dummy.arc "-A,StandaloneAcceleratorMethod=TestSum")
arcane_add_test_sequential(standalone_accelerator_testbinop dummy.arc "-A,StandaloneAcceleratorMethod=TestBinOp")
arcane_add_accelerator_test_sequential(standalone_accelerator_testsum dummy.arc "-A,StandaloneAcceleratorMethod=TestSum")
arcane_add_accelerator_test_sequential(standalone_accelerator_testsum_hostpinned dummy.arc "-A,StandaloneAcceleratorMethod=TestSum" "-We,ARCANE_DEFAULT_DATA_MEMORY_RESOURCE,HostPinned")
arcane_add_accelerator_test_sequential(standalone_accelerator_testbinop dummy.arc "-A,StandaloneAcceleratorMethod=TestBinOp")
arcane_add_accelerator_test_sequential(standalone_accelerator_testemptykernel dummy.arc "-A,StandaloneAcceleratorMethod=TestEmptyKernel")
endif()
Expand Down
48 changes: 46 additions & 2 deletions arcane/src/arcane/utils/MemoryUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

#include "arcane/utils/MemoryUtils.h"

#include "arcane/utils/PlatformUtils.h"
#include "arcane/utils/FatalErrorException.h"
#include "arcane/utils/MemoryAllocator.h"
#include "arcane/utils/IMemoryRessourceMng.h"
#include "arcane/utils/String.h"
#include "arcane/utils/internal/IMemoryRessourceMngInternal.h"
#include "arcane/utils/internal/MemoryUtilsInternal.h"
#include "arcane/utils/internal/MemoryResourceMng.h"
Expand All @@ -31,11 +32,54 @@
IMemoryAllocator* global_accelerator_host_memory_allocator = nullptr;
MemoryResourceMng global_default_data_memory_resource_mng;
IMemoryRessourceMng* global_data_memory_resource_mng = nullptr;
eMemoryResource global_data_memory_resource = eMemoryResource::Host;
} // namespace

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

eMemoryResource MemoryUtils::
getDefaultDataMemoryResource()
{
return global_data_memory_resource;
}

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

void MemoryUtils::
setDefaultDataMemoryResource(eMemoryResource v)
{
global_data_memory_resource = v;
}

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

eMemoryResource MemoryUtils::
getMemoryResourceFromName(const String& name)
{
eMemoryResource v = eMemoryResource::Unknown;
if (name.null())
return v;
if (name == "Device")
v = eMemoryResource::Device;
else if (name == "Host")
v = eMemoryResource::Host;
else if (name == "HostPinned")
v = eMemoryResource::HostPinned;
else if (name == "UnifiedMemory")
v = eMemoryResource::UnifiedMemory;
else
ARCANE_FATAL("Invalid name '{0}' for memory resource. Valid names are "

Check warning on line 74 in arcane/src/arcane/utils/MemoryUtils.cc

View check run for this annotation

Codecov / codecov/patch

arcane/src/arcane/utils/MemoryUtils.cc#L74

Added line #L74 was not covered by tests
"'Device', 'Host', 'HostPinned' or 'UnifieMemory'.",
name);
return v;
}

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

IMemoryRessourceMng* MemoryUtils::
setDataMemoryResourceMng(IMemoryRessourceMng* mng)
{
Expand Down Expand Up @@ -63,7 +107,7 @@
IMemoryAllocator* MemoryUtils::
getDefaultDataAllocator()
{
return getDataMemoryResourceMng()->getAllocator(eMemoryResource::UnifiedMemory);
return getDataMemoryResourceMng()->getAllocator(getDefaultDataMemoryResource());
}

/*---------------------------------------------------------------------------*/
Expand Down
63 changes: 48 additions & 15 deletions arcane/src/arcane/utils/MemoryUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,29 +29,49 @@ namespace Arcane::MemoryUtils
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
* \brief Allocateur par défaut pour les données.
* \brief Ressource mémoire utilisée par l'allocateur par défaut pour les données.
*
* Si un runtime accélérateur est initialisé, l'allocateur retourné permet
* d'allouer en mémoire unifiée et donc la zone allouée sera accessible à la
* fois sur l'accélérateur et sur l'hôte. Sinon, retourne un allocateur
* aligné.
* Par défaut, si un runtime accélérateur est initialisé, la ressource
* associé est eMemoryResource::UnifiedMemory. Sinon, il s'agit de
* eMemoryResource::Host.
*
* Il est garanti que l'alignement est au moins celui retourné par
* AlignedMemoryAllocator::Simd().
* \sa getDefaultDataAllocator();
*/
extern "C++" ARCANE_UTILS_EXPORT IMemoryAllocator*
getDefaultDataAllocator();
extern "C++" ARCANE_UTILS_EXPORT eMemoryResource
getDefaultDataMemoryResource();

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
* \brief Retourne l'allocateur sur l'hôte ou sur le device.
* \brief Retourne la ressource mémoire par son nom.
*
* Si un runtime accélérateur est initialisé, l'allocateur retourné permet
* d'allouer en utilisant la mémoire de l'accélérateur par défaut
* (eMemoryResource::Device). Sinon, utilise l'allocateur de l'hôte
* (eMemoryResource::Host).
* Le nom correspond au nom de la valeur de l'énumération (par exemple
* 'Device' pour eMemoryResource::Device.
*
* Si \a name est nul, retourn eMemoryResource::Unknown.
* Si \a name ne correspondant pas à une valeur valide, lève une exception.
*/
extern "C++" ARCANE_UTILS_EXPORT eMemoryResource
getMemoryResourceFromName(const String& name);

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
* \brief Allocateur par défaut pour les données.
*
* L'allocateur par défaut pour les données est un allocateur qui permet
* d'accéder à la zone mémoire à la fois par l'hôte et l'accélérateur.
*
* Il est possible de récupérer la ressource mémoire associée via
* getDefaultDataMemoryResource();
*
* Cet appel est équivalent à getAllocator(getDefaultDataMemoryResource()).
*
* Il est garanti que l'alignement est au moins celui retourné par
* AlignedMemoryAllocator::Simd().
*/
extern "C++" ARCANE_UTILS_EXPORT IMemoryAllocator*
getDeviceOrHostAllocator();
getDefaultDataAllocator();

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Expand All @@ -65,6 +85,19 @@ getDeviceOrHostAllocator();
extern "C++" ARCANE_UTILS_EXPORT MemoryAllocationOptions
getDefaultDataAllocator(eMemoryLocationHint hint);

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
* \brief Retourne l'allocateur sur l'hôte ou sur le device.
*
* Si un runtime accélérateur est initialisé, l'allocateur retourné permet
* d'allouer en utilisant la mémoire de l'accélérateur par défaut
* (eMemoryResource::Device). Sinon, utilise l'allocateur de l'hôte
* (eMemoryResource::Host).
*/
extern "C++" ARCANE_UTILS_EXPORT IMemoryAllocator*
getDeviceOrHostAllocator();

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
Expand Down
11 changes: 11 additions & 0 deletions arcane/src/arcane/utils/internal/MemoryUtilsInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ getDataMemoryResourceMng();
extern "C++" ARCANE_UTILS_EXPORT IMemoryAllocator*
setAcceleratorHostMemoryAllocator(IMemoryAllocator* a);

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!
* \brief Positionne la ressource mémoire utilisée pour l'allocateur
* mémoire des données.
*
* \sa getDefaultDataMemoryResource();
*/
extern "C++" ARCANE_UTILS_EXPORT void
setDefaultDataMemoryResource(eMemoryResource mem_resource);

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

Expand Down
23 changes: 23 additions & 0 deletions arcane/src/arcane/utils/tests/TestMemory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "arcane/utils/Exception.h"
#include "arcane/utils/MemoryUtils.h"
#include "arcane/utils/NumericTypes.h"
#include "arcane/utils/internal/MemoryUtilsInternal.h"

#include <random>

Expand Down Expand Up @@ -173,6 +174,28 @@ TEST(Memory, Basic)
}
}

/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
namespace
{
void _checkSetDataMemoryResource(const String& name, eMemoryResource expected_mem_resource)
{
eMemoryResource v = MemoryUtils::getMemoryResourceFromName(name);
ASSERT_EQ(v, expected_mem_resource);
MemoryUtils::setDefaultDataMemoryResource(v);
eMemoryResource v2 = MemoryUtils::getDefaultDataMemoryResource();
ASSERT_EQ(v2, expected_mem_resource);
}
} // namespace

TEST(Memory, Allocator)
{
_checkSetDataMemoryResource("Device", eMemoryResource::Device);
_checkSetDataMemoryResource("HostPinned", eMemoryResource::HostPinned);
_checkSetDataMemoryResource("Host", eMemoryResource::Host);
_checkSetDataMemoryResource("UnifiedMemory", eMemoryResource::UnifiedMemory);
}

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

Expand Down
Loading