1 #ifndef CPPAD_CG_LANGUAGE_C_ARRAYS_INCLUDED 2 #define CPPAD_CG_LANGUAGE_C_ARRAYS_INCLUDED 22 void LanguageC<Base>::printArrayCreationOp(OperationNode<Base>& array) {
23 CPPADCG_ASSERT_KNOWN(array.getArguments().size() > 0,
"Invalid number of arguments for array creation operation");
24 const size_t id = getVariableID(array);
25 const std::vector<Argument<Base> >& args = array.getArguments();
26 const size_t argSize = args.size();
28 size_t startPos =
id - 1;
30 bool firstElement =
true;
31 for (
size_t i = 0; i < argSize; i++) {
32 bool newValue = !isSameArgument(args[i], _tmpArrayValues[startPos + i]);
36 _code << _indentation << auxArrayName_ <<
" = " << _nameGen->generateTemporaryArray(array, getVariableID(array)) <<
"; // size: " << args.size() <<
"\n";
41 size_t newI = printArrayCreationUsingLoop(startPos, array, i, _tmpArrayValues);
45 _code << _indentation << auxArrayName_ <<
"[" << i <<
"] = ";
49 _tmpArrayValues[startPos + i] = &args[i];
59 void LanguageC<Base>::printSparseArrayCreationOp(OperationNode<Base>& array) {
60 const std::vector<size_t>& info = array.getInfo();
61 CPPADCG_ASSERT_KNOWN(info.size() > 0,
"Invalid number of information elements for sparse array creation operation");
63 const std::vector<Argument<Base> >& args = array.getArguments();
64 const size_t argSize = args.size();
66 CPPADCG_ASSERT_KNOWN(info.size() == argSize + 1,
"Invalid number of arguments for sparse array creation operation");
71 const size_t id = getVariableID(array);
72 size_t startPos =
id - 1;
74 bool firstElement =
true;
75 for (
size_t i = 0; i < argSize; i++) {
76 bool newValue = !isSameArgument(args[i], _tmpSparseArrayValues[startPos + i]);
80 _code << _indentation << auxArrayName_ <<
" = " << _nameGen->generateTemporarySparseArray(array, getVariableID(array))
81 <<
"; // nnz: " << args.size() <<
" size:" << info[0] <<
"\n";
86 size_t newI = printArrayCreationUsingLoop(startPos, array, i, _tmpSparseArrayValues);
90 _code << _indentation << auxArrayName_ <<
"[" << i <<
"] = ";
94 _code << _C_SPARSE_INDEX_ARRAY <<
"[";
95 if (startPos != 0) _code << startPos <<
"+";
96 _code << i <<
"] = " << info[i + 1] <<
";\n";
98 _tmpSparseArrayValues[startPos + i] = &args[i];
102 for (
size_t j = i; j < newI; j++) {
103 _code << _indentation << _C_SPARSE_INDEX_ARRAY <<
"[";
104 if (startPos != 0) _code << startPos <<
"+";
105 _code << j <<
"] = " << info[j + 1] <<
";\n";
114 _code << _indentation
115 << _C_SPARSE_INDEX_ARRAY <<
"[";
116 if (startPos != 0) _code << startPos <<
"+";
117 _code << i <<
"] = " << info[i + 1] <<
";\n";
128 const std::vector<Argument<Base> >& args = array.
getArguments();
129 const size_t argSize = args.size();
130 size_t i = starti + 1;
132 std::ostringstream arrayAssign;
135 if (ref.getOperation() !=
nullptr) {
139 if (op == CGOpCode::Inv) {
143 for (; i < argSize; i++) {
144 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
147 if (args[i].getOperation() ==
nullptr ||
148 args[i].getOperation()->getOperationType() != CGOpCode::Inv ||
149 !_nameGen->isConsecutiveInIndepArray(*args[i - 1].getOperation(), getVariableID(*args[i - 1].getOperation()),
150 *args[i].getOperation(), getVariableID(*args[i].getOperation()))) {
159 const std::string& indep = _nameGen->getIndependentArrayName(refOp, getVariableID(refOp));
160 size_t start = _nameGen->getIndependentArrayIndex(refOp, getVariableID(refOp));
161 long offset = long(start) - starti;
163 arrayAssign << indep <<
"[i]";
165 arrayAssign << indep <<
"[" << offset <<
" + i]";
167 }
else if (op == CGOpCode::LoopIndexedIndep) {
171 size_t pos = refOp.
getInfo()[1];
172 IndexPattern* refIp = _info->loopIndependentIndexPatterns[pos];
177 if (refIp->getType() == IndexPatternType::Linear) {
179 }
else if (refIp->getType() == IndexPatternType::Sectioned) {
185 for (; i < argSize; i++) {
186 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
189 if (args[i].getOperation() ==
nullptr ||
190 args[i].getOperation()->getOperationType() != CGOpCode::LoopIndexedIndep) {
194 if (!_nameGen->isInSameIndependentArray(refOp, getVariableID(refOp),
195 *args[i].getOperation(), getVariableID(*args[i].getOperation())))
198 pos = args[i].getOperation()->getInfo()[1];
199 const IndexPattern* ip = _info->loopIndependentIndexPatterns[pos];
201 if (!isOffsetBy(ip, refIp,
long(i) -
long(starti))) {
209 std::unique_ptr<Plane2DIndexPattern> p2dip;
210 if (refLIp !=
nullptr) {
211 p2dip.reset(encapsulateIndexPattern(*refLIp, starti));
213 assert(refSecp !=
nullptr);
214 p2dip.reset(encapsulateIndexPattern(*refSecp, starti));
218 op2->getInfo()[1] = std::numeric_limits<size_t>::max();
219 op2->getArguments().push_back(_info->auxIterationIndexOp);
221 arrayAssign << _nameGen->generateIndexedIndependent(*op2, 0, *p2dip);
222 }
else if (getVariableID(refOp) >= this->_minTemporaryVarID && op != CGOpCode::LoopIndexedDep && op != CGOpCode::LoopIndexedTmp && op != CGOpCode::Tmp) {
226 for (; i < argSize; i++) {
227 if (isSameArgument(args[i], tmpArrayValues[startPos + i]))
229 else if (args[i].getOperation() ==
nullptr)
233 if (getVariableID(opNode2) < this->_minTemporaryVarID)
237 if (op2 == CGOpCode::LoopIndexedIndep || op2 == CGOpCode::LoopIndexedDep || op2 == CGOpCode::LoopIndexedTmp || op2 == CGOpCode::Tmp)
240 if (!_nameGen->isConsecutiveInTemporaryVarArray(*args[i - 1].getOperation(), getVariableID(*args[i - 1].getOperation()),
241 *args[i].getOperation(), getVariableID(*args[i].getOperation())))
249 const std::string& tmpName = _nameGen->getTemporaryVarArrayName(refOp, getVariableID(refOp));
250 size_t start = _nameGen->getTemporaryVarArrayIndex(refOp, getVariableID(refOp));
251 long offset = long(start) - starti;
253 arrayAssign << tmpName <<
"[i]";
255 arrayAssign << tmpName <<
"[" << offset <<
" + i]";
265 const Base& value = *args[starti].getParameter();
266 for (; i < argSize; i++) {
267 if (args[i].getParameter() ==
nullptr || *args[i].getParameter() != value) {
272 if (oldArg !=
nullptr && oldArg->getParameter() !=
nullptr && *oldArg->getParameter() == value) {
280 arrayAssign << value;
286 _code << _indentation <<
"for(i = " << starti <<
"; i < " << i <<
"; i++) " 287 << auxArrayName_ <<
"[i] = " << arrayAssign.str() <<
";\n";
292 for (
size_t ii = starti; ii < i; ii++) {
293 tmpArrayValues[startPos + ii] = &args[ii];
302 return _nameGen->generateTemporaryArray(op);
304 return _nameGen->generateTemporarySparseArray(op);
309 CPPADCG_ASSERT_KNOWN(op.
getArguments().size() == 2,
"Invalid number of arguments for array element operation");
310 CPPADCG_ASSERT_KNOWN(op.
getArguments()[0].getOperation() !=
nullptr,
"Invalid argument for array element operation");
311 CPPADCG_ASSERT_KNOWN(op.
getInfo().size() == 1,
"Invalid number of information indexes for array element operation");
314 std::string arrayName;
315 if (arrayOp.getOperationType() == CGOpCode::ArrayCreation)
316 arrayName = _nameGen->generateTemporaryArray(arrayOp, getVariableID(arrayOp));
318 arrayName = _nameGen->generateTemporarySparseArray(arrayOp, getVariableID(arrayOp));
320 _code <<
"(" << arrayName <<
")[" << op.
getInfo()[0] <<
"]";
329 _ss << dataArrayName <<
"[" << pos <<
"]";
330 printArrayStructInit(_ss.str(), *arrays[k]);
336 const std::string& aName = createVariableName(array);
339 auto itLast = _atomicFuncArrays.find(dataArrayName);
340 bool firstTime = itLast == _atomicFuncArrays.end() || itLast->second.scope != _info->scope[array];
341 AtomicFuncArray& lastArray = firstTime ? _atomicFuncArrays[dataArrayName] : itLast->second;
343 bool changed =
false;
350 if (firstTime || aName != lastArray.data) {
351 _code << _indentation;
352 _code << dataArrayName <<
".data = " << aName <<
"; ";
353 lastArray.data = aName;
357 if (firstTime ||
"NULL" != lastArray.data) {
358 if (!changed) _code << _indentation;
359 _code << dataArrayName <<
".data = NULL; ";
360 lastArray.data =
"NULL";
365 if (firstTime || size != lastArray.size) {
366 if (!changed) _code << _indentation;
367 _code << dataArrayName <<
".size = " << size <<
"; ";
368 lastArray.size = size;
371 if (firstTime || lastArray.sparse) {
372 if (!changed) _code << _indentation;
373 _code << dataArrayName <<
".sparse = " <<
false <<
";";
374 lastArray.sparse =
false;
379 CPPADCG_ASSERT_KNOWN(array.
getOperationType() == CGOpCode::SparseArrayCreation,
"Invalid node type");
381 size_t size = array.
getInfo()[0];
384 if (firstTime || aName != lastArray.data) {
385 _code << _indentation;
386 _code << dataArrayName <<
".data = " << aName <<
"; ";
387 lastArray.data = aName;
391 if (firstTime ||
"NULL" != lastArray.data) {
392 _code << _indentation;
393 _code << dataArrayName <<
".data = NULL; ";
394 lastArray.data =
"NULL";
399 if (firstTime || size != lastArray.size) {
400 if (!changed) _code << _indentation;
401 _code << dataArrayName <<
".size = " << size <<
"; ";
402 lastArray.size = size;
405 if (firstTime || !lastArray.sparse) {
406 if (!changed) _code << _indentation;
407 _code << dataArrayName <<
".sparse = " <<
true <<
"; ";
408 lastArray.sparse =
true;
411 if (firstTime || nnz != lastArray.nnz) {
412 if (!changed) _code << _indentation;
413 _code << dataArrayName <<
".nnz = " << nnz <<
"; ";
419 size_t id = getVariableID(array);
420 if (firstTime ||
id != lastArray.idx_id) {
421 if (!changed) _code << _indentation;
422 _code << dataArrayName <<
".idx = &(" << _C_SPARSE_INDEX_ARRAY <<
"[" << (
id - 1) <<
"]);";
423 lastArray.idx_id = id;
427 lastArray.idx_id = std::numeric_limits<size_t>::max();
431 lastArray.scope = _info->scope[array];
439 size_t id = getVariableID(ty);
443 for (
size_t i = 0; i < tySize; i++) {
444 _tmpArrayValues[
id - 1 + i] =
nullptr;
447 for (
size_t i = 0; i < tySize; i++) {
448 _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