HPCToolkit
Metric-AExpr.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // Prof::Metric::AExpr and derived classes
50 //
51 //***************************************************************************
52 
53 //************************ System Include Files ******************************
54 
55 #include <iostream>
56 using std::endl;
57 
58 #include <sstream>
59 #include <string>
60 #include <algorithm>
61 
62 #include <cmath>
63 #include <cfloat>
64 
65 //************************* User Include Files *******************************
66 
67 #include <include/uint.h>
68 
69 #include "Metric-AExpr.hpp"
70 
72 #include <lib/support/NaN.h>
73 
74 //************************ Forward Declarations ******************************
75 
76 #define AEXPR_DO_CHECK 0
77 #if (AEXPR_DO_CHECK)
78 # define AEXPR_CHECK(x) if (!isok(x)) { return c_FP_NAN_d; }
79 #else
80 # define AEXPR_CHECK(x)
81 #endif
82 
83 
84 //****************************************************************************
85 
86 namespace Prof {
87 
88 namespace Metric {
89 
90 
91 // ----------------------------------------------------------------------
92 // class AExpr
93 // ----------------------------------------------------------------------
94 
95 std::string
97 {
98  std::ostringstream os;
99  dump(os);
100  return os.str();
101 }
102 
103 
104 void
105 AExpr::dump_opands(std::ostream& os, AExpr** opands, uint sz, const char* sep)
106 {
107  for (uint i = 0; i < sz; ++i) {
108  opands[i]->dumpMe(os);
109  if (i < (sz - 1)) {
110  os << sep;
111  }
112  }
113 }
114 
115 
116 // ----------------------------------------------------------------------
117 // class Const
118 // ----------------------------------------------------------------------
119 
120 std::ostream&
121 Const::dumpMe(std::ostream& os) const
122 {
123  os << m_c;
124  return os;
125 }
126 
127 
128 // ----------------------------------------------------------------------
129 // class Neg
130 // ----------------------------------------------------------------------
131 
132 double
133 Neg::eval(const Metric::IData& mdata) const
134 {
135  double z = m_expr->eval(mdata);
136 
137  AEXPR_CHECK(z);
138  return -z;
139 }
140 
141 
142 std::ostream&
143 Neg::dumpMe(std::ostream& os) const
144 {
145  os << "-(";
146  m_expr->dumpMe(os);
147  os << ")";
148  return os;
149 }
150 
151 
152 // ----------------------------------------------------------------------
153 // class Var
154 // ----------------------------------------------------------------------
155 
156 std::ostream&
157 Var::dumpMe(std::ostream& os) const
158 {
159  os << m_name;
160  return os;
161 }
162 
163 
164 // ----------------------------------------------------------------------
165 // class Power
166 // ----------------------------------------------------------------------
167 
168 double
169 Power::eval(const Metric::IData& mdata) const
170 {
171  double b = m_base->eval(mdata);
172  double e = m_exponent->eval(mdata);
173  double z = pow(b, e);
174 
175  AEXPR_CHECK(z);
176  return z;
177 }
178 
179 
180 std::ostream&
181 Power::dumpMe(std::ostream& os) const
182 {
183  os << "(";
184  m_base->dumpMe(os);
185  os << "**";
186  m_exponent->dumpMe(os);
187  os << ")";
188  return os;
189 }
190 
191 
192 // ----------------------------------------------------------------------
193 // class Divide
194 // ----------------------------------------------------------------------
195 
196 double
197 Divide::eval(const Metric::IData& mdata) const
198 {
199  double n = m_numerator->eval(mdata);
200  double d = m_denominator->eval(mdata);
201 
202  double z = c_FP_NAN_d;
203  if (isok(d) && d != 0.0) {
204  z = n / d;
205  }
206 
207  AEXPR_CHECK(z);
208  return z;
209 }
210 
211 
212 std::ostream&
213 Divide::dumpMe(std::ostream& os) const
214 {
215  os << "(";
216  m_numerator->dumpMe(os);
217  os << " / ";
218  m_denominator->dumpMe(os);
219  os << ")";
220  return os;
221 }
222 
223 
224 // ----------------------------------------------------------------------
225 // class Minus
226 // ----------------------------------------------------------------------
227 
228 double
229 Minus::eval(const Metric::IData& mdata) const
230 {
231  double m = m_minuend->eval(mdata);
232  double s = m_subtrahend->eval(mdata);
233  double z = (m - s);
234 
235  AEXPR_CHECK(z);
236  return z;
237 }
238 
239 
240 std::ostream&
241 Minus::dumpMe(std::ostream& os) const
242 {
243  os << "(";
244  m_minuend->dumpMe(os);
245  os << " - ";
246  m_subtrahend->dumpMe(os); os << ")";
247  return os;
248 }
249 
250 
251 // ----------------------------------------------------------------------
252 // class Plus
253 // ----------------------------------------------------------------------
254 
256 {
257  for (uint i = 0; i < m_sz; ++i) {
258  delete m_opands[i];
259  }
260  delete[] m_opands;
261 }
262 
263 
264 double
265 Plus::eval(const Metric::IData& mdata) const
266 {
267  double z = evalSum(mdata, m_opands, m_sz);
268 
269  AEXPR_CHECK(z);
270  return z;
271 }
272 
273 
274 std::ostream&
275 Plus::dumpMe(std::ostream& os) const
276 {
277  if (m_sz > 1) { os << "("; }
278  dump_opands(os, m_opands, m_sz, " + ");
279  if (m_sz > 1) { os << ")"; }
280  return os;
281 }
282 
283 
284 // ----------------------------------------------------------------------
285 // class Times
286 // ----------------------------------------------------------------------
287 
289 {
290  for (uint i = 0; i < m_sz; ++i) {
291  delete m_opands[i];
292  }
293  delete[] m_opands;
294 }
295 
296 
297 double
298 Times::eval(const Metric::IData& mdata) const
299 {
300  double z = 1.0;
301  for (uint i = 0; i < m_sz; ++i) {
302  double x = m_opands[i]->eval(mdata);
303  z *= x;
304  }
305 
306  AEXPR_CHECK(z);
307  return z;
308 }
309 
310 
311 std::ostream&
312 Times::dumpMe(std::ostream& os) const
313 {
314  if (m_sz > 1) { os << "("; }
315  dump_opands(os, m_opands, m_sz, " * ");
316  if (m_sz > 1) { os << ")"; }
317  return os;
318 }
319 
320 
321 // ----------------------------------------------------------------------
322 // class Max
323 // ----------------------------------------------------------------------
324 
326 {
327  for (uint i = 0; i < m_sz; ++i) {
328  delete m_opands[i];
329  }
330  delete[] m_opands;
331 }
332 
333 
334 double
335 Max::eval(const Metric::IData& mdata) const
336 {
337  double z = m_opands[0]->eval(mdata);
338  for (uint i = 1; i < m_sz; ++i) {
339  double x = m_opands[i]->eval(mdata);
340  z = std::max(z, x);
341  }
342 
343  AEXPR_CHECK(z);
344  return z;
345 }
346 
347 
348 std::ostream&
349 Max::dumpMe(std::ostream& os) const
350 {
351  os << "max(";
352  dump_opands(os, m_opands, m_sz);
353  os << ")";
354  return os;
355 }
356 
357 
358 // ----------------------------------------------------------------------
359 // class Min
360 // ----------------------------------------------------------------------
361 
363 {
364  for (uint i = 0; i < m_sz; ++i) {
365  delete m_opands[i];
366  }
367  delete[] m_opands;
368 }
369 
370 
371 double
372 Min::eval(const Metric::IData& mdata) const
373 {
374  double z = DBL_MAX;
375  for (uint i = 0; i < m_sz; ++i) {
376  double x = m_opands[i]->eval(mdata);
377  if (x != 0.0) {
378  z = std::min(z, x);
379  }
380  }
381 
382  if (z == DBL_MAX) { z = DBL_MIN; }
383 
384  AEXPR_CHECK(z);
385  return z;
386 }
387 
388 
389 std::ostream&
390 Min::dumpMe(std::ostream& os) const
391 {
392  os << "min(";
393  dump_opands(os, m_opands, m_sz);
394  os << ")";
395  return os;
396 }
397 
398 
399 // ----------------------------------------------------------------------
400 // class Mean
401 // ----------------------------------------------------------------------
402 
404 {
405  for (uint i = 0; i < m_sz; ++i) {
406  delete m_opands[i];
407  }
408  delete[] m_opands;
409 }
410 
411 
412 double
413 Mean::eval(const Metric::IData& mdata) const
414 {
415  double z = evalMean(mdata, m_opands, m_sz);
416 
417  AEXPR_CHECK(z);
418  return z;
419 }
420 
421 
422 std::ostream&
423 Mean::dumpMe(std::ostream& os) const
424 {
425  os << "mean(";
426  dump_opands(os, m_opands, m_sz);
427  os << ")";
428  return os;
429 }
430 
431 
432 // ----------------------------------------------------------------------
433 // class StdDev
434 // ----------------------------------------------------------------------
435 
437 {
438  for (uint i = 0; i < m_sz; ++i) {
439  delete m_opands[i];
440  }
441  delete[] m_opands;
442 }
443 
444 
445 double
446 StdDev::eval(const Metric::IData& mdata) const
447 {
448  std::pair<double, double> v_m = evalVariance(mdata, m_opands, m_sz);
449  double z = sqrt(v_m.first);
450 
451  AEXPR_CHECK(z);
452  return z;
453 }
454 
455 
456 std::ostream&
457 StdDev::dumpMe(std::ostream& os) const
458 {
459  os << "stddev(";
460  dump_opands(os, m_opands, m_sz);
461  os << ")";
462  return os;
463 }
464 
465 
466 // ----------------------------------------------------------------------
467 // class CoefVar
468 // ----------------------------------------------------------------------
469 
471 {
472  for (uint i = 0; i < m_sz; ++i) {
473  delete m_opands[i];
474  }
475  delete[] m_opands;
476 }
477 
478 
479 double
480 CoefVar::eval(const Metric::IData& mdata) const
481 {
482  std::pair<double, double> v_m = evalVariance(mdata, m_opands, m_sz);
483  double sdev = sqrt(v_m.first); // always non-negative
484  double mean = v_m.second;
485  double z = 0.0;
486  if (mean > epsilon) {
487  z = sdev / mean;
488  }
489 
490  AEXPR_CHECK(z);
491  return z;
492 }
493 
494 
495 std::ostream&
496 CoefVar::dumpMe(std::ostream& os) const
497 {
498  os << "coefvar(";
499  dump_opands(os, m_opands, m_sz);
500  os << ")";
501  return os;
502 }
503 
504 
505 // ----------------------------------------------------------------------
506 // class RStdDev
507 // ----------------------------------------------------------------------
508 
510 {
511  for (uint i = 0; i < m_sz; ++i) {
512  delete m_opands[i];
513  }
514  delete[] m_opands;
515 }
516 
517 
518 double
519 RStdDev::eval(const Metric::IData& mdata) const
520 {
521  std::pair<double, double> v_m = evalVariance(mdata, m_opands, m_sz);
522  double sdev = sqrt(v_m.first); // always non-negative
523  double mean = v_m.second;
524  double z = 0.0;
525  if (mean > epsilon) {
526  z = (sdev / mean) * 100;
527  }
528 
529  AEXPR_CHECK(z);
530  return z;
531 }
532 
533 
534 std::ostream&
535 RStdDev::dumpMe(std::ostream& os) const
536 {
537  os << "r-stddev(";
538  dump_opands(os, m_opands, m_sz);
539  os << ")";
540  return os;
541 }
542 
543 
544 // ----------------------------------------------------------------------
545 // class NumSource
546 // ----------------------------------------------------------------------
547 
548 std::ostream&
549 NumSource::dumpMe(std::ostream& os) const
550 {
551  os << "num-src()";
552  return os;
553 }
554 
555 
556 //****************************************************************************
557 
558 
559 } // namespace Metric
560 
561 } // namespace Prof
const double c_FP_NAN_d
Definition: NaN.c:73
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual std::ostream & dump(std::ostream &os=std::cout) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual std::string toString() const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
static bool isok(double x)
#define AEXPR_CHECK(x)
unsigned int uint
Definition: uint.h:124
virtual double eval(const Metric::IData &mdata) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
#define epsilon
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
static void dump_opands(std::ostream &os, AExpr **opands, uint sz, const char *sep=", ")
static double evalMean(const Metric::IData &mdata, AExpr **opands, uint sz)
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const =0
static std::pair< double, double > evalVariance(const Metric::IData &mdata, AExpr **opands, uint sz)
virtual double eval(const Metric::IData &mdata) const
static double evalSum(const Metric::IData &mdata, AExpr **opands, uint sz)
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const
<!-- ********************************************************************--> n<!-- HPCToolkit Experiment DTD --> n<!-- Version 2.1 --> n<!-- ********************************************************************--> n<!ELEMENT HPCToolkitExperiment(Header,(SecCallPathProfile|SecFlatProfile) *)> n<!ATTLIST HPCToolkitExperiment\n version CDATA #REQUIRED > n n<!-- ******************************************************************--> n n<!-- Info/NV:flexible name-value pairs:(n) ame;(t) ype;(v) alue --> n<!ELEMENT Info(NV *)> n<!ATTLIST Info\n n CDATA #IMPLIED > n<!ELEMENT NV EMPTY > n<!ATTLIST NV\n n CDATA #REQUIRED\n t CDATA #IMPLIED\n v CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Header --> n<!-- ******************************************************************--> n<!ELEMENT Header(Info *)> n<!ATTLIST Header\n n CDATA #REQUIRED > n n<!-- ******************************************************************--> n<!-- Section Header --> n<!-- ******************************************************************--> n<!ELEMENT SecHeader(MetricTable?, MetricDBTable?, TraceDBTable?, LoadModuleTable?, FileTable?, ProcedureTable?, Info *)> n n<!-- MetricTable:--> n<!ELEMENT MetricTable(Metric) * > n n<!-- Metric:(i) d;(n) ame --> n<!--(v) alue-type:transient type of values --> n<!--(t) ype:persistent type of metric --> n<!-- fmt:format;show;--> n<!ELEMENT Metric(MetricFormula *, Info?)> n<!ATTLIST Metric\n i CDATA #REQUIRED\n n CDATA #REQUIRED\n es CDATA #IMPLIED\n em CDATA #IMPLIED\n ep CDATA #IMPLIED\n v(raw|final|derived-incr|derived) \"raw\\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ fmt CDATA #IMPLIED\ show (1|0) \1\\ show-percent (1|0) \1> n n<!-- MetricFormula represents derived metrics: (t)ype; (frm): formula --> n<!ELEMENT MetricFormula (Info?)> n<!ATTLIST MetricFormula\ t (combine|finalize) \finalize\\ i CDATA #IMPLIED\ frm CDATA #REQUIRED> n n<!-- Metric data, used in sections: (n)ame [from Metric]; (v)alue --> n<!ELEMENT M EMPTY> n<!ATTLIST M\ n CDATA #REQUIRED\ v CDATA #REQUIRED> n n<!-- MetricDBTable: --> n<!ELEMENT MetricDBTable (MetricDB)*> n n<!-- MetricDB: (i)d; (n)ame --> n<!-- (t)ype: persistent type of metric --> n<!-- db-glob: file glob describing files in metric db --> n<!-- db-id: id within metric db --> n<!-- db-num-metrics: number of metrics in db --> n<!-- db-header-sz: size (in bytes) of a db file header --> n<!ELEMENT MetricDB EMPTY> n<!ATTLIST MetricDB\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ t (inclusive|exclusive|nil) \nil\\ partner CDATA #IMPLIED\ db-glob CDATA #IMPLIED\ db-id CDATA #IMPLIED\ db-num-metrics CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- TraceDBTable: --> n<!ELEMENT TraceDBTable (TraceDB)> n n<!-- TraceDB: (i)d --> n<!-- db-min-time: min beginning time stamp (global) --> n<!-- db-max-time: max ending time stamp (global) --> n<!ELEMENT TraceDB EMPTY> n<!ATTLIST TraceDB\ i CDATA #REQUIRED\ db-glob CDATA #IMPLIED\ db-min-time CDATA #IMPLIED\ db-max-time CDATA #IMPLIED\ db-header-sz CDATA #IMPLIED> n n<!-- LoadModuleTable assigns a short name to a load module --> n<!ELEMENT LoadModuleTable (LoadModule)*> n n<!ELEMENT LoadModule (Info?)> n<!ATTLIST LoadModule\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- FileTable assigns a short name to a file --> n<!ELEMENT FileTable (File)*> n n<!ELEMENT File (Info?)> n<!ATTLIST File\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!-- ProcedureTable assigns a short name to a procedure --> n<!ELEMENT ProcedureTable (Procedure)*> n n<!-- Info/NV: flexible name-value pairs: (n)ame; (t)ype; (v)alue --> n<!-- f: family of the procedure (fake, root, ...)--> n<!ELEMENT Procedure (Info?)> n<!ATTLIST Procedure\ i CDATA #REQUIRED\ n CDATA #REQUIRED\ f CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Call path profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecCallPathProfile (SecHeader, SecCallPathProfileData)> n<!ATTLIST SecCallPathProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecCallPathProfileData (PF|M)*> n<!-- Procedure frame --> n<!-- (i)d: unique identifier for cross referencing --> n<!-- (s)tatic scope id --> n<!-- (n)ame: a string or an id in ProcedureTable --> n<!-- (lm) load module: a string or an id in LoadModuleTable --> n<!-- (f)ile name: a string or an id in LoadModuleTable --> n<!-- (l)ine range: \beg-end\ (inclusive range) --> n<!-- (a)lien: whether frame is alien to enclosing P --> n<!-- (str)uct: hpcstruct node id --> n<!-- (t)ype: hpcrun node type: memory access, variable declaration, ... --> n<!-- (v)ma-range-set: \{[beg-end), [beg-end)...}\ --> n<!ELEMENT PF (PF|Pr|L|C|S|M)*> n<!ATTLIST PF\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Procedure (static): GOAL: replace with 'P' --> n<!ELEMENT Pr (Pr|L|C|S|M)*> n<!ATTLIST Pr\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ n CDATA #REQUIRED\ lm CDATA #IMPLIED\ f CDATA #IMPLIED\ l CDATA #IMPLIED\ a (1|0) \0\\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Callsite (a special StatementRange) --> n<!ELEMENT C (PF|M)*> n<!ATTLIST C\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n n<!-- ****************************************************************** --> n<!-- Section: Flat profile --> n<!-- ****************************************************************** --> n<!ELEMENT SecFlatProfile (SecHeader, SecFlatProfileData)> n<!ATTLIST SecFlatProfile\ i CDATA #REQUIRED\ n CDATA #REQUIRED> n n<!ELEMENT SecFlatProfileData (LM|M)*> n<!-- Load module: (i)d; (n)ame; (v)ma-range-set --> n<!ELEMENT LM (F|P|M)*> n<!ATTLIST LM\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ v CDATA #IMPLIED> n<!-- File --> n<!ELEMENT F (P|L|S|M)*> n<!ATTLIST F\ i CDATA #IMPLIED\ n CDATA #REQUIRED> n<!-- Procedure (Note 1) --> n<!ELEMENT P (P|A|L|S|C|M)*> n<!ATTLIST P\ i CDATA #IMPLIED\ n CDATA #REQUIRED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Alien (Note 1) --> n<!ELEMENT A (A|L|S|C|M)*> n<!ATTLIST A\ i CDATA #IMPLIED\ f CDATA #IMPLIED\ n CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Loop (Note 1,2) --> n<!ELEMENT L (A|Pr|L|S|C|M)*> n<!ATTLIST L\ i CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ f CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Statement (Note 2) --> n<!-- (it): trace record identifier --> n<!ELEMENT S (S|M)*> n<!ATTLIST S\ i CDATA #IMPLIED\ it CDATA #IMPLIED\ s CDATA #IMPLIED\ l CDATA #IMPLIED\ str CDATA #IMPLIED\ v CDATA #IMPLIED> n<!-- Note 1: Contained Cs may not contain PFs --> n<!-- Note 2: The 's' attribute is not used for flat profiles --> n
virtual double eval(const Metric::IData &mdata) const
virtual std::ostream & dumpMe(std::ostream &os=std::cout) const