ExaTN
tensor_graph.hpp
1 
29 #ifndef EXATN_RUNTIME_TENSOR_GRAPH_HPP_
30 #define EXATN_RUNTIME_TENSOR_GRAPH_HPP_
31 
32 #include "Identifiable.hpp"
33 
34 #include "tensor_exec_state.hpp"
35 #include "tensor_operation.hpp"
36 #include "tensor.hpp"
37 
38 #include <vector>
39 #include <memory>
40 #include <atomic>
41 #include <mutex>
42 
43 #include <cassert>
44 
45 namespace exatn {
46 namespace runtime {
47 
48 // Tensor Graph node
49 class TensorOpNode {
50 
51 public:
52  TensorOpNode():
53  op_(nullptr), is_noop_(true), executing_(false), executed_(false), error_(0)
54  {}
55 
56  TensorOpNode(std::shared_ptr<TensorOperation> tens_op):
57  op_(tens_op), is_noop_(false), executing_(false), executed_(false), error_(0)
58  {}
59 
60  TensorOpNode(const TensorOpNode &) = delete;
61  TensorOpNode & operator=(const TensorOpNode &) = delete;
62  TensorOpNode(TensorOpNode &&) noexcept = delete;
63  TensorOpNode & operator=(TensorOpNode &&) noexcept = delete;
64  ~TensorOpNode() = default;
65 
67  inline bool isDummy() const {return is_noop_;}
68 
72  inline std::shared_ptr<TensorOperation> & getOperation() {return op_;}
73 
75  inline VertexIdType getId() const {return id_;}
76 
78  inline bool isExecuting() {return executing_.load();}
79 
81  inline bool isExecuted(int * error_code = nullptr) {
82  bool ans = executed_.load();
83  if(error_code != nullptr && ans) *error_code = error_.load();
84  return ans;
85  }
86 
88  inline void setId(VertexIdType id) {
89  id_ = id;
90  return;
91  }
92 
94  inline void setExecuting() {
95  auto executing = executing_.load();
96  auto executed = executed_.load();
97  assert(!executing && !executed);
98  executing_.store(true);
99  return;
100  }
101 
103  inline void setExecuted(int error_code = 0) {
104  auto executing = executing_.load();
105  auto executed = executed_.load();
106  assert(executing && !executed);
107  error_.store(error_code);
108  executed_.store(true);
109  executing_.store(false);
110  return;
111  }
112 
114  inline void setIdle() {
115  auto executed = executed_.load();
116  assert(!executed);
117  error_.store(0);
118  executing_.store(false);
119  return;
120  }
121 
122  inline void lock() {mtx_.lock();}
123  inline void unlock() {mtx_.unlock();}
124 
125 protected:
126  std::shared_ptr<TensorOperation> op_; //stored tensor operation
127  bool is_noop_; //TRUE if the stored tensor operation is NOOP (dummy node)
128  std::atomic<bool> executing_; //TRUE if the stored tensor operation is currently being executed
129  std::atomic<bool> executed_; //TRUE if the stored tensor operation has been executed to completion
130  std::atomic<int> error_; //execution error code (0:success)
131  VertexIdType id_; //graph vertex id
132 
133 private:
134  std::recursive_mutex mtx_; //object access mutex
135 };
136 
137 
138 // Public Tensor Graph API
139 class TensorGraph : public Identifiable, public Cloneable<TensorGraph> {
140 
141 public:
142  TensorGraph() = default;
143  TensorGraph(const TensorGraph &) = delete;
144  TensorGraph & operator=(const TensorGraph &) = delete;
145  TensorGraph(TensorGraph &&) noexcept = default;
146  TensorGraph & operator=(TensorGraph &&) noexcept = default;
147  virtual ~TensorGraph() = default;
148 
150  virtual VertexIdType addOperation(std::shared_ptr<TensorOperation> op) = 0;
151 
154  virtual void addDependency(VertexIdType dependent,
155  VertexIdType dependee) = 0;
156 
159  virtual bool dependencyExists(VertexIdType vertex_id1,
160  VertexIdType vertex_id2) = 0;
161 
165  virtual TensorOpNode & getNodeProperties(VertexIdType vertex_id) = 0;
166 
168  virtual std::size_t getNodeDegree(VertexIdType vertex_id) = 0;
169 
171  virtual std::size_t getNumNodes() = 0;
172 
174  virtual std::size_t getNumDependencies() = 0;
175 
177  virtual std::vector<VertexIdType> getNeighborList(VertexIdType vertex_id) = 0;
178 
180  virtual void computeShortestPath(VertexIdType startIndex,
181  std::vector<double> & distances,
182  std::vector<VertexIdType> & paths) = 0;
183 
185  virtual void printIt() = 0;
186 
188  virtual std::shared_ptr<TensorGraph> clone() = 0;
189 
190 
192  void setNodeExecuting(VertexIdType vertex_id) {
193  return getNodeProperties(vertex_id).setExecuting();
194  }
195 
197  void setNodeExecuted(VertexIdType vertex_id, int error_code = 0) {
198  TensorOpNode & node_properties = getNodeProperties(vertex_id);
199  node_properties.setExecuted(error_code);
200  auto & op = node_properties.getOperation();
201  auto & output_tensor = *(op->getTensorOperand(0));
202  lock();
203  auto update_cnt = exec_state_.registerWriteCompletion(output_tensor);
204  unlock();
205  return;
206  }
207 
209  void setNodeIdle(VertexIdType vertex_id) {
210  return getNodeProperties(vertex_id).setIdle();
211  }
212 
214  bool nodeExecuting(VertexIdType vertex_id) {
215  return getNodeProperties(vertex_id).isExecuting();
216  }
217 
220  bool nodeExecuted(VertexIdType vertex_id, int * error_code = nullptr) {
221  return getNodeProperties(vertex_id).isExecuted(error_code);
222  }
223 
225  inline std::size_t getTensorUpdateCount(const Tensor & tensor) {
226  lock();
227  auto upd_cnt = exec_state_.getTensorUpdateCount(tensor);
228  unlock();
229  return upd_cnt;
230  }
231 
233  inline void registerDependencyFreeNode(VertexIdType node_id) {
234  lock();
235  exec_state_.registerDependencyFreeNode(node_id);
236  unlock();
237  return;
238  }
239 
242  inline bool extractDependencyFreeNode(VertexIdType * node_id) {
243  lock();
244  auto avail = exec_state_.extractDependencyFreeNode(node_id);
245  unlock();
246  return avail;
247  }
248 
250  inline void registerExecutingNode(VertexIdType node_id) {
251  lock();
252  exec_state_.registerExecutingNode(node_id);
253  unlock();
254  return;
255  }
256 
258  inline bool extractExecutingNode(VertexIdType * node_id) {
259  lock();
260  auto avail = exec_state_.extractExecutingNode(node_id);
261  unlock();
262  return avail;
263  }
264 
267  inline bool progressFrontNode(VertexIdType node_executed) {
268  return exec_state_.progressFrontNode(node_executed);
269  }
270 
272  inline VertexIdType getFrontNode() const {
273  return exec_state_.getFrontNode();
274  }
275 
277  inline bool hasUnexecutedNodes() {
278  return (exec_state_.getFrontNode() < this->getNumNodes());
279  }
280 
281  inline void lock() {mtx_.lock();}
282  inline void unlock() {mtx_.unlock();}
283 
284 protected:
285  TensorExecState exec_state_; //tensor graph execution state
286 
287 private:
288  std::recursive_mutex mtx_; //object access mutex
289 };
290 
291 } // namespace runtime
292 } // namespace exatn
293 
294 #endif //EXATN_RUNTIME_TENSOR_GRAPH_HPP_
exatn::numerics::Tensor
Definition: tensor.hpp:63
exatn::runtime::TensorGraph::setNodeExecuting
void setNodeExecuting(VertexIdType vertex_id)
Definition: tensor_graph.hpp:192
exatn::runtime::TensorOpNode::isExecuted
bool isExecuted(int *error_code=nullptr)
Definition: tensor_graph.hpp:81
exatn::runtime::TensorExecState::registerWriteCompletion
std::size_t registerWriteCompletion(const Tensor &tensor)
Definition: tensor_exec_state.cpp:62
exatn::runtime::TensorGraph::hasUnexecutedNodes
bool hasUnexecutedNodes()
Definition: tensor_graph.hpp:277
exatn::runtime::TensorGraph::dependencyExists
virtual bool dependencyExists(VertexIdType vertex_id1, VertexIdType vertex_id2)=0
exatn::runtime::TensorExecState::registerExecutingNode
void registerExecutingNode(VertexIdType node_id)
Definition: tensor_exec_state.cpp:94
exatn::runtime::TensorOpNode::setIdle
void setIdle()
Definition: tensor_graph.hpp:114
exatn::runtime::TensorExecState::extractDependencyFreeNode
bool extractDependencyFreeNode(VertexIdType *node_id)
Definition: tensor_exec_state.cpp:84
exatn::runtime::TensorGraph::getFrontNode
VertexIdType getFrontNode() const
Definition: tensor_graph.hpp:272
exatn::runtime::TensorOpNode::getId
VertexIdType getId() const
Definition: tensor_graph.hpp:75
exatn::runtime::TensorGraph::nodeExecuting
bool nodeExecuting(VertexIdType vertex_id)
Definition: tensor_graph.hpp:214
exatn::runtime::TensorExecState::getFrontNode
VertexIdType getFrontNode() const
Definition: tensor_exec_state.cpp:117
exatn::runtime::TensorGraph::registerExecutingNode
void registerExecutingNode(VertexIdType node_id)
Definition: tensor_graph.hpp:250
exatn::runtime::TensorGraph::getNeighborList
virtual std::vector< VertexIdType > getNeighborList(VertexIdType vertex_id)=0
exatn::runtime::TensorGraph::nodeExecuted
bool nodeExecuted(VertexIdType vertex_id, int *error_code=nullptr)
Definition: tensor_graph.hpp:220
exatn::runtime::TensorGraph::getNodeDegree
virtual std::size_t getNodeDegree(VertexIdType vertex_id)=0
exatn
Definition: DriverClient.hpp:10
exatn::runtime::TensorOpNode::isExecuting
bool isExecuting()
Definition: tensor_graph.hpp:78
exatn::runtime::TensorOpNode::setId
void setId(VertexIdType id)
Definition: tensor_graph.hpp:88
exatn::runtime::TensorOpNode::setExecuted
void setExecuted(int error_code=0)
Definition: tensor_graph.hpp:103
exatn::runtime::TensorGraph::getNumNodes
virtual std::size_t getNumNodes()=0
exatn::runtime::TensorGraph::extractDependencyFreeNode
bool extractDependencyFreeNode(VertexIdType *node_id)
Definition: tensor_graph.hpp:242
exatn::Cloneable
Definition: Identifiable.hpp:18
exatn::runtime::TensorGraph::setNodeExecuted
void setNodeExecuted(VertexIdType vertex_id, int error_code=0)
Definition: tensor_graph.hpp:197
exatn::runtime::TensorExecState::registerDependencyFreeNode
void registerDependencyFreeNode(VertexIdType node_id)
Definition: tensor_exec_state.cpp:78
exatn::runtime::TensorGraph::clone
virtual std::shared_ptr< TensorGraph > clone()=0
exatn::runtime::TensorOpNode
Definition: tensor_graph.hpp:49
exatn::runtime::TensorGraph::printIt
virtual void printIt()=0
exatn::runtime::TensorGraph::progressFrontNode
bool progressFrontNode(VertexIdType node_executed)
Definition: tensor_graph.hpp:267
exatn::runtime::TensorGraph::extractExecutingNode
bool extractExecutingNode(VertexIdType *node_id)
Definition: tensor_graph.hpp:258
exatn::runtime::TensorGraph::setNodeIdle
void setNodeIdle(VertexIdType vertex_id)
Definition: tensor_graph.hpp:209
exatn::runtime::TensorGraph::computeShortestPath
virtual void computeShortestPath(VertexIdType startIndex, std::vector< double > &distances, std::vector< VertexIdType > &paths)=0
exatn::Identifiable
Definition: Identifiable.hpp:9
exatn::runtime::TensorOpNode::isDummy
bool isDummy() const
Definition: tensor_graph.hpp:67
exatn::runtime::TensorExecState::extractExecutingNode
bool extractExecutingNode(VertexIdType *node_id)
Definition: tensor_exec_state.cpp:100
exatn::runtime::TensorExecState::progressFrontNode
bool progressFrontNode(VertexIdType node_executed)
Definition: tensor_exec_state.cpp:110
exatn::runtime::TensorGraph::addOperation
virtual VertexIdType addOperation(std::shared_ptr< TensorOperation > op)=0
exatn::runtime::TensorGraph::getNumDependencies
virtual std::size_t getNumDependencies()=0
exatn::runtime::TensorExecState::getTensorUpdateCount
std::size_t getTensorUpdateCount(const Tensor &tensor)
Definition: tensor_exec_state.cpp:70
exatn::runtime::TensorGraph::getNodeProperties
virtual TensorOpNode & getNodeProperties(VertexIdType vertex_id)=0
exatn::runtime::TensorOpNode::setExecuting
void setExecuting()
Definition: tensor_graph.hpp:94
exatn::runtime::TensorOpNode::getOperation
std::shared_ptr< TensorOperation > & getOperation()
Definition: tensor_graph.hpp:72
exatn::runtime::TensorGraph::addDependency
virtual void addDependency(VertexIdType dependent, VertexIdType dependee)=0
exatn::runtime::TensorGraph::getTensorUpdateCount
std::size_t getTensorUpdateCount(const Tensor &tensor)
Definition: tensor_graph.hpp:225
exatn::runtime::TensorGraph
Definition: tensor_graph.hpp:139
exatn::runtime::TensorGraph::registerDependencyFreeNode
void registerDependencyFreeNode(VertexIdType node_id)
Definition: tensor_graph.hpp:233