Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit cb53a44

Browse files
rfrankeOpenModelica-Hudson
authored andcommitted
[Cpp] Implement array fill assignments
This prevents temporary arrays with all equal elements. Also fix the assignment of bool(ean) arrays in CodegenCpp.tpl. Belonging to [master]: - #2792 - OpenModelica/OpenModelica-testsuite#1078
1 parent e2321ae commit cb53a44

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

Compiler/Template/CodegenCpp.tpl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10989,19 +10989,22 @@ case eqn as SES_ARRAY_CALL_ASSIGN(lhs=lhs as CREF(__)) then
1098910989
'localData->helpVars[<%hidx%>] && !localData->helpVars_saved[<%hidx%>] /* edge */'
1099010990
;separator=" || ")C*/, &varDecls /*BUFD*/,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
1099110991
match expTypeFromExpShort(eqn.exp)
10992-
case "boolean"
10992+
case "bool"
1099310993
case "int" then
10994+
let lhsStr = cref1(lhs.componentRef, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, context, varDeclsCref, stateDerVectorName, useFlatArrayNotation)
1099410995
<<
1099510996
<%if not assignToStartValues then '<%startFixedExp%>'%>
1099610997
<%preExp%>
10997-
<%cref1(lhs.componentRef,simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace, context, varDeclsCref, stateDerVectorName, useFlatArrayNotation)%>=<%expPart%>;
10998+
<%lhsStr%>.assign(<%expPart%>);
1099810999
>>
1099911000
case "double" then
1100011001
<<
1100111002
<%if not assignToStartValues then '<%startFixedExp%>'%>
1100211003
<%preExp%>
1100311004
<%assignDerArray(context, expPart, lhs, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)%>
1100411005
>>
11006+
else
11007+
error(sourceInfo(), 'Unsupported type of array call assign: <%expTypeFromExpShort(eqn.exp)%>')
1100511008
end equationArrayCallAssign;
1100611009

1100711010
template assignDerArray(Context context, String arr, Exp lhs_ecr, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation)

SimulationRuntime/cpp/Include/Core/Math/Array.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ template<typename T> class BaseArray
8888
virtual T& operator()(const vector<size_t>& idx) = 0;
8989
virtual void assign(const T* data) = 0;
9090
virtual void assign(const BaseArray<T>& b) = 0;
91+
virtual void assign(const T& value) = 0; // fill value
9192
virtual std::vector<size_t> getDims() const = 0;
9293
virtual int getDim(size_t dim) const = 0; // { (int)getDims()[dim - 1]; }
93-
9494
virtual size_t getNumElems() const = 0;
9595
virtual size_t getNumDims() const = 0;
9696
virtual void setDims(const std::vector<size_t>& v) = 0;
@@ -271,6 +271,17 @@ class RefArray : public BaseArray<T>
271271
_ref_array, CopyCArray2RefArray<T>());
272272
}
273273

274+
/**
275+
* Assigns value reference to each array element
276+
* @param value new value for each element
277+
* a.assign(value)
278+
*/
279+
virtual void assign(const T& value)
280+
{
281+
for (size_t i = 0; i < nelems; i++)
282+
*_ref_array[i] = value;
283+
}
284+
274285
/**
275286
* Access to data (read-only)
276287
*/
@@ -757,6 +768,20 @@ class StatArray : public BaseArray<T>
757768
}
758769
}
759770

771+
/**
772+
* Assigns value to each array element
773+
* @param value new array value
774+
* a.assign(value)
775+
*/
776+
virtual void assign(const T& value)
777+
{
778+
if (nelems > 0) {
779+
if (_data == NULL)
780+
throw std::runtime_error("Cannot assign value to uninitialized StatArray!");
781+
std::fill(_data, _data + nelems, value);
782+
}
783+
}
784+
760785
/**
761786
* Access to data
762787
*/
@@ -1397,6 +1422,12 @@ class DynArray : public BaseArray<T>
13971422
std::copy(data, data + _nelems, _array_data);
13981423
}
13991424

1425+
virtual void assign(const T& value)
1426+
{
1427+
if (_nelems > 0)
1428+
std::fill(_array_data, _array_data + _nelems, value);
1429+
}
1430+
14001431
virtual void resize(const std::vector<size_t>& dims)
14011432
{
14021433
if (dims.size() != ndims)

SimulationRuntime/cpp/Include/Core/Math/ArraySlice.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ class ArraySliceConst: public BaseArray<T> {
176176
"Can't assign array to ArraySliceConst");
177177
}
178178

179+
virtual void assign(const T& value) {
180+
throw ModelicaSimulationError(MODEL_ARRAY_FUNCTION,
181+
"Can't assign value to ArraySliceConst");
182+
}
183+
179184
virtual std::vector<size_t> getDims() const {
180185
return _dims;
181186
}
@@ -340,6 +345,10 @@ class ArraySlice: public ArraySliceConst<T> {
340345
setDataDim(_idxs.size(), otherArray.getData());
341346
}
342347

348+
virtual void assign(const T& value) {
349+
setEachDim(_idxs.size(), value);
350+
}
351+
343352
virtual T& operator()(size_t i) {
344353
return _baseArray(ArraySliceConst<T>::baseIdx(1, &i));
345354
}
@@ -390,5 +399,25 @@ class ArraySlice: public ArraySliceConst<T> {
390399
}
391400
return processed;
392401
}
402+
403+
/**
404+
* recursive method for muli-dimensional fill of each element
405+
*/
406+
void setEachDim(size_t dim, const T& value) {
407+
const BaseArray<int> *iset = ArraySliceConst<T>::_isets[dim - 1];
408+
size_t size = iset? iset->getNumElems(): _idxs[dim - 1].size();
409+
if (size == 0)
410+
size = _baseArray.getDim(dim);
411+
for (size_t i = 1; i <= size; i++) {
412+
if (iset)
413+
_baseIdx[dim - 1] = iset->getNumElems() > 0? (*iset)(i): i;
414+
else
415+
_baseIdx[dim - 1] = _idxs[dim - 1].size() > 0? _idxs[dim - 1][i - 1]: i;
416+
if (dim > 1)
417+
setEachDim(dim - 1, value);
418+
else
419+
_baseArray(_baseIdx) = value;
420+
}
421+
}
393422
};
394423
/** @} */ // end of math

0 commit comments

Comments
 (0)