Poplar and PopLibs
ProfileValue.hpp
1// Copyright (c) 2019 Graphcore Ltd. All rights reserved.
2
3#ifndef poplar_Profile_hpp
4#define poplar_Profile_hpp
5
6#include <poplar/OptionFlags.hpp>
7#include <poplar/StringRef.hpp>
8
9#include <map>
10#include <memory>
11#include <string>
12#include <type_traits>
13
14#include <cstdint>
15
16namespace poplar {
17
18namespace core {
19class MutableProfileValue;
20}
21
40public:
41 enum class Type {
42 BOOL_,
43 STRING,
44 NUMBER,
45 VECTOR,
46 MAP,
47 };
48
49 using Boolean = bool;
50 using Number = double;
51 using String = std::string;
52 using Vector = std::vector<ProfileValue>;
53 using Map = std::map<std::string, ProfileValue>;
54
55 struct Storage {
56 std::aligned_union<1, Boolean, Number, String, Vector, Map>::type buffer;
57 };
58
59 // Get the type of this value.
60 Type type() const;
61
62 // String access. Throws if type() != Type::STRING.
63 const String &asString() const;
64
65 // Boolean access. Throws if type() != Type::BOOL_.
66 Boolean asBool() const;
67 // Number access (asInt() truncates). Throws if type() != Type::NUMBER.
68 std::int64_t asInt() const;
69 // Number access (asUInt() truncates). Throws if type() != Type::NUMBER or not
70 // representable as uint64_t
71 std::uint64_t asUint() const;
72 double asDouble() const;
73
74 // Map access.
75 // Throws if type() != Type::MAP, or if the key does not exist.
76 const ProfileValue &operator[](StringRef s) const;
77 // Returns nullptr if the key does not exist.
78 const ProfileValue *getOrNull(StringRef s) const;
79 const Map &asMap() const;
80
81 // Array access. Throws if type() != Type::VECTOR or if it is out of range.
82 const ProfileValue &operator[](std::size_t i) const;
83 const Vector &asVector() const;
84
85 // Converts each element to std::uint64_t
86 // Throws if type() != Type::VECTOR or element.type() != Type::NUMBER
87 std::vector<std::uint64_t> toUintVector() const;
88
89 // Array or map size. Throws if type() != Type::MAP && type() != Type::VECTOR.
90 std::size_t size() const;
91
92 // If the value is a vector that only contains numbers, these return
93 // their sum. Otherwise they throw an exception.
94 double sumDouble() const;
95 std::int64_t sumInt() const;
96 std::uint64_t sumUint() const;
97 // If the value is a vector of vectors of numbers return their sum. Otherwise
98 // throw an exception. Useful eg to accumulate totals over all compute sets
99 // across all tiles
100 std::int64_t sum2DInt() const;
101 std::uint64_t sum2DUint() const;
102
103 // Compare values for equality. Note this will involve traversing the
104 // entire tree of values until it finds an inequality so it may be slow.
105 bool operator==(const ProfileValue &other) const;
106 bool operator!=(const ProfileValue &other) const;
107
108 // Default value is 0.0.
109 ProfileValue() : ProfileValue(0.0) {}
110
111 ProfileValue(String init);
112 ProfileValue(Vector init);
113 ProfileValue(Map init);
114 ProfileValue(Number init);
115 explicit ProfileValue(Boolean init);
116
117 // Disambiguate cast from integral type to Number
118 template <class T, typename = typename std::enable_if<
119 std::is_integral<T>::value>::type>
120 ProfileValue(T init) : ProfileValue(ProfileValue::Number(init)) {}
121
122 // Disambiguate conversion from const char* to bool, which is preferred over
123 // std::string
124 ProfileValue(const char *init) : ProfileValue(ProfileValue::String(init)) {}
125
127
128 ProfileValue(const ProfileValue &other);
129 ProfileValue(ProfileValue &&other) noexcept;
130
131 ProfileValue &operator=(const ProfileValue &other);
132 ProfileValue &operator=(ProfileValue &&other) noexcept;
133 ProfileValue &operator=(Boolean init);
134 ProfileValue &operator=(Number init);
135 ProfileValue &operator=(String init);
136 ProfileValue &operator=(Vector init);
137 ProfileValue &operator=(Map init);
138
139 // Disambiguate cast from any non-boolean integral type to Number
140 template <class T, typename = typename std::enable_if<
141 std::is_integral<T>::value>::type>
142 ProfileValue &operator=(T init) {
143 return operator=(ProfileValue::Number(init));
144 }
145
146private:
147 friend class core::MutableProfileValue;
148
149 // Size of this should be about 3 pointers (24 bytes) which uses more memory
150 // than storing a single pointer (8 bytes) but is faster and simpler.
151 Storage v;
152 Type t;
153};
154
155void serializeToJSON(std::ostream &out, const ProfileValue &val,
156 bool prettyPrint = false);
157
158void serializeToCBOR(std::ostream &out, const ProfileValue &val,
159 bool withTag = true);
160
162std::ostream &operator<<(std::ostream &os, const ProfileValue &v);
163
199void printGraphSummary(std::ostream &out, const std::string &databasePath,
200 const OptionFlags &opts);
201
224void printExecutionSummary(std::ostream &out, const std::string &databasePath,
225 const OptionFlags &opts);
226
240void printProfileSummary(std::ostream &out, const std::string &databasePath,
241 const OptionFlags &opts = {});
242
243} // namespace poplar
244
245#endif // poplar_Profile_hpp
A set of option/value string flags to be used in various APIs.
Definition: OptionFlags.hpp:24
ProfileValue represents a read-only JSON-like tree of values that are used to store the output of the...
Definition: ProfileValue.hpp:39
Poplar classes and functions.
Definition: ArrayRef.hpp:14
std::ostream & operator<<(std::ostream &os, const DebugNameAndId &dnai)
Display the path name of the DebugNameAndId.
void printGraphSummary(std::ostream &out, const std::string &databasePath, const OptionFlags &opts)
Print a summary of the static graph profiling information - primarily memory use.
void printExecutionSummary(std::ostream &out, const std::string &databasePath, const OptionFlags &opts)
Print a summary of the execution profiling information - primarily cycle counts.
void printProfileSummary(std::ostream &out, const std::string &databasePath, const OptionFlags &opts={})
Equivalent to calling printGraphSummary() followed by printExecutionSummary().