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.
cupti_pcsampling.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#if defined(TIMEMORY_USE_CUPTI_PCSAMPLING)
26
28
29# if !defined(TIMEMORY_CUPTI_HEADER_MODE)
31# endif
32
35
36namespace tim
37{
38namespace cupti
39{
40//
42pcdata::pcdata(CUpti_PCSamplingData&& _data)
43: totalNumPcs{ _data.totalNumPcs }
44, remainingNumPcs{ _data.remainingNumPcs }
45, rangeId{ _data.rangeId }
46{
47 // samples.reserve(_sz);
48 for(size_t i = 0; i < totalNumPcs; ++i)
49 {
50 if(!_data.pPcData[i].stallReason)
51 continue;
52 pcsample _sample{ _data.pPcData[i] };
53 auto itr = samples.find(_sample);
54 if(itr == samples.end())
55 samples.insert(std::move(_sample));
56 else
57 *itr += _sample;
58 }
59 component::cupti_pcsampling::free_pcsampling_data(_data);
60}
61} // namespace cupti
62//
63namespace component
64{
65//
66TIMEMORY_CUPTI_INLINE CUpti_PCSamplingData
67cupti_pcsampling::get_pcsampling_data(size_t numStallReasons, size_t numPcsToCollect)
68{
69 // User buffer to hold collected PC Sampling data in PC-To-Counter format
70 CUpti_PCSamplingData pcSamplingData = {};
71 pcSamplingData.size = sizeof(CUpti_PCSamplingData);
72 pcSamplingData.collectNumPcs = numPcsToCollect;
73 pcSamplingData.pPcData =
74 TIMEMORY_CUPTI_CALLOC(CUpti_PCSamplingPCData, pcSamplingData.collectNumPcs);
75 for(size_t i = 0; i < pcSamplingData.collectNumPcs; ++i)
76 pcSamplingData.pPcData[i].stallReason =
77 TIMEMORY_CUPTI_CALLOC(CUpti_PCSamplingStallReason, numStallReasons);
78 return pcSamplingData;
79}
80//
82cupti_pcsampling::free_pcsampling_data(CUpti_PCSamplingData pcSamplingData)
83{
84 // Free memory
85 for(size_t i = 0; i < pcSamplingData.collectNumPcs; i++)
86 {
87 if(pcSamplingData.pPcData[i].stallReason)
88 {
89 free(pcSamplingData.pPcData[i].stallReason);
90 pcSamplingData.pPcData[i].stallReason = nullptr;
91 }
92 }
93
94 if(pcSamplingData.pPcData)
95 {
96 free(pcSamplingData.pPcData);
97 pcSamplingData.pPcData = nullptr;
98 }
99}
100//
101inline const char*
102getStallReason(const uint32_t& stallReasonCount,
103 const uint32_t& pcSamplingStallReasonIndex, uint32_t* pStallReasonIndex,
104 char** pStallReasons)
105{
106 for(uint32_t i = 0; i < stallReasonCount; i++)
107 {
108 if(pStallReasonIndex[i] == pcSamplingStallReasonIndex)
109 {
110 return pStallReasons[i];
111 }
112 }
113 return "ERROR_STALL_REASON_INDEX_NOT_FOUND";
114}
115//
117printPCSamplingData(CUpti_PCSamplingData* pPcSamplingData,
118 const uint32_t& stallReasonCount, uint32_t* pStallReasonIndex,
119 char** pStallReasons)
120{
121 std::cout << "----- PC sampling data for range defined by cuptiPCSamplingStart() and "
122 "cuptiPCSamplingStop() -----"
123 << std::endl;
124 std::cout << "Number of PCs remaining to be collected: "
125 << pPcSamplingData->remainingNumPcs << ", ";
126 std::cout << "range id: " << pPcSamplingData->rangeId << ", ";
127 std::cout << "total samples: " << pPcSamplingData->totalSamples << ", ";
128 std::cout << "dropped samples: " << pPcSamplingData->droppedSamples << std::endl;
129 for(size_t i = 0; i < pPcSamplingData->totalNumPcs; i++)
130 {
131 std::cout << "\tpcOffset : 0x" << std::hex << pPcSamplingData->pPcData[i].pcOffset
132 << ", stallReasonCount: " << std::dec
133 << pPcSamplingData->pPcData[i].stallReasonCount << ", functionName: "
134 << demangle(pPcSamplingData->pPcData[i].functionName);
135 for(size_t j = 0; j < pPcSamplingData->pPcData[i].stallReasonCount; j++)
136 {
137 std::cout << "\n\t\tstallReason: "
138 << getStallReason(stallReasonCount,
139 pPcSamplingData->pPcData[i]
140 .stallReason[j]
141 .pcSamplingStallReasonIndex,
142 pStallReasonIndex, pStallReasons)
143 << ", samples: "
144 << pPcSamplingData->pPcData[i].stallReason[j].samples;
145 }
146 std::cout << std::endl;
147 }
148 std::cout << "-----------------------------------------------------------------------"
149 "---------------------------"
150 << std::endl;
151}
152//
153TIMEMORY_CUPTI_INLINE cupti_pcsampling::config_type
154 cupti_pcsampling::configure()
155{
156 CUcontext cuCtx;
157 CUdevice cuDevice;
158 cudaDeviceProp prop;
159 int deviceCount = 0;
160 int deviceNum = 0;
161
163 TIMEMORY_CUDA_DRIVER_API_CALL(cuDeviceGetCount(&deviceCount));
164
165 if(deviceCount == 0)
166 {
167 fprintf(stderr, "There is no device supporting CUDA.\n");
168 exit(EXIT_FAILURE);
169 }
170
171 // only check if value is still set to the default
172 if(get_configuration_data().region_totals)
173 get_configuration_data().region_totals =
174 settings::instance()->get<bool>("cupti_pcsampling_region_totals");
175
176 deviceNum = settings::instance()->get<int>("cupti_device");
177 if(deviceNum < 0)
178 {
179 deviceNum = 0;
180 TIMEMORY_CUDA_RUNTIME_API_CALL(cudaGetDevice(&deviceNum));
181 }
182
183 TIMEMORY_CUDA_RUNTIME_API_CALL(cudaGetDeviceProperties(&prop, deviceNum));
184 printf("Device Name: %s\n", prop.name);
185 printf("Device compute capability: %d.%d\n", prop.major, prop.minor);
186 if(prop.major < 7)
187 {
188 printf("Component is unavailable on this device, supported on devices with "
189 "compute capability 7.0 and higher\n");
190 exit(EXIT_FAILURE);
191 }
192
193 // cuda::device_sync();
194
195 // Create CUDA context
196 // TIMEMORY_CUDA_DRIVER_API_CALL(cuCtxCreate(&cuCtx, 0, cuDevice));
197 // Init device, context and setup callback
198 TIMEMORY_CUDA_DRIVER_API_CALL(cuDeviceGet(&cuDevice, deviceNum));
199 // TIMEMORY_CUDA_DRIVER_API_CALL(cuCtxCreate(&m_context, 0, m_device));
200 TIMEMORY_CUDA_DRIVER_API_CALL(cuDevicePrimaryCtxRetain(&cuCtx, cuDevice));
201 // TIMEMORY_CUDA_DRIVER_API_CALL(cuCtxGetCurrent(&cuCtx));
202 // TIMEMORY_CUDA_DRIVER_API_CALL(cuCtxCreate(&cuCtx, 0, deviceNum));
203
204 TIMEMORY_CUPTI_API_CALL(
205 cuptiRegisterComputeCrcCallback(&cupti::pcsample::compute_cubin_crc));
206
207 //----------------------------------------------------------------------------------//
208 // Enable PC Sampling
209 CUpti_PCSamplingEnableParams pcSamplingEnableParams = {};
210 pcSamplingEnableParams.size = CUpti_PCSamplingEnableParamsSize;
211 pcSamplingEnableParams.ctx = cuCtx;
212 TIMEMORY_CUPTI_API_CALL(cuptiPCSamplingEnable(&pcSamplingEnableParams));
213
214 //----------------------------------------------------------------------------------//
215 // Get number of supported stall reasons
216 size_t numStallReasons = 0;
217 CUpti_PCSamplingGetNumStallReasonsParams numStallReasonsParams = {};
218 numStallReasonsParams.size = CUpti_PCSamplingGetNumStallReasonsParamsSize;
219 numStallReasonsParams.ctx = cuCtx;
220 numStallReasonsParams.numStallReasons = &numStallReasons;
221 TIMEMORY_CUPTI_API_CALL(cuptiPCSamplingGetNumStallReasons(&numStallReasonsParams));
222
223 //----------------------------------------------------------------------------------//
224 // Get number of supported stall reason names and corresponding indexes
225 cupti::pcstall::allocate_arrays(numStallReasons);
226 uint32_t*& pStallReasonIndex = cupti::pcstall::get_index_array();
227 char**& pStallReasons = cupti::pcstall::get_name_array();
228 bool*& pStallReasonsEnabled = cupti::pcstall::get_bool_array();
229
230 CUpti_PCSamplingGetStallReasonsParams stallReasonsParams = {};
231 stallReasonsParams.size = CUpti_PCSamplingGetStallReasonsParamsSize;
232 stallReasonsParams.ctx = cuCtx;
233 stallReasonsParams.numStallReasons = numStallReasons;
234 stallReasonsParams.stallReasonIndex = pStallReasonIndex;
235 stallReasonsParams.stallReasons = pStallReasons;
236 cuptiPCSamplingGetStallReasons(&stallReasonsParams);
237
238 size_t stallReasonCount = numStallReasons;
239 for(size_t i = 0; i < numStallReasons; ++i)
240 pStallReasonsEnabled[i] = true;
241 auto _stall_reasons =
242 delimit(settings::instance()->get<std::string>("cupti_pcsampling_stall_reasons"));
243 if(!_stall_reasons.empty() && _stall_reasons.size() < stallReasonCount)
244 {
245 stallReasonCount = _stall_reasons.size();
246 // set all to false
247 for(size_t i = 0; i < numStallReasons; ++i)
248 pStallReasonsEnabled[i] = false;
249 // enable all that match
250 for(const auto& itr : _stall_reasons)
251 {
252 for(size_t i = 0; i < numStallReasons; ++i)
253 {
254 if(std::regex_search(pStallReasons[i], std::regex(itr + "$")))
255 pStallReasonsEnabled[i] = true;
256 }
257 }
258 // reorder the reasons that are enabled to the beginning
259 size_t _idx = 0;
260 for(size_t i = 0; i < numStallReasons; ++i)
261 {
262 if(pStallReasonsEnabled[i] && _idx != i)
263 {
264 std::swap(pStallReasonsEnabled[i], pStallReasonsEnabled[_idx]);
265 std::swap(pStallReasonIndex[i], pStallReasonIndex[_idx]);
266 std::swap(pStallReasons[i], pStallReasons[_idx]);
267 ++_idx;
268 }
269 }
270 }
272 {
273 printf("[runtime]> numStallReasons = %lu\n", (unsigned long) numStallReasons);
274 printf("[compile]> numStallReasons = %lu\n",
275 (unsigned long) cupti::pcsample::stall_reasons_size);
276 for(size_t i = 0; i < stallReasonCount; ++i)
277 printf("%s index: %lu\n", pStallReasons[i],
278 (long unsigned) pStallReasonIndex[i]);
279 // check that there are not new stall reasons that have not been accounted for
280 assert(numStallReasons <= cupti::pcsample::stall_reasons_size);
281 }
282
283 //----------------------------------------------------------------------------------//
284 // User buffer to hold collected PC Sampling data in PC-To-Counter format
285 size_t _num_collect =
286 settings::instance()->get<size_t>("cupti_pcsampling_num_collect");
287 CUpti_PCSamplingData pcSamplingData =
288 get_pcsampling_data(stallReasonCount, _num_collect);
289
290 //----------------------------------------------------------------------------------//
291 // configuration info
292 //----------------------------------------------------------------------------------//
293
294 std::vector<CUpti_PCSamplingConfigurationInfo> pcSamplingConfigurationInfo{};
295
296 //------------------------ Sampling Period ------------------------//
297 auto _period = settings::instance()->get<int>("cupti_pcsampling_period");
298 CUpti_PCSamplingConfigurationInfo samplingPeriod = {};
299 samplingPeriod.attributeType =
300 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_SAMPLING_PERIOD;
301 samplingPeriod.attributeData.samplingPeriodData.samplingPeriod = _period;
302 pcSamplingConfigurationInfo.push_back(samplingPeriod);
303
304 //------------------------ Stall Reason ------------------------//
305 CUpti_PCSamplingConfigurationInfo stallReason = {};
306 stallReason.attributeType = CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_STALL_REASON;
307 stallReason.attributeData.stallReasonData.stallReasonCount = stallReasonCount;
308 stallReason.attributeData.stallReasonData.pStallReasonIndex = pStallReasonIndex;
309 pcSamplingConfigurationInfo.push_back(stallReason);
310
311 //------------------------ Scratch Buffer ------------------------//
312 CUpti_PCSamplingConfigurationInfo scratchBufferSize = {};
313 scratchBufferSize.attributeType =
314 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_SCRATCH_BUFFER_SIZE;
315 scratchBufferSize.attributeData.scratchBufferSizeData.scratchBufferSize =
316 10 * units::MB;
317 pcSamplingConfigurationInfo.push_back(scratchBufferSize);
318
319 //------------------------ Collect Mode ------------------------//
320 auto _serialized = settings::instance()->get<int>("cupti_pcsampling_serialized");
321 CUpti_PCSamplingConfigurationInfo collectionMode = {};
322 collectionMode.attributeType =
323 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_COLLECTION_MODE;
324 collectionMode.attributeData.collectionModeData.collectionMode =
325 (_serialized) ? CUPTI_PC_SAMPLING_COLLECTION_MODE_KERNEL_SERIALIZED
326 : CUPTI_PC_SAMPLING_COLLECTION_MODE_CONTINUOUS;
327 pcSamplingConfigurationInfo.push_back(collectionMode);
328
329 //------------------------ Start / Stop ------------------------//
330 CUpti_PCSamplingConfigurationInfo enableStartStop = {};
331 enableStartStop.attributeType =
332 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_ENABLE_START_STOP_CONTROL;
333 enableStartStop.attributeData.enableStartStopControlData.enableStartStopControl =
334 true;
335 pcSamplingConfigurationInfo.push_back(enableStartStop);
336
337 //------------------------ Output Data Fmt ------------------------//
338 CUpti_PCSamplingConfigurationInfo outputDataFormat = {};
339 outputDataFormat.attributeType =
340 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_OUTPUT_DATA_FORMAT;
341 outputDataFormat.attributeData.outputDataFormatData.outputDataFormat =
342 CUPTI_PC_SAMPLING_OUTPUT_DATA_FORMAT_PARSED;
343 pcSamplingConfigurationInfo.push_back(outputDataFormat);
344
345 //------------------------ Sample Data Buffer ------------------------//
346 CUpti_PCSamplingConfigurationInfo samplingDataBuffer = {};
347 samplingDataBuffer.attributeType =
348 CUPTI_PC_SAMPLING_CONFIGURATION_ATTR_TYPE_SAMPLING_DATA_BUFFER;
349 samplingDataBuffer.attributeData.samplingDataBufferData.samplingDataBuffer =
350 (void*) pcSamplingData.pPcData;
351 pcSamplingConfigurationInfo.push_back(samplingDataBuffer);
352
353 //------------------------ Config Info Params ------------------------//
354 CUpti_PCSamplingConfigurationInfoParams pcSamplingConfigurationInfoParams = {};
355 pcSamplingConfigurationInfoParams.size = CUpti_PCSamplingConfigurationInfoParamsSize;
356 pcSamplingConfigurationInfoParams.ctx = cuCtx;
357 pcSamplingConfigurationInfoParams.numAttributes = pcSamplingConfigurationInfo.size();
358 pcSamplingConfigurationInfoParams.pPCSamplingConfigurationInfo =
359 pcSamplingConfigurationInfo.data();
360 TIMEMORY_CUPTI_API_CALL(
361 cuptiPCSamplingSetConfigurationAttribute(&pcSamplingConfigurationInfoParams));
362
363 for(auto itr : pcSamplingConfigurationInfo)
364 TIMEMORY_CUPTI_API_CALL(itr.attributeStatus);
365
366 // At start of code region
367 CUpti_PCSamplingStartParams pcSamplingStartParams = {};
368 pcSamplingStartParams.size = CUpti_PCSamplingStartParamsSize;
369 pcSamplingStartParams.ctx = cuCtx;
370 // cuptiPCSamplingStart(&pcSamplingStartParams);
371
372 // At end of code region
373 CUpti_PCSamplingStopParams pcSamplingStopParams = {};
374 pcSamplingStopParams.size = CUpti_PCSamplingStopParamsSize;
375 pcSamplingStopParams.ctx = cuCtx;
376 // cuptiPCSamplingStop(&pcSamplingStopParams);
377
378 return std::make_tuple(cuCtx, pcSamplingEnableParams, numStallReasonsParams,
379 stallReasonsParams, pcSamplingData,
380 std::move(pcSamplingConfigurationInfo),
381 pcSamplingConfigurationInfoParams, pcSamplingStartParams,
382 pcSamplingStopParams, stallReasonCount, _num_collect);
383}
384
387{
388 auto& _cfg = get_configuration_data();
389 if(!_cfg.enabled)
390 std::tie(_cfg.enabled, _cfg.data) = std::make_tuple(true, configure());
391}
392
395{
396 auto& _cfg = get_configuration_data();
397 if(_cfg.enabled)
398 {
399 _cfg.enabled = false;
400 CUcontext cuCtx = _cfg.context();
401 // Disable PC Sampling
402 CUpti_PCSamplingDisableParams pcSamplingDisableParams = {};
403 pcSamplingDisableParams.size = CUpti_PCSamplingDisableParamsSize;
404 pcSamplingDisableParams.ctx = cuCtx;
405 TIMEMORY_CUPTI_API_CALL(cuptiPCSamplingDisable(&pcSamplingDisableParams));
406 // Destroy CUDA context
407 // TIMEMORY_CUDA_DRIVER_API_CALL(cuCtxDestroy(cuCtx));
408 }
409}
410
413{
414 auto& _cfg = get_configuration_data();
415 if(!_cfg.enabled)
416 return data_type{};
417
418 auto pcSamplingData =
419 get_pcsampling_data(_cfg.num_stall_reasons(), _cfg.num_collect_pcs());
420
421 CUpti_PCSamplingGetDataParams pcSamplingGetDataParams = {};
422 pcSamplingGetDataParams.size = CUpti_PCSamplingGetDataParamsSize;
423 pcSamplingGetDataParams.ctx = _cfg.context();
424 pcSamplingGetDataParams.pcSamplingData = static_cast<void*>(&pcSamplingData);
425 TIMEMORY_CUPTI_API_CALL(cuptiPCSamplingGetData(&pcSamplingGetDataParams));
426 if(settings::debug())
427 printPCSamplingData(&pcSamplingData, _cfg.num_stall_reasons(),
428 cupti::pcstall::get_index_array(),
429 cupti::pcstall::get_name_array());
430 return data_type{ std::move(pcSamplingData) };
431}
432
434cupti_pcsampling::sample()
435{
436 cupti::pcdata _data = record();
437 for(auto&& itr : _data.samples)
438 {
439 component_tuple<cupti_pcsampling> _bundle{ itr.name() };
440 _bundle.push();
441 _bundle.store(std::move(itr));
442 _bundle.pop();
443 }
444}
445
447cupti_pcsampling::store(const value_type& _data)
448{
449 value = _data;
450 if(get_configuration_data().region_totals)
451 for(auto& itr : get_stack())
452 itr->value += value;
453}
454
456cupti_pcsampling::store(value_type&& _data)
457{
458 value = std::move(_data);
459 if(get_configuration_data().region_totals)
460 for(auto& itr : get_stack())
461 itr->value += value;
462}
463
466{
467 auto _n = tracker_type::start();
468 if(_n == 0)
469 {
470 initialize();
471 TIMEMORY_CUPTI_API_CALL(
472 cuptiPCSamplingStart(&get_configuration_data().start_params()));
473 }
474 if(get_configuration_data().region_totals)
475 get_stack().insert(this);
476}
477
480{
481 sample();
482 if(get_configuration_data().region_totals)
483 get_stack().erase(this);
484
485 auto _n = tracker_type::stop();
486 if(_n == 0)
487 {
488 TIMEMORY_CUPTI_API_CALL(
489 cuptiPCSamplingStop(&get_configuration_data().stop_params()));
490 // finalize();
491 }
492}
493
495cupti_pcsampling::set_started()
496{
497 base_type::set_started();
498}
499
501cupti_pcsampling::set_stopped()
502{
503 // don't increment laps
504 if(get_is_running())
505 set_is_running(false);
506}
507
509 cupti_pcsampling::get_display() const
510{
511 std::stringstream ss;
512 ss.precision(base_type::get_precision());
513 ss.width(base_type::get_width());
514 ss.setf(base_type::get_format_flags());
515 ss << load();
516 return ss.str();
517}
518//
519TIMEMORY_CUPTI_INLINE std::vector<int64_t>
521{
522 auto _n = cupti::pcstall::get_size();
523 std::vector<int64_t> _data{};
524 _data.reserve(_n);
525 auto _val = load();
526 for(size_t i = 0; i < _n; ++i)
527 {
528 if(cupti::pcstall::enabled(i) && strlen(cupti::pcstall::name(i)) > 0)
529 {
530 // this is a packed field so directly emplacing it can cause compiler errors
531 uint32_t _v = _val.stalls[i].samples;
532 _data.emplace_back(static_cast<int64_t>(_v));
533 }
534 }
535 return _data;
536}
537//
538TIMEMORY_CUPTI_INLINE std::vector<std::string>
539 cupti_pcsampling::label_array()
540{
541 auto _n = cupti::pcstall::get_size();
542 std::vector<std::string> _data{};
543 _data.reserve(_n);
544 for(size_t i = 0; i < _n; ++i)
545 {
546 if(cupti::pcstall::enabled(i) && strlen(cupti::pcstall::name(i)) > 0)
547 _data.push_back(std::string{ cupti::pcstall::name(i) });
548 }
549 return _data;
550}
551//
552} // namespace component
553} // namespace tim
554
555#endif // TIMEMORY_USE_CUPTI_PCSAMPLING
#define TIMEMORY_CUPTI_INLINE
Definition: types.hpp:34
#define TIMEMORY_CUDA_RUNTIME_API_CALL(...)
Definition: macros.hpp:499
#define TIMEMORY_CUDA_DRIVER_API_CALL(...)
Definition: macros.hpp:394
void load(Archive &ar, tim::node::graph< Tp > &d)
Definition: node.hpp:520
void store(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:564
void record(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:634
void stop(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:386
void start(TupleT< Tp... > &obj, Args &&... args)
Definition: functional.cpp:316
constexpr auto get_size(const Tp &, std::tuple<>) -> size_t
Definition: types.hpp:877
std::bitset< scope_count > data_type
Definition: types.hpp:399
Definition: kokkosp.cpp:39
void configure(std::initializer_list< EnumT > components, Args &&... args)
Definition: configure.hpp:50
void initialize(CompList< CompTypes... > &obj, std::initializer_list< EnumT > components)
Definition: initialize.hpp:53
std::string demangle(const char *_mangled_name, int *_status=nullptr)
Definition: demangle.hpp:47
tim::mpl::apply< std::string > string
Definition: macros.hpp:53
void finalize()
Definition: types.hpp:119
auto get(const auto_bundle< Tag, Types... > &_obj)
ContainerT delimit(const std::string &line, const std::string &delimiters="\"',;: ", PredicateT &&predicate=[](const std::string &s) -> std::string { return s;})
Definition: delimit.hpp:68
Definition for various functions for store in operations.