Skip to content

Commit 519601a

Browse files
authored
Declare and save metric units in Spot (LLNL#303)
* CalQL: Add SELECT ... AS ... UNIT ... * Add attribute unit support in MetadataDB * Add attribute units in Spot controller * Add units in default metric options * Check for internal query parse errors in SpotController
1 parent fc4ef96 commit 519601a

File tree

11 files changed

+234
-83
lines changed

11 files changed

+234
-83
lines changed

include/caliper/reader/CaliperMetadataDB.h

+9
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,15 @@ class CaliperMetadataDB : public CaliperMetadataAccessInterface
129129
/// attributes.
130130
void add_attribute_aliases(const std::map<std::string, std::string>& aliases);
131131

132+
/// \brief Add a set of attribute units
133+
///
134+
/// This adds a "attribute.unit" meta-attribute for the aliased attribute
135+
/// to export alias information in a cali data stream.
136+
/// Currently this is limited to new attributes created with
137+
/// create_attribute() in this database. It does not apply to imported
138+
/// attributes.
139+
void add_attribute_units(const std::map<std::string, std::string>& aliases);
140+
132141
/// \brief print usage statistics
133142
std::ostream&
134143
print_statistics(std::ostream& os);

include/caliper/reader/QuerySpec.h

+11-8
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ struct QuerySpec
2020
//
2121
// --- Types
2222
//
23-
23+
2424
/// \brief Template type for list-style query options
2525
template<class T>
2626
struct SelectionList {
2727
enum SelectionOpt {
28-
Default, ///< Take the default
28+
Default, ///< Take the default
2929
None, ///< Take none
30-
All, ///< Take all available
30+
All, ///< Take all available
3131
List ///< User-defined list
3232
} selection; ///< Selection specification
3333

34-
/// \brief User-defined list
34+
/// \brief User-defined list
3535
std::vector<T> list;
3636
};
3737

@@ -45,7 +45,7 @@ struct QuerySpec
4545
};
4646

4747
static const FunctionSignature FunctionSignatureTerminator;
48-
48+
4949
/// \brief An aggregation function invocation in a query spec
5050
struct AggregationOp {
5151
FunctionSignature op; ///< The aggregation operator
@@ -61,7 +61,7 @@ struct QuerySpec
6161

6262
AggregationOp(const FunctionSignature& s, const std::vector<std::string>& a)
6363
: op(s), args(a)
64-
{ }
64+
{ }
6565
};
6666

6767
/// \brief Sort description.
@@ -96,15 +96,15 @@ struct QuerySpec
9696
enum Opt {
9797
Default, User
9898
} opt; ///< Default or user-defined formatter
99-
FunctionSignature formatter; ///< The formatter to use. Signatures provided by FormatProcessor.
99+
FunctionSignature formatter; ///< The formatter to use. Signatures provided by FormatProcessor.
100100
std::vector<std::string> args; ///< Arguments to the formatter.
101101
};
102102

103103
struct PreprocessSpec {
104104
std::string target;
105105
AggregationOp op;
106106
};
107-
107+
108108
//
109109
// --- Data members
110110
//
@@ -134,6 +134,9 @@ struct QuerySpec
134134
/// \brief Output aliases for attributes (i.e., "select x AS y" )
135135
std::map<std::string, std::string> aliases;
136136

137+
/// \brief Units for attributes (i.e. SELECT x AS y UNIT z)
138+
std::map<std::string, std::string> units;
139+
137140
/// \brief List of preprocessing operations (i.e., "LET y=f(x)")
138141
std::vector<PreprocessSpec> preprocess_ops;
139142
};

src/caliper/ConfigManager.cpp

+25-8
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,16 @@ join_stringlist(const std::vector<std::string>& list)
130130

