1 #ifndef CPPAD_CG_EVALUATOR_CG_INCLUDED 2 #define CPPAD_CG_EVALUATOR_CG_INCLUDED 25 template<
class ScalarIn,
class ScalarOut,
class FinalEvaluatorType>
62 printOutPriOperations_(true) {
70 printOutPriOperations_ = print;
89 CPPAD_ASSERT_KNOWN(indep !=
nullptr || n == 0,
"null array with a non-zero size");
100 for (
const auto& it : atomicEvalResults_) {
101 for (
const ScalarOut* e : it.second) {
105 atomicEvalResults_.clear();
115 if (node.
getName() !=
nullptr) {
116 if (a.getOperationNode() !=
nullptr) {
128 CPPADCG_ASSERT_KNOWN(args.size() == 1,
"Invalid number of arguments for print()");
131 if (printOutPriOperations_) {
133 std::cout << nodePri.getBeforeString() << out << nodePri.getAfterString();
136 if (out.getOperationNode() !=
nullptr) {
138 ActiveOut out2(*outHandler_->makePrintNode(nodePri.getBeforeString(), *out.getOperationNode(), nodePri.getAfterString()));
139 if (out.isValueDefined())
140 out2.setValue(out.getValue());
153 CPPADCG_ASSERT_KNOWN(op == CGOpCode::AtomicForward || op == CGOpCode::AtomicReverse,
154 "Invalid operation type");
157 if (evals_[node] !=
nullptr) {
161 const std::vector<size_t>& info = node.
getInfo();
162 const std::vector<Argument<ScalarIn> >& inArgs = node.
getArguments();
164 CPPADCG_ASSERT_KNOWN(info.size() == 3,
"Invalid number of information data for atomic operation");
168 CPPADCG_ASSERT_KNOWN(inArgs.size() == 2 * p1,
"Invalid number of information data for atomic operation");
170 if (outHandler_ ==
nullptr) {
171 throw CGException(
"Evaluator is unable to determine the new CodeHandler for an atomic operation");
174 std::vector<Argument<ScalarOut> > outArgs(inArgs.size());
176 std::vector<std::vector<ScalarOut>> outVals(inArgs.size());
177 bool valuesDefined =
true;
178 bool allParameters =
true;
180 for (
size_t i = 0; i < inArgs.size(); i++) {
181 auto* a = inArgs[i].getOperation();
182 CPPADCG_ASSERT_KNOWN(a !=
nullptr,
"Invalid argument for atomic operation");
184 outArgs[i] = asArgument(makeArray(*a, outVals[i], valuesDefined, allParameters));
187 this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(op, info, outArgs)));
190 const std::map<size_t, CGAbstractAtomicFun<ScalarIn>*>& afun = this->handler_.
getAtomicFunctions();
193 if (op == CGOpCode::AtomicForward) {
194 auto itAFun = afun.find(
id);
195 if (itAFun == afun.end()) {
197 throw CGException(
"Atomic function for ID ",
id,
" is not defined in evaluator");
201 auto& atomic = *itAFun->second;
205 for (
size_t i = 0; i < tx.size(); ++i)
207 for (
size_t i = 0; i < ty.size(); ++i)
210 atomic.forward(q, p, vx, vy, tx, ty);
212 std::vector<ScalarOut*>& yOut = atomicEvalResults_[&node];
213 assert(yOut.empty());
214 yOut.resize(ty.size());
215 for (
size_t i = 0; i < ty.size(); ++i) {
216 if (ty[i].isValueDefined())
217 yOut[i] =
new ScalarOut(ty[i].getValue());
230 if (evals_[node] !=
nullptr) {
231 return *evals_[node];
235 const std::vector<size_t>& info = node.
getInfo();
236 CPPADCG_ASSERT_KNOWN(args.size() == 2,
"Invalid number of arguments for array element");
237 CPPADCG_ASSERT_KNOWN(args[0].getOperation() !=
nullptr,
"Invalid argument for array element");
238 CPPADCG_ASSERT_KNOWN(args[1].getOperation() !=
nullptr,
"Invalid argument for array element");
239 CPPADCG_ASSERT_KNOWN(info.size() == 1,
"Invalid number of information data for array element");
240 size_t index = info[0];
242 ArgOut arrayArg = asArgument(makeArray(*args[0].getOperation()));
244 FinalEvaluatorType& thisOps =
static_cast<FinalEvaluatorType&
>(*this);
245 const NodeIn& atomicNode = *args[1].getOperation();
246 thisOps.evalAtomicOperation(atomicNode);
247 ArgOut atomicArg = *evals_[atomicNode]->getOperationNode();
249 ActiveOut out(*outHandler_->makeNode(CGOpCode::ArrayElement, {index}, {arrayArg, atomicArg}));
251 auto it = atomicEvalResults_.find(&atomicNode);
252 if (it != atomicEvalResults_.end()) {
253 const std::vector<ScalarOut*>& yOut = it->second;
254 if (index < yOut.size() && yOut[index] !=
nullptr)
255 out.setValue(*yOut[index]);
263 return makeDenseArray(node);
265 return makeSparseArray(node);
270 std::vector<ScalarOut>& values,
272 bool& allParameters) {
273 const std::vector<ActiveOut>* arrayActiveOut;
277 result = makeDenseArray(node);
280 result = makeSparseArray(node);
284 processArray(*arrayActiveOut, values, valuesDefined, allParameters);
290 CPPADCG_ASSERT_KNOWN(node.
getOperationType() == CGOpCode::ArrayCreation,
"Invalid array creation operation");
294 if (evals_[node] !=
nullptr) {
295 return *evals_[node];
298 if (outHandler_ ==
nullptr) {
299 throw CGException(
"Evaluator is unable to determine the new CodeHandler for an array creation operation");
303 const std::vector<ActiveOut>& array = this->evalArrayCreationOperation(node);
306 return *this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(CGOpCode::ArrayCreation, {}, asArguments(array))));
310 CPPADCG_ASSERT_KNOWN(node.
getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid sparse array creation operation");
314 if (evals_[node] !=
nullptr) {
315 return *evals_[node];
318 if (outHandler_ ==
nullptr) {
319 throw CGException(
"Evaluator is unable to determine the new CodeHandler for a sparse array creation operation");
323 const std::vector<ActiveOut>& array = this->evalSparseArrayCreationOperation(node);
326 return *this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(CGOpCode::SparseArrayCreation, node.
getInfo(), asArguments(array))));
329 static inline void processArray(
const std::vector<ActiveOut>& array,
330 std::vector<ScalarOut>& values,
332 bool& allParameters) {
333 values.resize(array.size());
334 for (
size_t i = 0; i < array.size(); i++) {
335 if (!array[i].isValueDefined()) {
336 valuesDefined =
false;
337 allParameters =
false;
340 values[i] = array[i].getValue();
341 if (!array[i].isParameter())
342 allParameters =
false;
348 for (
size_t i = 0; i < tx.size(); i++) {
349 if (!tx[i].isParameter()) {
356 static inline bool isValuesDefined(
const std::vector<ArgOut>& tx) {
357 for (
size_t i = 0; i < tx.size(); i++) {
358 if (tx[i].getOperationNode() !=
nullptr) {
370 template<
class ScalarIn,
class ScalarOut>
371 class Evaluator<ScalarIn, ScalarOut,
CG<ScalarOut> > :
public EvaluatorCG<ScalarIn, ScalarOut, Evaluator<ScalarIn, ScalarOut, CG<ScalarOut> > > {
CodeHandler< ScalarOut > * outHandler_
void evalAtomicOperation(const NodeIn &node)
const std::string * getName() const
const std::vector< Argument< Base > > & getArguments() const
bool printOutPriOperations_
size_t getHandlerPosition() const
std::map< const NodeIn *, std::vector< ScalarOut * > > atomicEvalResults_
void analyzeOutIndeps(const ActiveOut *indep, size_t n)
bool isPrintOutPrintOperations() const
CGOpCode getOperationType() const
void setPrintOutPrintOperations(bool print)
const std::map< size_t, CGAbstractAtomicFun< Base > *> & getAtomicFunctions() const
ActiveOut evalArrayElement(const NodeIn &node)
size_t getManagedNodesCount() const
void setName(const std::string &name)
void processActiveOut(const NodeIn &node, ActiveOut &a)
ActiveOut evalPrint(const NodeIn &node)
const std::vector< size_t > & getInfo() const