Commit 0225796d authored by Eisenhauer, Greg's avatar Eisenhauer, Greg
Browse files

Remove GlobalServices, make Kokkos and PerfStubs lazy singletons

parent 056228c3
Loading
Loading
Loading
Loading
+12 −58
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
#include <atomic>
#include <fstream>
#include <ios> //std::ios_base::failure
#include <mutex>

#include "adios2/core/IO.h"
#include "adios2/helper/adiosCommDummy.h"
@@ -51,48 +50,21 @@ namespace adios2
namespace core
{

class ADIOS::GlobalServices
{
public:
    GlobalServices() {}

    ~GlobalServices() {}
static std::atomic_uint adios_count(0); // total adios objects during runtime

    void CheckStatus()
#ifdef PERFSTUBS_USE_TIMERS
struct PerfStubsGuard
{
        if (wasGlobalShutdown)
    PerfStubsGuard() { ps_initialize_(); }
    ~PerfStubsGuard() { ps_finalize_(); }
    static PerfStubsGuard &GetInstance()
    {
            helper::Throw<std::logic_error>(
                "Core", "ADIOS::GlobalServices", "CheckStatus",
                "Global Services was already shutdown. Make sure there is one "
                "true global ADIOS object that is created first and destructed "
                "last to ensure Global services are initialized only once");
        }
    }

    void Finalize() { wasGlobalShutdown = true; }

#ifdef ADIOS2_HAVE_KOKKOS
    void Init_Kokkos_API()
    {
        if (isKokkosInitialized)
            return;
        if (helper::KokkosIsInitialized())
            return;
        helper::KokkosInit();
        std::atexit(helper::KokkosFinalize);
        isKokkosInitialized = true;
        static PerfStubsGuard guard;
        return guard;
    }
    bool isKokkosInitialized = false;
#endif
    bool wasGlobalShutdown = false;
};

ADIOS::GlobalServices ADIOS::m_GlobalServices;

std::mutex PerfStubsMutex;
static std::atomic_uint adios_refcount(0); // adios objects at the same time
static std::atomic_uint adios_count(0);    // total adios objects during runtime
static void InitPerfStubs() { PerfStubsGuard::GetInstance(); }
#endif

/** User defined options from ~/.config/adios2/adios2.yaml and ~/.config/hpc-campaign/config.yaml if
 * they exist */
@@ -130,19 +102,9 @@ ADIOS::ADIOS(const std::string configFile, helper::Comm comm, const std::string
: m_HostLanguage(hostLanguage), m_Comm(std::move(comm)), m_ConfigFile(configFile),
  m_CampaignManager(m_Comm)
{
    ++adios_refcount;
    ++adios_count;
#ifdef PERFSTUBS_USE_TIMERS
    {
        std::lock_guard<std::mutex> lck(PerfStubsMutex);
        static bool perfstubsInit(false);
        if (!perfstubsInit)
        {
            PERFSTUBS_INITIALIZE();
            perfstubsInit = true;
            atexit(ps_finalize_);
        }
    }
    InitPerfStubs();
#endif
    ProcessUserConfig();
    if (!configFile.empty())
@@ -161,9 +123,6 @@ ADIOS::ADIOS(const std::string configFile, helper::Comm comm, const std::string
            m_ConfigFileContents = YAMLInit(configFile);
        }
    }
#ifdef ADIOS2_HAVE_KOKKOS
    m_GlobalServices.Init_Kokkos_API();
#endif
    if (m_UserOptions.campaign.active)
    {
        std::string campaignName =
@@ -186,11 +145,6 @@ ADIOS::ADIOS(const std::string hostLanguage) : ADIOS("", helper::CommDummy(), ho

ADIOS::~ADIOS()
{
    --adios_refcount;
    if (!adios_refcount)
    {
        m_GlobalServices.Finalize();
    }
    if (m_UserOptions.campaign.active)
    {
        m_CampaignManager.Close();
+0 −9
Original line number Diff line number Diff line
@@ -216,15 +216,6 @@ private:
    void ProcessUserConfig();
    static adios2::HostOptions LoadHostConfig();

private:
    /* Global services that we want to initialize at most once and shutdown
       automatically when the ADIOS object is destructed. This only works
       properly if the app creates an ADIOS object that is created before all
       other ADIOS objects and is destructed after all other ADIOS objects are
       destructed*/
    class GlobalServices;
    static class GlobalServices m_GlobalServices;

public:
    /** Global service AWS SDK initialization */
    static void Global_init_AWS_API();
+37 −17
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ namespace helper
{
void MemcpyGPUToBuffer(char *dst, const char *GPUbuffer, size_t byteCount)
{
    EnsureKokkosInitialized();
    using mem_space = Kokkos::DefaultExecutionSpace::memory_space;
    Kokkos::View<const char *, mem_space, Kokkos::MemoryTraits<Kokkos::Unmanaged>> srcView(
        GPUbuffer, byteCount);
@@ -64,6 +65,7 @@ void MemcpyGPUToBuffer(char *dst, const char *GPUbuffer, size_t byteCount)

void MemcpyBufferToGPU(char *GPUbuffer, const char *src, size_t byteCount)
{
    EnsureKokkosInitialized();
    using mem_space = Kokkos::DefaultExecutionSpace::memory_space;
    Kokkos::View<const char *, Kokkos::HostSpace, Kokkos::MemoryTraits<Kokkos::Unmanaged>> srcView(
        src, byteCount);
@@ -106,10 +108,15 @@ bool IsGPUbuffer(const void *ptr)
    return false;
}

void KokkosFinalize() { Kokkos::finalize(); }

void KokkosInit()
/** RAII guard that initializes Kokkos on first use and finalizes at program exit.
 *  Replaces the eager init that was previously done in every ADIOS constructor. */
struct KokkosGuard
{
    bool m_weInitialized = false;
    KokkosGuard()
    {
        if (Kokkos::is_initialized())
            return;
        Kokkos::InitializationSettings settings;
#ifdef ADIOS2_HAVE_KOKKOS_CUDA
        int device_id;
@@ -127,13 +134,26 @@ void KokkosInit()
#endif
        // GetDevice not supported for SYCL, use the default device
        Kokkos::initialize(settings);
        m_weInitialized = true;
    }
    ~KokkosGuard()
    {
        if (m_weInitialized)
            Kokkos::finalize();
    }
    static KokkosGuard &GetInstance()
    {
        static KokkosGuard guard;
        return guard;
    }
};

bool KokkosIsInitialized() { return Kokkos::is_initialized(); }
void EnsureKokkosInitialized() { KokkosGuard::GetInstance(); }

template <class T>
void GPUMinMax(const T *values, const size_t size, T &min, T &max)
{
    EnsureKokkosInitialized();
    KokkosMinMaxImpl(values, size, min, max);
}

+1 −3
Original line number Diff line number Diff line
@@ -31,9 +31,7 @@ ADIOS2_EXPORT void GPUMinMax(const T *values, const size_t size, T &min, T &max)
ADIOS2_EXPORT void MemcpyGPUToBuffer(char *dst, const char *GPUbuffer, size_t byteCount);
ADIOS2_EXPORT void MemcpyBufferToGPU(char *GPUbuffer, const char *src, size_t byteCount);

ADIOS2_EXPORT void KokkosFinalize();
ADIOS2_EXPORT void KokkosInit();
ADIOS2_EXPORT bool KokkosIsInitialized();
ADIOS2_EXPORT void EnsureKokkosInitialized();
ADIOS2_EXPORT bool IsGPUbuffer(const void *ptr);

} // helper