131131
class ConfigManager::OptionSpec
132132
{
133+
struct select_expr_t {
134+
std::string expression;
135+
std::string alias;
136+
std::string unit;
137+
};
138+
133139
struct query_arg_t {
134-
std::vector< std::pair<std::string, std::string> > select;
135-
std::vector< std::string > groupby;
136-
std::vector< std::string > let;
140+
std::vector< select_expr_t > select;
141+
std::vector< std::string > groupby;
142+
std::vector< std::string > let;
137143
};
138144

139145
struct option_spec_t {
@@ -161,7 +167,11 @@ class ConfigManager::OptionSpec
161167
void parse_select(const std::vector<StringConverter>& list, query_arg_t& qarg) {
162168
for (const StringConverter& sc : list) {
163169
std::map<std::string, StringConverter> dict = sc.rec_dict();
164-
qarg.select.push_back(std::make_pair(dict["expr"].to_string(), dict["as"].to_string()));
170+
qarg.select.push_back( {
171+
dict["expr"].to_string(),
172+
dict["as" ].to_string(),
173+
dict["unit"].to_string()
174+
} );
165175
}
166176
}
167177

@@ -446,13 +456,20 @@ struct ConfigManager::Options::OptionsImpl
446456
continue;
447457

448458
for (const auto &p : l_it->second.select) {
449-
if (p.first.empty())
459+
if (p.expression.empty())
450460
break;
461+
451462
if (!ret.empty())
452463
ret.append(",");
453-
ret.append(p.first);
454-
if (use_alias && !p.second.empty())
455-
ret.append(" as \"").append(p.second).append("\"");
464+
465+
ret.append(p.expression);
466+
467+
if (use_alias) {
468+
if (!p.alias.empty())
469+
ret.append(" as \"").append(p.alias).append("\"");
470+
if (!p.unit.empty())
471+
ret.append(" unit \"").append(p.unit).append("\"");
472+
}
456473
}
457474
}
458475

src/caliper/controllers/controllers.cpp

+22-22
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ const char* builtin_option_specs =
152152
" ["
153153
" { \"level\" : \"local\", "
154154
" \"let\" : [ \"ibw.bytes.written=first(sum#io.bytes.written,io.bytes.written)\" ],"
155-
" \"select\" : [ { \"expr\": \"sum(ibw.bytes.written)\", \"as\": \"Bytes written\" } ]"
155+
" \"select\" : [ { \"expr\": \"sum(ibw.bytes.written)\", \"as\": \"Bytes written\", \"unit\": \"Byte\" } ]"
156156
" },"
157157
" { \"level\" : \"cross\", \"select\":"
158-
" [ { \"expr\": \"avg(sum#ibw.bytes.written)\", \"as\": \"Avg written\"},"
159-
" { \"expr\": \"sum(sum#ibw.bytes.written)\", \"as\": \"Total written\"}"
158+
" [ { \"expr\": \"avg(sum#ibw.bytes.written)\", \"as\": \"Avg written\", \"unit\": \"Byte\" },"
159+
" { \"expr\": \"sum(sum#ibw.bytes.written)\", \"as\": \"Total written\", \"unit\": \"Byte\" }"
160160
" ]"
161161
" }"
162162
" ]"
@@ -171,11 +171,11 @@ const char* builtin_option_specs =
171171
" ["
172172
" { \"level\" : \"local\", "
173173
" \"let\" : [ \"ibr.bytes.read=first(sum#io.bytes.read,io.bytes.read)\" ],"
174-
" \"select\" : [ { \"expr\": \"sum(ibr.bytes.read)\", \"as\": \"Bytes read\" } ] "
174+
" \"select\" : [ { \"expr\": \"sum(ibr.bytes.read)\", \"as\": \"Bytes read\", \"unit\": \"Byte\" } ] "
175175
" },"
176176
" { \"level\" : \"cross\", \"select\":"
177-
" [ { \"expr\": \"avg(sum#ibr.bytes.read)\", \"as\": \"Avg read\" },"
178-
" { \"expr\": \"sum(sum#ibr.bytes.read)\", \"as\": \"Total read\" }"
177+
" [ { \"expr\": \"avg(sum#ibr.bytes.read)\", \"as\": \"Avg read\", \"unit\": \"Byte\" },"
178+
" { \"expr\": \"sum(sum#ibr.bytes.read)\", \"as\": \"Total read\", \"unit\": \"Byte\" }"
179179
" ]"
180180
" }"
181181
" ]"
@@ -205,13 +205,13 @@ const char* builtin_option_specs =
205205
" \"select\" :"
206206
" ["
207207
" { \"expr\": \"io.region\", \"as\": \"I/O\" },"
208-
" { \"expr\": \"ratio(irb.bytes.read,irb.time,8e-6)\", \"as\": \"Read Mbit/s\" }"
208+
" { \"expr\": \"ratio(irb.bytes.read,irb.time,8e-6)\", \"as\": \"Read Mbit/s\", \"unit\": \"Mb/s\" }"
209209
" ]"
210210
" },"
211211
" { \"level\": \"cross\", \"select\":"
212212
" [ "
213-
" { \"expr\": \"avg(irb.bytes.read/irb.time)\", \"as\": \"Avg read Mbit/s\" },"
214-
" { \"expr\": \"max(irb.bytes.read/irb.time)\", \"as\": \"Max read Mbit/s\" }"
213+
" { \"expr\": \"avg(irb.bytes.read/irb.time)\", \"as\": \"Avg read Mbit/s\", \"unit\": \"Mb/s\" },"
214+
" { \"expr\": \"max(irb.bytes.read/irb.time)\", \"as\": \"Max read Mbit/s\", \"unit\": \"Mb/s\" }"
215215
" ]"
216216
" }"
217217
" ]"
@@ -234,13 +234,13 @@ const char* builtin_option_specs =
234234
" \"select\" :"
235235
" ["
236236
" { \"expr\": \"io.region\", \"as\": \"I/O\" },"
237-
" { \"expr\": \"ratio(iwb.bytes.written,iwb.time,8e-6)\", \"as\": \"Write Mbit/s\" }"
237+
" { \"expr\": \"ratio(iwb.bytes.written,iwb.time,8e-6)\", \"as\": \"Write Mbit/s\", \"unit\": \"Mb/s\" }"
238238
" ]"
239239
" },"
240240
" { \"level\": \"cross\", \"select\":"
241241
" [ "
242-
" { \"expr\": \"avg(iwb.bytes.written/iwb.time)\", \"as\": \"Avg write Mbit/s\" },"
243-
" { \"expr\": \"max(iwb.bytes.written/iwb.time)\", \"as\": \"Max write Mbit/s\" }"
242+
" { \"expr\": \"avg(iwb.bytes.written/iwb.time)\", \"as\": \"Avg write Mbit/s\", \"unit\": \"Mb/s\" },"
243+
" { \"expr\": \"max(iwb.bytes.written/iwb.time)\", \"as\": \"Max write Mbit/s\", \"unit\": \"Mb/s\" }"
244244
" ]"
245245
" }"
246246
" ]"
@@ -259,10 +259,10 @@ const char* builtin_option_specs =
259259
" [ \"mem.highwatermark.bytes = first(max#alloc.region.highwatermark,alloc.region.highwatermark)\", "
260260
" \"mem.highwatermark = scale(mem.highwatermark.bytes,1e-6)\" "
261261
" ],"
262-
" \"select\" : [ { \"expr\": \"max(mem.highwatermark)\", \"as\": \"Allocated (MB)\" } ]"
262+
" \"select\" : [ { \"expr\": \"max(mem.highwatermark)\", \"as\": \"Allocated MB\", \"unit\": \"MB\" } ]"
263263
" },"
264264
" { \"level\" : \"cross\", "
265-
" \"select\" : [ { \"expr\": \"max(max#mem.highwatermark)\", \"as\": \"Allocated (MB)\" } ] "
265+
" \"select\" : [ { \"expr\": \"max(max#mem.highwatermark)\", \"as\": \"Allocated MB\", \"unit\": \"MB\" } ] "
266266
" }"
267267
" ]"
268268
"},"
@@ -276,13 +276,13 @@ const char* builtin_option_specs =
276276
" ["
277277
" { \"level\" : \"local\","
278278
" \"let\" : [ \"mrb.time=first(pcp.time.duration,sum#pcp.time.duration)\" ],"
279-
" \"select\" : [ { \"expr\": \"ratio(mem.bytes.read,mrb.time,1e-6)\", \"as\": \"MB/s (r)\" } ]"
279+
" \"select\" : [ { \"expr\": \"ratio(mem.bytes.read,mrb.time,1e-6)\", \"as\": \"MB/s (r)\", \"unit\": \"MB/s\" } ]"
280280
" },"
281281
" { \"level\" : \"cross\", \"select\": "
282282
" ["
283-
" { \"expr\" : \"avg(mem.bytes.read/mrb.time)\", \"as\": \"Avg MB/s (r)\" },"
284-
" { \"expr\" : \"max(mem.bytes.read/mrb.time)\", \"as\": \"Max MB/s (r)\" },"
285-
" { \"expr\" : \"sum(mem.bytes.read/mrb.time)\", \"as\": \"Total MB/s (r)\" }"
283+
" { \"expr\" : \"avg(mem.bytes.read/mrb.time)\", \"as\": \"Avg MB/s (r)\", \"unit\": \"MB/s\" },"
284+
" { \"expr\" : \"max(mem.bytes.read/mrb.time)\", \"as\": \"Max MB/s (r)\", \"unit\": \"MB/s\" },"
285+
" { \"expr\" : \"sum(mem.bytes.read/mrb.time)\", \"as\": \"Total MB/s (r)\", \"unit\": \"MB/s\" }"
286286
" ] "
287287
" }"
288288
" ]"
@@ -297,13 +297,13 @@ const char* builtin_option_specs =
297297
" ["
298298
" { \"level\" : \"local\","
299299
" \"let\" : [ \"mwb.time=first(pcp.time.duration,sum#pcp.time.duration) \" ],"
300-
" \"select\" : [ { \"expr\": \"ratio(mem.bytes.written,mwb.time,1e-6)\", \"as\": \"MB/s (w)\" } ]"
300+
" \"select\" : [ { \"expr\": \"ratio(mem.bytes.written,mwb.time,1e-6)\", \"as\": \"MB/s (w)\", \"unit\": \"MB/s\" } ]"
301301
" },"
302302
" { \"level\" : \"cross\", \"select\": "
303303
" ["
304-
" { \"expr\" : \"avg(mem.bytes.written/mwb.time)\", \"as\": \"Avg MB/s (w)\" },"
305-
" { \"expr\" : \"max(mem.bytes.written/mwb.time)\", \"as\": \"Max MB/s (w)\" },"
306-
" { \"expr\" : \"sum(mem.bytes.written/mwb.time)\", \"as\": \"Total MB/s (w)\" },"
304+
" { \"expr\" : \"avg(mem.bytes.written/mwb.time)\", \"as\": \"Avg MB/s (w)\", \"unit\": \"MB/s\" },"
305+
" { \"expr\" : \"max(mem.bytes.written/mwb.time)\", \"as\": \"Max MB/s (w)\", \"unit\": \"MB/s\" },"
306+
" { \"expr\" : \"sum(mem.bytes.written/mwb.time)\", \"as\": \"Total MB/s (w)\", \"unit\": \"MB/s\" },"
307307
" ] "
308308
" }"
309309
" ]"

src/mpi/controllers/SpotController.cpp

+25-16
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,22 @@ constexpr int spot_format_version = 2;
4141
// Helper functions
4242
//
4343

44+
QuerySpec
45+
parse_spec(const char* query)
46+
{
47+
CalQLParser parser(query);
48+
49+
if (parser.error())
50+
Log(0).stream() << "[spot controller]: Internal query parse error: " << parser.error_msg()
51+
<< std::endl;
52+
53+
return parser.spec();
54+
}
55+
4456
/// \brief Perform process-local aggregation of channel data into \a output_agg
4557
void
4658
local_aggregate(const char* query, Caliper& c, Channel* channel, CaliperMetadataDB& db, Aggregator& output_agg) {
47-
QuerySpec spec(CalQLParser(query).spec());
59+
QuerySpec spec(parse_spec(query));
4860

4961
RecordSelector filter(spec);
5062
Preprocessor prp(spec);
@@ -186,9 +198,9 @@ class SpotTimeseriesController : public cali::ChannelController
186198
" cali.channel"
187199
",loop"
188200
",block"
189-
",max(sum#loop.iterations) as \"Iterations\""
190-
",max(sum#time.duration) as \"Time (s)\""
191-
",avg(loop.iterations/time.duration) as \"Iter/s\"";
201+
",max(sum#loop.iterations) as \"Iterations\" unit iterations"
202+
",max(sum#time.duration) as \"Time (s)\" unit sec"
203+
",avg(loop.iterations/time.duration) as \"Iter/s\" unit iter/s";
192204

193205
std::string query =
194206
m_opts.query_let("cross", "")
@@ -197,12 +209,7 @@ class SpotTimeseriesController : public cali::ChannelController
197209
+ " group by "
198210
+ m_opts.query_groupby("cross", "cali.channel,loop,block");
199211

200-
CalQLParser parser(query.c_str());
201-
202-
if (parser.error())
203-
Log(0).stream() << parser.error_msg() << " " << query << std::endl;
204-
205-
return CalQLParser(query.c_str()).spec();
212+
return parse_spec(query.c_str());
206213
}
207214

208215
void flush() { }
@@ -360,6 +367,7 @@ class SpotController : public cali::ChannelController
360367
Aggregator cross_agg(spec);
361368

362369
m_db.add_attribute_aliases(spec.aliases);
370+
m_db.add_attribute_units(spec.units);
363371

364372
tsc->timeseries_local_aggregation(c, m_db, namebuf, std::max(blocksize, 1), cross_agg);
365373
cross_aggregate(cross_agg);
@@ -426,25 +434,26 @@ class SpotController : public cali::ChannelController
426434
// --- Setup output reduction aggregator (final cross-process aggregation)
427435
const char* cross_select =
428436
" *"
429-
",min(inclusive#sum#time.duration) as \"Min time/rank\""
430-
",max(inclusive#sum#time.duration) as \"Max time/rank\""
431-
",avg(inclusive#sum#time.duration) as \"Avg time/rank\"";
437+
",min(inclusive#sum#time.duration) as \"Min time/rank\" unit sec"
438+
",max(inclusive#sum#time.duration) as \"Max time/rank\" unit sec"
439+
",avg(inclusive#sum#time.duration) as \"Avg time/rank\" unit sec";
432440
std::string cross_query =
433441
std::string("select ")
434-
+ m_opts.query_select("cross", cross_select, false)
442+
+ m_opts.query_select("cross", cross_select)
435443
+ " group by "
436444
+ m_opts.query_groupby("cross", "prop:nested");
437445

438-
QuerySpec output_spec(CalQLParser(cross_query.c_str()).spec());
446+
QuerySpec output_spec(parse_spec(cross_query.c_str()));
439447
Aggregator output_agg(output_spec);
440448

441449
m_db.add_attribute_aliases(output_spec.aliases);
450+
m_db.add_attribute_units(output_spec.units);
442451

443452
// --- Flush Caliper buffers into intermediate aggregator to calculate
444453
// region profile inclusive times
445454
{
446455
std::string query = m_opts.query_let("local", "")
447-
+ " aggregate "
456+
+ " select "
448457
+ m_opts.query_select("local", "inclusive_sum(sum#time.duration)", false)
449458
+ " group by "
450459
+ m_opts.query_groupby("local", "prop:nested");

0 commit comments

Comments
 (0)