46 friend FinalEvaluatorType;
48 using SourceCodePath =
typename CodeHandler<ScalarIn>::SourceCodePath;
51 const ActiveOut* indep_;
53 std::map<size_t, std::vector<ActiveOut>* > evalsArrays_;
54 std::map<size_t, std::vector<ActiveOut>* > evalsSparseArrays_;
118 throw CGException(
"Dependent array sizes are different.");
149 throw CGException(
"The same evaluator cannot be used for simultaneous evaluations. "
150 "Either use a new one or wait for this one to finish its current evaluation.");
161 if(path_.capacity() == 0) {
165 FinalEvaluatorType&
thisOps =
static_cast<FinalEvaluatorType&
>(*this);
168 thisOps.prepareNewEvaluation();
174 CPPADCG_ASSERT_UNKNOWN(depth_ == 0);
190 inline void prepareNewEvaluation() {
200 for (
const auto&
p : evalsArrays_) {
203 evalsArrays_.clear();
205 for (
const auto&
p : evalsSparseArrays_) {
208 evalsSparseArrays_.clear();
211 inline void analyzeOutIndeps(
const ActiveOut*
indep,
217 if (
dep.isParameter()) {
219 return ActiveOut(
dep.getValue());
221 return evalOperations(*
dep.getOperationNode());
225 inline ActiveOut evalArg(
const std::vector<Argument<ScalarIn> >&
args,
230 inline ActiveOut evalArg(
const Argument<ScalarIn>&
arg,
232 if (
arg.getOperation() !=
nullptr) {
233 path_.back().argIndex =
pos;
234 ActiveOut
a = evalOperations(*
arg.getOperation());
238 return ActiveOut(*
arg.getParameter());
242 inline const ActiveOut& evalOperations(OperationNode<ScalarIn>& node) {
243 CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < handler_.
getManagedNodesCount(),
"this node is not managed by the code handler")
246 if (evals_[node] !=
nullptr) {
247 return *evals_[node];
251 FinalEvaluatorType&
thisOps =
static_cast<FinalEvaluatorType&
>(*this);
267 inline ActiveOut* saveEvaluation(
const OperationNode<ScalarIn>& node,
269 std::unique_ptr<ActiveOut>&
resultPtr = evals_[node];
270 CPPADCG_ASSERT_UNKNOWN(
resultPtr ==
nullptr);
275 FinalEvaluatorType&
thisOps =
static_cast<FinalEvaluatorType&
>(*this);
281 inline std::vector<ActiveOut>& evalArrayCreationOperation(
const OperationNode<ScalarIn>& node) {
283 CPPADCG_ASSERT_KNOWN(node.getOperationType() == CGOpCode::ArrayCreation,
"Invalid array creation operation");
284 CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < handler_.
getManagedNodesCount(),
"this node is not managed by the code handler")
287 auto it = evalsArrays_.find(node.getHandlerPosition());
288 if (
it != evalsArrays_.end()) {
292 const std::vector<Argument<ScalarIn> >&
args = node.getArguments();
296 evalsArrays_[node.getHandlerPosition()] =
resultArray;
299 for (
size_t a = 0;
a <
args.size();
a++) {
300 (*resultArray)[
a] = evalArg(
args,
a);
308 CPPADCG_ASSERT_KNOWN(node.
getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid array creation operation");
313 if (
it != evalsSparseArrays_.end()) {
324 for (
size_t a = 0;
a <
args.size();
a++) {
325 (*resultArray)[
a] = evalArg(
args,
a);
375 FinalEvaluatorType&
thisOps =
static_cast<FinalEvaluatorType&
>(*this);
379 case CGOpCode::Assign:
380 return thisOps.evalAssign(node);
391 case CGOpCode::Alias:
392 return thisOps.evalAlias(node);
395 case CGOpCode::ArrayElement:
396 return thisOps.evalArrayElement(node);
406 case CGOpCode::ComLt:
407 return thisOps.evalCompareLt(node);
409 case CGOpCode::ComLe:
410 return thisOps.evalCompareLe(node);
412 case CGOpCode::ComEq:
413 return thisOps.evalCompareEq(node);
415 case CGOpCode::ComGe:
416 return thisOps.evalCompareGe(node);
418 case CGOpCode::ComGt:
419 return thisOps.evalCompareGt(node);
421 case CGOpCode::ComNe:
422 return thisOps.evalCompareNe(node);
437 return thisOps.evalIndependent(node);
449 return thisOps.evalPrint(node);
473 case CGOpCode::UnMinus:
474 return thisOps.evalMinus(node);
477 return thisOps.evalUnsupportedOperation(node);
481 inline ActiveOut evalAssign(
const NodeIn& node) {
482 const std::vector<ArgIn>&
args = node.getArguments();
483 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for assign()")
488 const std::vector<ArgIn>&
args = node.getArguments();
489 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for abs()")
494 const std::vector<ArgIn>&
args = node.getArguments();
495 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for acos()")
500 const std::vector<ArgIn>&
args = node.getArguments();
501 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for addition")
506 const std::vector<ArgIn>&
args = node.getArguments();
507 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for alias")
511 inline ActiveOut evalArrayElement(
const NodeIn& node) {
512 const std::vector<ArgIn>&
args = node.getArguments();
513 const std::vector<size_t>&
info = node.getInfo();
514 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for array element")
518 size_t index =
info[0];
519 std::
vector<ActiveOut>& array =
this->evalArrayCreationOperation(*
args[0].getOperation());
522 thisOps.evalAtomicOperation(*
args[1].getOperation());
528 const std::vector<ArgIn>&
args = node.getArguments();
529 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for asin()")
534 const std::vector<ArgIn>&
args = node.getArguments();
535 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for atan()")
539 inline ActiveOut evalCompareLt(
const NodeIn& node) {
540 const std::vector<ArgIn>&
args = node.getArguments();
541 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareLt, )")
545 inline ActiveOut evalCompareLe(
const NodeIn& node) {
546 const std::vector<ArgIn>&
args = node.getArguments();
547 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareLe, )")
551 inline ActiveOut evalCompareEq(
const NodeIn& node) {
552 const std::vector<ArgIn>&
args = node.getArguments();
553 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareEq, )")
557 inline ActiveOut evalCompareGe(
const NodeIn& node) {
558 const std::vector<ArgIn>&
args = node.getArguments();
559 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareGe, )")
563 inline ActiveOut evalCompareGt(
const NodeIn& node) {
564 const std::vector<ArgIn>&
args = node.getArguments();
565 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareGt, )")
569 inline ActiveOut evalCompareNe(
const NodeIn& node) {
570 const std::vector<ArgIn>&
args = node.getArguments();
571 CPPADCG_ASSERT_KNOWN(
args.size() == 4,
"Invalid number of arguments for CondExpOp(CompareNe, )")
576 const std::vector<ArgIn>&
args = node.getArguments();
577 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for cosh()")
582 const std::vector<ArgIn>&
args = node.getArguments();
583 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for cos()")
588 const std::vector<ArgIn>&
args = node.getArguments();
589 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for division")
594 const std::vector<ArgIn>&
args = node.getArguments();
595 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for exp()")
599 inline ActiveOut evalIndependent(
const NodeIn& node) {
601 return this->indep_[index];
604 inline ActiveOut evalLog(
const NodeIn& node) {
605 const std::vector<ArgIn>&
args = node.getArguments();
606 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for log()")
611 const std::vector<ArgIn>&
args = node.getArguments();
612 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for multiplication")
617 const std::vector<ArgIn>&
args = node.getArguments();
618 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for pow()")
623 FinalEvaluatorType&
thisOps =
static_cast<FinalEvaluatorType&
>(*this);
624 return thisOps.evalUnsupportedOperation(node);
628 inline ActiveOut evalSign(
const NodeIn& node) {
629 const std::vector<ArgIn>&
args = node.getArguments();
630 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for sign()")
635 const std::vector<ArgIn>&
args = node.getArguments();
636 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for sinh()")
641 const std::vector<ArgIn>&
args = node.getArguments();
642 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for sin()")
647 const std::vector<ArgIn>&
args = node.getArguments();
648 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for sqrt()")
653 const std::vector<ArgIn>&
args = node.getArguments();
654 CPPADCG_ASSERT_KNOWN(
args.size() == 2,
"Invalid number of arguments for subtraction")
659 const std::vector<ArgIn>&
args = node.getArguments();
660 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for tanh()")
665 const std::vector<ArgIn>&
args = node.getArguments();
666 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for tan()")
671 const std::vector<ArgIn>&
args = node.getArguments();
672 CPPADCG_ASSERT_KNOWN(
args.size() == 1,
"Invalid number of arguments for unary minus")
676 inline ActiveOut evalUnsupportedOperation(
const NodeIn& node) {
677 throw CGException(
"Unknown operation code '", node.getOperationType(),
"'");
680 inline void evalAtomicOperation(
const NodeIn& node) {
681 throw CGException(
"Evaluator is unable to handle atomic functions for these variable types");
684 inline void processActiveOut(
const NodeIn& node,