Minsky
MathDAG::anonymous_namespace{equations.cc} Namespace Reference

Classes

struct  NoArgument
 
struct  VariableDefOrder
 

Functions

bool addTensorOp (const shared_ptr< VariableValue > &result, OperationDAGBase &nodeOp, EvalOpVector &ev)
 
void cumulate (EvalOpVector &ev, const ItemPtr &state, VariableValuePtr &r, const vector< vector< VariableValuePtr > > &argIdx, OperationType::Type op, OperationType::Type accum, double groupIdentity)
 

Variables

OperationFactory< OperationDAGBase, OperationDAG, OperationType::numOps-1 > operationDAGFactory
 

Function Documentation

◆ addTensorOp()

bool MathDAG::anonymous_namespace{equations.cc}::addTensorOp ( const shared_ptr< VariableValue > &  result,
OperationDAGBase nodeOp,
EvalOpVector ev 
)

Definition at line 88 of file equations.cc.

References minsky::TensorOpFactory::create(), MathDAG::OperationDAGBase::state, and minsky::tensorOpFactory.

Referenced by MathDAG::VariableDAG::addEvalOps(), MathDAG::OperationDAGBase::addEvalOps(), and MathDAG::VariableDAG::addTensorOp().

89  {
90  if (auto state=nodeOp.state)
91  try
92  {
93  auto ec=make_shared<EvalCommon>();
94  const TensorPtr rhs=tensorOpFactory.create(state,TensorsFromPort(ec));
95  if (!rhs) return false;
96  result->index(rhs->index());
97  result->rhs=rhs;
98  ev.emplace_back(EvalOpPtr(new TensorEval(result, ec, rhs)));
99  return true;
100  }
101  catch(const FallBackToScalar&) {/* fall back to scalar processing */}
102  return false;
103  }
A helper to evaluate a variable value.
std::shared_ptr< ITensor > create(const ItemPtr &, const TensorsFromPort &tp={})
create a tensor representation of the expression rooted at op. If expression doesn&#39;t contain any refe...
std::shared_ptr< ITensor > TensorPtr
TensorOpFactory tensorOpFactory
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cumulate()

void MathDAG::anonymous_namespace{equations.cc}::cumulate ( EvalOpVector ev,
const ItemPtr state,
VariableValuePtr r,
const vector< vector< VariableValuePtr > > &  argIdx,
OperationType::Type  op,
OperationType::Type  accum,
double  groupIdentity 
)

Definition at line 236 of file equations.cc.

References minsky::OperationType::add, minsky::OperationType::constant, minsky::OperationType::copy, minsky::OperationType::divide, minsky::OperationType::multiply, minsky::op, and minsky::VariableType::tempFlow.

Referenced by MathDAG::OperationDAGBase::addEvalOps().

239  {
240  assert(r);
241  // check if any arguments have x-vectors, and if so, initialise r.xVector
242  // For feature 47
243  for (auto& i: argIdx)
244  if (!i.empty())
245  {
246  // initialise r's xVector
247  r->hypercube(i[0]->hypercube());
248  break;
249  }
250  if (r->rank()>0)
251  throw runtime_error("Scalar processing not supported in tensor code, try adding an intermediate variable");
252  if (r->idx()==-1) r->allocValue();
253 
254  // short circuit multiplications if any of the terms are constant zero
255  if (accum==OperationType::multiply)
256  {
257  if (op==OperationType::divide)
258  for (auto& i: argIdx[1])
259  if (i->isZero())
260  throw runtime_error("divide by constant zero");
261  for (auto& i: argIdx)
262  for (auto& j: i)
263  if (j->isZero())
264  {
265  r=j;
266  return;
267  }
268  }
269 
270  {
271  size_t i=0;
272  if (accum==OperationType::add)
273  while (!argIdx.empty() && i<argIdx[0].size() && argIdx[0][i]->isZero())
274  i++;
275  if (!argIdx.empty() && i<argIdx[0].size())
276  {
277  ev.push_back(EvalOpPtr(OperationType::copy, state, r, *argIdx[0][i]));
278  for (++i; i<argIdx[0].size(); ++i)
279  if (accum!=OperationType::add || !argIdx[0][i]->isZero())
280  ev.push_back(EvalOpPtr(accum, state, r, *r, *argIdx[0][i]));
281  }
282  else
283  {
284  //TODO: could be cleaned up if we don't need to support constant operators
285  ev.push_back(EvalOpPtr(OperationType::constant, state, r));
286  dynamic_cast<ConstantEvalOp&>(*ev.back()).value=groupIdentity;
287  }
288  }
289 
290  if (argIdx.size()>1)
291  {
292  if (argIdx[1].size()==1)
293  // eliminate redundant copy operation when only one wire
294  ev.push_back(EvalOpPtr(op, state, r, *r, *argIdx[1][0]));
295  else if (argIdx[1].size()>1)
296  {
297  // multiple wires to second input port
298  const VariableValuePtr tmp(VariableType::tempFlow);
299  tmp->hypercube(r->hypercube());
300  size_t i=0;
301  if (accum==OperationType::add)
302  while (i<argIdx[1].size() && argIdx[1][i]->isZero()) i++;
303  if (i<argIdx[1].size())
304  {
305  ev.push_back(EvalOpPtr(OperationType::copy, state, tmp, *argIdx[1][i]));
306  for (++i; i<argIdx[1].size(); ++i)
307  if (accum!=OperationType::add || !argIdx[1][i]->isZero())
308  ev.push_back(EvalOpPtr(accum, state, tmp, *tmp, *argIdx[1][i]));
309  ev.push_back(EvalOpPtr(op, state, r, *r, *tmp));
310  }
311  }
312  }
313  }
a shared_ptr that default constructs a default target, and is always valid
Here is the caller graph for this function:

Variable Documentation

◆ operationDAGFactory

OperationFactory<OperationDAGBase, OperationDAG, OperationType::numOps-1> MathDAG::anonymous_namespace{equations.cc}::operationDAGFactory

Definition at line 174 of file equations.cc.

Referenced by MathDAG::OperationDAGBase::create().