timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
perfetto.cpp
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2020, The Regents of the University of California,
4// through Lawrence Berkeley National Laboratory (subject to receipt of any
5// required approvals from the U.S. Dept. of Energy). All rights reserved.
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to deal
9// in the Software without restriction, including without limitation the rights
10// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11// copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23// SOFTWARE.
24//
25
26#ifndef TIMEMORY_COMPONENTS_PERFETTO_PERFETTO_CPP_
27#define TIMEMORY_COMPONENTS_PERFETTO_PERFETTO_CPP_ 1
28
30
31#if !defined(TIMEMORY_COMPONENT_PERFETTO_HEADER_ONLY_MODE) || \
32 TIMEMORY_COMPONENT_PERFETTO_HEADER_ONLY_MODE < 1
34# define TIMEMORY_COMPONENT_PERFETTO_INLINE
35#else
36# define TIMEMORY_COMPONENT_PERFETTO_INLINE inline
37#endif
38
39#include "timemory/manager.hpp"
42#include "timemory/settings.hpp"
43
44#include <string>
45
46namespace tim
47{
48namespace component
49{
53{
54 return "perfetto_trace";
55}
56
60{
61 return "Provides Perfetto Tracing SDK: system profiling, app tracing and trace "
62 "analysis";
63}
64
68{
69 static auto _config = perfetto_trace::config{};
70 return _config;
71}
72
74void
76{
77#if defined(TIMEMORY_USE_PERFETTO)
78 DEBUG_PRINT_HERE("Initializing %s", label().c_str());
79 if(get_config().session)
80 return;
81
82 auto& args = get_tracing_init_args();
83 auto& _session = get_config().session;
84 auto shmem_size_hint =
85 tim::get_env<size_t>("TIMEMORY_PERFETTO_SHMEM_SIZE_HINT_KB", 40960);
86 auto buffer_size = tim::get_env<size_t>("TIMEMORY_PERFETTO_BUFFER_SIZE_KB", 1024000);
87
88 ::perfetto::TraceConfig cfg{};
89 ::perfetto::protos::gen::TrackEventConfig track_event_cfg{};
90
91 cfg.add_buffers()->set_size_kb(buffer_size);
92 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
93 ds_cfg->set_name("track_event");
94 ds_cfg->set_track_event_config_raw(track_event_cfg.SerializeAsString());
95
96 args.shmem_size_hint_kb = shmem_size_hint;
97
98 if(get_config().in_process)
99 args.backends |= ::perfetto::kInProcessBackend;
100
101 if(get_config().system_backend)
102 args.backends |= ::perfetto::kSystemBackend;
103
104 ::perfetto::Tracing::Initialize(args);
105 ::perfetto::TrackEvent::Register();
106
107 _session = ::perfetto::Tracing::NewTrace();
108 _session->Setup(cfg);
109 _session->StartBlocking();
110
111 /*
112 ::perfetto::ProcessTrack _process_track = ::perfetto::ProcessTrack::Current();
113 ::perfetto::protos::gen::TrackDescriptor _desc = _process_track.Serialize();
114 auto& _cmdline = settings::instance()->get_command_line();
115 if(!_cmdline.empty())
116 {
117 auto _name = _cmdline.at(0);
118 auto _pos = _name.find_last_of('/');
119 if(_pos != std::string::npos && _pos + 1 < _name.size())
120 _name = _name.substr(_pos + 1);
121 _desc.mutable_process()->set_process_name(_name);
122 }
123 else
124 {
125 std::string _category =
126 ::tim::trait::perfetto_category<TIMEMORY_PERFETTO_API>::value;
127 _desc.mutable_process()->set_process_name(TIMEMORY_JOIN("-", label(), _category));
128 }
129 ::perfetto::TrackEvent::SetTrackDescriptor(_process_track, _desc);
130 */
131#endif
132}
133
135void
137{
138#if defined(TIMEMORY_USE_PERFETTO)
139 DEBUG_PRINT_HERE("Finalizing %s", label().c_str());
140 dmp::barrier();
141
142 // Make sure the last event is closed for this example.
143 ::perfetto::TrackEvent::Flush();
144
145 auto& _session = get_config().session;
146 if(!_session)
147 return;
148
149 // Stop tracing and read the trace data.
150 _session->StopBlocking();
151 std::vector<char> trace_data(_session->ReadTraceBlocking());
152
153 auto _rank = dmp::rank();
154 std::string _label = label();
157 TIMEMORY_JOIN('_', _label, _category), "pftrace", dmp::is_initialized(), _rank);
158 // output to a unique filename per rank if DMP is initialized
159 printf("[%s]|%i> Outputting '%s'...\n", _label.c_str(), (int) _rank, _fname.c_str());
160 manager::instance()->add_file_output("binary", _label, _fname);
161
162 // Write the result into a file.
163 // Note: To save memory with longer traces, you can tell Perfetto to write
164 // directly into a file by passing a file descriptor into Setup() above.
165 std::ofstream output{};
166 output.open(_fname.c_str(), std::ios::out | std::ios::binary);
167 output.write(&trace_data[0], trace_data.size());
168 output.close();
169
170 dmp::barrier();
171 if(_rank == 0)
172 puts("");
173#endif
174}
175
178perfetto_trace::get_tracing_init_args()
179{
181 return _args;
182}
183
185void
187{
188 if(m_prefix)
189 backend::perfetto::trace_event_start<TIMEMORY_PERFETTO_API>(m_prefix);
190}
191
193void
194perfetto_trace::start(const char* _label)
195{
196 backend::perfetto::trace_event_start<TIMEMORY_PERFETTO_API>(_label);
197}
198
200void
202{
203 backend::perfetto::trace_event_stop<TIMEMORY_PERFETTO_API>();
204}
205
207void
209{
210 if(_prefix && m_prefix != _prefix)
211 {
212 m_prefix = _prefix;
213 }
214}
215
216} // namespace component
217} // namespace tim
218
219#endif // TIMEMORY_COMPONENTS_PERFETTO_PERFETTO_CPP_
static pointer_t instance()
Get a shared pointer to the instance for the current thread.
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
char const std::string & _prefix
Definition: config.cpp:55
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
#define TIMEMORY_COMPONENT_PERFETTO_INLINE
Definition: perfetto.cpp:34
Definition for various functions for storage_initializer in operations.
static std::string description()
Definition: perfetto.cpp:59
static config & get_config()
Definition: perfetto.cpp:67
void set_prefix(const char *)
Definition: perfetto.cpp:208
static std::string label()
Definition: perfetto.cpp:52
backend::perfetto::tracing_init_args TracingInitArgs
Definition: perfetto.hpp:53
static string_t compose_output_filename(string_t _tag, string_t _ext, bool _use_suffix=use_output_suffix(), int32_t _suffix=default_process_suffix(), bool _make_dir=false, std::string _explicit={})
Definition: settings.cpp:322
Provides the static category for perfetto traces.
#define DEBUG_PRINT_HERE(...)
Definition: macros.hpp:168
#define TIMEMORY_JOIN(delim,...)
Definition: macros.hpp:90