#include "base/callback.hh"
#include "base/cprintf.hh"
+#include "base/hostinfo.hh"
#include "base/misc.hh"
+#include "base/python.hh"
#include "base/statistics.hh"
#include "base/str.hh"
+#include "base/time.hh"
#include "base/trace.hh"
#ifdef __M5_NAN
public:
void dump(ostream &stream, const string &name, DisplayMode mode);
void display(ostream &stream, DisplayMode mode);
+ void python(ostream &stream, const string &name);
+ void python(Python &py, const string &name, const string &bin);
StatData *find(void *stat);
void mapStat(void *stat, StatData *data);
MainBin *orig = MainBin::curBin();
switch (mode) {
+ case mode_python:
+ python(stream, name);
+ break;
case mode_m5:
case mode_simplescalar:
display(stream, mode);
}
}
+void
+Data::python(ostream &stream, const string &name)
+{
+ Python py(stream);
+
+ ccprintf(stream, "import sys\n");
+ ccprintf(stream, "sys.path.append('.')\n");
+ ccprintf(stream, "from m5stats import *\n\n");
+
+ if (bins.empty()) {
+ python(py, name, "");
+ } else {
+ list<MainBin *>::iterator i = bins.begin();
+ list<MainBin *>::iterator end = bins.end();
+
+ while (i != end) {
+ (*i)->activate();
+ python(py, name, (*i)->name());
+ ++i;
+ }
+ }
+
+ py.next();
+ ccprintf(stream, "if __name__ == '__main__':\n");
+ ccprintf(stream, " program_display()\n");
+}
+
+void
+Data::python(Python &py, const string &name, const string &bin)
+{
+ py.start("collections.append");
+ py.start("Collection");
+ py.qarg(name);
+ py.qarg(bin);
+ py.qarg(hostname());
+ py.qarg(Time::start.date());
+ list_t::iterator i = allStats.begin();
+ list_t::iterator end = allStats.end();
+ while (i != end) {
+ StatData *stat = *i;
+ stat->python(py);
+ ++i;
+ }
+ py.end();
+ py.end();
+}
+
StatData *
Data::find(void *stat)
{
return Database::StatDB().find(const_cast<void *>((const void *)this));
}
+const StatData *
+getStatData(const void *stat)
+{
+ return Database::StatDB().find(const_cast<void *>(stat));
+}
+
void
DataAccess::map(StatData *data)
{
}
}
+void
+ScalarDataBase::python(Python &py) const
+{
+ py.start("Scalar");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+ py.kwarg("value", val());
+ py.end();
+}
+
+void
+VectorDataBase::python(Python &py) const
+{
+ const_cast<VectorDataBase *>(this)->update();
+
+ py.start("Vector");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+ py.kwarg("value", val());
+ if (!subnames.empty())
+ py.qkwarg("subnames", subnames);
+ if (!subdescs.empty())
+ py.qkwarg("subdescs", subdescs);
+ py.end();
+}
+
+void
+DistDataData::python(Python &py, const string &name) const
+{
+ string s = name.empty() ? "" : name + "=";
+
+ if (samples == 0 || fancy)
+ s += "SimpleDist";
+ else
+ s += "FullDist";
+
+ py.start(s);
+ py.arg(sum);
+ py.arg(squares);
+ py.arg(samples);
+ if (samples && !fancy) {
+ py.arg(min_val);
+ py.arg(min_val);
+ py.arg(underflow);
+ py.arg(vec);
+ py.arg(overflow);
+ py.arg(min);
+ py.arg(max);
+ py.arg(bucket_size);
+ py.arg(size);
+ }
+ py.end();
+}
+
+void
+FormulaDataBase::python(Python &py) const
+{
+ const_cast<FormulaDataBase *>(this)->update();
+
+ py.start("Formula");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+ py.qkwarg("formula", str());
+ if (!subnames.empty())
+ py.qkwarg("subnames", subnames);
+ if (!subdescs.empty())
+ py.qkwarg("subdescs", subdescs);
+ py.end();
+}
+
+void
+DistDataBase::python(Python &py) const
+{
+ const_cast<DistDataBase *>(this)->update();
+
+ py.start("Dist");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+ data.python(py, "dist");
+ py.end();
+}
+
+void
+VectorDistDataBase::python(Python &py) const
+{
+ const_cast<VectorDistDataBase *>(this)->update();
+
+ py.start("VectorDist");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+ if (!subnames.empty())
+ py.qkwarg("subnames", subnames);
+ if (!subdescs.empty())
+ py.qkwarg("subdescs", subdescs);
+
+ py.tuple("dist");
+ typedef std::vector<DistDataData>::const_iterator iter;
+ iter i = data.begin();
+ iter end = data.end();
+ while (i != end) {
+ i->python(py, "");
+ ++i;
+ }
+ py.endTuple();
+ py.end();
+}
+
+void
+Vector2dDataBase::python(Python &py) const
+{
+ const_cast<Vector2dDataBase *>(this)->update();
+
+ py.start("Vector2d");
+ py.qarg(name);
+ py.qarg(desc);
+ py.kwarg("binned", binned());
+ py.kwarg("precision", precision);
+ py.kwarg("flags", flags);
+ if (prereq)
+ py.qkwarg("prereq", prereq->name);
+
+ py.kwarg("value", vec);
+ if (!subnames.empty())
+ py.qkwarg("subnames", subnames);
+ if (!subdescs.empty())
+ py.qkwarg("subdescs", subdescs);
+ if (!y_subnames.empty())
+ py.qkwarg("ysubnames", y_subnames);
+
+ py.kwarg("x", x);
+ py.kwarg("y", y);
+ py.end();
+}
+
void
FormulaBase::val(rvec_t &vec) const
{
{
}
+string
+FormulaBase::str() const
+{
+ return root ? root->str() : "";
+}
+
Formula::Formula()
{
setInit();
#endif
class Callback;
+class Python;
/** The current simulated cycle. */
extern Tick curTick;
* @param stream The stream to print to.
*/
virtual void display(std::ostream &stream, DisplayMode mode) const = 0;
+ virtual void python(Python &py) const = 0;
bool dodisplay() const { return !prereq || !prereq->zero(); }
/**
virtual result_t total() const = 0;
virtual void display(std::ostream &stream, DisplayMode mode) const;
+ virtual void python(Python &py) const;
};
template <class T>
mutable std::vector<std::string> subdescs;
virtual void display(std::ostream &stream, DisplayMode mode) const;
+ virtual void python(Python &py) const;
virtual size_t size() const = 0;
virtual const rvec_t &val() const = 0;
int bucket_size;
int size;
bool fancy;
+
+ void python(Python &py, const std::string &name) const;
};
struct DistDataBase : public StatData
DistDataData data;
virtual void display(std::ostream &stream, DisplayMode mode) const;
+ virtual void python(Python &py) const;
virtual void update() = 0;
};
virtual size_t size() const = 0;
virtual void display(std::ostream &stream, DisplayMode mode) const;
+ virtual void python(Python &py) const;
virtual void update()
{
int s = size();
mutable int y;
virtual void display(std::ostream &stream, DisplayMode mode) const;
+ virtual void python(Python &py) const;
virtual void update()
{
if (subnames.size() < x)
void update(StatData *data) {}
};
+const StatData * getStatData(const void *stat);
+
/**
* A proxy class to access the stat at a given index in a VectorBase stat.
* Behaves like a ScalarBase.
params_t *params;
/** The index to access in the parent VectorBase. */
int index;
+ /** Keep a pointer to the original stat so was can get data */
+ void *stat;
protected:
/**
* @param p The params to use.
* @param i The index to access.
*/
- ScalarProxy(bin_t &b, params_t &p, int i)
- : bin(&b), params(&p), index(i) {}
+ ScalarProxy(bin_t &b, params_t &p, int i, void *s)
+ : bin(&b), params(&p), index(i), stat(s) {}
/**
* Create a copy of the provided ScalarProxy.
* @param sp The proxy to copy.
*/
ScalarProxy(const ScalarProxy &sp)
- : bin(sp.bin), params(sp.params), index(sp.index) {}
+ : bin(sp.bin), params(sp.params), index(sp.index), stat(sp.stat) {}
/**
* Set this proxy equal to the provided one.
* @param sp The proxy to copy.
bin = sp.bin;
params = sp.params;
index = sp.index;
+ stat = sp.stat;
return *this;
}
* This stat has no state. Nothing to reset
*/
void reset() { }
+
+ public:
+ const StatData *statData() const { return getStatData(stat); }
+ std::string str() const
+ {
+ return csprintf("%s[%d]", statData()->name, index);
+
+ }
};
template <typename T, template <typename T> class Storage, class Bin>
VectorBase<T, Storage, Bin>::operator[](int index)
{
assert (index >= 0 && index < size());
- return ScalarProxy<T, Storage, Bin>(bin, params, index);
+ return ScalarProxy<T, Storage, Bin>(bin, params, index, this);
}
template <typename T, template <typename T> class Storage, class Bin>
params_t *params;
int offset;
int len;
+ void *stat;
private:
mutable rvec_t *vec;
}
public:
- VectorProxy(bin_t &b, params_t &p, int o, int l)
- : bin(&b), params(&p), offset(o), len(l), vec(NULL)
- { }
+ VectorProxy(bin_t &b, params_t &p, int o, int l, void *s)
+ : bin(&b), params(&p), offset(o), len(l), stat(s), vec(NULL)
+ {
+ }
+
VectorProxy(const VectorProxy &sp)
: bin(sp.bin), params(sp.params), offset(sp.offset), len(sp.len),
- vec(NULL)
- { }
- ~VectorProxy() {
+ stat(sp.stat), vec(NULL)
+ {
+ }
+
+ ~VectorProxy()
+ {
if (vec)
delete vec;
}
params = sp.params;
offset = sp.offset;
len = sp.len;
+ stat = sp.stat;
if (vec)
delete vec;
vec = NULL;
ScalarProxy<T, Storage, Bin> operator[](int index)
{
assert (index >= 0 && index < size());
- return ScalarProxy<T, Storage, Bin>(*bin, *params, offset + index);
+ return ScalarProxy<T, Storage, Bin>(*bin, *params, offset + index,
+ stat);
}
size_t size() const { return len; }
{
int offset = index * y;
assert (index >= 0 && offset < size());
- return VectorProxy<T, Storage, Bin>(bin, params, offset, y);
+ return VectorProxy<T, Storage, Bin>(bin, params, offset, y, this);
}
//////////////////////////////////////////////////////////////////////
*@return True is stat is binned.
*/
virtual bool binned() const = 0;
+
+ /**
+ *
+ */
+ virtual std::string str() const = 0;
};
/** Reference counting pointer to a function Node. */
*@return True is stat is binned.
*/
virtual bool binned() const { return data->binned(); }
+
+ /**
+ *
+ */
+ virtual std::string str() const { return data->name; }
};
template <typename T, template <typename T> class Storage, class Bin>
*@return True is stat is binned.
*/
virtual bool binned() const { return proxy.binned(); }
+
+ /**
+ *
+ */
+ virtual std::string str() const { return proxy.str(); }
};
class VectorStatNode : public Node
*@return True is stat is binned.
*/
virtual bool binned() const { return data->binned(); }
+
+ virtual std::string str() const { return data->name; }
};
template <typename T>
*@return False since constants aren't binned.
*/
virtual bool binned() const { return false; }
+
+ virtual std::string str() const { return to_string(data[0]); }
};
template <typename T>
*@return False since Functors aren't binned
*/
virtual bool binned() const { return false; }
+ virtual std::string str() const { return to_string(functor()); }
};
template <typename T>
*@return False since Scalar's aren't binned
*/
virtual bool binned() const { return false; }
+ virtual std::string str() const { return to_string(scalar); }
+};
+
+template <class Op>
+struct OpString;
+
+template<>
+struct OpString<std::plus<result_t> >
+{
+ static std::string str() { return "+"; }
+};
+
+template<>
+struct OpString<std::minus<result_t> >
+{
+ static std::string str() { return "-"; }
+};
+
+template<>
+struct OpString<std::multiplies<result_t> >
+{
+ static std::string str() { return "*"; }
+};
+
+template<>
+struct OpString<std::divides<result_t> >
+{
+ static std::string str() { return "/"; }
+};
+
+template<>
+struct OpString<std::modulus<result_t> >
+{
+ static std::string str() { return "%"; }
+};
+
+template<>
+struct OpString<std::negate<result_t> >
+{
+ static std::string str() { return "-"; }
};
template <class Op>
*@return True if child of node is binned.
*/
virtual bool binned() const { return l->binned(); }
+
+ virtual std::string str() const
+ {
+ return OpString<Op>::str() + l->str();
+ }
};
template <class Op>
*@return True if either child of node is binned.
*/
virtual bool binned() const { return (l->binned() || r->binned()); }
+
+ virtual std::string str() const
+ {
+ return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
+ }
};
template <class Op>
*@return True if child of node is binned.
*/
virtual bool binned() const { return l->binned(); }
+
+ virtual std::string str() const
+ {
+ return csprintf("total(%s)", l->str());
+ }
};
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
struct MainBin
{
+ class BinBase;
+ friend class MainBin::BinBase;
+
private:
std::string _name;
char *mem;
*
*/
void update(StatData *);
+
+ std::string str() const;
+};
+
+class FormulaDataBase : public VectorDataBase
+{
+ public:
+ virtual std::string str() const = 0;
+ virtual bool check() const { return true; }
+ virtual void python(Python &py) const;
+};
+
+template <class T>
+class FormulaData : public FormulaDataBase
+{
+ protected:
+ T &s;
+ mutable rvec_t vec;
+
+ public:
+ FormulaData(T &stat) : s(stat) {}
+
+ virtual bool binned() const { return s.binned(); }
+ virtual bool zero() const { return s.zero(); }
+ virtual void reset() { s.reset(); }
+
+ virtual size_t size() const { return s.size(); }
+ virtual const rvec_t &val() const
+ {
+ s.val(vec);
+ return vec;
+ }
+ virtual result_t total() const { return s.total(); }
+ virtual void update()
+ {
+ VectorDataBase::update();
+ s.update(this);
+ }
+ virtual std::string str() const { return s.str(); }
};
class Temp;
virtual const rvec_t &val() const { formula.val(vec); return vec; }
virtual result_t total() const { return formula.total(); }
virtual bool binned() const { return formula.binned(); }
+
+ virtual std::string str() const { return formula.str(); }
};
/**