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.
kokkosp.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 all
15// 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// used by Kokkos decls
26#if !defined(TIMEMORY_LIBRARY_SOURCE)
27# define TIMEMORY_LIBRARY_SOURCE 1
28#endif
29
31
32#include "timemory/timemory.hpp"
33
34namespace kokkosp = tim::kokkosp;
35
36//--------------------------------------------------------------------------------------//
37
38namespace tim
39{
40template <>
41inline auto
42invoke_preinit<kokkosp::memory_tracker>(long)
43{
44 kokkosp::memory_tracker::label() = "kokkos_memory";
45 kokkosp::memory_tracker::description() = "Kokkos Memory tracker";
46}
47} // namespace tim
48
49//--------------------------------------------------------------------------------------//
50
51namespace
52{
53std::string kokkos_banner =
54 "#---------------------------------------------------------------------------#";
55
56//--------------------------------------------------------------------------------------//
57
58bool
59configure_environment()
60{
61 tim::set_env("KOKKOS_PROFILE_LIBRARY", "libtimemory.so", 0);
62 return true;
63}
64
65auto env_configured = (configure_environment(), true);
66bool enable_kernel_logger = false;
67
68inline void
69add_kernel_logger()
70{
71 static bool _first = true;
72 if(!_first)
73 return;
74 _first = false;
75 using strvec_t = std::vector<std::string>;
76
77 tim::settings::instance()->insert<bool, bool&>(
78 std::string{ "TIMEMORY_KOKKOS_KERNEL_LOGGER" }, std::string{},
79 std::string{ "Enables kernel logging" }, enable_kernel_logger,
80 strvec_t({ "--timemory-kokkos-kernel-logger" }));
81}
82
83inline void
84setup_kernel_logger()
85{
86 if(tim::settings::debug() || tim::settings::verbose() > 3 || enable_kernel_logger)
87 {
88 kokkosp::logger_t::get_initializer() = [](kokkosp::logger_t& _obj) {
89 _obj.initialize<kokkosp::kernel_logger>();
90 };
91 }
92}
93
94} // namespace
95
96//--------------------------------------------------------------------------------------//
97
98extern "C"
99{
101 {
102 add_kernel_logger();
103 std::vector<std::string> _args = { argv, "--help" };
105 }
106
107 void kokkosp_parse_args(int argc, char** argv)
108 {
109 add_kernel_logger();
110
112
113 std::vector<std::string> _args{};
114 _args.reserve(argc);
115 for(int i = 0; i < argc; ++i)
116 _args.emplace_back(argv[i]);
117
119
120 setup_kernel_logger();
121 }
122
123 void kokkosp_declare_metadata(const char* key, const char* value)
124 {
125 tim::manager::add_metadata(key, value);
126 }
127
128 void kokkosp_init_library(const int loadSeq, const uint64_t interfaceVer,
129 const uint32_t devInfoCount, void* deviceInfo)
130 {
131 add_kernel_logger();
132
133 tim::consume_parameters(devInfoCount, deviceInfo);
134
135 tim::set_env("TIMEMORY_TIME_OUTPUT", "ON", 0);
136 tim::set_env("TIMEMORY_COUT_OUTPUT", "OFF", 0);
137 tim::set_env("TIMEMORY_ADD_SECONDARY", "OFF", 0);
138
139 printf("%s\n", kokkos_banner.c_str());
140 printf("# KokkosP: timemory Connector (sequence is %d, version: %llu)\n", loadSeq,
141 (unsigned long long) interfaceVer);
142 printf("%s\n\n", kokkos_banner.c_str());
143
144 if(tim::settings::output_path() == "timemory-output")
145 {
146 // timemory_init is expecting some args so generate some
147 std::array<char*, 1> cstr = { { strdup("kokkosp") } };
148 tim::timemory_init(1, cstr.data());
149 free(cstr[0]);
150 }
151 assert(env_configured);
152
153 // search unique and fallback environment variables
154 namespace operation = tim::operation;
155 operation::init<kokkosp::kokkos_bundle>(
156 operation::mode_constant<operation::init_mode::global>{});
157
158 // add at least one
159 if(kokkosp::kokkos_bundle::bundle_size() == 0)
160 kokkosp::kokkos_bundle::configure<tim::component::wall_clock>();
161
162 setup_kernel_logger();
163 }
164
166 {
167 printf("\n%s\n", kokkos_banner.c_str());
168 printf("KokkosP: Finalization of timemory Connector. Complete.\n");
169 printf("%s\n\n", kokkos_banner.c_str());
170
172
174 }
175
176 //----------------------------------------------------------------------------------//
177
178 void kokkosp_begin_parallel_for(const char* name, uint32_t devid, uint64_t* kernid)
179 {
180 auto pname =
181 (devid > std::numeric_limits<uint16_t>::max()) // junk device number
182 ? TIMEMORY_JOIN('/', "kokkos", name)
183 : TIMEMORY_JOIN('/', "kokkos", TIMEMORY_JOIN("", "dev", devid), name);
184 *kernid = kokkosp::get_unique_id();
185 kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid);
186 kokkosp::create_profiler<kokkosp::kokkos_bundle>(pname, *kernid);
187 kokkosp::start_profiler<kokkosp::kokkos_bundle>(*kernid);
188 }
189
190 void kokkosp_end_parallel_for(uint64_t kernid)
191 {
192 kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid);
193 kokkosp::stop_profiler<kokkosp::kokkos_bundle>(kernid);
194 kokkosp::destroy_profiler<kokkosp::kokkos_bundle>(kernid);
195 }
196
197 //----------------------------------------------------------------------------------//
198
199 void kokkosp_begin_parallel_reduce(const char* name, uint32_t devid, uint64_t* kernid)
200 {
201 auto pname =
202 (devid > std::numeric_limits<uint16_t>::max()) // junk device number
203 ? TIMEMORY_JOIN('/', "kokkos", name)
204 : TIMEMORY_JOIN('/', "kokkos", TIMEMORY_JOIN("", "dev", devid), name);
205 *kernid = kokkosp::get_unique_id();
206 kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid);
207 kokkosp::create_profiler<kokkosp::kokkos_bundle>(pname, *kernid);
208 kokkosp::start_profiler<kokkosp::kokkos_bundle>(*kernid);
209 }
210
211 void kokkosp_end_parallel_reduce(uint64_t kernid)
212 {
213 kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid);
214 kokkosp::stop_profiler<kokkosp::kokkos_bundle>(kernid);
215 kokkosp::destroy_profiler<kokkosp::kokkos_bundle>(kernid);
216 }
217
218 //----------------------------------------------------------------------------------//
219
220 void kokkosp_begin_parallel_scan(const char* name, uint32_t devid, uint64_t* kernid)
221 {
222 auto pname =
223 (devid > std::numeric_limits<uint16_t>::max()) // junk device number
224 ? TIMEMORY_JOIN('/', "kokkos", name)
225 : TIMEMORY_JOIN('/', "kokkos", TIMEMORY_JOIN("", "dev", devid), name);
226 *kernid = kokkosp::get_unique_id();
227 kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid);
228 kokkosp::create_profiler<kokkosp::kokkos_bundle>(pname, *kernid);
229 kokkosp::start_profiler<kokkosp::kokkos_bundle>(*kernid);
230 }
231
232 void kokkosp_end_parallel_scan(uint64_t kernid)
233 {
234 kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid);
235 kokkosp::stop_profiler<kokkosp::kokkos_bundle>(kernid);
236 kokkosp::destroy_profiler<kokkosp::kokkos_bundle>(kernid);
237 }
238
239 //----------------------------------------------------------------------------------//
240
241 void kokkosp_begin_fence(const char* name, uint32_t devid, uint64_t* kernid)
242 {
243 auto pname =
244 (devid > std::numeric_limits<uint16_t>::max()) // junk device number
245 ? TIMEMORY_JOIN('/', "kokkos", name)
246 : TIMEMORY_JOIN('/', "kokkos", TIMEMORY_JOIN("", "dev", devid), name);
247 *kernid = kokkosp::get_unique_id();
248 kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid);
249 kokkosp::create_profiler<kokkosp::kokkos_bundle>(pname, *kernid);
250 kokkosp::start_profiler<kokkosp::kokkos_bundle>(*kernid);
251 }
252
253 void kokkosp_end_fence(uint64_t kernid)
254 {
255 kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid);
256 kokkosp::stop_profiler<kokkosp::kokkos_bundle>(kernid);
257 kokkosp::destroy_profiler<kokkosp::kokkos_bundle>(kernid);
258 }
259
260 //----------------------------------------------------------------------------------//
261
262 void kokkosp_push_profile_region(const char* name)
263 {
264 kokkosp::logger_t{}.mark(1, __FUNCTION__, name);
265 kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>().push_back(
267 kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>().back().start();
268 }
269
271 {
272 kokkosp::logger_t{}.mark(-1, __FUNCTION__);
273 if(kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>().empty())
274 return;
275 kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>().back().stop();
276 kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>().pop_back();
277 }
278
279 //----------------------------------------------------------------------------------//
280
281 void kokkosp_create_profile_section(const char* name, uint32_t* secid)
282 {
283 *secid = kokkosp::get_unique_id();
284 auto pname = TIMEMORY_JOIN('/', "kokkos", name);
285 kokkosp::create_profiler<kokkosp::kokkos_bundle>(pname, *secid);
286 }
287
289 {
290 kokkosp::destroy_profiler<kokkosp::kokkos_bundle>(secid);
291 }
292
293 //----------------------------------------------------------------------------------//
294
295 void kokkosp_start_profile_section(uint32_t secid)
296 {
297 kokkosp::logger_t{}.mark(1, __FUNCTION__, secid);
298 kokkosp::start_profiler<kokkosp::kokkos_bundle>(secid);
299 }
300
301 void kokkosp_stop_profile_section(uint32_t secid)
302 {
303 kokkosp::logger_t{}.mark(-1, __FUNCTION__, secid);
304 kokkosp::start_profiler<kokkosp::kokkos_bundle>(secid);
305 }
306
307 //----------------------------------------------------------------------------------//
308
309 void kokkosp_allocate_data(const SpaceHandle space, const char* label,
310 const void* const ptr, const uint64_t size)
311 {
312 kokkosp::logger_t{}.mark(0, __FUNCTION__, space.name, label,
313 TIMEMORY_JOIN("", '[', ptr, ']'), size);
314 kokkosp::profiler_alloc_t<>{ TIMEMORY_JOIN('/', "kokkos/allocate", space.name,
315 label) }
316 .store(std::plus<int64_t>{}, size);
317 }
318
319 void kokkosp_deallocate_data(const SpaceHandle space, const char* label,
320 const void* const ptr, const uint64_t size)
321 {
322 kokkosp::logger_t{}.mark(0, __FUNCTION__, space.name, label,
323 TIMEMORY_JOIN("", '[', ptr, ']'), size);
324 kokkosp::profiler_alloc_t<>{ TIMEMORY_JOIN('/', "kokkos/deallocate", space.name,
325 label) }
326 .store(std::plus<int64_t>{}, size);
327 }
328
329 //----------------------------------------------------------------------------------//
330
331 void kokkosp_begin_deep_copy(SpaceHandle dst_handle, const char* dst_name,
332 const void* dst_ptr, SpaceHandle src_handle,
333 const char* src_name, const void* src_ptr, uint64_t size)
334 {
335 kokkosp::logger_t{}.mark(1, __FUNCTION__, dst_handle.name, dst_name,
336 TIMEMORY_JOIN("", '[', dst_ptr, ']'), src_handle.name,
337 src_name, TIMEMORY_JOIN("", '[', src_ptr, ']'), size);
338
339 auto name = TIMEMORY_JOIN('/', "kokkos/deep_copy",
340 TIMEMORY_JOIN('=', dst_handle.name, dst_name),
341 TIMEMORY_JOIN('=', src_handle.name, src_name));
342
343 auto& _data = kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>();
344 _data.emplace_back(name);
345 _data.back().audit(dst_handle, dst_name, dst_ptr, src_handle, src_name, src_ptr,
346 size);
347 _data.back().start();
348 _data.back().store(std::plus<int64_t>{}, size);
349 }
350
352 {
353 kokkosp::logger_t{}.mark(-1, __FUNCTION__);
354 auto& _data = kokkosp::get_profiler_stack<kokkosp::kokkos_bundle>();
355 if(_data.empty())
356 return;
357 _data.back().store(std::minus<int64_t>{}, 0);
358 _data.back().stop();
359 _data.pop_back();
360 }
361
362 //----------------------------------------------------------------------------------//
363
364 void kokkosp_profile_event(const char* name)
365 {
367 }
368
369 //----------------------------------------------------------------------------------//
370}
371
372//--------------------------------------------------------------------------------------//
373
375
376//--------------------------------------------------------------------------------------//
This is a variadic component wrapper where all components are allocated on the stack and cannot be di...
Definition: auto_tuple.hpp:65
static void add_metadata(const std::string &, const Tp &)
Add a metadata entry of a non-string type. If this fails to serialize, either include either the appr...
Definition: manager.hpp:479
#define TIMEMORY_INITIALIZE_STORAGE(...)
Definition: macros.hpp:362
void kokkosp_end_deep_copy()
Definition: kokkosp.cpp:351
void kokkosp_end_fence(uint64_t kernid)
Definition: kokkosp.cpp:253
void kokkosp_init_library(const int loadSeq, const uint64_t interfaceVer, const uint32_t devInfoCount, void *deviceInfo)
Definition: kokkosp.cpp:128
void kokkosp_push_profile_region(const char *name)
Definition: kokkosp.cpp:262
void kokkosp_start_profile_section(uint32_t secid)
Definition: kokkosp.cpp:295
void kokkosp_end_parallel_scan(uint64_t kernid)
Definition: kokkosp.cpp:232
void kokkosp_parse_args(int argc, char **argv)
Definition: kokkosp.cpp:107
void kokkosp_begin_parallel_reduce(const char *name, uint32_t devid, uint64_t *kernid)
Definition: kokkosp.cpp:199
void kokkosp_end_parallel_reduce(uint64_t kernid)
Definition: kokkosp.cpp:211
void kokkosp_begin_parallel_scan(const char *name, uint32_t devid, uint64_t *kernid)
Definition: kokkosp.cpp:220
void kokkosp_stop_profile_section(uint32_t secid)
Definition: kokkosp.cpp:301
void kokkosp_begin_deep_copy(SpaceHandle dst_handle, const char *dst_name, const void *dst_ptr, SpaceHandle src_handle, const char *src_name, const void *src_ptr, uint64_t size)
Definition: kokkosp.cpp:331
void kokkosp_profile_event(const char *name)
Definition: kokkosp.cpp:364
void kokkosp_pop_profile_region()
Definition: kokkosp.cpp:270
void kokkosp_finalize_library()
Definition: kokkosp.cpp:165
void kokkosp_begin_fence(const char *name, uint32_t devid, uint64_t *kernid)
Definition: kokkosp.cpp:241
void kokkosp_begin_parallel_for(const char *name, uint32_t devid, uint64_t *kernid)
Definition: kokkosp.cpp:178
void kokkosp_declare_metadata(const char *key, const char *value)
Definition: kokkosp.cpp:123
void kokkosp_create_profile_section(const char *name, uint32_t *secid)
Definition: kokkosp.cpp:281
void kokkosp_deallocate_data(const SpaceHandle space, const char *label, const void *const ptr, const uint64_t size)
Definition: kokkosp.cpp:319
void kokkosp_allocate_data(const SpaceHandle space, const char *label, const void *const ptr, const uint64_t size)
Definition: kokkosp.cpp:309
void kokkosp_destroy_profile_section(uint32_t secid)
Definition: kokkosp.cpp:288
void kokkosp_print_help(char *argv)
Definition: kokkosp.cpp:100
void kokkosp_end_parallel_for(uint64_t kernid)
Definition: kokkosp.cpp:190
::tim::statistics< Tp > max(::tim::statistics< Tp > lhs, const Tp &rhs)
Definition: statistics.hpp:320
void cleanup()
Definition: kokkosp.hpp:187
tim::component_bundle_t< project::kokkosp, kokkosp::kernel_logger * > logger_t
Definition: kokkosp.hpp:244
tim::component_bundle_t< project::kokkosp, kokkosp::memory_tracker, Tail... > profiler_t
Definition: kokkosp.hpp:248
uint64_t get_unique_id()
Definition: kokkosp.hpp:121
std::vector< string_t > strvec_t
Definition: popen.hpp:58
Definition: kokkosp.cpp:39
std::array< char *, 4 > _args
void set_env(const std::string &env_var, const Tp &_val, int override)
void timemory_finalize()
finalization of the specified types
timemory_argparse(argc, argv)
void timemory_init(Args &&... _args)
Definition: config.hpp:49
char ** argv
Definition: config.cpp:55
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
output_path
Definition: settings.cpp:1661
void consume_parameters(ArgsT &&...)
Definition: types.hpp:285
This component is provided to facilitate data tracking. The first template parameter is the type of d...
Definition: components.hpp:148
static std::string & label()
a reference is returned here so that it can be easily updated
Definition: components.hpp:466
static std::string & description()
a reference is returned here so that it can be easily updated
Definition: components.hpp:478
auto insert(Sp &&_env, const std::string &_name, const std::string &_desc, Vp _init, Args &&... _args)
Definition: settings.hpp:764
static settings * instance()
Definition: settings.hpp:536
char * strdup(const char *s)
Definition: timemory_c.c:41
#define TIMEMORY_JOIN(delim,...)
Definition: macros.hpp:90