1 #ifndef CPPAD_CG_EVALUATOR_CG_INCLUDED 2 #define CPPAD_CG_EVALUATOR_CG_INCLUDED 26 template<
class ScalarIn,
class ScalarOut,
class FinalEvaluatorType>
63 printOutPriOperations_(true) {
71 printOutPriOperations_ = print;
90 CPPAD_ASSERT_KNOWN(indep !=
nullptr || n == 0,
"null array with a non-zero size");
101 for (
const auto& it : atomicEvalResults_) {
102 for (
const ScalarOut* e : it.second) {
106 atomicEvalResults_.clear();
116 if (node.
getName() !=
nullptr) {
117 if (a.getOperationNode() !=
nullptr) {
129 CPPADCG_ASSERT_KNOWN(args.size() == 1,
"Invalid number of arguments for print()")
132 if (printOutPriOperations_) {
134 std::cout << nodePri.getBeforeString() << out << nodePri.getAfterString();
137 if (out.getOperationNode() !=
nullptr) {
139 ActiveOut out2(*outHandler_->makePrintNode(nodePri.getBeforeString(), *out.getOperationNode(), nodePri.getAfterString()));
140 if (out.isValueDefined())
141 out2.setValue(out.getValue());
154 CPPADCG_ASSERT_KNOWN(op == CGOpCode::AtomicForward || op == CGOpCode::AtomicReverse,
155 "Invalid operation type")
158 if (evals_[node] !=
nullptr) {
162 const std::vector<size_t>& info = node.
getInfo();
163 const std::vector<Argument<ScalarIn> >& inArgs = node.
getArguments();
165 CPPADCG_ASSERT_KNOWN(info.size() == 3,
"Invalid number of information data for atomic operation")
169 CPPADCG_ASSERT_KNOWN(inArgs.size() == 2 * p1,
"Invalid number of information data for atomic operation")
171 if (outHandler_ ==
nullptr) {
172 throw CGException(
"Evaluator is unable to determine the new CodeHandler for an atomic operation");
175 std::vector<Argument<ScalarOut> > outArgs(inArgs.size());
177 std::vector<std::vector<ScalarOut>> outVals(inArgs.size());
178 bool valuesDefined =
true;
179 bool allParameters =
true;
181 for (
size_t i = 0; i < inArgs.size(); i++) {
182 auto* a = inArgs[i].getOperation();
183 CPPADCG_ASSERT_KNOWN(a !=
nullptr,
"Invalid argument for atomic operation")
185 outArgs[i] = asArgument(makeArray(*a, outVals[i], valuesDefined, allParameters));
188 this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(op, info, outArgs)));
191 const std::map<size_t, CGAbstractAtomicFun<ScalarIn>*>& afun = this->handler_.
getAtomicFunctions();
194 if (op == CGOpCode::AtomicForward) {
195 auto itAFun = afun.find(
id);
196 if (itAFun == afun.end()) {
198 throw CGException(
"Atomic function for ID ",
id,
" is not defined in evaluator");
202 auto& atomic = *itAFun->second;
206 for (
size_t i = 0; i < tx.size(); ++i)
208 for (
size_t i = 0; i < ty.size(); ++i)
211 atomic.forward(q, p, vx, vy, tx, ty);
213 std::vector<ScalarOut*>& yOut = atomicEvalResults_[&node];
214 assert(yOut.empty());
215 yOut.resize(ty.size());
216 for (
size_t i = 0; i < ty.size(); ++i) {
217 if (ty[i].isValueDefined())
218 yOut[i] =
new ScalarOut(ty[i].getValue());
231 if (evals_[node] !=
nullptr) {
232 return *evals_[node];
236 const std::vector<size_t>& info = node.
getInfo();
237 CPPADCG_ASSERT_KNOWN(args.size() == 2,
"Invalid number of arguments for array element")
238 CPPADCG_ASSERT_KNOWN(args[0].getOperation() !=
nullptr,
"Invalid argument for array element")
239 CPPADCG_ASSERT_KNOWN(args[1].getOperation() !=
nullptr,
"Invalid argument for array element")
240 CPPADCG_ASSERT_KNOWN(info.size() == 1,
"Invalid number of information data for array element")
241 size_t index = info[0];
243 ArgOut arrayArg = asArgument(makeArray(*args[0].getOperation()));
245 auto& thisOps =
static_cast<FinalEvaluatorType&
>(*this);
246 const NodeIn& atomicNode = *args[1].getOperation();
247 thisOps.evalAtomicOperation(atomicNode);
248 ArgOut atomicArg = *evals_[atomicNode]->getOperationNode();
250 ActiveOut out(*outHandler_->makeNode(CGOpCode::ArrayElement, {index}, {arrayArg, atomicArg}));
252 auto it = atomicEvalResults_.find(&atomicNode);
253 if (it != atomicEvalResults_.end()) {
254 const std::vector<ScalarOut*>& yOut = it->second;
255 if (index < yOut.size() && yOut[index] !=
nullptr)
256 out.setValue(*yOut[index]);
264 return makeDenseArray(node);
266 return makeSparseArray(node);
271 std::vector<ScalarOut>& values,
273 bool& allParameters) {
274 const std::vector<ActiveOut>* arrayActiveOut;
278 result = makeDenseArray(node);
281 result = makeSparseArray(node);
285 processArray(*arrayActiveOut, values, valuesDefined, allParameters);
291 CPPADCG_ASSERT_KNOWN(node.
getOperationType() == CGOpCode::ArrayCreation,
"Invalid array creation operation")
295 if (evals_[node] !=
nullptr) {
296 return *evals_[node];
299 if (outHandler_ ==
nullptr) {
300 throw CGException(
"Evaluator is unable to determine the new CodeHandler for an array creation operation");
304 const std::vector<ActiveOut>& array = this->evalArrayCreationOperation(node);
307 return *this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(CGOpCode::ArrayCreation, {}, asArguments(array))));
311 CPPADCG_ASSERT_KNOWN(node.
getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid sparse array creation operation")
315 if (evals_[node] !=
nullptr) {
316 return *evals_[node];
319 if (outHandler_ ==
nullptr) {
320 throw CGException(
"Evaluator is unable to determine the new CodeHandler for a sparse array creation operation");
324 const std::vector<ActiveOut>& array = this->evalSparseArrayCreationOperation(node);
327 return *this->saveEvaluation(node,
ActiveOut(*outHandler_->makeNode(CGOpCode::SparseArrayCreation, node.
getInfo(), asArguments(array))));
330 static inline void processArray(
const std::vector<ActiveOut>& array,
331 std::vector<ScalarOut>& values,
333 bool& allParameters) {
334 values.resize(array.size());
335 for (
size_t i = 0; i < array.size(); i++) {
336 if (!array[i].isValueDefined()) {
337 valuesDefined =
false;
338 allParameters =
false;
341 values[i] = array[i].getValue();
342 if (!array[i].isParameter())
343 allParameters =
false;
349 for (
size_t i = 0; i < tx.size(); i++) {
350 if (!tx[i].isParameter()) {
357 static inline bool isValuesDefined(
const std::vector<ArgOut>& tx) {
358 for (
size_t i = 0; i < tx.size(); i++) {
359 if (tx[i].getOperationNode() !=
nullptr) {
371 template<
class ScalarIn,
class ScalarOut>
372 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