Blender  V3.3
deg_debug_stats_gnuplot.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. All rights reserved. */
3 
8 #include "DEG_depsgraph_debug.h"
9 
10 #include <algorithm>
11 #include <cstdarg>
12 
13 #include "BLI_compiler_attrs.h"
14 #include "BLI_math_base.h"
15 
16 #include "intern/depsgraph.h"
18 
19 #include "DNA_ID.h"
20 
21 #define NL "\r\n"
22 
23 namespace deg = blender::deg;
24 
25 namespace blender::deg {
26 namespace {
27 
28 struct DebugContext {
29  FILE *file;
30  const Depsgraph *graph;
31  const char *label;
32  const char *output_filename;
33 };
34 
35 struct StatsEntry {
36  const IDNode *id_node;
37  double time;
38 };
39 
40 /* TODO(sergey): De-duplicate with graphviz relation debugger. */
41 void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...) ATTR_PRINTF_FORMAT(2, 3);
42 void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
43 {
44  va_list args;
45  va_start(args, fmt);
46  vfprintf(ctx.file, fmt, args);
47  va_end(args);
48 }
49 
50 inline double get_node_time(const DebugContext & /*ctx*/, const Node *node)
51 {
52  /* TODO(sergey): Figure out a nice way to define which exact time
53  * we want to show. */
54  return node->stats.current_time;
55 }
56 
57 bool stat_entry_comparator(const StatsEntry &a, const StatsEntry &b)
58 {
59  return a.time > b.time;
60 }
61 
62 string gnuplotify_id_code(const string &name)
63 {
64  return string("") + name[0] + name[1];
65 }
66 
67 string gnuplotify_name(const string &name)
68 {
69  string result;
70  const int length = name.length();
71  for (int i = 0; i < length; i++) {
72  const char ch = name[i];
73  if (ch == '_') {
74  result += R"(\\\)";
75  }
76  result += ch;
77  }
78  return result;
79 }
80 
81 void write_stats_data(const DebugContext &ctx)
82 {
83  /* Fill in array of all stats which are to be displayed. */
84  Vector<StatsEntry> stats;
85  stats.reserve(ctx.graph->id_nodes.size());
86  for (const IDNode *id_node : ctx.graph->id_nodes) {
87  const double time = get_node_time(ctx, id_node);
88  if (time == 0.0) {
89  continue;
90  }
91  StatsEntry entry;
92  entry.id_node = id_node;
93  entry.time = time;
94  stats.append(entry);
95  }
96  /* Sort the data. */
97  std::sort(stats.begin(), stats.end(), stat_entry_comparator);
98  /* We limit number of entries, otherwise things become unreadable. */
99  stats.resize(min_ii(stats.size(), 32));
100  std::reverse(stats.begin(), stats.end());
101  /* Print data to the file stream. */
102  deg_debug_fprintf(ctx, "$data << EOD" NL);
103  for (const StatsEntry &entry : stats) {
104  deg_debug_fprintf(ctx,
105  "\"[%s] %s\",%f" NL,
106  gnuplotify_id_code(entry.id_node->id_orig->name).c_str(),
107  gnuplotify_name(entry.id_node->id_orig->name + 2).c_str(),
108  entry.time);
109  }
110  deg_debug_fprintf(ctx, "EOD" NL);
111 }
112 
113 void deg_debug_stats_gnuplot(const DebugContext &ctx)
114 {
115  /* Data itself. */
116  write_stats_data(ctx);
117  /* Optional label. */
118  if (ctx.label && ctx.label[0]) {
119  deg_debug_fprintf(ctx, "set title \"%s\"" NL, ctx.label);
120  }
121  /* Rest of the commands.
122  * TODO(sergey): Need to decide on the resolution somehow. */
123  deg_debug_fprintf(ctx, "set terminal pngcairo size 1920,1080" NL);
124  deg_debug_fprintf(ctx, "set output \"%s\"" NL, ctx.output_filename);
125  deg_debug_fprintf(ctx, "set grid" NL);
126  deg_debug_fprintf(ctx, "set datafile separator ','" NL);
127  deg_debug_fprintf(ctx, "set style fill solid" NL);
128  deg_debug_fprintf(ctx,
129  "plot \"$data\" using "
130  "($2*0.5):0:($2*0.5):(0.2):yticlabels(1) "
131  "with boxxyerrorbars t '' lt rgb \"#406090\"" NL);
132 }
133 
134 } // namespace
135 } // namespace blender::deg
136 
138  FILE *fp,
139  const char *label,
140  const char *output_filename)
141 {
142  if (depsgraph == nullptr) {
143  return;
144  }
145  deg::DebugContext ctx;
146  ctx.file = fp;
147  ctx.graph = (deg::Depsgraph *)depsgraph;
148  ctx.label = label;
149  ctx.output_filename = output_filename;
150  deg::deg_debug_stats_gnuplot(ctx);
151 }
MINLINE int min_ii(int a, int b)
size_t ATTR_PRINTF_FORMAT(3, 4)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
ID and Library types, which are fundamental for sdna.
void sort(btMatrix3x3 &U, btVector3 &sigma, btMatrix3x3 &V, int t)
Helper function of 3X3 SVD for sorting singular values.
OperationNode * node
void DEG_debug_stats_gnuplot(const Depsgraph *depsgraph, FILE *fp, const char *label, const char *output_filename)
#define NL
FILE * file
const IDNode * id_node
const Depsgraph * graph
const char * output_filename
double time
const char * label
const Depsgraph * depsgraph
static unsigned a[3]
Definition: RandGen.cpp:78
T length(const vec_base< T, Size > &a)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)