1 #ifndef CPPAD_CG_LANGUAGE_C_ARRAYS_INCLUDED 2 #define CPPAD_CG_LANGUAGE_C_ARRAYS_INCLUDED 23 void LanguageC<Base>::pushArrayCreationOp(OperationNode <Base>& array) {
24 CPPADCG_ASSERT_KNOWN(array.getArguments().size() > 0,
"Invalid number of arguments for array creation operation")
25 const size_t id = getVariableID(array);
26 const std::vector<Argument<Base> >& args = array.getArguments();
27 const size_t argSize = args.size();
29 size_t startPos =
id - 1;
31 bool firstElement =
true;
32 for (
size_t i = 0; i < argSize; i++) {
33 bool newValue = !isSameArgument(args[i], _tmpArrayValues[startPos + i]);
37 _streamStack << _indentation << auxArrayName_ <<
" = " << _nameGen->generateTemporaryArray(array, getVariableID(array)) <<
"; // size: " << args.size() <<
"\n";
42 size_t newI = printArrayCreationUsingLoop(startPos, array, i, _tmpArrayValues);
46 _streamStack << _indentation << auxArrayName_ <<
"[" << i <<
"] = ";
48 _streamStack <<
";\n";
50 _tmpArrayValues[startPos + i] = &args[i];
60 void LanguageC<Base>::pushSparseArrayCreationOp(OperationNode <Base>& array) {
61 const std::vector<size_t>& info = array.getInfo();
62 CPPADCG_ASSERT_KNOWN(!info.empty(),
"Invalid number of information elements for sparse array creation operation")
64 const std::vector<Argument<Base> >& args = array.getArguments();
65 const size_t argSize = args.size();
67 CPPADCG_ASSERT_KNOWN(info.size() == argSize + 1,
"Invalid number of arguments for sparse array creation operation")
72 const
size_t id = getVariableID(array);
73 size_t startPos =
id - 1;
75 bool firstElement = true;
76 for (
size_t i = 0; i < argSize; i++) {
77 bool newValue = !isSameArgument(args[i], _tmpSparseArrayValues[startPos + i]);
81 _streamStack << _indentation << auxArrayName_ <<
" = " << _nameGen->generateTemporarySparseArray(array, getVariableID(array))
82 <<
"; // nnz: " << args.size() <<
" size:" << info[0] <<
"\n";
87 size_t newI = printArrayCreationUsingLoop(startPos, array, i, _tmpSparseArrayValues);
91 _streamStack << _indentation << auxArrayName_ <<
"[" << i <<
"] = ";
95 _streamStack << _C_SPARSE_INDEX_ARRAY <<
"[";
96 if (startPos != 0) _streamStack << startPos <<
"+";
97 _streamStack << i <<
"] = " << info[i + 1] <<
";\n";
99 _tmpSparseArrayValues[startPos + i] = &args[i];
103 for (
size_t j = i; j < newI; j++) {
104 _streamStack << _indentation << _C_SPARSE_INDEX_ARRAY <<
"[";
105 if (startPos != 0) _streamStack << startPos <<
"+";
106 _streamStack << j <<
"] = " << info[j + 1] <<
";\n";
115 _streamStack << _indentation
116 << _C_SPARSE_INDEX_ARRAY <<
"[";
117 if (startPos != 0) _streamStack << startPos <<
"+";
118 _streamStack << i <<
"] = " << info[i + 1] <<
";\n";
129 const std::vector<Argument<Base> >& args = array.
getArguments();
130 const size_t argSize = args.size();
131 size_t i = starti + 1;
133 std::ostringstream arrayAssign;
136 if (ref.getOperation() !=
nullptr) {
140 if (op == CGOpCode::Inv) {
144 for (; i < argSize; i++) {
145 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
148 if (args[i].getOperation() ==
nullptr ||
149 args[i].getOperation()->getOperationType() != CGOpCode::Inv ||
150 !_nameGen->isConsecutiveInIndepArray(*args[i - 1].getOperation(), getVariableID(*args[i - 1].getOperation()),
151 *args[i].getOperation(), getVariableID(*args[i].getOperation()))) {
160 const std::string& indep = _nameGen->getIndependentArrayName(refOp, getVariableID(refOp));
161 size_t start = _nameGen->getIndependentArrayIndex(refOp, getVariableID(refOp));
162 long offset = long(start) - starti;
164 arrayAssign << indep <<
"[i]";
166 arrayAssign << indep <<
"[" << offset <<
" + i]";
168 }
else if (op == CGOpCode::LoopIndexedIndep) {
172 size_t pos = refOp.
getInfo()[1];
173 IndexPattern* refIp = _info->loopIndependentIndexPatterns[pos];
178 if (refIp->getType() == IndexPatternType::Linear) {
180 }
else if (refIp->getType() == IndexPatternType::Sectioned) {
186 for (; i < argSize; i++) {
187 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
190 if (args[i].getOperation() ==
nullptr ||
191 args[i].getOperation()->getOperationType() != CGOpCode::LoopIndexedIndep) {
195 if (!_nameGen->isInSameIndependentArray(refOp, getVariableID(refOp),
196 *args[i].getOperation(), getVariableID(*args[i].getOperation())))
199 pos = args[i].getOperation()->getInfo()[1];
200 const IndexPattern* ip = _info->loopIndependentIndexPatterns[pos];
202 if (!isOffsetBy(ip, refIp,
long(i) -
long(starti))) {
210 std::unique_ptr<Plane2DIndexPattern> p2dip;
211 if (refLIp !=
nullptr) {
212 p2dip.reset(encapsulateIndexPattern(*refLIp, starti));
214 assert(refSecp !=
nullptr);
215 p2dip.reset(encapsulateIndexPattern(*refSecp, starti));
219 op2->getInfo()[1] = (std::numeric_limits<size_t>::max)();
220 op2->getArguments().push_back(_info->auxIterationIndexOp);
222 arrayAssign << _nameGen->generateIndexedIndependent(*op2, 0, *p2dip);
223 }
else if (getVariableID(refOp) >= this->_minTemporaryVarID && op != CGOpCode::LoopIndexedDep && op != CGOpCode::LoopIndexedTmp && op != CGOpCode::Tmp) {
227 for (; i < argSize; i++) {
228 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
230 else if (args[i].getOperation() ==
nullptr)
234 if (getVariableID(opNode2) < this->_minTemporaryVarID)
238 if (op2 == CGOpCode::LoopIndexedIndep || op2 == CGOpCode::LoopIndexedDep || op2 == CGOpCode::LoopIndexedTmp || op2 == CGOpCode::Tmp)
241 if (!_nameGen->isConsecutiveInTemporaryVarArray(*args[i - 1].getOperation(), getVariableID(*args[i - 1].getOperation()),
242 *args[i].getOperation(), getVariableID(*args[i].getOperation())))
250 const std::string& tmpName = _nameGen->getTemporaryVarArrayName(refOp, getVariableID(refOp));
251 size_t start = _nameGen->getTemporaryVarArrayIndex(refOp, getVariableID(refOp));
252 long offset = long(start) - starti;
254 arrayAssign << tmpName <<
"[i]";
256 arrayAssign << tmpName <<
"[" << offset <<
" + i]";
266 const Base& value = *args[starti].getParameter();
267 for (; i < argSize; i++) {
268 if (args[i].getParameter() ==
nullptr || *args[i].getParameter() != value) {
273 if (oldArg !=
nullptr && oldArg->getParameter() !=
nullptr && *oldArg->getParameter() == value) {
281 arrayAssign << value;
287 _streamStack << _indentation <<
"for(i = " << starti <<
"; i < " << i <<
"; i++) " 288 << auxArrayName_ <<
"[i] = " << arrayAssign.str() <<
";\n";
293 for (
size_t ii = starti; ii < i; ii++) {
294 tmpArrayValues[startPos + ii] = &args[ii];
303 return _nameGen->generateTemporaryArray(op);
305 return _nameGen->generateTemporarySparseArray(op);
310 CPPADCG_ASSERT_KNOWN(op.
getArguments().size() == 2,
"Invalid number of arguments for array element operation")
311 CPPADCG_ASSERT_KNOWN(op.
getArguments()[0].getOperation() !=
nullptr,
"Invalid argument for array element operation")
312 CPPADCG_ASSERT_KNOWN(op.
getInfo().size() == 1,
"Invalid number of information indexes for array element operation")
315 std::string arrayName;
316 if (arrayOp.getOperationType() == CGOpCode::ArrayCreation)
317 arrayName = _nameGen->generateTemporaryArray(arrayOp, getVariableID(arrayOp));
319 arrayName = _nameGen->generateTemporarySparseArray(arrayOp, getVariableID(arrayOp));
321 _streamStack <<
"(" << arrayName <<
")[" << op.
getInfo()[0] <<
"]";
330 _ss << dataArrayName <<
"[" << pos <<
"]";
331 printArrayStructInit(_ss.str(), *arrays[k]);
337 const std::string& aName = createVariableName(array);
340 auto itLast = _atomicFuncArrays.find(dataArrayName);
341 bool firstTime = itLast == _atomicFuncArrays.end() || itLast->second.scope != _info->scope[array];
342 AtomicFuncArray& lastArray = firstTime ? _atomicFuncArrays[dataArrayName] : itLast->second;
344 bool changed =
false;
351 if (firstTime || aName != lastArray.data) {
352 _streamStack << _indentation;
353 _streamStack << dataArrayName <<
".data = " << aName <<
"; ";
354 lastArray.data = aName;
358 if (firstTime ||
"NULL" != lastArray.data) {
359 _streamStack << _indentation;
360 _streamStack << dataArrayName <<
".data = NULL; ";
361 lastArray.data =
"NULL";
366 if (firstTime || size != lastArray.size) {
367 if (!changed) _streamStack << _indentation;
368 _streamStack << dataArrayName <<
".size = " << size <<
"; ";
369 lastArray.size = size;
372 if (firstTime || lastArray.sparse) {
373 if (!changed) _streamStack << _indentation;
374 _streamStack << dataArrayName <<
".sparse = " <<
false <<
";";
375 lastArray.sparse =
false;
380 CPPADCG_ASSERT_KNOWN(array.
getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid node type")
382 size_t size = array.
getInfo()[0];
385 if (firstTime || aName != lastArray.data) {
386 _streamStack << _indentation;
387 _streamStack << dataArrayName <<
".data = " << aName <<
"; ";
388 lastArray.data = aName;
392 if (firstTime ||
"NULL" != lastArray.data) {
393 _streamStack << _indentation;
394 _streamStack << dataArrayName <<
".data = NULL; ";
395 lastArray.data =
"NULL";
400 if (firstTime || size != lastArray.size) {
401 if (!changed) _streamStack << _indentation;
402 _streamStack << dataArrayName <<
".size = " << size <<
"; ";
403 lastArray.size = size;
406 if (firstTime || !lastArray.sparse) {
407 if (!changed) _streamStack << _indentation;
408 _streamStack << dataArrayName <<
".sparse = " <<
true <<
"; ";
409 lastArray.sparse =
true;
412 if (firstTime || nnz != lastArray.nnz) {
413 if (!changed) _streamStack << _indentation;
414 _streamStack << dataArrayName <<
".nnz = " << nnz <<
"; ";
420 size_t id = getVariableID(array);
421 if (firstTime ||
id != lastArray.idx_id) {
422 if (!changed) _streamStack << _indentation;
423 _streamStack << dataArrayName <<
".idx = &(" << _C_SPARSE_INDEX_ARRAY <<
"[" << (
id - 1) <<
"]);";
424 lastArray.idx_id = id;
428 lastArray.idx_id = (std::numeric_limits<size_t>::max)();
432 lastArray.scope = _info->scope[array];
435 _streamStack <<
"\n";
440 size_t id = getVariableID(ty);
444 for (
size_t i = 0; i < tySize; i++) {
445 _tmpArrayValues[
id - 1 + i] =
nullptr;
448 for (
size_t i = 0; i < tySize; i++) {
449 _tmpSparseArrayValues[
id - 1 + i] =
nullptr;
const std::vector< Argument< Base > > & getArguments() const
CGOpCode getOperationType() const
size_t printArrayCreationUsingLoop(size_t startPos, Node &array, size_t startj, std::vector< const Arg *> &tmpArrayValues)
const std::vector< size_t > & getInfo() const