1 #ifndef CPPAD_CG_EVALUATOR_CG_INCLUDED
2 #define CPPAD_CG_EVALUATOR_CG_INCLUDED
26 template<
class ScalarIn,
class ScalarOut,
class FinalEvaluatorType>
90 CPPAD_ASSERT_KNOWN(indep !=
nullptr || n == 0,
"null array with a non-zero size");
102 for (
const ScalarOut* e : it.second) {
116 if (node.
getName() !=
nullptr) {
117 if (a.getOperationNode() !=
nullptr) {
118 a.getOperationNode()->setName(*node.
getName());
129 CPPADCG_ASSERT_KNOWN(args.size() == 1,
"Invalid number of arguments for print()")
134 std::cout << nodePri.getBeforeString() << out << nodePri.getAfterString();
137 if (out.getOperationNode() !=
nullptr) {
139 ActiveOut out2(*
outHandler_->makePrintNode(nodePri.getBeforeString(), *out.getOperationNode(), nodePri.getAfterString()));
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")
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));
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);
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();
254 const std::vector<ScalarOut*>& yOut = it->second;
255 if (index < yOut.size() && yOut[index] !=
nullptr)
262 inline ActiveOut makeArray(
const NodeIn& node) {
263 if (node.getOperationType() == CGOpCode::ArrayCreation) {
264 return makeDenseArray(node);
266 return makeSparseArray(node);
270 inline ActiveOut makeArray(
const NodeIn& node,
271 std::vector<ScalarOut>& values,
273 bool& allParameters) {
274 const std::vector<ActiveOut>* arrayActiveOut;
277 if (node.getOperationType() == CGOpCode::ArrayCreation) {
278 result = makeDenseArray(node);
279 arrayActiveOut = this->evalsArrays_[node.getHandlerPosition()];
281 result = makeSparseArray(node);
282 arrayActiveOut = this->evalsSparseArrays_[node.getHandlerPosition()];
285 processArray(*arrayActiveOut, values, valuesDefined, allParameters);
290 inline ActiveOut makeDenseArray(
const NodeIn& node) {
291 CPPADCG_ASSERT_KNOWN(node.getOperationType() == CGOpCode::ArrayCreation,
"Invalid array creation operation")
292 CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < this->handler_.getManagedNodesCount(), "this node is not managed by the code handler")
295 if (evals_[node] !=
nullptr) {
296 return *evals_[node];
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))));
310 inline ActiveOut makeSparseArray(
const NodeIn& node) {
311 CPPADCG_ASSERT_KNOWN(node.getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid sparse array creation operation")
312 CPPADCG_ASSERT_KNOWN(node.getHandlerPosition() < this->handler_.getManagedNodesCount(), "this node is not managed by the code handler")
315 if (evals_[node] !=
nullptr) {
316 return *evals_[node];
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> > > {
void setValue(const Base &val)
const Base & getValue() const
bool isValueDefined() const
const std::map< size_t, CGAbstractAtomicFun< Base > * > & getAtomicFunctions() const
void evalAtomicOperation(const NodeIn &node)
void processActiveOut(const NodeIn &node, ActiveOut &a)
bool printOutPriOperations_
ActiveOut evalArrayElement(const NodeIn &node)
ActiveOut evalPrint(const NodeIn &node)
CodeHandler< ScalarOut > * outHandler_
bool isPrintOutPrintOperations() const
void analyzeOutIndeps(const ActiveOut *indep, size_t n)
std::map< const NodeIn *, std::vector< ScalarOut * > > atomicEvalResults_
void setPrintOutPrintOperations(bool print)
const std::string * getName() const
const std::vector< size_t > & getInfo() const
CGOpCode getOperationType() const
const std::vector< Argument< Base > > & getArguments() const