26#ifdef PRECICE_COMPRESSION
41 using namespace std::chrono;
42 std::time_t
ts = sys_clk::to_time_t(c);
43 auto ms = duration_cast<microseconds>(c.time_since_epoch()) % 1000;
46 ss << std::put_time(std::localtime(&
ts),
"%FT%T") <<
"." << std::setw(3) << std::setfill(
'0') << ms.count();
65 auto initClock = Event::Clock::now();
66 auto initTime = std::chrono::system_clock::now();
103std::string toString(
Mode m)
109 return "fundamental";
122 PRECICE_DEBUG(
"Profiling is turned off. Backend will not start.");
131 auto exists = std::filesystem::exists(
_directory);
133 !(exists && !std::filesystem::is_directory(
_directory)),
134 "The destination folder \"{}\" exists but isn't a directory. Please remove the directory \"precice-run\" and try again.",
137 std::filesystem::create_directories(
_directory);
141 PRECICE_DEBUG(
"Starting backend with events-file: \"{}\"", filename);
145 using std::literals::operator
""sv;
146#ifdef PRECICE_COMPRESSION
147 _strm = LZMA_STREAM_INIT;
148 lzma_options_lzma options;
149 lzma_lzma_preset(&options, 0);
150 options.mode = LZMA_MODE_FAST;
151 if (lzma_alone_encoder(&_strm, &options) != LZMA_OK) {
152 throw std::runtime_error(
"Failed to init LZMA encoder");
154 auto compression =
"true"sv;
156 auto compression =
"false"sv;
161 R
"({{"name":"{}","rank":{},"size":{},"unix_us":"{}","tinit":"{}","mode":"{}","compression":{},"file_version":{}}})",
165 std::chrono::duration_cast<std::chrono::microseconds>(_initTime.time_since_epoch()).count(),
181 auto now = Event::Clock::now();
186#ifdef PRECICE_COMPRESSION
189 _strm.next_out =
reinterpret_cast<uint8_t *
>(_buf.data());
190 _strm.avail_out = _buf.size();
192 ret = lzma_code(&_strm, LZMA_FINISH);
193 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
194 throw std::runtime_error(
"Finalization failed");
196 _output.write(_buf.data(), _buf.size() - _strm.avail_out);
197 }
while (ret != LZMA_STREAM_END);
230 auto skipFlush =
_writeQueueMax != 1 && std::holds_alternative<StartEntry>(pe);
245template <
class OIter>
248 Event::Clock::time_point initClock;
250 EventWriter(OIter iter, Event::Clock::time_point tp) : out(iter), initClock(tp) {}
252 auto sinceInit(Event::Clock::time_point tp)
254 return std::chrono::duration_cast<std::chrono::microseconds>(tp - initClock).count();
257 void operator()(
const StartEntry &se)
261 se.eid, sinceInit(se.clock));
264 void operator()(
const StopEntry &se)
268 se.eid, sinceInit(se.clock));
271 void operator()(
const DataEntry &de)
275 de.eid, sinceInit(de.clock), de.did, de.dvalue);
278 void operator()(
const NameEntry &ne)
298#ifdef PRECICE_COMPRESSION
299 _strm.next_in =
reinterpret_cast<uint8_t *
>(
_inbuf.data());
300 _strm.avail_in =
_inbuf.size();
302 while (_strm.avail_in > 0) {
303 _strm.next_out =
reinterpret_cast<uint8_t *
>(_buf.data());
304 _strm.avail_out = _buf.size();
305 lzma_ret ret = lzma_code(&_strm, LZMA_RUN);
307 _output.write(_buf.data(), _buf.size() - _strm.avail_out);
315}
catch (
const std::bad_variant_access &e) {
324 _nameDict.insert(iter, {std::string(name),
id});
#define PRECICE_DEBUG(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_ASSERT(...)
#define PRECICE_UNREACHABLE(...)
static EventRegistry & instance()
Returns the only instance (singleton) of the EventRegistry class.
void startBackend()
Create the file and starts the filestream if profiling is turned on.
void initialize(std::string_view applicationName, int rank=0, int size=1)
Sets the global start time.
void clear()
Clears the registry.
void setWriteQueueMax(std::size_t size)
Sets the maximum size of the writequeue before calling flush(). Use 0 to flush on destruction.
void setDirectory(std::string_view directory)
Sets the directory where to write the event files to.
int nameToID(std::string_view name)
int _size
The amount of parallel instances of the current program.
std::vector< char > _inbuf
Buffer for the text to be written to file.
void finalize()
Sets the global end time and flushes buffers.
void setMode(Mode mode)
Sets the operational mode of the registry.
void stopBackend()
Stops the global event, flushes the buffers and closes the filestream.
Mode _mode
The operational mode of the registry.
std::vector< PendingEntry > _writeQueue
void put(PendingEntry pe)
Records an event.
std::map< std::string, int, std::less<> > _nameDict
int _rank
The rank/number of parallel instance of the current program.
std::size_t _writeQueueMax
Event::Clock::time_point _initClock
The initial time clock, used to take runtime measurements.
std::optional< int > _globalId
The id of the global event.
std::string _applicationName
The name of the current participant.
void putCritical(PendingEntry pe)
Records an event without flushing events.
EventRegistry(EventRegistry const &)=delete
Deleted copy and move SMFs for singleton pattern.
void flush()
Writes all recorded events to file and flushes the buffer.
std::chrono::system_clock::time_point _initTime
The initial time, used to describe when the run started.
contains profiling utilities.
std::chrono::system_clock sys_clk
std::chrono::steady_clock stdy_clk
Mode
The Mode of the Event utility.
constexpr int file_version
The version of the Events file. Increase on changes.
std::variant< StartEntry, StopEntry, DataEntry, NameEntry > PendingEntry
std::string timepoint_to_string(sys_clk::time_point c)
Converts the time_point into a string like "2019-01-10T18:30:46.834".