Skip to content

Commit cb92bb2

Browse files
authored
Merge pull request #2396 from DARMA-tasking/2389-make-invoke-without-a-message-work-with-tracing
#2389: trace: start tracing invoke calls
2 parents fcc894c + dfb53e7 commit cb92bb2

File tree

12 files changed

+237
-16
lines changed

12 files changed

+237
-16
lines changed

src/vt/context/runnable_context/trace.cc

+40
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,46 @@
5454

5555
namespace vt { namespace ctx {
5656

57+
Trace::Trace(
58+
trace::TraceEventIDType event, HandlerType const in_handler,
59+
NodeType const in_from_node, std::size_t msg_size
60+
) : is_collection_(false),
61+
event_(event),
62+
msg_size_(msg_size),
63+
is_traced_(HandlerManager::isHandlerTrace(in_handler)),
64+
from_node_(in_from_node),
65+
handler_(in_handler)
66+
{ }
67+
68+
Trace::Trace(
69+
trace::TraceEventIDType event, HandlerType const in_handler,
70+
NodeType const in_from_node, std::size_t msg_size,
71+
uint64_t in_idx1, uint64_t in_idx2, uint64_t in_idx3, uint64_t in_idx4
72+
) : is_collection_(false),
73+
event_(event),
74+
msg_size_(msg_size),
75+
is_traced_(HandlerManager::isHandlerTrace(in_handler)),
76+
from_node_(in_from_node),
77+
handler_(in_handler),
78+
idx1_(in_idx1),
79+
idx2_(in_idx2),
80+
idx3_(in_idx3),
81+
idx4_(in_idx4)
82+
{ }
83+
5784
void Trace::start(TimeType time) {
5885
if (not is_traced_) {
5986
return;
6087
}
6188

89+
// If our scheduler depth is zero, we need to end the between scheduler event
90+
if (theSched()->getSchedulerDepth() == 0 and not theTrace()->inInvokeContext()) {
91+
at_sched_depth_zero_ = true;
92+
theTrace()->setInInvokeContext(true);
93+
auto const end_between_sched_time = theTrace()->beginSchedulerLoop();
94+
time = std::max(time, end_between_sched_time);
95+
}
96+
6297
auto const trace_id = auto_registry::handlerTraceID(handler_);
6398

6499
if (is_collection_) {
@@ -82,6 +117,11 @@ void Trace::finish(TimeType time) {
82117
}
83118

84119
theTrace()->endProcessing(processing_tag_, time);
120+
121+
if (at_sched_depth_zero_) {
122+
theTrace()->endSchedulerLoop();
123+
theTrace()->setInInvokeContext(false);
124+
}
85125
}
86126

87127
void Trace::suspend(TimeType time) {

src/vt/context/runnable_context/trace.h

+36
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,40 @@ struct Trace {
6161

6262
Trace() = default;
6363

64+
/**
65+
* \brief Construct a new trace context (basic processing) without a message
66+
* directly
67+
*
68+
* \param[in] event the trace event
69+
* \param[in] in_handler the handler
70+
* \param[in] in_from_node from node
71+
* \param[in] msg_size size of message/payload (zero of not serializable
72+
*/
73+
Trace(
74+
trace::TraceEventIDType event, HandlerType const in_handler,
75+
NodeType const in_from_node, std::size_t msg_size
76+
);
77+
78+
/**
79+
* \brief Construct a new trace context (collection processing) without a
80+
* message directly
81+
*
82+
* \param[in] event the trace event
83+
* \param[in] in_handler the handler
84+
* \param[in] in_from_node from node
85+
* \param[in] msg_size size of message/payload (zero of not serializable
86+
* \param[in] in_idx1 1-dimension index
87+
* \param[in] in_idx2 2-dimension index
88+
* \param[in] in_idx3 3-dimension index
89+
* \param[in] in_idx4 4-dimension index
90+
*/
91+
Trace(
92+
trace::TraceEventIDType event, HandlerType const in_handler,
93+
NodeType const in_from_node, std::size_t msg_size,
94+
uint64_t in_idx1, uint64_t in_idx2, uint64_t in_idx3, uint64_t in_idx4
95+
);
96+
97+
6498
/**
6599
* \brief Construct a new trace context (basic processing event)
66100
*
@@ -123,6 +157,8 @@ struct Trace {
123157
uint64_t idx1_ = 0, idx2_ = 0, idx3_ = 0, idx4_ = 0;
124158
/// The open processing tag
125159
trace::TraceProcessingTag processing_tag_;
160+
/// At scheduler depth zero
161+
bool at_sched_depth_zero_ = false;
126162
};
127163

128164
#else

src/vt/objgroup/manager.impl.h

+16-1
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,26 @@ ObjGroupManager::invoke(ProxyElmType<ObjT> proxy, Args&&... args) {
220220
dest_node == this_node,
221221
fmt::format(
222222
"Attempting to invoke handler on node:{} instead of node:{}!\n",
223-
this_node, dest_node));
223+
this_node, dest_node
224+
)
225+
);
226+
227+
#if vt_check_enabled(trace_enabled)
228+
auto const ctrl = proxy::ObjGroupProxy::getID(proxy.getProxy());
229+
auto const han = auto_registry::makeAutoHandlerObjGroupParam<
230+
ObjT, decltype(f), f, void
231+
>(ctrl);
232+
auto const trace_event = theMsg()->makeTraceCreationSend(han, 0, false);
233+
234+
return runnable::makeRunnableVoidTraced(false, han, this_node, trace_event, 0)
235+
.withObjGroup(get(proxy))
236+
.runLambda(f, get(proxy), std::forward<Args>(args)...);
224237

238+
#else
225239
return runnable::makeRunnableVoid(false, uninitialized_handler, this_node)
226240
.withObjGroup(get(proxy))
227241
.runLambda(f, get(proxy), std::forward<Args>(args)...);
242+
#endif
228243
}
229244

230245

src/vt/registry/auto/auto_registry_common.h

+2
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ struct HandlersDispatcher final : BaseHandlersDispatcher {
130130
}
131131
} else if constexpr (std::is_same_v<ObjT, SentinelObject>) {
132132
std::apply(fp, msg->getTuple());
133+
} else if constexpr (std::is_same_v<MsgT, void>) {
134+
// do nothing
133135
} else {
134136
if constexpr (IsColTrait<ObjT>::value and IsWrapMsgTrait<MsgT>::value) {
135137
auto& m = msg->getMsg();

src/vt/runnable/make_runnable.h

+73-2
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,8 @@ RunnableMaker<U> makeRunnable(
351351
}
352352

353353
/**
354-
* \brief Make a new runnable without a message (void handler)
354+
* \brief Make a new runnable without a message (void handler) -- untraced
355+
* variant. Call \c makeRunnableVoidTraced if you want it to show up in tracing
355356
*
356357
* \param[in] is_threaded whether it is threaded
357358
* \param[in] handler the handler bits
@@ -364,11 +365,81 @@ inline RunnableMaker<BaseMsgType> makeRunnableVoid(
364365
) {
365366
// These are currently only types of registry entries that can be void
366367
auto r = new RunnableNew(is_threaded);
367-
// @todo: figure out how to trace this?
368368
r->addContextSetContext(r, from);
369369
return RunnableMaker<BaseMsgType>{r, nullptr, handler, from};
370370
}
371371

372+
/**
373+
* \brief Make a new runnable without a message (void handler) with tracing
374+
*
375+
* \param[in] is_threaded whether it is threaded
376+
* \param[in] handler the handler bits
377+
* \param[in] from the node that caused this runnable to execute
378+
*
379+
* \return the maker for further customization
380+
*/
381+
inline RunnableMaker<BaseMsgType> makeRunnableVoidTraced(
382+
bool is_threaded, HandlerType handler, NodeType from,
383+
[[maybe_unused]] trace::TraceEventIDType trace_event,
384+
[[maybe_unused]] std::size_t msg_size
385+
) {
386+
// These are currently only types of registry entries that can be void
387+
auto r = new RunnableNew(is_threaded);
388+
r->addContextSetContext(r, from);
389+
390+
#if vt_check_enabled(trace_enabled)
391+
auto const han_type = HandlerManager::getHandlerRegistryType(handler);
392+
if (han_type == auto_registry::RegistryTypeEnum::RegVrt or
393+
han_type == auto_registry::RegistryTypeEnum::RegGeneral or
394+
han_type == auto_registry::RegistryTypeEnum::RegObjGroup) {
395+
r->addContextTrace(trace_event, handler, from, msg_size);
396+
}
397+
#endif
398+
399+
return RunnableMaker<BaseMsgType>{r, nullptr, handler, from};
400+
}
401+
402+
/**
403+
* \brief Make a new runnable without a message (void handler) with tracing for
404+
* collections
405+
*
406+
* \param[in] is_threaded whether it is threaded
407+
* \param[in] handler the handler bits
408+
* \param[in] from the node that caused this runnable to execute
409+
* \param[in] idx1 1-dimension index
410+
* \param[in] idx2 2-dimension index
411+
* \param[in] idx3 3-dimension index
412+
* \param[in] idx4 4-dimension index
413+
*
414+
* \return the maker for further customization
415+
*/
416+
inline RunnableMaker<BaseMsgType> makeRunnableVoidTraced(
417+
bool is_threaded, HandlerType handler, NodeType from,
418+
[[maybe_unused]] trace::TraceEventIDType trace_event,
419+
[[maybe_unused]] std::size_t msg_size,
420+
[[maybe_unused]] uint64_t idx1,
421+
[[maybe_unused]] uint64_t idx2,
422+
[[maybe_unused]] uint64_t idx3,
423+
[[maybe_unused]] uint64_t idx4
424+
) {
425+
// These are currently only types of registry entries that can be void
426+
auto r = new RunnableNew(is_threaded);
427+
r->addContextSetContext(r, from);
428+
429+
#if vt_check_enabled(trace_enabled)
430+
auto const han_type = HandlerManager::getHandlerRegistryType(handler);
431+
if (han_type == auto_registry::RegistryTypeEnum::RegVrtCollection or
432+
han_type == auto_registry::RegistryTypeEnum::RegVrtCollectionMember) {
433+
r->addContextTrace(
434+
trace_event, handler, from, msg_size, idx1, idx2, idx3, idx4
435+
);
436+
}
437+
#endif
438+
439+
return RunnableMaker<BaseMsgType>{r, nullptr, handler, from};
440+
}
441+
442+
372443
}} /* end namespace vt::runnable */
373444

374445
#include "vt/runnable/make_runnable.impl.h"

src/vt/scheduler/scheduler.cc

+2
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,13 @@ void Scheduler::runSchedulerOnceImpl(bool msg_only) {
303303

304304
Scheduler::SchedulerLoopGuard::SchedulerLoopGuard(Scheduler* scheduler)
305305
: scheduler_{scheduler} {
306+
scheduler_->in_sched_depth_++;
306307
scheduler_->triggerEvent(SchedulerEventType::BeginSchedulerLoop);
307308
}
308309

309310
Scheduler::SchedulerLoopGuard::~SchedulerLoopGuard() {
310311
scheduler_->triggerEvent(SchedulerEventType::EndSchedulerLoop);
312+
scheduler_->in_sched_depth_--;
311313
}
312314

313315
void Scheduler::runSchedulerWhile(std::function<bool()> cond) {

src/vt/scheduler/scheduler.h

+8
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,11 @@ struct Scheduler : runtime::component::Component<Scheduler> {
343343
*/
344344
void setRecentTimeToStale() { is_recent_time_stale_ = true; }
345345

346+
/**
347+
* \brief Get the current recursive scheduler depth
348+
*/
349+
unsigned int getSchedulerDepth() const { return in_sched_depth_; }
350+
346351
#if vt_check_enabled(fcontext)
347352
/**
348353
* \brief Get the thread manager
@@ -363,6 +368,7 @@ struct Scheduler : runtime::component::Component<Scheduler> {
363368
| is_idle
364369
| is_idle_minus_term
365370
| action_depth_
371+
| in_sched_depth_
366372
| num_term_msgs_
367373
| event_triggers
368374
| event_triggers_once
@@ -430,6 +436,8 @@ struct Scheduler : runtime::component::Component<Scheduler> {
430436
bool is_idle_minus_term = true;
431437
// The depth of work action currently executing.
432438
unsigned int action_depth_ = 0;
439+
/// In-scheduler depth, zero indicates not in a scheduler
440+
unsigned int in_sched_depth_ = 0;
433441

434442
// The number of termination messages currently in the queue---they weakly
435443
// imply idleness for the stake of termination

src/vt/trace/trace.cc

+9-6
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,9 @@ TraceProcessingTag Trace::beginProcessing(
349349

350350
vt_debug_print(
351351
normal, trace,
352-
"event_start: ep={}, event={}, time={}, from={}, entry chare={}\n",
353-
ep, event, time, from_node, TraceRegistry::getEvent(ep).theEventSeq()
352+
"event_start: ep={}, event={}, time={}, from={}, entry chare={}, name={}\n",
353+
ep, event, time, from_node, TraceRegistry::getEvent(ep).theEventSeq(),
354+
TraceRegistry::getEvent(ep).theEventName()
354355
);
355356

356357
auto const type = TraceConstantsType::BeginProcessing;
@@ -394,9 +395,9 @@ void Trace::endProcessing(
394395

395396
vt_debug_print(
396397
normal, trace,
397-
"event_stop: ep={}, event={}, time={}, from_node={}, entry chare={}\n",
398+
"event_stop: ep={}, event={}, time={}, from_node={}, entry chare={}, name={}\n",
398399
ep, event, time, open_events_.back().node,
399-
TraceRegistry::getEvent(ep).theEventSeq()
400+
TraceRegistry::getEvent(ep).theEventSeq(), TraceRegistry::getEvent(ep).theEventName()
400401
);
401402

402403
vtAssert(
@@ -428,13 +429,15 @@ void Trace::pendingSchedulerLoop() {
428429
between_sched_event_ = TraceProcessingTag{};
429430
}
430431

431-
void Trace::beginSchedulerLoop() {
432+
TimeType Trace::beginSchedulerLoop() {
433+
auto const cur_time = timing::getCurrentTime();
432434
// Always end between-loop event. The pending case is not always triggered.
433-
endProcessing(between_sched_event_, timing::getCurrentTime());
435+
endProcessing(between_sched_event_, cur_time);
434436
between_sched_event_ = TraceProcessingTag{};
435437

436438
// Capture the current open event depth.
437439
event_holds_.push_back(open_events_.size());
440+
return cur_time;
438441
}
439442

440443
void Trace::endSchedulerLoop() {

src/vt/trace/trace.h

+22-6
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ struct Trace : runtime::component::Component<Trace>, TraceLite {
172172

173173
/**
174174
* \brief Scheduler trigger for \c sched::SchedulerEvent::BeginSchedulerLoop
175+
*
176+
* \return the time the between scheduler event was ended
175177
*/
176-
void beginSchedulerLoop();
178+
TimeType beginSchedulerLoop();
177179

178180
/**
179181
* \brief Scheduler trigger for \c sched::SchedulerEvent::EndSchedulerLoop
@@ -361,6 +363,22 @@ struct Trace : runtime::component::Component<Trace>, TraceLite {
361363
*/
362364
bool inIdleEvent() const;
363365

366+
/**
367+
* \brief Set if we are inside an invoke context
368+
*
369+
* \param[in] set the variable value to set
370+
*/
371+
void setInInvokeContext(bool set) {
372+
inside_invoke_context_ = set;
373+
}
374+
375+
/**
376+
* \brief Return if we are inside an invoke context
377+
*
378+
* \return whether we are inside an invoke context
379+
*/
380+
bool inInvokeContext() const { return inside_invoke_context_; }
381+
364382
friend void insertNewUserEvent(UserEventIDType event, std::string const& name);
365383

366384
template <typename SerializerT>
@@ -385,7 +403,8 @@ struct Trace : runtime::component::Component<Trace>, TraceLite {
385403
| trace_enabled_cur_phase_
386404
| flush_event_
387405
| between_sched_event_type_
388-
| between_sched_event_;
406+
| between_sched_event_
407+
| inside_invoke_context_;
389408

390409
s.skip(log_file_); // definition unavailable
391410
}
@@ -398,15 +417,12 @@ struct Trace : runtime::component::Component<Trace>, TraceLite {
398417
int incremental_flush_mode = 0;
399418

400419
private:
401-
402-
403420
ObjGroupProxyType spec_proxy_ = vt::no_obj_group;
404421

405-
406-
407422
// Processing event between top-level loops.
408423
TraceEntryIDType between_sched_event_type_ = no_trace_entry_id;
409424
TraceProcessingTag between_sched_event_;
425+
bool inside_invoke_context_ = false;
410426
};
411427

412428
}} //end namespace vt::trace

src/vt/vrt/collection/balance/lb_invoke/lb_manager.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ void LBManager::startLB(
366366
break;
367367
}
368368

369-
runLB(phase, cb);
369+
proxy_[theContext()->getNode()].template invoke<&LBManager::runLB>(phase, cb);
370370
}
371371

372372
/*static*/

0 commit comments

Comments
 (0)