19#include "src/utils.hpp"
23UITrace::UITrace(std::map<otf2::definition::location_group *, std::vector<Slot *>,
LocationGroupCmp> slotsVec,
26 const otf2::chrono::duration &runtime,
const otf2::chrono::duration &startTime,
27 const otf2::chrono::duration &timePerPx) :
29 timePerPx_(timePerPx) {
30 communications_ = communications;
31 collectiveCommunications_ = collectiveCommunications;
33 startTime_ = startTime;
35 for (
auto &item: slotsVec) {
36 slots_.insert({item.first,
Range(item.second)});
46 auto minDuration = timePerPixel * MIN_SLOT_SIZE_PX;
47 std::map<otf2::definition::location_group *, std::vector<Slot *>,
LocationGroupCmp> newSlots;
48 for (
const auto &item: trace->
getSlots()) {
49 auto locationGroup = item.first;
50 auto slots = item.second;
51 auto newSlotsForRank = optimize<Slot, SlotKind>(
55 &UITrace::aggregateSlots);
57 newSlots.insert({locationGroup, newSlotsForRank});
64 minDuration = timePerPixel * MIN_COMMUNICATION_SIZE_PX;
65 auto communicationsByRank = groupBy<Communication *, otf2::reference<otf2::definition::location_group>>(
67 [](
const Communication *c) {
return c->getStartEvent()->getLocation()->location_group().ref(); },
70 auto rankR = r->getStartEvent()->getLocation()->location_group().ref();
79 std::vector<Communication *> newCommunications;
80 for (
const auto &item: communicationsByRank) {
81 auto communications = item.second;
82 auto newCommunicationsForRank = optimize<Communication>(
85 [](
Communication *starter, std::vector<Communication *> &) {
return starter; });
86 newCommunications.insert(newCommunications.end(), newCommunicationsForRank.begin(),
87 newCommunicationsForRank.end());
92 minDuration = timePerPixel * MIN_COLLECTIVE_EVENT_SIZE_PX;
93 auto newCollectiveCommunications = optimize<CollectiveCommunicationEvent>(minDuration,
95 &UITrace::aggregateCollectiveCommunications);
97 return new UITrace(newSlots,
Range(newCommunications),
Range(newCollectiveCommunications),
102requires std::is_base_of_v<TimedElement, T>
103std::vector<T *> UITrace::optimize(types::TraceTime minDuration,
105 std::function<T *(T *, std::vector<T *> &stats)> aggregate) {
108 return optimize<T, uint8_t>(
111 [](
const T *) {
return 0; },
112 [aggregate](T *starter, std::map<uint8_t, std::vector<T *>> &stats) {
113 return aggregate(starter, stats[0]);
117template<
class T,
typename K>
118requires std::is_base_of_v<TimedElement, T>
119std::vector<T *> UITrace::optimize(types::TraceTime minDuration,
121 std::function<K(
const T *)> keySelector,
122 std::function<T *(T *, std::map<K, std::vector<T *>> &stats)> aggregate) {
123 std::vector<T *> newElements;
124 T *intervalStarter =
nullptr;
125 std::map<K, std::vector<T *>> stats;
127 for (
const auto &element: elements) {
129 if (intervalStarter !=
nullptr && (element->getStartTime() > intervalStarter->getStartTime() + minDuration)) {
130 newElements.push_back(aggregate(intervalStarter, stats));
133 intervalStarter =
nullptr;
137 if (element->getDuration() < minDuration) {
138 if (intervalStarter ==
nullptr) {
139 intervalStarter = element;
143 if (!stats.contains(keySelector(element))) {
144 stats.insert({keySelector(element), std::vector<T *>()});
147 stats.at(keySelector(element)).push_back(element);
149 newElements.push_back(element);
154 if (intervalStarter) {
155 newElements.push_back(aggregate(intervalStarter, stats));
161requires std::is_base_of_v<TimedElement, T>
162static T *longest(std::vector<T *> ls) {
163 return *std::max_element(ls.begin(), ls.end(), [](T *lhs, T *rhs) {
164 return lhs->getDuration() > rhs->getDuration();
169requires std::is_base_of_v<TimedElement, T>
170static T *last(std::vector<T *> ls) {
171 return *std::max_element(ls.begin(), ls.end(), [](T *lhs, T *rhs) {
172 return lhs->getEndTime() < rhs->getEndTime();
177Slot *UITrace::aggregateSlots(
const Slot *intervalStarter, std::map<SlotKind, std::vector<Slot *>> &stats) {
178 std::vector<Slot *>* elements;
181 if (stats.contains(MPI)) {
182 elements = &stats.at(MPI);
183 }
else if (stats.contains(OpenMP)) {
184 elements = &stats.at(OpenMP);
186 elements = &stats.at(Plain);
189 auto longestSlot = longest(*elements);
190 auto intervalEnder = last(*elements);
192 return new Slot(intervalStarter->
startTime, intervalEnder->endTime, longestSlot->location, longestSlot->region);
197 std::vector<CollectiveCommunicationEvent *> &stats) {
198 auto longestEvent = longest(stats);
199 auto intervalEnder = last(stats);
202 intervalEnder->getEndTime(),
203 longestEvent->getLocation());
205 std::vector<CollectiveCommunicationEvent::Member *> singletonMembers;
206 singletonMembers.push_back(singleMember);
209 singletonMembers, longestEvent->getLocation(), longestEvent->getCommunicator(),
210 longestEvent->getOperation(), longestEvent->getRoot()
A class representing a member of a collective operation.
A class representing an MPI collective operation.
otf2::chrono::duration getStartTime() const override
virtual otf2::definition::location * getLocation() const =0
Class representing any (successful or unsuccessful) communication.
const CommunicationEvent * getStartEvent() const
types::TraceTime getStartTime() const override
Returns the start time of the current object.
A custom range implementation around std::vector<T>s.
A Slot represents a visual slot to be rendered in the UI. It contains the information of a location.
SlotKind getKind() const
Returns the kind of the current Slot object.
otf2::chrono::duration startTime
Start time of the slot relative to the trace start time.
Trace representing a section of a larger trace.
Trace * subtrace(otf2::chrono::duration from, otf2::chrono::duration to) override
Creates a subtrace of the current trace.
virtual types::TraceTime getStartTime() const =0
Returns the start time of the current object.
Abstract base class for a trace.
virtual otf2::chrono::duration getRuntime() const =0
Returns the runtime of the current trace.
virtual std::map< otf2::definition::location_group *, Range< Slot * >, LocationGroupCmp > getSlots() const =0
Returns a map of slots of the current trace.
virtual Range< CollectiveCommunicationEvent * > getCollectiveCommunications()=0
Returns collective communication events of the current trace.
virtual Range< Communication * > getCommunications()=0
Returns communication objects of the current trace.
Trace facilitating a subtrace optimized for rendering.
Trace * subtrace(otf2::chrono::duration from, otf2::chrono::duration to) override
Creates a subtrace of the current trace.
static UITrace * forResolution(Trace *trace, otf2::chrono::duration timePerPixel)
A comparator for otf2::definition::location_group objects.