Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
profiling.hpp
Go to the documentation of this file.
1 // Copyright (c) 2019-2024, Lawrence Livermore National Security, LLC and
2 // other Serac Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
13 #pragma once
14 
15 #include <string>
16 #include <sstream>
17 
18 #include "serac/serac_config.hpp"
19 
20 #ifdef SERAC_USE_ADIAK
21 #include "adiak.hpp"
22 #endif
23 
24 #ifdef SERAC_USE_CALIPER
25 #include "caliper/cali-manager.h"
26 #include "caliper/cali.h"
27 #endif
28 
29 #include "mpi.h"
30 
81 #ifdef SERAC_USE_ADIAK
82 #define SERAC_SET_METADATA(name, data) adiak::value(name, data)
83 #else
84 #define SERAC_SET_METADATA(name, data)
85 #endif
86 
87 #ifdef SERAC_USE_CALIPER
88 
89 #define SERAC_MARK_FUNCTION CALI_CXX_MARK_FUNCTION
90 #define SERAC_MARK_LOOP_BEGIN(id, name) CALI_CXX_MARK_LOOP_BEGIN(id, name)
91 #define SERAC_MARK_LOOP_ITER(id, i) CALI_CXX_MARK_LOOP_ITERATION(id, i)
92 #define SERAC_MARK_LOOP_END(id) CALI_CXX_MARK_LOOP_END(id)
93 #define SERAC_MARK_BEGIN(name) serac::profiling::detail::startCaliperRegion(name)
94 #define SERAC_MARK_END(name) serac::profiling::detail::endCaliperRegion(name)
95 
96 #define SERAC_CONCAT_(a, b) a##b
97 #define SERAC_CONCAT(a, b) SERAC_CONCAT_(a, b)
98 
99 namespace serac::profiling::detail {
100 
104 inline const char* make_cstr(const char* str) { return str; }
105 
109 inline const char* make_cstr(const std::string& str) { return str.c_str(); }
110 
111 } // namespace serac::profiling::detail
112 
113 #define SERAC_PROFILE_SCOPE(name) \
114  cali::ScopeAnnotation SERAC_CONCAT(region, __LINE__)(serac::profiling::detail::make_cstr(name))
115 
116 // We use decltype(auto) here instead of the default auto for a different set of type deduction rules -
117 // the latter uses template type deduction rules but the former uses those for decltype, which we need
118 // in order for the return type to take into account the value category (rvalue, lvalue) of the expression
119 // We have to return (expr) instead of expr to ensure that reference-ness is propagated through correctly
120 // in Clang - GCC handles this correctly without the parentheses as expected
121 #define SERAC_PROFILE_EXPR(name, expr) \
122  [&]() -> decltype(auto) { \
123  const cali::ScopeAnnotation SERAC_CONCAT(region, __LINE__)(serac::profiling::detail::make_cstr(name)); \
124  return (expr); \
125  }()
126 
130 #define SERAC_PROFILE_EXPR_LOOP(name, expr, ntest) \
131  ( \
132  [&]() { \
133  for (int SERAC_CONCAT(i, __LINE__) = 0; SERAC_CONCAT(i, __LINE__) < ntest - 1; SERAC_CONCAT(i, __LINE__)++) \
134  SERAC_PROFILE_EXPR(serac::profiling::detail::make_cstr(name), expr); \
135  }(), \
136  SERAC_PROFILE_EXPR(serac::profiling::detail::make_cstr(name), expr))
137 
138 #else // SERAC_USE_CALIPER not defined
139 
140 // Define all these as nothing so annotated code will still compile
141 #define SERAC_MARK_FUNCTION
142 #define SERAC_MARK_LOOP_BEGIN(id, name)
143 #define SERAC_MARK_LOOP_ITER(id, i)
144 #define SERAC_MARK_LOOP_END(id)
145 #define SERAC_MARK_BEGIN(name)
146 #define SERAC_MARK_END(name)
147 #define SERAC_PROFILE_SCOPE(name)
148 #define SERAC_PROFILE_EXPR(name, expr) expr
149 #define SERAC_PROFILE_EXPR_LOOP(name, expr, ntest) expr
150 
151 #endif
152 
154 namespace serac::profiling {
155 
162 void initialize([[maybe_unused]] MPI_Comm comm = MPI_COMM_WORLD, [[maybe_unused]] std::string options = "");
163 
167 void finalize();
168 
170 namespace detail {
171 
177 void startCaliperRegion(const char* name);
178 
184 void endCaliperRegion(const char* name);
185 
186 } // namespace detail
187 
189 template <typename... T>
190 std::string concat(T... args)
191 {
192  std::stringstream ss;
193  // this fold expression is a more elegant way to implement the concatenation,
194  // but nvcc incorrectly generates warning "warning: expression has no effect"
195  // when using the fold expression version
196  // (ss << ... << args);
197  ((ss << args), ...);
198  return ss.str();
199 }
200 
201 } // namespace serac::profiling
detail namespace
Definition: profiling.hpp:170
void endCaliperRegion(const char *name)
Caliper methods for marking the end of a region.
void startCaliperRegion(const char *name)
Caliper method for marking the start of a profiling region.
profiling namespace
Definition: profiling.cpp:15
std::string concat(T... args)
Produces a string by applying << to all arguments.
Definition: profiling.hpp:190
void finalize()
Concludes performance monitoring and writes collected data to a file.
Definition: profiling.cpp:56
void initialize([[maybe_unused]] MPI_Comm comm, [[maybe_unused]] std::string options)
Initializes performance monitoring using the Caliper and Adiak libraries.
Definition: profiling.cpp:23