From cdbad963b01b7205b1065f6ca6e90b65318fe387 Mon Sep 17 00:00:00 2001 From: Alejandro Gallo Date: Tue, 30 Nov 2021 12:04:44 +0100 Subject: [PATCH] Add user printing mechanism (cherry pick) --- atrip.org | 97 +++++++++++++++++++++++++++++++++-------- include/atrip/Atrip.hpp | 3 +- include/atrip/Debug.hpp | 47 ++++++++++++++++---- src/atrip/Atrip.cxx | 32 +++++++++----- 4 files changed, 142 insertions(+), 37 deletions(-) diff --git a/atrip.org b/atrip.org index a69fa03..72d2601 100644 --- a/atrip.org +++ b/atrip.org @@ -1847,7 +1847,7 @@ namespace atrip { , *Vhhhp = nullptr , *Vppph = nullptr ; - int maxIterations = 0, iterationMod = -1; + int maxIterations = 0, iterationMod = -1, percentageMod = -1; bool barrier = false; bool chrono = false; Input& with_epsilon_i(CTF::Tensor * t) { ei = t; return *this; } @@ -1859,6 +1859,7 @@ namespace atrip { Input& with_Vabci(CTF::Tensor * t) { Vppph = t; return *this; } Input& with_maxIterations(int i) { maxIterations = i; return *this; } Input& with_iterationMod(int i) { iterationMod = i; return *this; } + Input& with_percentageMod(int i) { percentageMod = i; return *this; } Input& with_barrier(bool i) { barrier = i; return *this; } Input& with_chrono(bool i) { chrono = i; return *this; } }; @@ -1888,6 +1889,12 @@ using namespace atrip; int Atrip::rank; int Atrip::np; +// user printing block +IterationDescriptor IterationDescription::descriptor; +void atrip::registerIterationDescriptor(IterationDescriptor d) { + IterationDescription::descriptor = d; +} + void Atrip::init() { MPI_Comm_rank(MPI_COMM_WORLD, &Atrip::rank); MPI_Comm_size(MPI_COMM_WORLD, &Atrip::np); @@ -1968,15 +1975,6 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { auto abcIndex = getABCRange(np, rank, tuplesList); size_t nIterations = abcIndex.second - abcIndex.first; -#ifdef ATRIP_BENCHMARK - { const size_t maxIterations = in.maxIterations; - if (maxIterations != 0) { - abcIndex.second = abcIndex.first + maxIterations % (nIterations + 1); - nIterations = maxIterations % (nIterations + 1); - } - } -#endif - WITH_RANK << "abcIndex = " << pretty_print(abcIndex) << "\n"; LOG(0,"Atrip") << "#iterations: " << nIterations << "\n"; @@ -1986,6 +1984,12 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { double energy(0.); + size_t iterationMod + = (in.percentageMod > 0) + ? nIterations * in.percentageMod / 100 + : in.iterationMod + ; + auto const isFakeTuple = [&tuplesList](size_t const i) { return i >= tuplesList.size(); }; @@ -2151,7 +2155,16 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { chrono["mpi:barrier"].stop(); chrono["oneshot-mpi:barrier"].stop(); - if (iteration % in.iterationMod == 0) { + if (iteration % iterationMod == 0) { + + if (IterationDescription::descriptor) { + IterationDescription::descriptor({ + iteration, + nIterations, + chrono["iterations"].count() + }); + } + LOG(0,"Atrip") << "iteration " << iteration << " [" << 100 * iteration / nIterations << "%]" @@ -2419,9 +2432,12 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { #+end_src -** Debug +** Debug and Logging +*** Macros + #+begin_src c++ :tangle (atrip-debug-h) #pragma once +#include #define ATRIP_BENCHMARK //#define ATRIP_DONT_SLICE #define ATRIP_DEBUG 1 @@ -2429,10 +2445,12 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { #define ATRIP_USE_DGEMM //#define ATRIP_PRINT_TUPLES -#define LOG(level, name) if (Atrip::rank == 0) std::cout << name << ": " +#ifndef ATRIP_DEBUG +#define ATRIP_DEBUG 1 +#endif #if ATRIP_DEBUG == 4 -# pragma message("WARNING: You have OCD debugging ABC triples "\ +# pragma message("WARNING: You have OCD debugging ABC triples " \ "expect GB of output and consult your therapist") # include # define HAVE_OCD @@ -2445,7 +2463,7 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { # define WITH_DBG # define DBG(...) dbg(__VA_ARGS__) #elif ATRIP_DEBUG == 3 -# pragma message("WARNING: You have crazy debugging ABC triples,"\ +# pragma message("WARNING: You have crazy debugging ABC triples," \ " expect GB of output") # include # define OCD_Barrier(com) @@ -2467,7 +2485,7 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { # define WITH_CRAZY_DEBUG if (false) # define WITH_DBG # define DBG(...) dbg(__VA_ARGS__) -#elif ATRIP_DEBUG == 1 +#else # define OCD_Barrier(com) # define WITH_OCD if (false) # define WITH_ROOT if (false) @@ -2476,11 +2494,54 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { # define WITH_DBG if (false) # define WITH_CRAZY_DEBUG if (false) # define DBG(...) -#else -# error("ATRIP_DEBUG is not defined!") #endif #+end_src +And users of the library can redefine the =LOG= macro +which in case of not being defined is defined as follows: + +#+begin_src c++ :tangle (atrip-debug-h) +#ifndef LOG +#define LOG(level, name) if (Atrip::rank == 0) std::cout << name << ": " +#endif +#+end_src + +Furthermore, if you do not wish to see any output from ATRIP, simply +define =ATRIP_NO_OUTPUT= + + +#+begin_src c++ :tangle (atrip-debug-h) +#ifdef ATRIP_NO_OUTPUT +# undef LOG +# define LOG(level, name) if (false) std::cout << name << ": " +#endif +#+end_src + +*** Iteration informer + +In general a code writer will want to write some messages in every iteration. +A developer then can register a function to be used in this sense. +The input of the function is an [[IterationDescriptor]] structure and the output +should be nothing. + +#+name: IterationDescriptor +#+begin_src c++ :tangle (atrip-debug-h) +namespace atrip { + + struct IterationDescription; + using IterationDescriptor = std::function; + struct IterationDescription { + static IterationDescriptor descriptor; + size_t currentIteration; + size_t totalIterations; + double currentElapsedTime; + }; + + void registerIterationDescriptor(IterationDescriptor); + +} +#+end_src + ** Include header #+begin_src c++ :tangle (atrip-main-h) diff --git a/include/atrip/Atrip.hpp b/include/atrip/Atrip.hpp index a0cad96..a8bcd78 100644 --- a/include/atrip/Atrip.hpp +++ b/include/atrip/Atrip.hpp @@ -24,7 +24,7 @@ namespace atrip { , *Vhhhp = nullptr , *Vppph = nullptr ; - int maxIterations = 0, iterationMod = -1; + int maxIterations = 0, iterationMod = -1, percentageMod = -1; bool barrier = false; bool chrono = false; Input& with_epsilon_i(CTF::Tensor * t) { ei = t; return *this; } @@ -36,6 +36,7 @@ namespace atrip { Input& with_Vabci(CTF::Tensor * t) { Vppph = t; return *this; } Input& with_maxIterations(int i) { maxIterations = i; return *this; } Input& with_iterationMod(int i) { iterationMod = i; return *this; } + Input& with_percentageMod(int i) { percentageMod = i; return *this; } Input& with_barrier(bool i) { barrier = i; return *this; } Input& with_chrono(bool i) { chrono = i; return *this; } }; diff --git a/include/atrip/Debug.hpp b/include/atrip/Debug.hpp index 9153954..6bdfde2 100644 --- a/include/atrip/Debug.hpp +++ b/include/atrip/Debug.hpp @@ -1,5 +1,6 @@ -// [[file:../../atrip.org::*Debug][Debug:1]] +// [[file:../../atrip.org::*Macros][Macros:1]] #pragma once +#include #define ATRIP_BENCHMARK //#define ATRIP_DONT_SLICE #define ATRIP_DEBUG 1 @@ -7,10 +8,12 @@ #define ATRIP_USE_DGEMM //#define ATRIP_PRINT_TUPLES -#define LOG(level, name) if (Atrip::rank == 0) std::cout << name << ": " +#ifndef ATRIP_DEBUG +#define ATRIP_DEBUG 1 +#endif #if ATRIP_DEBUG == 4 -# pragma message("WARNING: You have OCD debugging ABC triples "\ +# pragma message("WARNING: You have OCD debugging ABC triples " \ "expect GB of output and consult your therapist") # include # define HAVE_OCD @@ -23,7 +26,7 @@ # define WITH_DBG # define DBG(...) dbg(__VA_ARGS__) #elif ATRIP_DEBUG == 3 -# pragma message("WARNING: You have crazy debugging ABC triples,"\ +# pragma message("WARNING: You have crazy debugging ABC triples," \ " expect GB of output") # include # define OCD_Barrier(com) @@ -45,7 +48,7 @@ # define WITH_CRAZY_DEBUG if (false) # define WITH_DBG # define DBG(...) dbg(__VA_ARGS__) -#elif ATRIP_DEBUG == 1 +#else # define OCD_Barrier(com) # define WITH_OCD if (false) # define WITH_ROOT if (false) @@ -54,7 +57,35 @@ # define WITH_DBG if (false) # define WITH_CRAZY_DEBUG if (false) # define DBG(...) -#else -# error("ATRIP_DEBUG is not defined!") #endif -// Debug:1 ends here +// Macros:1 ends here + +// [[file:../../atrip.org::*Macros][Macros:2]] +#ifndef LOG +#define LOG(level, name) if (Atrip::rank == 0) std::cout << name << ": " +#endif +// Macros:2 ends here + +// [[file:../../atrip.org::*Macros][Macros:3]] +#ifdef ATRIP_NO_OUTPUT +# undef LOG +# define LOG(level, name) if (false) std::cout << name << ": " +#endif +// Macros:3 ends here + +// [[file:../../atrip.org::IterationDescriptor][IterationDescriptor]] +namespace atrip { + + struct IterationDescription; + using IterationDescriptor = std::function; + struct IterationDescription { + static IterationDescriptor descriptor; + size_t currentIteration; + size_t totalIterations; + double currentElapsedTime; + }; + + void registerIterationDescriptor(IterationDescriptor); + +} +// IterationDescriptor ends here diff --git a/src/atrip/Atrip.cxx b/src/atrip/Atrip.cxx index 06c4079..a6addc6 100644 --- a/src/atrip/Atrip.cxx +++ b/src/atrip/Atrip.cxx @@ -12,6 +12,12 @@ using namespace atrip; int Atrip::rank; int Atrip::np; +// user printing block +IterationDescriptor IterationDescription::descriptor; +void atrip::registerIterationDescriptor(IterationDescriptor d) { + IterationDescription::descriptor = d; +} + void Atrip::init() { MPI_Comm_rank(MPI_COMM_WORLD, &Atrip::rank); MPI_Comm_size(MPI_COMM_WORLD, &Atrip::np); @@ -92,15 +98,6 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { auto abcIndex = getABCRange(np, rank, tuplesList); size_t nIterations = abcIndex.second - abcIndex.first; -#ifdef ATRIP_BENCHMARK - { const size_t maxIterations = in.maxIterations; - if (maxIterations != 0) { - abcIndex.second = abcIndex.first + maxIterations % (nIterations + 1); - nIterations = maxIterations % (nIterations + 1); - } - } -#endif - WITH_RANK << "abcIndex = " << pretty_print(abcIndex) << "\n"; LOG(0,"Atrip") << "#iterations: " << nIterations << "\n"; @@ -110,6 +107,12 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { double energy(0.); + size_t iterationMod + = (in.percentageMod > 0) + ? nIterations * in.percentageMod / 100 + : in.iterationMod + ; + auto const isFakeTuple = [&tuplesList](size_t const i) { return i >= tuplesList.size(); }; @@ -275,7 +278,16 @@ Atrip::Output Atrip::run(Atrip::Input const& in) { chrono["mpi:barrier"].stop(); chrono["oneshot-mpi:barrier"].stop(); - if (iteration % in.iterationMod == 0) { + if (iteration % iterationMod == 0) { + + if (IterationDescription::descriptor) { + IterationDescription::descriptor({ + iteration, + nIterations, + chrono["iterations"].count() + }); + } + LOG(0,"Atrip") << "iteration " << iteration << " [" << 100 * iteration / nIterations << "%]"