From 0fbdbb833021f5de5d2d89237135f3ec9080065f Mon Sep 17 00:00:00 2001 From: Josep Pocurull Serra Date: Thu, 14 Dec 2023 19:11:10 +0100 Subject: [PATCH] ENH: add profiling hooks for Extrae into the OpenFOAM profiling (#3043) - the hooks are defined as weak symbols and are compiled into OpenFOAM by default. If the library is not loaded (via LD_PRELOAD) the hooks have no effect. - https://tools.bsc.es/extrae - https://tools.bsc.es/paraver --- CONTRIBUTORS.md | 1 + src/OpenFOAM/Make/options | 6 + .../global/profiling/profilingTrigger.C | 117 ++++++++++++++++++ 3 files changed, 124 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 76cfb3487d..d4744fce46 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -46,6 +46,7 @@ It is likely incomplete... - Victor Olesen - Evangelos Papoutsis-Kiachagias - Juho Peltola +- Josep Pocurull - Johan Roenby - Henrik Rusche - Bruno Santos diff --git a/src/OpenFOAM/Make/options b/src/OpenFOAM/Make/options index a214db6653..14c87912a7 100644 --- a/src/OpenFOAM/Make/options +++ b/src/OpenFOAM/Make/options @@ -10,6 +10,12 @@ ifeq (,$(findstring ~libz,$(WM_COMPILE_CONTROL))) LIB_LIBS += -lz endif +/* extrae profiling hooks [https://tools.bsc.es/extrae] */ +ifeq (,$(findstring windows,$(WM_OSTYPE))) +ifeq (,$(findstring ~extrae,$(WM_COMPILE_CONTROL))) + EXE_INC += -DHAVE_EXTRAE +endif +endif /* Never self-link (WM_PROJECT == OpenFOAM), but do link to Pstream */ diff --git a/src/OpenFOAM/global/profiling/profilingTrigger.C b/src/OpenFOAM/global/profiling/profilingTrigger.C index 341baae0a8..95d6fadc63 100644 --- a/src/OpenFOAM/global/profiling/profilingTrigger.C +++ b/src/OpenFOAM/global/profiling/profilingTrigger.C @@ -7,6 +7,7 @@ ------------------------------------------------------------------------------- Copyright (C) 2009-2016 Bernhard Gschaider Copyright (C) 2016-2023 OpenCFD Ltd. + Copyright (C) 2023 Josep Pocurull Serra, Barcelona Supercomputing Center ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -30,6 +31,115 @@ License #include "profilingTrigger.H" #include "profilingInformation.H" +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// Extrae profiling hooks +// ---------------------- +// https://tools.bsc.es/extrae +// ---------------------- + +#ifdef HAVE_EXTRAE +#include +#include + +// Weak functions for Extrae C api +extern "C" +{ + typedef unsigned extrae_type_t; + typedef unsigned long long extrae_value_t; + + // Adds to the Paraver Configuration File human readable information + // regarding type and its values. + void Extrae_define_event_type + ( + extrae_type_t *type, + char *type_description, + unsigned *nvalues, + extrae_value_t *values, + char **values_description + ) __attribute__((weak)); + + // Adds a single timestamped event into the tracefile + void Extrae_event + ( + extrae_type_t type, + extrae_value_t value + ) __attribute__((weak)); + +} // End extern "C" + + +// Descriptor for the events +static char myExtrae_description[] = "OpenFOAM Extrae Profiling"; + +static void open_extrae_region(const std::string& name) +{ + // Event history (by name) of profiling triggers + static std::map event_history; + + // Scratch space for transcribing map -> flat lists + static Foam::DynamicList eventNames; + static Foam::DynamicList eventValues; + + + if (event_history.empty()) + { + event_history.insert(std::make_pair("End", 0)); + } + + extrae_type_t event_type = 7000; + extrae_value_t event_name; + + // Check if there is already an event with that name + auto iter = event_history.find(name); + if (iter != event_history.end()) + { + event_name = iter->second; + } + else + { + // Update extrae defined events + + event_name = static_cast(event_history.size()); + event_history.insert(std::make_pair(name, event_name)); + + unsigned numEvents = event_history.size(); + + const Foam::label len(numEvents); + + eventNames.resize_nocopy(len); + eventValues.resize_nocopy(len); + + Foam::label i = 0; + for (const auto& iter : event_history) + { + eventNames[i] = const_cast(iter.first.data()); + eventValues[i] = iter.second; + ++i; + } + + Extrae_define_event_type + ( + &event_type, + myExtrae_description, + &numEvents, + eventValues.data(), + eventNames.data() + ); + } + + Extrae_event(event_type, event_name); +} + + +static void close_extrae_region() +{ + Extrae_event(7000, 0); +} + +#endif /* HAVE_EXTRAE */ + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // Foam::profilingTrigger::profilingTrigger() noexcept @@ -48,6 +158,9 @@ Foam::profilingTrigger::profilingTrigger(const std::string& name) : ptr_(profiling::New(name)) { + #ifdef HAVE_EXTRAE + if (Extrae_event) open_extrae_region(std::string(name)); + #endif } @@ -69,6 +182,10 @@ bool Foam::profilingTrigger::running() const noexcept void Foam::profilingTrigger::stop() { + #ifdef HAVE_EXTRAE + if (Extrae_event) close_extrae_region(); + #endif + if (ptr_) { // profiling info pointer managed by pool storage, so no delete here