TVM  0.9.4
GraphProbe.h
Go to the documentation of this file.
1 
3 #pragma once
4 
5 #include <tvm/api.h>
6 
7 #include <tvm/Variable.h>
10 #include <tvm/diagnostic/matrix.h>
11 #include <tvm/graph/CallGraph.h>
13 
14 #include <mpark/variant.hpp>
15 
16 #include <Eigen/Core>
17 
18 #include <iosfwd>
19 #include <map>
20 #include <memory>
21 #include <optional>
22 #include <tuple>
23 #include <vector>
24 
25 namespace tvm::diagnostic
26 {
37 {
38 public:
41  using OutputVal = std::tuple<Output, VariablePtr, Eigen::MatrixXd>;
42 
44  {
45  ProbeNode(const Output & o) : val(o) {}
46  ProbeNode(const Update & u) : val(u) {}
47  mpark::variant<Output, Update> val;
48  std::vector<std::unique_ptr<ProbeNode>> children;
49 
50  ProbeNode & operator=(const ProbeNode &) = delete;
51  ProbeNode(const ProbeNode &) = delete;
52  };
53 
59  static constexpr auto absInRange = [](double rmin, double rmax) {
60  return [rmin, rmax](const Eigen::MatrixXd & M) { return hasElemAbsInRange(M, rmin, rmax); };
61  };
62 
67  static constexpr auto hasNan = [](const Eigen::MatrixXd & M) { return M.hasNaN(); };
68 
71 
80  template<typename T, typename MethodT, typename EnumOutput, typename ConvertT = std::nullopt_t>
81  void registerAccessor(EnumOutput o, MethodT method, ConvertT convert = std::nullopt);
82 
84  template<typename T>
85  void registerTVMFunction();
86 
88  template<typename T>
89  void registerTVMConstraint();
90 
92  template<typename T>
93  void registerTVMTaskDynamics();
94 
101  std::vector<OutputVal> listOutputVal(const graph::CallGraph * const g, bool verbose = false) const;
102 
109  std::vector<OutputVal> listOutputVal(const Output & o, bool verbose = false) const;
110 
114  std::unique_ptr<ProbeNode> followUp(
115  const Output & o,
116  const std::function<bool(const Eigen::MatrixXd &)> & select = [](const Eigen::MatrixXd &) { return true; }) const;
117 
121  std::vector<std::unique_ptr<ProbeNode>> followUp(
122  const graph::CallGraph * const g,
123  const std::function<bool(const Eigen::MatrixXd &)> & select = [](const Eigen::MatrixXd &) { return true; }) const;
124 
126  void print(std::ostream & os, const std::unique_ptr<ProbeNode> & root) const;
128  void print(std::ostream & os, const std::vector<std::unique_ptr<ProbeNode>> & roots) const;
129 
130 private:
132  struct Processed
133  {
134  Processed() = default;
135  Processed(const graph::internal::Log & log);
136 
137  std::map<Output, bool> outputs;
138  std::map<Update, bool> updates;
139  std::vector<Output> allOutputs;
140  };
141 
143  bool addOutputVal(std::vector<OutputVal> & ov, const Output & o) const;
145  std::vector<OutputVal> outputVal(const Output & o) const;
147  std::vector<OutputVal> listOutputVal(const std::vector<graph::internal::Log::Output> & o, bool verbose) const;
149  std::unique_ptr<ProbeNode> followUp(const Output & o,
150  const std::function<bool(const Eigen::MatrixXd &)> & select,
151  Processed & processed) const;
153  std::unique_ptr<ProbeNode> followUp(const Update & u,
154  const std::function<bool(const Eigen::MatrixXd &)> & select,
155  Processed & processed) const;
156 
158  void print(std::ostream & os, const std::unique_ptr<ProbeNode> & node, int depth) const;
159 
160  using OutputKey = std::pair<std::size_t, graph::internal::Log::EnumValue>;
161  using VarMatrixPair = std::pair<VariablePtr, Eigen::MatrixXd>;
162  const graph::internal::Log & log_;
163  std::unordered_map<OutputKey, std::function<Eigen::MatrixXd(uintptr_t)>, internal::PairHasher> outputAccessor_;
164  std::unordered_map<OutputKey, std::function<std::vector<VarMatrixPair>(uintptr_t)>, internal::PairHasher>
165  varDepOutputAccessor_;
166 };
167 
168 template<typename T, typename MethodT, typename EnumOutput, typename ConvertT>
169 inline void GraphProbe::registerAccessor(EnumOutput o, MethodT method, ConvertT convertIn)
170 {
171  using CheckAccessor = internal::CheckAccessor<T, MethodT>;
172  if constexpr(CheckAccessor::isVoidAccessor)
173  {
174  using ReturnT = typename CheckAccessor::ReturnT;
175  auto convert = internal::MakeConvert<ReturnT>(std::move(convertIn));
176  OutputKey k{std::type_index(typeid(T)).hash_code(), tvm::graph::internal::Log::EnumValue(o)};
177  outputAccessor_[k] = [method, convert](uintptr_t t) { return convert((reinterpret_cast<T *>(t)->*method)()); };
178  }
179  else if constexpr(CheckAccessor::isVariableAccessor)
180  {
181  using ReturnT = typename CheckAccessor::ReturnT;
182  auto convert = internal::MakeConvert<ReturnT>(std::move(convertIn));
183  OutputKey k{std::type_index(typeid(T)).hash_code(), tvm::graph::internal::Log::EnumValue(o)};
184  varDepOutputAccessor_[k] = [method, convert](uintptr_t t) {
185  std::vector<VarMatrixPair> ret;
186  T * ptr = reinterpret_cast<T *>(t);
187  for(const auto & v : ptr->variables())
188  ret.emplace_back(v, convert((ptr->*method)(*v)));
189  return ret;
190  };
191  }
192  else
193  {
194  static_assert(!std::is_same_v<T, T>, "Provided method does not have a valid signature");
195  }
196 }
197 
198 template<typename T>
200 {
201  using GetVectorT = const Eigen::VectorXd & (T::*)() const;
202  using GetJacobianT = tvm::internal::MatrixConstRefWithProperties (T::*)(const Variable &) const;
203  using GetJDotT = MatrixConstRef (T::*)(const Variable &) const;
204  registerAccessor<T>(T::Output::Value, static_cast<GetVectorT>(&T::value));
205  registerAccessor<T>(T::Output::Velocity, static_cast<GetVectorT>(&T::velocity));
206  registerAccessor<T>(T::Output::Jacobian, static_cast<GetJacobianT>(&T::jacobian));
207  registerAccessor<T>(T::Output::NormalAcceleration, static_cast<GetVectorT>(&T::normalAcceleration));
208  registerAccessor<T>(T::Output::JDot, static_cast<GetJDotT>(&T::JDot));
209 }
210 
211 template<typename T>
213 {
214  using GetVectorT = const Eigen::VectorXd & (T::*)() const;
215  using GetJacobianT = tvm::internal::MatrixConstRefWithProperties (T::*)(const Variable &) const;
216  registerAccessor<T>(T::Output::Value, static_cast<GetVectorT>(&T::value));
217  registerAccessor<T>(T::Output::Jacobian, static_cast<GetJacobianT>(&T::jacobian));
218  registerAccessor<T>(T::Output::L, static_cast<GetVectorT>(&T::l));
219  registerAccessor<T>(T::Output::U, static_cast<GetVectorT>(&T::u));
220  registerAccessor<T>(T::Output::E, static_cast<GetVectorT>(&T::e));
221 }
222 
223 template<typename T>
225 {
226  using GetVectorT = const Eigen::VectorXd & (T::Impl::*)() const;
227  registerAccessor<typename T::Impl>(T::Impl::Output::Value, static_cast<GetVectorT>(&T::Impl::value));
228 }
229 } // namespace tvm::diagnostic
230 
231 TVM_DLLAPI std::ostream & operator<<(std::ostream & os,
232  const std::vector<tvm::diagnostic::GraphProbe::OutputVal> & vals);
TVM_DLLAPI std::ostream & operator<<(std::ostream &os, const std::vector< tvm::diagnostic::GraphProbe::OutputVal > &vals)
#define TVM_DLLAPI
Definition: api.h:35
Definition: Variable.h:49
Definition: GraphProbe.h:37
std::vector< OutputVal > listOutputVal(const graph::CallGraph *const g, bool verbose=false) const
void print(std::ostream &os, const std::unique_ptr< ProbeNode > &root) const
void registerTVMConstraint()
Definition: GraphProbe.h:212
void registerTVMFunction()
Definition: GraphProbe.h:199
void print(std::ostream &os, const std::vector< std::unique_ptr< ProbeNode >> &roots) const
void registerAccessor(EnumOutput o, MethodT method, ConvertT convert=std::nullopt)
Definition: GraphProbe.h:169
void registerTVMTaskDynamics()
Definition: GraphProbe.h:224
std::vector< OutputVal > listOutputVal(const Output &o, bool verbose=false) const
std::unique_ptr< ProbeNode > followUp(const Output &o, const std::function< bool(const Eigen::MatrixXd &)> &select=[](const Eigen::MatrixXd &) { return true;}) const
std::tuple< Output, VariablePtr, Eigen::MatrixXd > OutputVal
Definition: GraphProbe.h:41
std::vector< std::unique_ptr< ProbeNode > > followUp(const graph::CallGraph *const g, const std::function< bool(const Eigen::MatrixXd &)> &select=[](const Eigen::MatrixXd &) { return true;}) const
GraphProbe(const graph::internal::Log &log=tvm::graph::internal::Logger::logger().log())
Definition: CallGraph.h:23
Definition: Log.h:56
static Logger & logger()
Definition: GraphProbe.h:26
bool hasElemAbsInRange(const Eigen::MatrixBase< Derived > &A, typename Derived::Scalar emin, typename Derived::Scalar emax)
Definition: matrix.h:53
ObjectWithProperties< Eigen::Ref< const Eigen::MatrixXd > > MatrixConstRefWithProperties
Definition: MatrixWithProperties.h:164
std::unordered_map< KeyWithId, Value, HashId< KeyWithId >, IdEqual< KeyWithId >, Allocator > unordered_map
Definition: map.h:44
Eigen::Ref< const Eigen::MatrixXd > MatrixConstRef
Definition: defs.h:48
Definition: GraphProbe.h:44
mpark::variant< Output, Update > val
Definition: GraphProbe.h:47
std::vector< std::unique_ptr< ProbeNode > > children
Definition: GraphProbe.h:48
ProbeNode(const ProbeNode &)=delete
ProbeNode(const Output &o)
Definition: GraphProbe.h:45
ProbeNode & operator=(const ProbeNode &)=delete
ProbeNode(const Update &u)
Definition: GraphProbe.h:46