HTGS  v2.0
The Hybrid Task Graph Scheduler
TaskGraphProfiler.hpp
Go to the documentation of this file.
1 // NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the software in any medium, provided that you keep intact this entire notice. You may improve, modify and create derivative works of the software or any portion of the software, and you may copy and distribute such modifications or works. Modified works should carry a notice stating that you changed the software and should note the date and nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the source of the software.
2 // NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE.
3 // You are solely responsible for determining the appropriateness of using and distributing the software and you assume all risks associated with its use, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of operation. This software is not intended to be used in any situation where a failure could cause risk of injury or damage to property. The software developed by NIST employees is not subject to copyright protection within the United States.
4 
5 //
6 // Created by tjb3 on 3/22/17.
7 //
8 
17 #ifndef HTGS_TASKGRAPHPROFILER_HPP
18 #define HTGS_TASKGRAPHPROFILER_HPP
19 
23 #include <htgs/api/TGTask.hpp>
24 #include <htgs/utils/ProfileUtils.hpp>
25 #include <set>
26 namespace htgs {
27 
28  class TaskManagerProfile;
29 
43  public:
44 
49  TaskGraphProfiler(int flags) : flags(flags) {
50  taskManagerProfiles = new std::map<AnyTaskManager *, TaskManagerProfile *>();
51  }
52 
57  for (auto v : *taskManagerProfiles) {
58  delete v.second;
59  v.second = nullptr;
60  }
61 
62  delete taskManagerProfiles;
63  taskManagerProfiles = nullptr;
64 
65  if (profileUtils) {
66  delete profileUtils;
67  profileUtils = nullptr;
68  }
69  }
70 
75  void buildProfile(AnyTaskGraphConf *graphConf) {
77  taskGraphComputeTime = graphConf->getGraphComputeTime();
78  }
79 
83  void printProfiles() {
84  for (auto t : *taskManagerProfiles) {
85  std::cout << t.first->getName() << " addr: " << t.first->getAddress() << " id: " << t.first->getThreadId()
86  << " Profile: " << *t.second << std::endl;
87  }
88  }
89 
102  std::string genDotProfile(std::string curDotGraph, int colorFlag) {
103  std::string ret = "";
104 
105  // If all threading is disabled, then compute the averages only, based on first thread
106  if ((flags & DOTGEN_FLAG_SHOW_ALL_THREADING) == 0) {
107  computeAverages();
108  }
109 
110  bool useColorMap = false;
111  std::unordered_map<std::string, std::string> *colorMap = nullptr;
112  if (colorFlag != 0) {
113  useColorMap = true;
114  colorMap = genColorMap(colorFlag);
115  }
116 
117  for (auto t : *taskManagerProfiles) {
118  auto tMan = t.first;
119  auto tProfile = t.second;
120 
121  auto tFun = tMan->getTaskFunction();
122 
123  std::string dotId = tMan->getTaskFunction()->getDotId();
124 
125  if (curDotGraph.find(dotId + ";") != std::string::npos) {
126 
127  std::string aliveLabel =
128  ((flags & DOTGEN_FLAG_SHOW_TASK_LIVING_STATUS) != 0) ? ("\\nLiving threads: " + std::to_string(tMan->getThreadsRemaining())) : "";
129  std::string inOutLabel =
130  (((flags & DOTGEN_FLAG_SHOW_IN_OUT_TYPES) != 0) ? ("\\nin: " + tFun->inTypeName() + "\\nout: "
131  + tFun->outTypeName()) : "");
132  std::string threadLabel =
133  (((flags & DOTGEN_FLAG_SHOW_ALL_THREADING) != 0) ? "" : (" x" + std::to_string(tFun->getNumThreads())));
134  ret += dotId + "[label=\"" + tFun->getDotLabelName();
135  ret += threadLabel + inOutLabel + "\\n";
136  ret += tProfile->genDot(flags);
137  ret += (tFun->debugDotNode() != "" ? ("\\n" + tFun->debugDotNode() + "\\n") : "");
138  ret += aliveLabel;
139  ret += (tFun->getDotCustomProfile() != "" ? ("\\n" + tFun->getDotCustomProfile() + "\\n") : "");
140  ret += "\",shape=" + tFun->getDotShape();
141  ret += ",style=filled";
142  ret += ",fillcolor=" + tFun->getDotFillColor();
143  ret +=(useColorMap ? ",penwidth=5,color=\"" + colorMap->at(dotId) + "\"" : ", color=" + tFun->getDotShapeColor());
144  ret += ",width=.2,height=.2];\n";
145  }
146 // else if (curDotGraph.find("subgraph cluster_" + dotId) != std::string::npos)
147 // {
148 // Add custom profiling for execution pipeline and TGTask
149 // ret += tMan->getTaskFunction()->genCustomDot(profileUtils, colorFlag);
150 // }
151  }
152 
153  delete colorMap;
154  colorMap = nullptr;
155 
156  return ret;
157  }
158 
159 
165  {
166  return profileUtils;
167  }
168 
173  std::map<AnyTaskManager *, TaskManagerProfile *> *getTaskManagerProfiles()
174  {
175  return taskManagerProfiles;
176  }
177 
178 
179  private:
180 
185  std::map<AnyTaskManager *, TaskManagerProfile *> finalProfiles;
186  // Address + name + thread ID = unique
187 
188  // Group using Address + name ... thread ID = 0 is final version
189 
190  std::multimap<std::string, std::pair<AnyTaskManager *, TaskManagerProfile *>> averageMap;
191 
192  std::set<std::string> keys;
193 
194  // Gather multimap
195  for (auto t : *taskManagerProfiles) {
196  auto tMan = t.first;
197  std::string key =
198  (tMan->getInputConnector() != nullptr ? tMan->getInputConnector()->getDotId() : "")
199  + (tMan->getOutputConnector() != nullptr ? tMan->getOutputConnector()->getDotId() : "")
200  + tMan->getAddress() + tMan->getName();
201 
202  keys.insert(key);
203  averageMap.insert(std::pair<std::string, std::pair<AnyTaskManager *, TaskManagerProfile *>>(key, t));
204  }
205 
206  // Loop through each key
207  for (auto key : keys) {
208  auto valRange = averageMap.equal_range(key);
209 
210  AnyTaskManager *mainManager = nullptr;
211  TaskManagerProfile *finalProfile = new TaskManagerProfile();
212 
213  int count = 0;
214  for (auto i = valRange.first; i != valRange.second; ++i) {
215  auto profilePair = (*i).second;
216 
217  finalProfile->setMaxQueueSize(profilePair.second->getMaxQueueSize());
218  finalProfile->sum(profilePair.second);
219 
220  delete profilePair.second;
221  profilePair.second = nullptr;
222 
223  if (profilePair.first->getThreadId() == 0) {
224  mainManager = profilePair.first;
225  }
226 
227  count++;
228  }
229 
230  if (finalProfile != nullptr && mainManager != nullptr) {
231  finalProfile->average(count);
232  finalProfiles.insert(std::pair<AnyTaskManager *, TaskManagerProfile *>(mainManager, finalProfile));
233  } else {
234  std::cout << "Something screwy happened . . ." << std::endl;
235  }
236  }
237 
238  taskManagerProfiles->clear();
239 
240  for (auto t : finalProfiles) {
241  taskManagerProfiles->insert(t);
242  }
243 
244  }
245 
254  std::unordered_map<std::string, std::string> *genColorMap(int colorFlag) {
255  std::unordered_map<std::string, std::string> *colorMap = new std::unordered_map<std::string, std::string>();
256 
257 
258  std::deque<double> vals;
259  for (auto v : *taskManagerProfiles) {
260  double val = v.second->getValue(colorFlag);
261  if (val > 0) {
262  totalTime += val;
263  }
264 
265  if (maxTime < val)
266  maxTime = val;
267  }
268 
269 
270  if (colorFlag == DOTGEN_COLOR_COMP_TIME)
271  {
272  profileUtils = new ProfileUtils(taskGraphComputeTime);
273  } else {
274  profileUtils = new ProfileUtils(maxTime);
275  }
276 
277 
278 
279  for (auto v : *taskManagerProfiles) {
280  if (v.second->getValue(colorFlag) == 0.0) {
281  colorMap->insert(std::pair<std::string, std::string>(v.first->getTaskFunction()->getDotId(), "black"));
282  continue;
283  }
284 
285  double tManTime = v.second->getValue(colorFlag);
286 
287  std::string color = profileUtils->getColorForTime(tManTime);
288 
289  colorMap->insert(std::pair<std::string, std::string>(v.first->getTaskFunction()->getDotId(), color));
290  }
291 
292 
293 
294  return colorMap;
295  }
296 
297 
298  std::map<AnyTaskManager *, TaskManagerProfile *> *taskManagerProfiles;
299  int flags;
300 
301  ProfileUtils *profileUtils = nullptr;
302 
303  double totalTime = 0.0;
304  double maxTime = 0.0;
305  double taskGraphComputeTime;
306 };
307 }
308 
309 #endif //HTGS_TASKGRAPHPROFILER_HPP
ProfileUtils * getProfileUtils()
Gets the profile utility class to obtain color codes based on the total execution time...
Definition: TaskGraphProfiler.hpp:164
std::map< AnyTaskManager *, TaskManagerProfile * > * taskManagerProfiles
The profile data for all task managers.
Definition: TaskGraphProfiler.hpp:298
void sum(TaskManagerProfile *other)
Computes the sum for the compute time and wait time between this profile and some other profile...
Definition: TaskManagerProfile.hpp:142
unsigned long long int getGraphComputeTime() const
Gets the total time the graph was computing.
Definition: AnyTaskGraphConf.hpp:536
std::string genDotProfile(std::string curDotGraph, int colorFlag)
Generates the dot profile for the graph.
Definition: TaskGraphProfiler.hpp:102
#define DOTGEN_COLOR_COMP_TIME
Creates color map using compute time.
Definition: TaskGraphDotGenFlags.hpp:56
int flags
The DOTGEN bit flags.
Definition: TaskGraphProfiler.hpp:299
void gatherProfilingData(std::map< AnyTaskManager *, TaskManagerProfile *> *taskManagerProfiles)
Gathers profiling data for this task graph&#39;s task managers, which is added into the task manager prof...
Definition: AnyTaskGraphConf.hpp:189
#define DOTGEN_FLAG_SHOW_TASK_LIVING_STATUS
Shows the number of threads that are alive running the task.
Definition: TaskGraphDotGenFlags.hpp:98
Holds the TGTask class implementation.
void setMaxQueueSize(size_t maxQueueSize)
Sets the max queue size for the profile.
Definition: TaskManagerProfile.hpp:152
void buildProfile(AnyTaskGraphConf *graphConf)
Builds a profile for the graph, (called after execution is done)
Definition: TaskGraphProfiler.hpp:75
std::map< AnyTaskManager *, TaskManagerProfile * > * getTaskManagerProfiles()
Gets the task manager profiles for all tasks in all graphs and sub-graphs.
Definition: TaskGraphProfiler.hpp:173
double maxTime
The maximum time from all task managers.
Definition: TaskGraphProfiler.hpp:304
std::unordered_map< std::string, std::string > * genColorMap(int colorFlag)
Generates the color map.
Definition: TaskGraphProfiler.hpp:254
double totalTime
Total execution time for all task managers.
Definition: TaskGraphProfiler.hpp:303
Implements a task manager profile that holds profiling data for a task manager.
Definition: TaskManagerProfile.hpp:27
void printProfiles()
Prints the profile data to console.
Definition: TaskGraphProfiler.hpp:83
Implements the base class used by the TaskGraphConf, which removes the template arguments and impleme...
void computeAverages()
Computes the averages for all profile data.
Definition: TaskGraphProfiler.hpp:184
The parent class for a Task that removes the template arguments.
Definition: AnyTaskManager.hpp:45
#define DOTGEN_FLAG_SHOW_IN_OUT_TYPES
Shows input and output types for all tasks.
Definition: TaskGraphDotGenFlags.hpp:32
Implements the base class for the TaskGraphConf class, removing the template arguments and providing ...
Definition: AnyTaskGraphConf.hpp:66
Implements the TaskManagerProfile class that is used to gather profile data for a task manager...
std::string getColorForTime(double time)
Gets the color for a given time relative to the entire graph&#39;s execution time.
Definition: ProfileUtils.hpp:23
TaskGraphProfiler(int flags)
Constructs the task graph profiler.
Definition: TaskGraphProfiler.hpp:49
~TaskGraphProfiler()
Destructor.
Definition: TaskGraphProfiler.hpp:56
void average(int count)
Computes the average compute and wait time for the profile.
Definition: TaskManagerProfile.hpp:158
#define DOTGEN_FLAG_SHOW_ALL_THREADING
Shows all threading fully expanded during dot generation.
Definition: TaskGraphDotGenFlags.hpp:26
The task graph profiler that gathers profile data and communicates via graphviz.
Definition: TaskGraphProfiler.hpp:42
Definition: ProfileUtils.hpp:13
Definition: Bookkeeper.hpp:23
ExecutionPipeline encapsulates a task graph and duplicates it, such that each duplicate task graph ex...