OMCompiler/Compiler/Template/CodegenCppHpcom.tpl
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /* | ||
| 2 | * This file is part of OpenModelica. | ||
| 3 | * | ||
| 4 | * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), | ||
| 5 | * c/o Linköpings universitet, Department of Computer and Information Science, | ||
| 6 | * SE-58183 Linköping, Sweden. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF AGPL VERSION 3 LICENSE OR | ||
| 11 | * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. | ||
| 12 | * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES | ||
| 13 | * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GNU AGPL | ||
| 14 | * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. | ||
| 15 | * | ||
| 16 | * The OpenModelica software and the OSMC (Open Source Modelica Consortium) | ||
| 17 | * Public License (OSMC-PL) are obtained from OSMC, either from the above | ||
| 18 | * address, from the URLs: | ||
| 19 | * http://www.openmodelica.org or | ||
| 20 | * https://github.com/OpenModelica/ or | ||
| 21 | * http://www.ida.liu.se/projects/OpenModelica, | ||
| 22 | * and in the OpenModelica distribution. | ||
| 23 | * | ||
| 24 | * GNU AGPL version 3 is obtained from: | ||
| 25 | * https://www.gnu.org/licenses/licenses.html#GPL | ||
| 26 | * | ||
| 27 | * This program is distributed WITHOUT ANY WARRANTY; without | ||
| 28 | * even the implied warranty of MERCHANTABILITY or FITNESS | ||
| 29 | * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH | ||
| 30 | * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. | ||
| 31 | * | ||
| 32 | * See the full OSMC Public License conditions for more details. | ||
| 33 | * | ||
| 34 | */ | ||
| 35 | |||
| 36 | // This file defines template-extensions for transforming Modelica code into parallel hpcom-code. | ||
| 37 | // | ||
| 38 | // There are one root template intended to be called from the code generator: | ||
| 39 | // translateModel. These template do not return any | ||
| 40 | // result but instead write the result to files. All other templates return | ||
| 41 | // text and are used by the root templates (most of them indirectly). | ||
| 42 | |||
| 43 | package CodegenCppHpcom | ||
| 44 | |||
| 45 | import interface SimCodeBackendTV; | ||
| 46 | import interface SimCodeTV; | ||
| 47 | import CodegenUtil.*; | ||
| 48 | import CodegenCppCommon.*; | ||
| 49 | import CodegenCppInit.*; | ||
| 50 | import CodegenCpp.*; //unqualified import, no need the CodegenC is optional when calling a template; or mandatory when the same named template exists in this package (name hiding) | ||
| 51 | |||
| 52 | |||
| 53 | |||
| 54 | 1 | template translateModel(SimCode simCode) | |
| 55 | ::= | ||
| 56 | match simCode | ||
| 57 | case SIMCODE(modelInfo = MODELINFO(__), makefileParams = MAKEFILE_PARAMS(__), hpcomData = HPCOMDATA(__)) then | ||
| 58 | let target = simulationCodeTarget() | ||
| 59 | let &extraFuncs = buffer "" /*BUFD*/ | ||
| 60 | let &extraFuncsDecl = buffer "" /*BUFD*/ | ||
| 61 | let &extraResidualsFuncsDecl = buffer "" /*BUFD*/ | ||
| 62 | let &dummyTypeElemCreation = buffer "" //remove this workaround if GCC > 4.4 is the default compiler | ||
| 63 | let stateDerVectorName = "__zDot" | ||
| 64 | let useMemoryOptimization = Flags.isSet(Flags.HPCOM_MEMORY_OPT) | ||
| 65 | |||
| 66 | let className = lastIdentOfPath(modelInfo.name) | ||
| 67 | let numRealVars = numRealvarsHpcom(modelInfo, hpcomData.hpcOmMemory) | ||
| 68 | let numIntVars = numIntvarsHpcom(modelInfo, hpcomData.hpcOmMemory) | ||
| 69 | let numBoolVars = numBoolvarsHpcom(modelInfo, hpcomData.hpcOmMemory) | ||
| 70 | let numStringVars = numStringvars(modelInfo) | ||
| 71 | let numPreVars = numPreVarsHpcom(modelInfo, hpcomData.hpcOmMemory) | ||
| 72 | |||
| 73 | let() = textFile(simulationMainFile(target, simCode, &extraFuncs, &extraFuncsDecl, "", | ||
| 74 | (if Flags.isSet(USEMPI) then "#include <mpi.h>" else ""), | ||
| 75 | (if Flags.isSet(USEMPI) then mpiInit() else ""), | ||
| 76 | (if Flags.isSet(USEMPI) then mpiFinalize() else ""), | ||
| 77 | numRealVars, numIntVars, numBoolVars, numStringVars, numPreVars), | ||
| 78 | 'OMCpp<%fileNamePrefix%>Main.cpp') | ||
| 79 | let() = textFile(simulationCppFile(simCode, contextOther, updateHpcom(allEquations, simCode, &extraFuncs, &extraFuncsDecl, "", contextOther, stateDerVectorName, false), | ||
| 80 | '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', '<%numStringVars%>-1', &extraFuncs, &extraFuncsDecl, className, | ||
| 81 | additionalHpcomConstructorDefinitions(hpcomData.schedules), | ||
| 82 | additionalHpcomConstructorBodyStatements(hpcomData.schedules, className, CodegenUtil.dotPath(modelInfo.name)), | ||
| 83 | additionalHpcomDestructorBodyStatements(hpcomData.schedules), | ||
| 84 | stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>.cpp') | ||
| 85 | |||
| 86 | let() = textFile(simulationHeaderFile(simCode ,contextOther, &extraFuncs, &extraFuncsDecl, "", | ||
| 87 | additionalHpcomIncludes(simCode, &extraFuncs, &extraFuncsDecl, className, false), | ||
| 88 | "", | ||
| 89 | additionalHpcomProtectedMemberDeclaration(simCode, &extraFuncs, &extraFuncsDecl, "", false), | ||
| 90 | memberVariableDefine(modelInfo, varToArrayIndexMapping, '<%numRealVars%>-1', '<%numIntVars%>-1', '<%numBoolVars%>-1', '<%numStringVars%>-1', Flags.isSet(Flags.GEN_DEBUG_SYMBOLS), false), | ||
| 91 | false), 'OMCpp<%fileNamePrefix%>.h') | ||
| 92 | |||
| 93 | let() = textFile(simulationTypesHeaderFile(simCode, &extraFuncs, &extraFuncsDecl, "", &dummyTypeElemCreation, modelInfo.functions, literals,stateDerVectorName,false), 'OMCpp<%fileNamePrefix%>Types.h') | ||
| 94 | let() = textFile(simulationMakefile(target,simCode, &extraFuncs, &extraFuncsDecl, ""), '<%fileNamePrefix%>.makefile') | ||
| 95 | |||
| 96 | let &extraFuncsFun = buffer "" /*BUFD*/ | ||
| 97 | let &extraFuncsDeclFun = buffer "" /*BUFD*/ | ||
| 98 | let() = textFile(simulationFunctionsHeaderFile(simCode, &extraFuncsFun, &extraFuncsDeclFun, "",modelInfo.functions, literals,stateDerVectorName,false), 'OMCpp<%fileNamePrefix%>Functions.h') | ||
| 99 | let() = textFile(simulationFunctionsFile(simCode, &extraFuncsFun, &extraFuncsDeclFun, "", modelInfo.functions, literals,externalFunctionIncludes,stateDerVectorName,false), 'OMCpp<%fileNamePrefix%>Functions.cpp') | ||
| 100 | let &extraFuncsInit = buffer "" /*BUFD*/ | ||
| 101 | let &extraFuncsDeclInit = buffer "" /*BUFD*/ | ||
| 102 | let &complexStartExpressions = buffer "" | ||
| 103 | let() = textFile(modelInitXMLFile(simCode, numRealVars, numIntVars, numBoolVars, numStringVars, "", "", "", false, "", complexStartExpressions, stateDerVectorName),'<%fileNamePrefix%>_init.xml') | ||
| 104 | let() = textFile(simulationInitCppFile(simCode ,&extraFuncsInit, &extraFuncsDeclInit, '<%className%>Initialize', dummyTypeElemCreation, stateDerVectorName, false, complexStartExpressions), 'OMCpp<%fileNamePrefix%>Initialize.cpp') | ||
| 105 | |||
| 106 | let _ = match boolOr(Flags.isSet(Flags.HARDCODED_START_VALUES), Flags.isSet(Flags.GEN_DEBUG_SYMBOLS)) | ||
| 107 | case true then | ||
| 108 | let()= textFile(simulationInitParameterCppFile(simCode, &extraFuncsInit, &extraFuncsDeclInit, '<%className%>Initialize', stateDerVectorName, false),'OMCpp<%fileNamePrefix%>InitializeParameter.cpp') | ||
| 109 | let()= textFile(simulationInitAlgVarsCppFile(simCode , &extraFuncsInit , &extraFuncsDeclInit, '<%className%>Initialize', stateDerVectorName, false),'OMCpp<%fileNamePrefix%>InitializeAlgVars.cpp') | ||
| 110 | "" | ||
| 111 | else | ||
| 112 | "" | ||
| 113 | |||
| 114 | let() = textFile(simulationInitHeaderFile(simCode, &extraFuncsInit, &extraFuncsDeclInit, '<%className%>Initialize'), 'OMCpp<%fileNamePrefix%>Initialize.h') | ||
| 115 | |||
| 116 | let &jacobianVarsInit = buffer "" /*BUFD*/ | ||
| 117 | let() = textFile(simulationJacobianHeaderFile(simCode, &extraFuncs, &extraFuncsDecl, "", &jacobianVarsInit, Flags.isSet(Flags.GEN_DEBUG_SYMBOLS)), 'OMCpp<%fileNamePrefix%>Jacobian.h') | ||
| 118 | let() = textFile(simulationJacobianCppFile(simCode, &extraFuncs, &extraFuncsDecl, "", &jacobianVarsInit, stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>Jacobian.cpp') | ||
| 119 | let() = textFile(simulationStateSelectionCppFile(simCode, &extraFuncs, &extraFuncsDecl, "", stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>StateSelection.cpp') | ||
| 120 | let() = textFile(simulationStateSelectionHeaderFile(simCode, &extraFuncs, &extraFuncsDecl, ""), 'OMCpp<%fileNamePrefix%>StateSelection.h') | ||
| 121 | |||
| 122 | let()= textFile(simulationMixedSystemCppFile(simCode, updateResiduals(simCode, extraResidualsFuncsDecl, className, stateDerVectorName /*=__zDot*/, false), | ||
| 123 | &extraFuncs, &extraFuncsDecl, "", stateDerVectorName, false),'OMCpp<%fileNamePrefix%>Mixed.cpp') | ||
| 124 | let() = textFile(simulationMixedSystemHeaderFile(simCode, &extraResidualsFuncsDecl), 'OMCpp<%fileNamePrefix%>Mixed.h') | ||
| 125 | let() = textFile(simulationWriteOutputHeaderFile(simCode, &extraFuncs, &extraFuncsDecl, ""), 'OMCpp<%fileNamePrefix%>WriteOutput.h') | ||
| 126 | let() = textFile(simulationWriteOutputCppFile(simCode, &extraFuncs, &extraFuncsDecl, "", stateDerVectorName, false), 'OMCpp<%fileNamePrefix%>WriteOutput.cpp') | ||
| 127 | let() = textFile(simulationFactoryFile(simCode, &extraFuncs, &extraFuncsDecl, ""), 'OMCpp<%fileNamePrefix%>FactoryExport.cpp') | ||
| 128 | |||
| 129 | let() = textFile(simulationMainRunScript(simCode, &extraFuncs, &extraFuncsDecl, ""), '<%fileNamePrefix%><%simulationMainRunScriptSuffix(simCode, &extraFuncs, &extraFuncsDecl, "")%>') | ||
| 130 | let jac = (jacobianMatrices |> JAC_MATRIX(columns=mat) => | ||
| 131 | (mat |> JAC_COLUMN(columnEqns=eqs) => algloopfiles(eqs,simCode, &extraFuncs, &extraFuncsDecl, "", contextAlgloopJacobian, 0, stateDerVectorName, false) ;separator="") | ||
| 132 | ;separator="") | ||
| 133 | let alg = algloopfiles(listAppend(allEquations, initialEquations), simCode, &extraFuncs, &extraFuncsDecl, "", contextAlgloop, 0, stateDerVectorName, false) | ||
| 134 | let clk = getSubPartitions(clockedPartitions) |> subPartition hasindex i fromindex 1 => | ||
| 135 | match subPartition | ||
| 136 | case SUBPARTITION(__) then | ||
| 137 | algloopfiles(listAppend(equations, removedEquations), simCode, &extraFuncs, &extraFuncsDecl, "", contextAlgloop, i, stateDerVectorName, false) | ||
| 138 | ; separator = "\n" | ||
| 139 | let() = textFile(algloopMainfile(simCode, &extraFuncs, &extraFuncsDecl, "", contextAlgloop), 'OMCpp<%fileNamePrefix%>AlgLoopMain.cpp') | ||
| 140 | let() = textFile(calcHelperMainfile(simCode, &extraFuncs, &extraFuncsDecl, ""), 'OMCpp<%fileNamePrefix%>CalcHelperMain.cpp') | ||
| 141 | "" | ||
| 142 | // empty result of the top-level template .., only side effects | ||
| 143 | end match | ||
| 144 | end translateModel; | ||
| 145 | |||
| 146 | // HEADER | ||
| 147 | 1 | template additionalHpcomIncludes(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 148 | "Generates code for header file for simulation target." | ||
| 149 | ::= | ||
| 150 | match simCode | ||
| 151 | case SIMCODE(__) then | ||
| 152 | << | ||
| 153 | <%additionalHpcomIncludesForParallelCode(simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace)%> | ||
| 154 | >> | ||
| 155 | end match | ||
| 156 | end additionalHpcomIncludes; | ||
| 157 | |||
| 158 | 1 | template additionalHpcomIncludesForParallelCode(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) | |
| 159 | ::= | ||
| 160 | let type = getConfigString(HPCOM_CODE) | ||
| 161 | match type | ||
| 162 | case ("openmp") then | ||
| 163 | << | ||
| 164 | #include <omp.h> | ||
| 165 | >> | ||
| 166 | case ("pthreads") | ||
| 167 | case ("pthreads_spin") then | ||
| 168 | << | ||
| 169 | >> | ||
| 170 | case ("tbb") then | ||
| 171 | << | ||
| 172 | #include <tbb/tbb.h> | ||
| 173 | #include <tbb/flow_graph.h> | ||
| 174 | #include <tbb/tbb_stddef.h> | ||
| 175 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 176 | #include <tbb/task_arena.h> | ||
| 177 | #endif | ||
| 178 | >> | ||
| 179 | case ("mpi") then // MF: mpi.h | ||
| 180 | << | ||
| 181 | #include <mpi.h> | ||
| 182 | >> | ||
| 183 | else "" | ||
| 184 | end match | ||
| 185 | end additionalHpcomIncludesForParallelCode; | ||
| 186 | |||
| 187 | 1 | template additionalHpcomProtectedMemberDeclaration(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 188 | "Generates class declarations." | ||
| 189 | ::= | ||
| 190 | match simCode | ||
| 191 | case SIMCODE(modelInfo = MODELINFO(__), hpcomData=HPCOMDATA(schedules=schedulesOpt)) then | ||
| 192 | let &extraFuncsDecl += generateAdditionalFunctionHeaders(hpcomData.schedules) | ||
| 193 | let &extraFuncsDecl += generateAdditionalHpcomVarHeaders(hpcomData.schedules) | ||
| 194 | let type = getConfigString(HPCOM_CODE) | ||
| 195 | |||
| 196 | << | ||
| 197 | static long unsigned int getThreadNumber() | ||
| 198 | { | ||
| 199 | <% match type | ||
| 200 | case ("openmp") then | ||
| 201 | << | ||
| 202 | return (long unsigned int)omp_get_thread_num(); | ||
| 203 | >> | ||
| 204 | case ("mpi") then | ||
| 205 | << | ||
| 206 | return -1; //not supported | ||
| 207 | >> | ||
| 208 | case ("tbb") then | ||
| 209 | << | ||
| 210 | return -1; //not supported | ||
| 211 | >> | ||
| 212 | else | ||
| 213 | << | ||
| 214 | #if defined(USE_THREAD) | ||
| 215 | return std::hash<std::thread::id>()(std::this_thread::get_id()); | ||
| 216 | #else | ||
| 217 | return 0; | ||
| 218 | #endif | ||
| 219 | >> | ||
| 220 | end match %> | ||
| 221 | } | ||
| 222 | <% if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 223 | << | ||
| 224 | std::vector<MeasureTimeData*> *measureTimeArrayHpcom; | ||
| 225 | std::vector<MeasureTimeData*> *measureTimeSchedulerArrayHpcom_evaluateODE; | ||
| 226 | std::vector<MeasureTimeData*> *measureTimeSchedulerArrayHpcom_evaluateDAE; | ||
| 227 | std::vector<MeasureTimeData*> *measureTimeSchedulerArrayHpcom_evaluateZeroFuncs; | ||
| 228 | //MeasureTimeValues *measuredStartValuesODE, *measuredEndValuesODE; | ||
| 229 | MeasureTimeValues *measuredSchedulerStartValues, *measuredSchedulerEndValues; | ||
| 230 | |||
| 231 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 232 | std::vector<MeasureTimeData*> *measureTimeThreadArrayOdeHpcom; | ||
| 233 | std::vector<MeasureTimeData*> *measureTimeThreadArrayDaeHpcom; | ||
| 234 | std::vector<MeasureTimeData*> *measureTimeThreadArrayZeroFuncHpcom; | ||
| 235 | <%List.intRange(getConfigInt(NUM_PROC)) |> threadIdx => 'MeasureTimeValues* measuredSchedulerStartValues_<%intSub(threadIdx,1)%>;'; separator="\n"%> | ||
| 236 | <%List.intRange(getConfigInt(NUM_PROC)) |> threadIdx => 'MeasureTimeValues* measuredSchedulerEndValues_<%intSub(threadIdx,1)%>;'; separator="\n"%> | ||
| 237 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 238 | >>%> | ||
| 239 | >> | ||
| 240 | end match | ||
| 241 | end additionalHpcomProtectedMemberDeclaration; | ||
| 242 | |||
| 243 | ✗ | template generateAdditionalStructHeaders(Schedule odeSchedule) | |
| 244 | ::= | ||
| 245 | let type = getConfigString(HPCOM_CODE) | ||
| 246 | match odeSchedule | ||
| 247 | case TASKDEPSCHEDULE(__) then | ||
| 248 | match type | ||
| 249 | case ("openmp") then | ||
| 250 | << | ||
| 251 | >> | ||
| 252 | case ("tbb") then | ||
| 253 | << | ||
| 254 | //Required for Intel TBB | ||
| 255 | struct VoidFunctionBody { | ||
| 256 | function<void(void)> void_function; | ||
| 257 | VoidFunctionBody(function<void(void)> void_function) : void_function(void_function) { } | ||
| 258 | FORCE_INLINE void operator()( tbb::flow::continue_msg ) const | ||
| 259 | { | ||
| 260 | void_function(); | ||
| 261 | } | ||
| 262 | }; | ||
| 263 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 264 | struct TbbArenaFunctor | ||
| 265 | { | ||
| 266 | tbb::flow::graph * g; | ||
| 267 | tbb::flow::broadcast_node<tbb::flow::continue_msg> * sn; | ||
| 268 | |||
| 269 | TbbArenaFunctor( ) | ||
| 270 | { | ||
| 271 | g = NULL; | ||
| 272 | sn = NULL; | ||
| 273 | } | ||
| 274 | |||
| 275 | TbbArenaFunctor( tbb::flow::graph & in_g , tbb::flow::broadcast_node<tbb::flow::continue_msg> & in_sn ) | ||
| 276 | { | ||
| 277 | g = &in_g; | ||
| 278 | sn = &in_sn; | ||
| 279 | } | ||
| 280 | |||
| 281 | void operator()() | ||
| 282 | { | ||
| 283 | sn->try_put( tbb::flow::continue_msg() ); | ||
| 284 | g->wait_for_all(); | ||
| 285 | } | ||
| 286 | |||
| 287 | }; | ||
| 288 | #endif | ||
| 289 | >> | ||
| 290 | else "" | ||
| 291 | end match | ||
| 292 | else "" | ||
| 293 | end match | ||
| 294 | end generateAdditionalStructHeaders; | ||
| 295 | |||
| 296 | 1 | template generateAdditionalFunctionHeaders(Option<tuple<Schedule,Schedule,Schedule>> schedulesOpt) | |
| 297 | ::= | ||
| 298 | let type = getConfigString(HPCOM_CODE) | ||
| 299 | << | ||
| 300 | FORCE_INLINE void evaluateParallel(const UPDATETYPE command, int evaluateMode); | ||
| 301 | <%match schedulesOpt | ||
| 302 | case SOME((odeSchedule as THREADSCHEDULE(__),_,_)) then | ||
| 303 | match type | ||
| 304 | case ("openmp") then | ||
| 305 | << | ||
| 306 | >> | ||
| 307 | else | ||
| 308 | let headers = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => generateThreadFunctionHeaderDecl(i0); separator="\n" | ||
| 309 | << | ||
| 310 | <%headers%> | ||
| 311 | >> | ||
| 312 | end match | ||
| 313 | case SOME((odeSchedule as TASKDEPSCHEDULE(__),daeSchedule as TASKDEPSCHEDULE(__),zeroFuncSchedule as TASKDEPSCHEDULE(__))) then | ||
| 314 | match type | ||
| 315 | case ("openmp") then | ||
| 316 | << | ||
| 317 | >> | ||
| 318 | case ("tbb") then | ||
| 319 | let voidfuncsOde = odeSchedule.tasks |> task => ( | ||
| 320 | match task | ||
| 321 | case ((task as CALCTASK(__),parents)) then | ||
| 322 | << | ||
| 323 | void taskFuncOde_<%task.index%>(); | ||
| 324 | >> | ||
| 325 | else "" | ||
| 326 | ); separator="\n" | ||
| 327 | let voidfuncsDae = daeSchedule.tasks |> task => ( | ||
| 328 | match task | ||
| 329 | case ((task as CALCTASK(__),parents)) then | ||
| 330 | << | ||
| 331 | void taskFuncAll_<%task.index%>(); | ||
| 332 | >> | ||
| 333 | else "" | ||
| 334 | ); separator="\n" | ||
| 335 | let voidfuncsZeroFunc = zeroFuncSchedule.tasks |> task => ( | ||
| 336 | match task | ||
| 337 | case ((task as CALCTASK(__),parents)) then | ||
| 338 | << | ||
| 339 | void taskFuncZeroFunc_<%task.index%>(); | ||
| 340 | >> | ||
| 341 | else "" | ||
| 342 | ); separator="\n" | ||
| 343 | << | ||
| 344 | <%generateAdditionalStructHeaders(odeSchedule)%> | ||
| 345 | |||
| 346 | <%voidfuncsOde%> | ||
| 347 | <%voidfuncsDae%> | ||
| 348 | <%voidfuncsZeroFunc%> | ||
| 349 | >> | ||
| 350 | else "" | ||
| 351 | end match | ||
| 352 | else "" | ||
| 353 | end match%> | ||
| 354 | >> | ||
| 355 | end generateAdditionalFunctionHeaders; | ||
| 356 | |||
| 357 | 1 | template generateAdditionalHpcomVarHeaders(Option<tuple<Schedule,Schedule,Schedule>> schedulesOpt) | |
| 358 | ::= | ||
| 359 | let type = getConfigString(HPCOM_CODE) | ||
| 360 | << | ||
| 361 | UPDATETYPE _command; | ||
| 362 | int _evaluateMode; | ||
| 363 | <% | ||
| 364 | match schedulesOpt | ||
| 365 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=true),_,_)) then | ||
| 366 | match type | ||
| 367 | case ("pthreads") | ||
| 368 | case ("pthreads_spin") then | ||
| 369 | << | ||
| 370 | <%List.intRange(getConfigInt(NUM_PROC)) |> thIdx hasindex i0 fromindex 0 => generateThreadHeaderDecl(i0, type)%> | ||
| 371 | <%createBarrierByName("levelBarrier","", getConfigInt(NUM_PROC), type)%> | ||
| 372 | <%createLockByLockName("measureTimeArrayLock", "", type)%> | ||
| 373 | bool _simulationFinished; | ||
| 374 | >> | ||
| 375 | else "" | ||
| 376 | end match | ||
| 377 | case SOME((odeSchedule as THREADSCHEDULE(__),daeSchedule as THREADSCHEDULE(__),zeroFuncSchedule as THREADSCHEDULE(__))) then | ||
| 378 | let odeLocks = createLockArrayByName(listLength(odeSchedule.outgoingDepTasks),"_lockOde",type)//odeSchedule.outgoingDepTasks |> task => createLockByDepTask(task, "_lockOde", type); separator="\n" | ||
| 379 | let daeLocks = createLockArrayByName(listLength(daeSchedule.outgoingDepTasks),"_lockDae",type)//daeSchedule.outgoingDepTasks |> task => createLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 380 | let zeroFuncLocks = createLockArrayByName(listLength(zeroFuncSchedule.outgoingDepTasks),"_lockZeroFunc",type)//daeSchedule.outgoingDepTasks |> task => createLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 381 | match type | ||
| 382 | case ("openmp") then | ||
| 383 | let threadDecl = arrayList(odeSchedule.threadTasks) |> tt hasindex i0 fromindex 0 => generateThreadHeaderDecl(i0, type); separator="\n" | ||
| 384 | << | ||
| 385 | <%odeLocks%> | ||
| 386 | <%daeLocks%> | ||
| 387 | <%zeroFuncLocks%> | ||
| 388 | <%threadDecl%> | ||
| 389 | >> | ||
| 390 | case "mpi" then | ||
| 391 | << | ||
| 392 | //MF Todo BLABLUB | ||
| 393 | >> | ||
| 394 | else | ||
| 395 | let threadDecl = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => generateThreadHeaderDecl(i0, type); separator="\n" | ||
| 396 | let thLocks = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => createLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 397 | let thLocks1 = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => createLockByLockName(i0, "th_lock1", type); separator="\n" | ||
| 398 | << | ||
| 399 | bool _terminateThreads; | ||
| 400 | <%odeLocks%> | ||
| 401 | <%daeLocks%> | ||
| 402 | <%zeroFuncLocks%> | ||
| 403 | <%thLocks%> | ||
| 404 | <%thLocks1%> | ||
| 405 | <%threadDecl%> | ||
| 406 | >> | ||
| 407 | end match | ||
| 408 | case SOME((odeSchedule as TASKDEPSCHEDULE(__),_,_)) then | ||
| 409 | match type | ||
| 410 | case ("openmp") then | ||
| 411 | << >> | ||
| 412 | case ("tbb") then | ||
| 413 | << | ||
| 414 | tbb::flow::graph _tbbGraphOde; | ||
| 415 | tbb::flow::broadcast_node<tbb::flow::continue_msg> _tbbStartNodeOde; | ||
| 416 | tbb::flow::graph _tbbGraphAll; | ||
| 417 | tbb::flow::broadcast_node<tbb::flow::continue_msg> _tbbStartNodeAll; | ||
| 418 | tbb::flow::graph _tbbGraphZeroFunc; | ||
| 419 | tbb::flow::broadcast_node<tbb::flow::continue_msg> _tbbStartNodeZeroFunc; | ||
| 420 | std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* > _tbbNodeListOde; | ||
| 421 | std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* > _tbbNodeListAll; | ||
| 422 | std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* > _tbbNodeListZeroFunc; | ||
| 423 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 424 | tbb::task_arena _tbbArena; | ||
| 425 | TbbArenaFunctor _tbbArenaFunctorOde; | ||
| 426 | TbbArenaFunctor _tbbArenaFunctorAll; | ||
| 427 | TbbArenaFunctor _tbbArenaFunctorZeroFunc; | ||
| 428 | #endif | ||
| 429 | >> | ||
| 430 | else "" | ||
| 431 | end match | ||
| 432 | else "" | ||
| 433 | end match | ||
| 434 | %> | ||
| 435 | >> | ||
| 436 | end generateAdditionalHpcomVarHeaders; | ||
| 437 | |||
| 438 | 1 | template generateThreadHeaderDecl(Integer threadIdx, String iType) | |
| 439 | ::= | ||
| 440 | match iType | ||
| 441 | case ("openmp") then | ||
| 442 | << | ||
| 443 | >> | ||
| 444 | else | ||
| 445 | << | ||
| 446 | thread* evaluateThread<%threadIdx%>; | ||
| 447 | >> | ||
| 448 | end match | ||
| 449 | end generateThreadHeaderDecl; | ||
| 450 | |||
| 451 | ✗ | template generateThreadFunctionHeaderDecl(Integer threadIdx) | |
| 452 | ::= | ||
| 453 | << | ||
| 454 | void evaluateThreadFunc<%threadIdx%>(); | ||
| 455 | >> | ||
| 456 | end generateThreadFunctionHeaderDecl; | ||
| 457 | |||
| 458 | 1 | template additionalHpcomConstructorDefinitions(Option<tuple<Schedule,Schedule,Schedule>> scheduleOpt) | |
| 459 | ::= | ||
| 460 | let type = getConfigString(HPCOM_CODE) | ||
| 461 | match scheduleOpt | ||
| 462 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=true),_,_)) then | ||
| 463 | match type | ||
| 464 | case ("pthreads") | ||
| 465 | case ("pthreads_spin") then | ||
| 466 | << | ||
| 467 | ,_command(IContinuous::UNDEF_UPDATE) | ||
| 468 | ,_simulationFinished(false) | ||
| 469 | ,<%initializeBarrierByName("levelBarrier","",getConfigInt(NUM_PROC),type)%> | ||
| 470 | >> | ||
| 471 | else "" | ||
| 472 | case SOME((odeSchedule as TASKDEPSCHEDULE(__),daeSchedule as TASKDEPSCHEDULE(__),zeroFuncSchedule as TASKDEPSCHEDULE(__))) then | ||
| 473 | match type | ||
| 474 | case ("tbb") then | ||
| 475 | << | ||
| 476 | ,_tbbGraphOde() | ||
| 477 | ,_tbbGraphAll() | ||
| 478 | ,_tbbGraphZeroFunc() | ||
| 479 | ,_tbbStartNodeOde(_tbbGraphOde) | ||
| 480 | ,_tbbStartNodeAll(_tbbGraphAll) | ||
| 481 | ,_tbbStartNodeZeroFunc(_tbbGraphZeroFunc) | ||
| 482 | ,_tbbNodeListOde(<%listLength(odeSchedule.tasks)%>,NULL) | ||
| 483 | ,_tbbNodeListAll(<%listLength(daeSchedule.tasks)%>,NULL) | ||
| 484 | ,_tbbNodeListZeroFunc(<%listLength(zeroFuncSchedule.tasks)%>,NULL) | ||
| 485 | >> | ||
| 486 | else "" | ||
| 487 | end match | ||
| 488 | else "" | ||
| 489 | end match | ||
| 490 | end additionalHpcomConstructorDefinitions; | ||
| 491 | |||
| 492 | 1 | template additionalHpcomConstructorBodyStatements(Option<tuple<Schedule,Schedule,Schedule>> schedulesOpt, String modelNamePrefixStr, String fullModelName) | |
| 493 | ::= | ||
| 494 | let type = getConfigString(HPCOM_CODE) | ||
| 495 | let threadMeasureTimeBlocks = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateThreadMeasureTimeDeclaration(fullModelName, getConfigInt(NUM_PROC)) else "" | ||
| 496 | let schedulerSpecificReturn = match schedulesOpt | ||
| 497 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=true),daeSchedule as LEVELSCHEDULE(useFixedAssignments=true),zeroFuncSchedule as LEVELSCHEDULE(useFixedAssignments=true))) then | ||
| 498 | match type | ||
| 499 | case ("pthreads") | ||
| 500 | case ("pthreads_spin") then | ||
| 501 | let threadFuncs = List.intRange(intSub(getConfigInt(NUM_PROC),1)) |> tt hasindex i0 fromindex 1 => generateThread(i0, type, modelNamePrefixStr,"evaluateThreadFunc"); separator="\n" | ||
| 502 | << | ||
| 503 | <%threadFuncs%> | ||
| 504 | |||
| 505 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 506 | << | ||
| 507 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 508 | measureTimeSchedulerArrayHpcom_evaluateODE = new std::vector<MeasureTimeData*>(size_t(<%listLength(odeSchedule.tasksOfLevels)%>), NULL); | ||
| 509 | MeasureTime::addResultContentBlock("<%fullModelName%>","functions_HPCOM_Sections_ODE",measureTimeSchedulerArrayHpcom_evaluateODE); | ||
| 510 | measuredSchedulerStartValues = MeasureTime::getZeroValues(); | ||
| 511 | measuredSchedulerEndValues = MeasureTime::getZeroValues(); | ||
| 512 | <%List.intRange(listLength(odeSchedule.tasksOfLevels)) |> levelIdx => '(*measureTimeSchedulerArrayHpcom_evaluateODE)[<%intSub(levelIdx,1)%>] = new MeasureTimeData("evaluateODE_level_<%levelIdx%>");'; separator="\n"%> | ||
| 513 | |||
| 514 | measureTimeSchedulerArrayHpcom_evaluateDAE = new std::vector<MeasureTimeData*>(size_t(<%listLength(daeSchedule.tasksOfLevels)%>), NULL); | ||
| 515 | MeasureTime::addResultContentBlock("<%fullModelName%>","functions_HPCOM_Sections_DAE",measureTimeSchedulerArrayHpcom_evaluateDAE); | ||
| 516 | measuredSchedulerStartValues = MeasureTime::getZeroValues(); | ||
| 517 | measuredSchedulerEndValues = MeasureTime::getZeroValues(); | ||
| 518 | <%List.intRange(listLength(daeSchedule.tasksOfLevels)) |> levelIdx => '(*measureTimeSchedulerArrayHpcom_evaluateDAE)[<%intSub(levelIdx,1)%>] = new MeasureTimeData("evaluateDAE_level_<%levelIdx%>");'; separator="\n"%> | ||
| 519 | |||
| 520 | measureTimeSchedulerArrayHpcom_evaluateZeroFuncs = new std::vector<MeasureTimeData*>(size_t(<%listLength(zeroFuncSchedule.tasksOfLevels)%>), NULL); | ||
| 521 | MeasureTime::addResultContentBlock("<%fullModelName%>","functions_HPCOM_Sections_ZeroFuncs",measureTimeSchedulerArrayHpcom_evaluateZeroFuncs); | ||
| 522 | measuredSchedulerStartValues = MeasureTime::getZeroValues(); | ||
| 523 | measuredSchedulerEndValues = MeasureTime::getZeroValues(); | ||
| 524 | <%List.intRange(listLength(zeroFuncSchedule.tasksOfLevels)) |> levelIdx => '(*measureTimeSchedulerArrayHpcom_evaluateZeroFuncs)[<%intSub(levelIdx,1)%>] = new MeasureTimeData("evaluateZeroFunc_level_<%levelIdx%>");'; separator="\n"%> | ||
| 525 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 526 | >> | ||
| 527 | %> | ||
| 528 | >> | ||
| 529 | else "" | ||
| 530 | end match | ||
| 531 | case SOME((odeSchedule as THREADSCHEDULE(__),daeSchedule as THREADSCHEDULE(__),zeroFuncSchedule as THREADSCHEDULE(__))) then | ||
| 532 | let initLocksOde = initializeArrayLocks(listLength(odeSchedule.outgoingDepTasks),"_lockOde",type)//odeSchedule.outgoingDepTasks |> task => initializeLockByDepTask(task, "_lockOde", type); separator="\n" | ||
| 533 | let assignLocksOde = assignArrayLocks(listLength(odeSchedule.outgoingDepTasks),"_lockOde",type)//odeSchedule.outgoingDepTasks |> task => assignLockByDepTask(task, "_lockOde", type); separator="\n" | ||
| 534 | let initLocksDae = initializeArrayLocks(listLength(daeSchedule.outgoingDepTasks),"_lockDae",type)//daeSchedule.outgoingDepTasks |> task => initializeLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 535 | let assignLocksDae = assignArrayLocks(listLength(daeSchedule.outgoingDepTasks),"_lockDae",type)//daeSchedule.outgoingDepTasks |> task => assignLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 536 | let initLocksZeroFunc = initializeArrayLocks(listLength(zeroFuncSchedule.outgoingDepTasks),"_lockZeroFunc",type)//daeSchedule.outgoingDepTasks |> task => initializeLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 537 | let assignLocksZeroFunc = assignArrayLocks(listLength(zeroFuncSchedule.outgoingDepTasks),"_lockZeroFunc",type)//daeSchedule.outgoingDepTasks |> task => assignLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 538 | |||
| 539 | match type | ||
| 540 | case ("openmp") then | ||
| 541 | let threadFuncs = arrayList(odeSchedule.threadTasks) |> tt hasindex i0 fromindex 0 => generateThread(i0, type, modelNamePrefixStr,"evaluateThreadFunc"); separator="\n" | ||
| 542 | << | ||
| 543 | omp_set_dynamic(0); | ||
| 544 | <%threadFuncs%> | ||
| 545 | <%initLocksOde%> | ||
| 546 | <%initLocksDae%> | ||
| 547 | <%initLocksZeroFunc%> | ||
| 548 | >> | ||
| 549 | case ("mpi") then | ||
| 550 | << | ||
| 551 | //MF: Initialize MPI related stuff - nothing todo? | ||
| 552 | >> | ||
| 553 | else | ||
| 554 | let threadFuncs = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => generateThread(i0, type, modelNamePrefixStr,"evaluateThreadFunc"); separator="\n" | ||
| 555 | let threadLocksInit = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => initializeLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 556 | let threadLocksInit1 = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => initializeLockByLockName(i0, "th_lock1", type); separator="\n" | ||
| 557 | let threadAssignLocks = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => assignLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 558 | let threadAssignLocks1 = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => assignLockByLockName(i0, "th_lock1", type); separator="\n" | ||
| 559 | << | ||
| 560 | _terminateThreads = false; | ||
| 561 | _command = IContinuous::UNDEF_UPDATE; | ||
| 562 | _evaluateMode = -1; | ||
| 563 | |||
| 564 | <%initLocksOde%> | ||
| 565 | <%initLocksDae%> | ||
| 566 | <%initLocksZeroFunc%> | ||
| 567 | <%threadLocksInit%> | ||
| 568 | <%threadLocksInit1%> | ||
| 569 | |||
| 570 | <%assignLocksDae%> | ||
| 571 | <%assignLocksOde%> | ||
| 572 | <%assignLocksZeroFunc%> | ||
| 573 | <%threadAssignLocks%> | ||
| 574 | <%threadAssignLocks1%> | ||
| 575 | |||
| 576 | <%threadFuncs%> | ||
| 577 | >> | ||
| 578 | case SOME((odeSchedule as TASKDEPSCHEDULE(__),daeSchedule as TASKDEPSCHEDULE(__),zeroFuncSchedule as TASKDEPSCHEDULE(__))) then | ||
| 579 | match type | ||
| 580 | case ("tbb") then | ||
| 581 | let tbbVars = generateTbbConstructorExtension(odeSchedule.tasks, daeSchedule.tasks, zeroFuncSchedule.tasks, modelNamePrefixStr) | ||
| 582 | << | ||
| 583 | <%tbbVars%> | ||
| 584 | >> | ||
| 585 | else "" | ||
| 586 | else "" | ||
| 587 | end match | ||
| 588 | << | ||
| 589 | <%schedulerSpecificReturn%> | ||
| 590 | <%threadMeasureTimeBlocks%> | ||
| 591 | >> | ||
| 592 | end additionalHpcomConstructorBodyStatements; | ||
| 593 | |||
| 594 | ✗ | template generateThreadMeasureTimeDeclaration(String fullModelName, Integer numberOfThreads) | |
| 595 | ::= | ||
| 596 | << | ||
| 597 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 598 | measureTimeThreadArrayOdeHpcom = new std::vector<MeasureTimeData*>(size_t(<%numberOfThreads%>), NULL); | ||
| 599 | measureTimeThreadArrayDaeHpcom = new std::vector<MeasureTimeData*>(size_t(<%numberOfThreads%>), NULL); | ||
| 600 | measureTimeThreadArrayZeroFuncHpcom = new std::vector<MeasureTimeData*>(size_t(<%numberOfThreads%>), NULL); | ||
| 601 | MeasureTime::addResultContentBlock("<%fullModelName%>","evaluateODE_threads",measureTimeThreadArrayOdeHpcom); | ||
| 602 | MeasureTime::addResultContentBlock("<%fullModelName%>","evaluateDAE_threads",measureTimeThreadArrayDaeHpcom); | ||
| 603 | MeasureTime::addResultContentBlock("<%fullModelName%>","evaluateZeroFunc_threads",measureTimeThreadArrayZeroFuncHpcom); | ||
| 604 | <%List.intRange(numberOfThreads) |> threadIdx => 'measuredSchedulerStartValues_<%intSub(threadIdx,1)%> = MeasureTime::getZeroValues();'; separator="\n"%> | ||
| 605 | <%List.intRange(numberOfThreads) |> threadIdx => 'measuredSchedulerEndValues_<%intSub(threadIdx,1)%> = MeasureTime::getZeroValues();'; separator="\n"%> | ||
| 606 | <%List.intRange(numberOfThreads) |> threadIdx => '(*measureTimeThreadArrayOdeHpcom)[<%intSub(threadIdx,1)%>] = new MeasureTimeData("evaluateODE_thread_<%threadIdx%>");'; separator="\n"%> | ||
| 607 | <%List.intRange(numberOfThreads) |> threadIdx => '(*measureTimeThreadArrayDaeHpcom)[<%intSub(threadIdx,1)%>] = new MeasureTimeData("evaluateDAE_thread_<%threadIdx%>");'; separator="\n"%> | ||
| 608 | <%List.intRange(numberOfThreads) |> threadIdx => '(*measureTimeThreadArrayZeroFuncHpcom)[<%intSub(threadIdx,1)%>] = new MeasureTimeData("evaluateZeroFunc_thread_<%threadIdx%>");'; separator="\n"%> | ||
| 609 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 610 | >> | ||
| 611 | end generateThreadMeasureTimeDeclaration; | ||
| 612 | |||
| 613 | ✗ | template initializeArrayLocks(Integer numComms, String lockName, String iType) | |
| 614 | ::= | ||
| 615 | match(iType) | ||
| 616 | case "openmp" then | ||
| 617 | << | ||
| 618 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 619 | omp_init_lock(&<%lockName%>_[i]); | ||
| 620 | >> | ||
| 621 | case "pthreads" then | ||
| 622 | << | ||
| 623 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 624 | <%lockName%>_[i] = new alignedLock(); | ||
| 625 | >> | ||
| 626 | case "pthreads_spin" then | ||
| 627 | << | ||
| 628 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 629 | <%lockName%>_[i] = new alignedSpinlock(); | ||
| 630 | >> | ||
| 631 | else | ||
| 632 | << | ||
| 633 | //Unsupported parallel instrumentation | ||
| 634 | >> | ||
| 635 | end initializeArrayLocks; | ||
| 636 | |||
| 637 | ✗ | template assignArrayLocks(Integer numComms, String lockName, String iType) | |
| 638 | ::= | ||
| 639 | match iType | ||
| 640 | case ("openmp") then | ||
| 641 | << | ||
| 642 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 643 | omp_set_lock(&<%lockName%>_[i]); | ||
| 644 | >> | ||
| 645 | case ("pthreads") | ||
| 646 | case ("pthreads_spin") then | ||
| 647 | << | ||
| 648 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 649 | <%lockName%>_[i]->lock(); | ||
| 650 | >> | ||
| 651 | |||
| 652 | else | ||
| 653 | << | ||
| 654 | //Unsupported parallel instrumentation | ||
| 655 | >> | ||
| 656 | end match | ||
| 657 | end assignArrayLocks; | ||
| 658 | |||
| 659 | ✗ | template createLockArrayByName(Integer numComms, String lockName, String iType) | |
| 660 | ::= | ||
| 661 | match(iType) | ||
| 662 | case "openmp" then | ||
| 663 | << | ||
| 664 | omp_lock_t <%lockName%>_[<%numComms%>]; | ||
| 665 | >> | ||
| 666 | case "pthreads" then | ||
| 667 | << | ||
| 668 | alignedLock* <%lockName%>_[<%numComms%>]; | ||
| 669 | >> | ||
| 670 | case "pthreads_spin" then | ||
| 671 | << | ||
| 672 | alignedSpinlock* <%lockName%>_[<%numComms%>]; | ||
| 673 | >> | ||
| 674 | else | ||
| 675 | << | ||
| 676 | //Unsupported parallel instrumentation | ||
| 677 | >> | ||
| 678 | end createLockArrayByName; | ||
| 679 | |||
| 680 | ✗ | template destroyArrayLocks(Integer numComms, String lockName, String iType) | |
| 681 | ::= | ||
| 682 | match(iType) | ||
| 683 | case "openmp" then | ||
| 684 | << | ||
| 685 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 686 | omp_destroy_lock(&<%lockName%>_[i]); | ||
| 687 | >> | ||
| 688 | case "pthreads" | ||
| 689 | case "pthreads_spin" then | ||
| 690 | << | ||
| 691 | for(unsigned i=0;i<<%numComms%>;++i) | ||
| 692 | delete <%lockName%>_[i]; | ||
| 693 | >> | ||
| 694 | else | ||
| 695 | << | ||
| 696 | //Unsupported parallel instrumentation | ||
| 697 | >> | ||
| 698 | end destroyArrayLocks; | ||
| 699 | |||
| 700 | 1 | template additionalHpcomDestructorBodyStatements(Option<tuple<Schedule,Schedule,Schedule>> schedulesOpt) | |
| 701 | ::= | ||
| 702 | let type = getConfigString(HPCOM_CODE) | ||
| 703 | |||
| 704 | let schedulerSpecificCode = match schedulesOpt | ||
| 705 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=true),_,_)) then | ||
| 706 | match type | ||
| 707 | case ("pthreads") | ||
| 708 | case ("pthreads_spin") then | ||
| 709 | << | ||
| 710 | _simulationFinished = true; | ||
| 711 | //_evaluateBarrier.wait(); | ||
| 712 | _levelBarrier.wait(); | ||
| 713 | //_evaluateBarrier.wait(); | ||
| 714 | _levelBarrier.wait(); | ||
| 715 | >> | ||
| 716 | else "" | ||
| 717 | case SOME((odeSchedule as THREADSCHEDULE(__),daeSchedule as THREADSCHEDULE(__),zeroFuncSchedule as THREADSCHEDULE(__))) then | ||
| 718 | let destroyLocksOde = destroyArrayLocks(listLength(odeSchedule.outgoingDepTasks),"_lockOde",type)//odeSchedule.outgoingDepTasks |> task => destroyLockByDepTask(task, "_lockOde", type); separator="\n" | ||
| 719 | let destroyLocksDae = destroyArrayLocks(listLength(daeSchedule.outgoingDepTasks),"_lockDae",type)//daeSchedule.outgoingDepTasks |> task => destroyLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 720 | let destroyLocksZeroFunc = destroyArrayLocks(listLength(zeroFuncSchedule.outgoingDepTasks),"_lockZeroFunc",type)//daeSchedule.outgoingDepTasks |> task => destroyLockByDepTask(task, "_lockDae", type); separator="\n" | ||
| 721 | match type | ||
| 722 | case ("openmp") then | ||
| 723 | << | ||
| 724 | <%destroyLocksOde%> | ||
| 725 | <%destroyLocksDae%> | ||
| 726 | <%destroyLocksZeroFunc%> | ||
| 727 | >> | ||
| 728 | case "mpi" then | ||
| 729 | << | ||
| 730 | //MF: Destruct MPI related stuff - nothing at the moment. | ||
| 731 | >> | ||
| 732 | else | ||
| 733 | let destroyThreads = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => function_HPCOM_destroyThread(i0, type); separator="\n" | ||
| 734 | let threadLocksDel = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => destroyLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 735 | let threadLocksDel1 = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => destroyLockByLockName(i0, "th_lock1", type); separator="\n" | ||
| 736 | let joinThreads = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => function_HPCOM_joinThread(i0, type); separator="\n" | ||
| 737 | let threadReleaseLocks = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => releaseLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 738 | << | ||
| 739 | _terminateThreads = true; | ||
| 740 | <%threadReleaseLocks%> | ||
| 741 | <%joinThreads%> | ||
| 742 | <%destroyLocksOde%> | ||
| 743 | <%destroyLocksDae%> | ||
| 744 | <%destroyLocksZeroFunc%> | ||
| 745 | <%threadLocksDel%> | ||
| 746 | <%threadLocksDel1%> | ||
| 747 | <%destroyThreads%> | ||
| 748 | >> | ||
| 749 | case SOME((odeSchedule as TASKDEPSCHEDULE(__),_,_)) then | ||
| 750 | match type | ||
| 751 | case ("tbb") then | ||
| 752 | << | ||
| 753 | for(std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* >::iterator it = _tbbNodeListOde.begin(); it != _tbbNodeListOde.end(); it++) | ||
| 754 | delete *it; | ||
| 755 | for(std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* >::iterator it = _tbbNodeListAll.begin(); it != _tbbNodeListAll.end(); it++) | ||
| 756 | delete *it; | ||
| 757 | for(std::vector<tbb::flow::continue_node<tbb::flow::continue_msg>* >::iterator it = _tbbNodeListZeroFunc.begin(); it != _tbbNodeListZeroFunc.end(); it++) | ||
| 758 | delete *it; | ||
| 759 | >> | ||
| 760 | else "" | ||
| 761 | else "" | ||
| 762 | end match | ||
| 763 | << | ||
| 764 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 765 | <%List.intRange(getConfigInt(NUM_PROC)) |> threadIdx => 'delete measuredSchedulerStartValues_<%intSub(threadIdx,1)%>;'; separator="\n"%> | ||
| 766 | <%List.intRange(getConfigInt(NUM_PROC)) |> threadIdx => 'delete measuredSchedulerEndValues_<%intSub(threadIdx,1)%>;'; separator="\n"%> | ||
| 767 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 768 | <%schedulerSpecificCode%> | ||
| 769 | >> | ||
| 770 | end additionalHpcomDestructorBodyStatements; | ||
| 771 | |||
| 772 | 1 | template updateHpcom(list<SimEqSystem> allEquationsPlusWhen, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation) | |
| 773 | ::= | ||
| 774 | let &varDecls = buffer "" /*BUFD*/ | ||
| 775 | |||
| 776 | match simCode | ||
| 777 | case SIMCODE(modelInfo = MODELINFO(__), hpcomData=HPCOMDATA(__)) then | ||
| 778 | let &extraFuncsPar = buffer "" | ||
| 779 | let parCode = generateParallelEvaluate(allEquationsPlusWhen, modelInfo.name, simCode, extraFuncsPar ,extraFuncsDecl, extraFuncsNamespace, hpcomData.schedules, context, stateDerVectorName, lastIdentOfPath(modelInfo.name), useFlatArrayNotation) | ||
| 780 | << | ||
| 781 | <%equationFunctions(allEquations, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete,stateDerVectorName,useFlatArrayNotation,false)%> | ||
| 782 | |||
| 783 | <%createEvaluateConditions(allEquations, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextOther, stateDerVectorName, useFlatArrayNotation)%> | ||
| 784 | |||
| 785 | <%clockedFunctions(getSubPartitions(clockedPartitions), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL), "none")))%> | ||
| 786 | |||
| 787 | <%parCode%> | ||
| 788 | |||
| 789 | <%extraFuncsPar%> | ||
| 790 | >> | ||
| 791 | end match | ||
| 792 | end updateHpcom; | ||
| 793 | |||
| 794 | 1 | template generateParallelEvaluate(list<SimEqSystem> allEquationsPlusWhen, Absyn.Path name, | |
| 795 | SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Option<tuple<Schedule, Schedule, Schedule>> schedulesOpt, Context context, Text stateDerVectorName /*=__zDot*/, | ||
| 796 | String modelNamePrefixStr, Boolean useFlatArrayNotation) | ||
| 797 | ::= | ||
| 798 | match simCode | ||
| 799 | case SIMCODE(modelInfo = MODELINFO(__)) then | ||
| 800 | let &varDecls = buffer "" /*BUFD*/ | ||
| 801 | let measureTimeEvaluateOdeStart = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeStartCode("measuredFunctionStartValues", "evaluateODE", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 802 | let measureTimeEvaluateOdeEnd = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeEndCode("measuredFunctionStartValues", "measuredFunctionEndValues", "(*measureTimeFunctionsArray)[0]", "evaluateODE", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 803 | |||
| 804 | let measureTimeEvaluateAllStart = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeStartCode("measuredFunctionStartValues", "evaluateAll", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 805 | let measureTimeEvaluateAllEnd = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeEndCode("measuredFunctionStartValues", "measuredFunctionEndValues", "(*measureTimeFunctionsArray)[1]", "evaluateAll", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 806 | |||
| 807 | let measureTimeEvaluateZeroFuncStart = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeStartCode("measuredFunctionStartValues", "evaluateZeroFuncs", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 808 | let measureTimeEvaluateZeroFuncEnd = if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then generateMeasureTimeEndCode("measuredFunctionStartValues", "measuredFunctionEndValues", "(*measureTimeFunctionsArray)[4]", "evaluateZeroFuncs", "MEASURETIME_MODELFUNCTIONS") else "" | ||
| 809 | |||
| 810 | let type = getConfigString(HPCOM_CODE) | ||
| 811 | |||
| 812 | // Head of function is the same for all schedulers and parallelization methods: | ||
| 813 | let functionHead = | ||
| 814 | << | ||
| 815 | //using type: <%type%> | ||
| 816 | |||
| 817 | void <%lastIdentOfPath(name)%>::evaluateZeroFuncs(const UPDATETYPE command) | ||
| 818 | { | ||
| 819 | <%measureTimeEvaluateZeroFuncStart%> | ||
| 820 | evaluateParallel(command, 1); | ||
| 821 | <%measureTimeEvaluateZeroFuncEnd%> | ||
| 822 | } | ||
| 823 | |||
| 824 | bool <%lastIdentOfPath(name)%>::evaluateAll(const UPDATETYPE command) | ||
| 825 | { | ||
| 826 | <%measureTimeEvaluateAllStart%> | ||
| 827 | |||
| 828 | <%createTimeConditionTreatments(timeEventLength(simCode), clockedPartitions)%> | ||
| 829 | |||
| 830 | <%varDecls%> | ||
| 831 | |||
| 832 | evaluateParallel(command, -1); | ||
| 833 | <%measureTimeEvaluateAllEnd%> | ||
| 834 | |||
| 835 | return _state_var_reinitialized; | ||
| 836 | } | ||
| 837 | |||
| 838 | void <%lastIdentOfPath(name)%>::evaluateODE(const UPDATETYPE command) | ||
| 839 | { | ||
| 840 | <%measureTimeEvaluateOdeStart%> | ||
| 841 | evaluateParallel(command, 0); | ||
| 842 | <%measureTimeEvaluateOdeEnd%> | ||
| 843 | } | ||
| 844 | |||
| 845 | //evaluateMode = 0 : evaluateODE | ||
| 846 | //evaluateMode < 0 : evaluateAll | ||
| 847 | //evaluateMode > 0 : evaluateZeroFunc | ||
| 848 | void <%lastIdentOfPath(name)%>::evaluateParallel(const UPDATETYPE command, int evaluateMode) | ||
| 849 | >> | ||
| 850 | |||
| 851 | match schedulesOpt | ||
| 852 | case SOME((odeSchedule as EMPTYSCHEDULE(tasks=SERIALTASKLIST(tasks=taskListOde)), daeSchedule as EMPTYSCHEDULE(tasks=SERIALTASKLIST(tasks=taskListDae)), zeroFuncsSchedule as EMPTYSCHEDULE(tasks=SERIALTASKLIST(tasks=taskListZeroFunc)))) then | ||
| 853 | << | ||
| 854 | <%functionHead%> | ||
| 855 | { | ||
| 856 | if(evaluateMode == 0) //evaluate ODE | ||
| 857 | { | ||
| 858 | <%parallelThreadCodeWithSplit(allEquationsPlusWhen, taskListOde, 1, 1, "", "", &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateODE_Th1", useFlatArrayNotation)%> | ||
| 859 | } | ||
| 860 | else if(evaluateMode < 0) //evaluate All | ||
| 861 | { | ||
| 862 | <%parallelThreadCodeWithSplit(allEquationsPlusWhen, taskListDae, 1, 1, "", "", &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateAll_Th1", useFlatArrayNotation)%> | ||
| 863 | } | ||
| 864 | else //evaluate ZeroFuncs | ||
| 865 | { | ||
| 866 | <%parallelThreadCodeWithSplit(allEquationsPlusWhen, taskListZeroFunc, 1, 1, "", "", &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateZeroFunc_Th1", useFlatArrayNotation)%> | ||
| 867 | } | ||
| 868 | } | ||
| 869 | >> | ||
| 870 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=false, tasksOfLevels=tasksOfLevelsOde), daeSchedule as LEVELSCHEDULE(useFixedAssignments=false, tasksOfLevels=tasksOfLevelsDae), zeroFuncSchedule as LEVELSCHEDULE(useFixedAssignments=false, tasksOfLevels=tasksOfLevelsZeroFunc))) then | ||
| 871 | let odeEqs = tasksOfLevelsOde |> tasks => generateLevelCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 872 | let daeEqs = tasksOfLevelsDae |> tasks => generateLevelCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 873 | let zeroFuncEqs = tasksOfLevelsZeroFunc |> tasks => generateLevelCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 874 | |||
| 875 | match type | ||
| 876 | case ("openmp") then | ||
| 877 | let &extraFuncsDecl += | ||
| 878 | << | ||
| 879 | void evaluateODE_Parallel(); | ||
| 880 | void evaluateAll_Parallel(); | ||
| 881 | void evaluateZeroFuncs_Parallel(); | ||
| 882 | >> | ||
| 883 | |||
| 884 | << | ||
| 885 | void <%lastIdentOfPath(name)%>::evaluateODE_Parallel() | ||
| 886 | { | ||
| 887 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 888 | { | ||
| 889 | <%odeEqs%> | ||
| 890 | } | ||
| 891 | } | ||
| 892 | |||
| 893 | void <%lastIdentOfPath(name)%>::evaluateAll_Parallel() | ||
| 894 | { | ||
| 895 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 896 | { | ||
| 897 | <%daeEqs%> | ||
| 898 | } | ||
| 899 | } | ||
| 900 | |||
| 901 | void <%lastIdentOfPath(name)%>::evaluateZeroFuncs_Parallel() | ||
| 902 | { | ||
| 903 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 904 | { | ||
| 905 | <%zeroFuncEqs%> | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | <%functionHead%> | ||
| 910 | { | ||
| 911 | this->_evaluateMode = _evaluateMode; | ||
| 912 | this->_command = command; | ||
| 913 | if(evaluateMode == 0) | ||
| 914 | { | ||
| 915 | evaluateODE_Parallel(); | ||
| 916 | } | ||
| 917 | else if(evaluateMode < 0) | ||
| 918 | { | ||
| 919 | evaluateAll_Parallel(); | ||
| 920 | } | ||
| 921 | else | ||
| 922 | { | ||
| 923 | evaluateZeroFuncs_Parallel(); | ||
| 924 | } | ||
| 925 | } | ||
| 926 | >> | ||
| 927 | else | ||
| 928 | << | ||
| 929 | <%functionHead%> | ||
| 930 | { | ||
| 931 | throw std::runtime_error("Type <%type%> is unsupported for level scheduling."); | ||
| 932 | } | ||
| 933 | >> | ||
| 934 | end match | ||
| 935 | case SOME((odeSchedule as LEVELSCHEDULE(useFixedAssignments=true), daeSchedule as LEVELSCHEDULE(useFixedAssignments=true), zeroFuncSchedule as LEVELSCHEDULE(useFixedAssignments=true))) then | ||
| 936 | match type | ||
| 937 | case ("openmp") then | ||
| 938 | let odeEqs = HpcOmCodegenUtil.convertFixedLevelScheduleToLevelThreadLists(odeSchedule, getConfigInt(NUM_PROC)) |> tasks hasindex i0 fromindex 0 => generateLevelFixedCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, name, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 939 | let daeEqs = HpcOmCodegenUtil.convertFixedLevelScheduleToLevelThreadLists(daeSchedule, getConfigInt(NUM_PROC)) |> tasks hasindex i0 fromindex 0 => generateLevelFixedCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, name, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 940 | let zeroFuncEqs = HpcOmCodegenUtil.convertFixedLevelScheduleToLevelThreadLists(zeroFuncSchedule, getConfigInt(NUM_PROC)) |> tasks hasindex i0 fromindex 0 => generateLevelFixedCodeForLevel(allEquationsPlusWhen, tasks, type, &varDecls, name, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 941 | |||
| 942 | let &extraFuncsDecl += | ||
| 943 | << | ||
| 944 | void evaluateODE_Parallel(); | ||
| 945 | void evaluateAll_Parallel(); | ||
| 946 | void evaluateZeroFuncs_Parallel(); | ||
| 947 | >> | ||
| 948 | |||
| 949 | << | ||
| 950 | void <%lastIdentOfPath(name)%>::evaluateODE_Parallel() | ||
| 951 | { | ||
| 952 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 953 | { | ||
| 954 | int threadNum = getThreadNumber(); | ||
| 955 | <%odeEqs%> | ||
| 956 | } | ||
| 957 | } | ||
| 958 | |||
| 959 | void <%lastIdentOfPath(name)%>::evaluateAll_Parallel() | ||
| 960 | { | ||
| 961 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 962 | { | ||
| 963 | int threadNum = getThreadNumber(); | ||
| 964 | <%daeEqs%> | ||
| 965 | } | ||
| 966 | } | ||
| 967 | |||
| 968 | void <%lastIdentOfPath(name)%>::evaluateZeroFuncs_Parallel() | ||
| 969 | { | ||
| 970 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 971 | { | ||
| 972 | int threadNum = getThreadNumber(); | ||
| 973 | <%zeroFuncEqs%> | ||
| 974 | } | ||
| 975 | } | ||
| 976 | |||
| 977 | <%functionHead%> | ||
| 978 | { | ||
| 979 | this->_evaluateMode = _evaluateMode; | ||
| 980 | this->_command = command; | ||
| 981 | if(evaluateMode == 0) | ||
| 982 | { | ||
| 983 | evaluateODE_Parallel(); | ||
| 984 | } | ||
| 985 | else if(evaluateMode < 0) | ||
| 986 | { | ||
| 987 | evaluateAll_Parallel(); | ||
| 988 | } | ||
| 989 | else | ||
| 990 | { | ||
| 991 | evaluateZeroFuncs_Parallel(); | ||
| 992 | } | ||
| 993 | } | ||
| 994 | >> | ||
| 995 | case ("pthreads") | ||
| 996 | case ("pthreads_spin") then | ||
| 997 | let eqsFuncs = arrayList(HpcOmCodegenUtil.convertFixedLevelScheduleToTaskLists(odeSchedule, daeSchedule, zeroFuncSchedule, getConfigInt(NUM_PROC))) |> tasks hasindex i0 fromindex 0 => generateLevelFixedCodeForThread(allEquationsPlusWhen, tasks, i0, type, &varDecls, name, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), useFlatArrayNotation); separator="\n" | ||
| 998 | let threadLocks = List.intRange(getConfigInt(NUM_PROC)) |> tt => createLockByLockName('threadLock<%tt%>', "", type); separator="\n" | ||
| 999 | << | ||
| 1000 | <%eqsFuncs%> | ||
| 1001 | |||
| 1002 | <%functionHead%> | ||
| 1003 | { | ||
| 1004 | this->_command = command; | ||
| 1005 | this->_evaluateMode = evaluateMode; | ||
| 1006 | |||
| 1007 | if(evaluateMode == 0) //evaluate ODE | ||
| 1008 | { | ||
| 1009 | _levelBarrier.wait(); | ||
| 1010 | evaluateThreadFuncODE_0(); | ||
| 1011 | _levelBarrier.wait(); | ||
| 1012 | |||
| 1013 | <%generateStateVarPrefetchCode(simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace)%> | ||
| 1014 | } | ||
| 1015 | else if(evaluateMode < 0) //evaluate All | ||
| 1016 | { | ||
| 1017 | _levelBarrier.wait(); | ||
| 1018 | evaluateThreadFuncAll_0(); | ||
| 1019 | _levelBarrier.wait(); | ||
| 1020 | } | ||
| 1021 | else //evaluate ZeroFuncs | ||
| 1022 | { | ||
| 1023 | _levelBarrier.wait(); | ||
| 1024 | evaluateThreadFuncZeroFunc_0(); | ||
| 1025 | _levelBarrier.wait(); | ||
| 1026 | } | ||
| 1027 | } | ||
| 1028 | >> | ||
| 1029 | else | ||
| 1030 | << | ||
| 1031 | <%functionHead%> | ||
| 1032 | { | ||
| 1033 | throw std::runtime_error("Type <%type%> is unsupported for levelfix scheduling."); | ||
| 1034 | } | ||
| 1035 | >> | ||
| 1036 | end match | ||
| 1037 | case SOME((odeSchedule as THREADSCHEDULE(threadTasks=threadTasksOde), daeSchedule as THREADSCHEDULE(threadTasks=threadTasksDae), zeroFuncSchedule as THREADSCHEDULE(threadTasks=threadTasksZeroFunc))) then | ||
| 1038 | match type | ||
| 1039 | case ("openmp") then | ||
| 1040 | let threadAssignLocksOde = arrayList(threadTasksOde) |> tt hasindex i0 fromindex 0 => function_HPCOM_assignThreadLocks(arrayGet(threadTasksOde, intAdd(i0, 1)), "_lockOde", i0, type); separator="\n" | ||
| 1041 | let threadReleaseLocksOde = arrayList(threadTasksOde) |> tt hasindex i0 fromindex 0 => function_HPCOM_releaseThreadLocks(arrayGet(threadTasksOde, intAdd(i0, 1)), "_lockOde", i0, type); separator="\n" | ||
| 1042 | let threadAssignLocksDae = arrayList(threadTasksOde) |> tt hasindex i0 fromindex 0 => function_HPCOM_assignThreadLocks(arrayGet(threadTasksDae, intAdd(i0, 1)), "_lockDae", i0, type); separator="\n" | ||
| 1043 | let threadReleaseLocksDae = arrayList(threadTasksOde) |> tt hasindex i0 fromindex 0 => function_HPCOM_releaseThreadLocks(arrayGet(threadTasksDae, intAdd(i0, 1)), "_lockDae", i0, type); separator="\n" | ||
| 1044 | let threadAssignLocksZeroFunc = arrayList(threadTasksZeroFunc) |> tt hasindex i0 fromindex 0 => function_HPCOM_assignThreadLocks(arrayGet(threadTasksZeroFunc, intAdd(i0, 1)), "_lockZeroFunc", i0, type); separator="\n" | ||
| 1045 | let threadReleaseLocksZeroFunc = arrayList(threadTasksZeroFunc) |> tt hasindex i0 fromindex 0 => function_HPCOM_releaseThreadLocks(arrayGet(threadTasksZeroFunc, intAdd(i0, 1)), "_lockZeroFunc", i0, type); separator="\n" | ||
| 1046 | |||
| 1047 | let odeEqs = arrayList(threadTasksOde) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,intSub(arrayLength(threadTasksOde),1),type,"_lockOde",&varDecls,simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateODE", useFlatArrayNotation); separator="\n" | ||
| 1048 | let daeEqs = arrayList(threadTasksDae) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,intSub(arrayLength(threadTasksDae),1),type,"_lockDae",&varDecls,simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateAll", useFlatArrayNotation); separator="\n" | ||
| 1049 | let zeroFuncEqs = arrayList(threadTasksZeroFunc) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,intSub(arrayLength(threadTasksZeroFunc),1),type,"_lockZeroFunc",&varDecls,simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), "evaluateZeroFunc", useFlatArrayNotation); separator="\n" | ||
| 1050 | |||
| 1051 | let &extraFuncsDecl += | ||
| 1052 | << | ||
| 1053 | void evaluateODE_Parallel(); | ||
| 1054 | void evaluateAll_Parallel(); | ||
| 1055 | void evaluateZeroFuncs_Parallel(); | ||
| 1056 | >> | ||
| 1057 | << | ||
| 1058 | void <%lastIdentOfPath(name)%>::evaluateODE_Parallel() | ||
| 1059 | { | ||
| 1060 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 1061 | { | ||
| 1062 | int threadNum = getThreadNumber(); | ||
| 1063 | <%threadAssignLocksOde%> | ||
| 1064 | #pragma omp barrier | ||
| 1065 | <%odeEqs%> | ||
| 1066 | #pragma omp barrier | ||
| 1067 | <%threadReleaseLocksOde%> | ||
| 1068 | } | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | void <%lastIdentOfPath(name)%>::evaluateAll_Parallel() | ||
| 1072 | { | ||
| 1073 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 1074 | { | ||
| 1075 | int threadNum = getThreadNumber(); | ||
| 1076 | <%threadAssignLocksDae%> | ||
| 1077 | #pragma omp barrier | ||
| 1078 | <%daeEqs%> | ||
| 1079 | #pragma omp barrier | ||
| 1080 | <%threadReleaseLocksDae%> | ||
| 1081 | } | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | void <%lastIdentOfPath(name)%>::evaluateZeroFuncs_Parallel() | ||
| 1085 | { | ||
| 1086 | #pragma omp parallel num_threads(<%getConfigInt(NUM_PROC)%>) | ||
| 1087 | { | ||
| 1088 | int threadNum = getThreadNumber(); | ||
| 1089 | <%threadAssignLocksZeroFunc%> | ||
| 1090 | #pragma omp barrier | ||
| 1091 | <%zeroFuncEqs%> | ||
| 1092 | #pragma omp barrier | ||
| 1093 | <%threadReleaseLocksZeroFunc%> | ||
| 1094 | } | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | <%functionHead%> | ||
| 1098 | { | ||
| 1099 | this->_evaluateMode = _evaluateMode; | ||
| 1100 | this->_command = command; | ||
| 1101 | if(evaluateMode == 0) | ||
| 1102 | { | ||
| 1103 | evaluateODE_Parallel(); | ||
| 1104 | } | ||
| 1105 | else if(evaluateMode < 0) | ||
| 1106 | { | ||
| 1107 | evaluateAll_Parallel(); | ||
| 1108 | } | ||
| 1109 | else | ||
| 1110 | { | ||
| 1111 | evaluateZeroFuncs_Parallel(); | ||
| 1112 | } | ||
| 1113 | } | ||
| 1114 | >> | ||
| 1115 | case ("mpi") then | ||
| 1116 | << | ||
| 1117 | <%functionHead%> | ||
| 1118 | { | ||
| 1119 | // MFlehmig: Todo | ||
| 1120 | } | ||
| 1121 | >> | ||
| 1122 | else | ||
| 1123 | let &mainThreadCode = buffer "" /*BUFD*/ | ||
| 1124 | let threadFuncs = List.intRange(arrayLength(odeSchedule.threadTasks)) |> threadIdx => generateThreadFunc(allEquationsPlusWhen, arrayGet(odeSchedule.threadTasks, threadIdx), arrayGet(daeSchedule.threadTasks, threadIdx), arrayGet(zeroFuncSchedule.threadTasks, threadIdx), type, intSub(threadIdx, 1), modelNamePrefixStr, &varDecls, simCode, extraFuncs, extraFuncsDecl, lastIdentOfPath(name), &mainThreadCode, useFlatArrayNotation); separator="\n" | ||
| 1125 | let threadAssignLocks1 = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => assignLockByLockName(i0, "th_lock1", type); separator="\n" | ||
| 1126 | let threadReleaseLocks = listRest(arrayList(odeSchedule.threadTasks)) |> tt hasindex i0 fromindex 1 => releaseLockByLockName(i0, "th_lock", type); separator="\n" | ||
| 1127 | << | ||
| 1128 | <%threadFuncs%> | ||
| 1129 | |||
| 1130 | <%functionHead%> | ||
| 1131 | { | ||
| 1132 | this->_evaluateMode = _evaluateMode; | ||
| 1133 | this->_command = command; | ||
| 1134 | <%threadReleaseLocks%> | ||
| 1135 | <%mainThreadCode%> | ||
| 1136 | <%threadAssignLocks1%> | ||
| 1137 | } | ||
| 1138 | >> | ||
| 1139 | end match | ||
| 1140 | case SOME((odeSchedule as TASKDEPSCHEDULE(__), daeSchedule as TASKDEPSCHEDULE(__), zeroFuncSchedule as TASKDEPSCHEDULE(__))) then | ||
| 1141 | match type | ||
| 1142 | case ("openmp") then | ||
| 1143 | let odeTaskEqs = function_HPCOM_TaskDep(odeSchedule.tasks, allEquationsPlusWhen, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1144 | let daeTaskEqs = function_HPCOM_TaskDep(daeSchedule.tasks, allEquationsPlusWhen, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1145 | let zeroFuncTaskEqs = function_HPCOM_TaskDep(zeroFuncSchedule.tasks, allEquationsPlusWhen, type, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1146 | << | ||
| 1147 | <%functionHead%> | ||
| 1148 | { | ||
| 1149 | this->_evaluateMode = _evaluateMode; | ||
| 1150 | this->_command = command; | ||
| 1151 | <%&varDecls%> | ||
| 1152 | if(_evaluateMode == 0) | ||
| 1153 | { | ||
| 1154 | <%odeTaskEqs%> | ||
| 1155 | } | ||
| 1156 | else if(_evaluateMode < 0) | ||
| 1157 | { | ||
| 1158 | <%daeTaskEqs%> | ||
| 1159 | } | ||
| 1160 | else | ||
| 1161 | { | ||
| 1162 | <%zeroFuncTaskEqs%> | ||
| 1163 | } | ||
| 1164 | } | ||
| 1165 | >> | ||
| 1166 | case ("tbb") then | ||
| 1167 | let taskFuncs = function_HPCOM_TaskDep_voidfunc(odeSchedule.tasks, daeSchedule.tasks, zeroFuncSchedule.tasks, allEquationsPlusWhen,type, name, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1168 | << | ||
| 1169 | //void functions for functionhandling in tbb_nodes | ||
| 1170 | <%taskFuncs%> | ||
| 1171 | |||
| 1172 | <%functionHead%> | ||
| 1173 | { | ||
| 1174 | this->_evaluateMode = _evaluateMode; | ||
| 1175 | this->_command = command; | ||
| 1176 | <%&varDecls%> | ||
| 1177 | if(_evaluateMode == 0) | ||
| 1178 | { | ||
| 1179 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 1180 | _tbbArena.execute(_tbbArenaFunctorOde); | ||
| 1181 | #else | ||
| 1182 | _tbbStartNodeOde.try_put(tbb::flow::continue_msg()); | ||
| 1183 | _tbbGraphOde.wait_for_all(); | ||
| 1184 | #endif | ||
| 1185 | } | ||
| 1186 | else if(_evaluateMode < 0) | ||
| 1187 | { | ||
| 1188 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 1189 | _tbbArena.execute(_tbbArenaFunctorAll); | ||
| 1190 | #else | ||
| 1191 | _tbbStartNodeAll.try_put(tbb::flow::continue_msg()); | ||
| 1192 | _tbbGraphAll.wait_for_all(); | ||
| 1193 | #endif | ||
| 1194 | } | ||
| 1195 | else | ||
| 1196 | { | ||
| 1197 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 1198 | _tbbArena.execute(_tbbArenaFunctorZeroFunc); | ||
| 1199 | #else | ||
| 1200 | _tbbStartNodeZeroFunc.try_put(tbb::flow::continue_msg()); | ||
| 1201 | _tbbGraphZeroFunc.wait_for_all(); | ||
| 1202 | #endif | ||
| 1203 | } | ||
| 1204 | } | ||
| 1205 | >> | ||
| 1206 | else "" | ||
| 1207 | end match | ||
| 1208 | else "" | ||
| 1209 | end generateParallelEvaluate; | ||
| 1210 | |||
| 1211 | 1 | template generateStateVarPrefetchCode(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) | |
| 1212 | ::= | ||
| 1213 | match simCode | ||
| 1214 | case SIMCODE(modelInfo = MODELINFO(vars = vars as SIMVARS(__))) then | ||
| 1215 | << | ||
| 1216 | <%(List.intRange3(0, 8, intSub(listLength(vars.stateVars), 1)) |> index => | ||
| 1217 | 'PREFETCH(&__z[<%index%>], 0, 3);' | ||
| 1218 | ;separator="\n")%> | ||
| 1219 | >> | ||
| 1220 | else '' | ||
| 1221 | end match | ||
| 1222 | end generateStateVarPrefetchCode; | ||
| 1223 | |||
| 1224 | ✗ | template generateLevelCodeForLevel(list<SimEqSystem> allEquationsPlusWhen, TaskList tasksOfLevel, String iType, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1225 | ::= | ||
| 1226 | match(tasksOfLevel) | ||
| 1227 | case(PARALLELTASKLIST(__)) then | ||
| 1228 | let odeEqs = tasks |> task => generateLevelCodeForTask(allEquationsPlusWhen,task,iType, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1229 | << | ||
| 1230 | #pragma omp sections | ||
| 1231 | { | ||
| 1232 | <%odeEqs%> | ||
| 1233 | } | ||
| 1234 | >> | ||
| 1235 | case(SERIALTASKLIST(__)) then | ||
| 1236 | let odeEqs = tasks |> task => generateLevelCodeForTask(allEquationsPlusWhen,task,iType, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1237 | << | ||
| 1238 | #pragma omp master | ||
| 1239 | { | ||
| 1240 | <%odeEqs%> | ||
| 1241 | } | ||
| 1242 | #pragma omp barrier | ||
| 1243 | >> | ||
| 1244 | else | ||
| 1245 | << | ||
| 1246 | >> | ||
| 1247 | end match | ||
| 1248 | end generateLevelCodeForLevel; | ||
| 1249 | |||
| 1250 | ✗ | template generateLevelCodeForTask(list<SimEqSystem> allEquationsPlusWhen, Task iTask, String iType, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1251 | ::= | ||
| 1252 | << | ||
| 1253 | #pragma omp section | ||
| 1254 | { | ||
| 1255 | <%taskCode(allEquationsPlusWhen, iTask, iType, "", &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation)%> | ||
| 1256 | } | ||
| 1257 | >> | ||
| 1258 | end generateLevelCodeForTask; | ||
| 1259 | |||
| 1260 | ✗ | template generateLevelFixedCodeForLevel(list<SimEqSystem> allEquationsPlusWhen, array<list<HpcOmSimCode.Task>> tasksOfLevel, String iType, Text &varDecls, Absyn.Path name, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1261 | ::= | ||
| 1262 | let eqs = (arrayList(tasksOfLevel) |> threadTasks hasindex i0 => | ||
| 1263 | << | ||
| 1264 | if(threadNum == <%i0%>) { | ||
| 1265 | <%threadTasks |> t => taskCode(allEquationsPlusWhen, t, iType, "", varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n"%> | ||
| 1266 | } | ||
| 1267 | >>; separator="\n") | ||
| 1268 | |||
| 1269 | << | ||
| 1270 | <%eqs%> | ||
| 1271 | #pragma omp barrier | ||
| 1272 | >> | ||
| 1273 | end generateLevelFixedCodeForLevel; | ||
| 1274 | |||
| 1275 | 1 | template generateLevelFixedCodeForThread(list<SimEqSystem> allEquationsPlusWhen, tuple<list<list<HpcOmSimCode.Task>>,list<list<HpcOmSimCode.Task>>,list<list<HpcOmSimCode.Task>>> tasksOfLevels, | |
| 1276 | Integer iThreadIdx, String iType, Text &varDecls, Absyn.Path name, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, | ||
| 1277 | Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1278 | ::= | ||
| 1279 | match iType | ||
| 1280 | case ("pthreads") | ||
| 1281 | case ("pthreads_spin") then | ||
| 1282 | match(tasksOfLevels) | ||
| 1283 | case((odeTasksOfLevel, daeTasksOfLevel, zeroFuncTasksOfLevel)) then | ||
| 1284 | let odeEqs = odeTasksOfLevel |> tasks hasindex levelIdx => generateLevelFixedCodeForThreadLevel(allEquationsPlusWhen, tasks, iThreadIdx, "evaluateODE", iType, levelIdx, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1285 | let daeEqs = daeTasksOfLevel |> tasks hasindex levelIdx => generateLevelFixedCodeForThreadLevel(allEquationsPlusWhen, tasks, iThreadIdx, "evaluateDAE", iType, levelIdx, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1286 | let zeroFuncEqs = zeroFuncTasksOfLevel |> tasks hasindex levelIdx => generateLevelFixedCodeForThreadLevel(allEquationsPlusWhen, tasks, iThreadIdx, "evaluateZeroFuncs", iType, levelIdx, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1287 | let &extraFuncsDecl += | ||
| 1288 | << | ||
| 1289 | void evaluateThreadFuncODE_<%iThreadIdx%>(); | ||
| 1290 | void evaluateThreadFuncAll_<%iThreadIdx%>(); | ||
| 1291 | void evaluateThreadFuncZeroFunc_<%iThreadIdx%>(); | ||
| 1292 | void evaluateThreadFunc<%iThreadIdx%>(); | ||
| 1293 | <%\n%> | ||
| 1294 | >> | ||
| 1295 | << | ||
| 1296 | void <%lastIdentOfPath(name)%>::evaluateThreadFuncODE_<%iThreadIdx%>() | ||
| 1297 | { | ||
| 1298 | <%odeEqs%> | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | void <%lastIdentOfPath(name)%>::evaluateThreadFuncAll_<%iThreadIdx%>() | ||
| 1302 | { | ||
| 1303 | <%daeEqs%> | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | void <%lastIdentOfPath(name)%>::evaluateThreadFuncZeroFunc_<%iThreadIdx%>() | ||
| 1307 | { | ||
| 1308 | <%zeroFuncEqs%> | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | <%if (intGt(iThreadIdx, 0)) then | ||
| 1312 | << | ||
| 1313 | void <%lastIdentOfPath(name)%>::evaluateThreadFunc<%iThreadIdx%>() | ||
| 1314 | { | ||
| 1315 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 1316 | << | ||
| 1317 | MeasureTimeValues *valuesStart = MeasureTime::getZeroValues(); | ||
| 1318 | MeasureTimeValues *valuesEnd = MeasureTime::getZeroValues(); | ||
| 1319 | >>%> | ||
| 1320 | |||
| 1321 | while(!_simulationFinished) | ||
| 1322 | { | ||
| 1323 | //_evaluateBarrier.wait(); | ||
| 1324 | _levelBarrier.wait(); | ||
| 1325 | if(_simulationFinished) | ||
| 1326 | { | ||
| 1327 | //_evaluateBarrier.wait(); | ||
| 1328 | _levelBarrier.wait(); | ||
| 1329 | break; | ||
| 1330 | } | ||
| 1331 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then '<%generateMeasureTimeStartCode("valuesStart", 'evaluateODEThread<%iThreadIdx%>', "MEASURETIME_MODELFUNCTIONS")%>'%> | ||
| 1332 | if(_evaluateMode == 0) | ||
| 1333 | { | ||
| 1334 | evaluateThreadFuncODE_<%iThreadIdx%>(); | ||
| 1335 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 1336 | << | ||
| 1337 | <%generateMeasureTimeEndCode("valuesStart", "valuesEnd", '(*measureTimeThreadArrayOdeHpcom)[<%iThreadIdx%>]', 'evaluateODEThread<%iThreadIdx%>', "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1338 | >>%> | ||
| 1339 | } | ||
| 1340 | else if(_evaluateMode < 0) | ||
| 1341 | { | ||
| 1342 | evaluateThreadFuncAll_<%iThreadIdx%>(); | ||
| 1343 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 1344 | << | ||
| 1345 | <%generateMeasureTimeEndCode("valuesStart", "valuesEnd", '(*measureTimeThreadArrayDaeHpcom)[<%iThreadIdx%>]', 'evaluateDaeThread<%iThreadIdx%>', "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1346 | >>%> | ||
| 1347 | } | ||
| 1348 | else | ||
| 1349 | { | ||
| 1350 | evaluateThreadFuncZeroFunc_<%iThreadIdx%>(); | ||
| 1351 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 1352 | << | ||
| 1353 | <%generateMeasureTimeEndCode("valuesStart", "valuesEnd", '(*measureTimeThreadArrayZeroFuncHpcom)[<%iThreadIdx%>]', 'evaluateZeroFuncThread<%iThreadIdx%>', "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1354 | >>%> | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | //_evaluateBarrier.wait(); | ||
| 1358 | _levelBarrier.wait(); | ||
| 1359 | } | ||
| 1360 | <%if boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")) then | ||
| 1361 | << | ||
| 1362 | delete valuesStart; | ||
| 1363 | delete valuesEnd; | ||
| 1364 | >>%> | ||
| 1365 | } | ||
| 1366 | >> | ||
| 1367 | %> | ||
| 1368 | >> | ||
| 1369 | else "" | ||
| 1370 | end generateLevelFixedCodeForThread; | ||
| 1371 | |||
| 1372 | 7 | template generateLevelFixedCodeForThreadLevel(list<SimEqSystem> allEquationsPlusWhen, list<HpcOmSimCode.Task> tasksOfLevel, | |
| 1373 | Integer iThreadIdx, String functionName, String iType, Integer iLevelIdx, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1374 | ::= | ||
| 1375 | let tasks = tasksOfLevel |> t => taskCode(allEquationsPlusWhen, t, iType, "", varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1376 | << | ||
| 1377 | //Start of Level <%iLevelIdx%> | ||
| 1378 | <%if intEq(iThreadIdx, 0) then | ||
| 1379 | << | ||
| 1380 | <%generateMeasureTimeStartCode("measuredSchedulerStartValues", '<%functionName%>_level_<%intAdd(iLevelIdx,1)%>', "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1381 | >> | ||
| 1382 | %> | ||
| 1383 | |||
| 1384 | <%if(stringEq(tasks,"")) then '' else ''%> | ||
| 1385 | <%tasks%> | ||
| 1386 | _levelBarrier.wait(); | ||
| 1387 | |||
| 1388 | <%if intEq(iThreadIdx, 0) then | ||
| 1389 | << | ||
| 1390 | <%generateMeasureTimeEndCode("measuredSchedulerStartValues", "measuredSchedulerEndValues", '(*measureTimeSchedulerArrayHpcom_<%functionName%>)[<%iLevelIdx%>]', '<%functionName%>_level_<%intAdd(iLevelIdx,1)%>', "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1391 | >> | ||
| 1392 | %> | ||
| 1393 | //End of Level <%iLevelIdx%> | ||
| 1394 | >> | ||
| 1395 | end generateLevelFixedCodeForThreadLevel; | ||
| 1396 | |||
| 1397 | ✗ | template function_HPCOM_TaskDep(list<tuple<Task,list<Integer>>> tasks, list<SimEqSystem> allEquationsPlusWhen, String iType, | |
| 1398 | Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1399 | ::= | ||
| 1400 | let odeEqs = tasks |> t => function_HPCOM_TaskDep0(t,allEquationsPlusWhen, iType, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1401 | << | ||
| 1402 | |||
| 1403 | int t[0]; | ||
| 1404 | #pragma omp parallel | ||
| 1405 | { | ||
| 1406 | #pragma omp master | ||
| 1407 | { | ||
| 1408 | <%odeEqs%> | ||
| 1409 | } | ||
| 1410 | } | ||
| 1411 | >> | ||
| 1412 | end function_HPCOM_TaskDep; | ||
| 1413 | |||
| 1414 | ✗ | template function_HPCOM_TaskDep0(tuple<Task,list<Integer>> taskIn, list<SimEqSystem> allEquationsPlusWhen, String iType, Text &varDecls, | |
| 1415 | SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1416 | ::= | ||
| 1417 | match taskIn | ||
| 1418 | case ((task as CALCTASK(__),parents)) then | ||
| 1419 | let taskEqs = taskCode(allEquationsPlusWhen, task, iType, "", &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace,useFlatArrayNotation); separator="\n" | ||
| 1420 | let parentDependencies = parents |> p => 't[<%p%>]'; separator = "," | ||
| 1421 | let taskDependencies = parents |> p => '<%p%>'; separator = "," | ||
| 1422 | let depIn = if intGt(listLength(parents),0) then 'depend(in:<%parentDependencies%>) ' else "" | ||
| 1423 | << | ||
| 1424 | //TG_NODE: <%task.index%> TG_PARENTS: <%taskDependencies%> | ||
| 1425 | #pragma omp task <%depIn%>depend(out:t[<%task.index%>]) | ||
| 1426 | { | ||
| 1427 | <%taskEqs%> | ||
| 1428 | } | ||
| 1429 | >> | ||
| 1430 | end match | ||
| 1431 | end function_HPCOM_TaskDep0; | ||
| 1432 | |||
| 1433 | ✗ | template generateTbbConstructorExtension(list<tuple<Task,list<Integer>>> odeTasks, list<tuple<Task,list<Integer>>> daeTasks, list<tuple<Task,list<Integer>>> zeroFuncTasks, String modelNamePrefixStr) | |
| 1434 | ::= | ||
| 1435 | let odeNodes = odeTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionNodes(t,i,"Ode",modelNamePrefixStr); separator="\n" | ||
| 1436 | let odeEdges = odeTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionEdges(t,i,"Ode",modelNamePrefixStr); separator="\n" | ||
| 1437 | let daeNodes = daeTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionNodes(t,i,"All",modelNamePrefixStr); separator="\n" | ||
| 1438 | let daeEdges = daeTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionEdges(t,i,"All",modelNamePrefixStr); separator="\n" | ||
| 1439 | let zeroFuncNodes = zeroFuncTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionNodes(t,i,"ZeroFunc",modelNamePrefixStr); separator="\n" | ||
| 1440 | let zeroFuncEdges = zeroFuncTasks |> t hasindex i fromindex 0 => generateTbbConstructorExtensionEdges(t,i,"ZeroFunc",modelNamePrefixStr); separator="\n" | ||
| 1441 | << | ||
| 1442 | tbb::flow::continue_node<tbb::flow::continue_msg> *tbb_task; | ||
| 1443 | <%odeNodes%> | ||
| 1444 | <%odeEdges%> | ||
| 1445 | <%daeNodes%> | ||
| 1446 | <%daeEdges%> | ||
| 1447 | <%zeroFuncNodes%> | ||
| 1448 | <%zeroFuncEdges%> | ||
| 1449 | #if TBB_INTERFACE_VERSION >= 8000 | ||
| 1450 | _tbbArena = tbb::task_arena(<%getConfigInt(NUM_PROC)%>); | ||
| 1451 | _tbbArenaFunctorOde = TbbArenaFunctor(_tbbGraphOde,_tbbStartNodeOde); | ||
| 1452 | _tbbArenaFunctorAll = TbbArenaFunctor(_tbbGraphAll,_tbbStartNodeAll); | ||
| 1453 | _tbbArenaFunctorZeroFunc = TbbArenaFunctor(_tbbGraphZeroFunc,_tbbStartNodeZeroFunc); | ||
| 1454 | #endif | ||
| 1455 | >> | ||
| 1456 | end generateTbbConstructorExtension; | ||
| 1457 | |||
| 1458 | ✗ | template generateTbbConstructorExtensionNodes(tuple<Task,list<Integer>> taskIn, Integer taskIndex, String funcSuffix, String modelNamePrefixStr) | |
| 1459 | ::= | ||
| 1460 | match taskIn | ||
| 1461 | case ((task as CALCTASK(__),parents)) then | ||
| 1462 | << | ||
| 1463 | tbb_task = new tbb::flow::continue_node<tbb::flow::continue_msg>(_tbbGraph<%funcSuffix%>,VoidFunctionBody(bind<void>(&<%modelNamePrefixStr%>::taskFunc<%funcSuffix%>_<%task.index%>,this))); | ||
| 1464 | _tbbNodeList<%funcSuffix%>.at(<%taskIndex%>) = tbb_task; | ||
| 1465 | >> | ||
| 1466 | end match | ||
| 1467 | end generateTbbConstructorExtensionNodes; | ||
| 1468 | |||
| 1469 | ✗ | template generateTbbConstructorExtensionEdges(tuple<Task,list<Integer>> taskIn, Integer taskIndex, String funcSuffix, String modelNamePrefixStr) | |
| 1470 | ::= | ||
| 1471 | match taskIn | ||
| 1472 | case ((task as CALCTASK(__),parents)) then | ||
| 1473 | let parentEdges = parents |> p => 'tbb::flow::make_edge(*(_tbbNodeList<%funcSuffix%>.at(<%intSub(p,1)%>)),*(_tbbNodeList<%funcSuffix%>.at(<%taskIndex%>)));'; separator = "\n" | ||
| 1474 | let startNodeEdge = if intEq(0, listLength(parents)) then 'tbb::flow::make_edge(_tbbStartNode<%funcSuffix%>,*(_tbbNodeList<%funcSuffix%>.at(<%taskIndex%>)));' else "" | ||
| 1475 | << | ||
| 1476 | <%parentEdges%> | ||
| 1477 | <%startNodeEdge%> | ||
| 1478 | >> | ||
| 1479 | end match | ||
| 1480 | end generateTbbConstructorExtensionEdges; | ||
| 1481 | |||
| 1482 | ✗ | template function_HPCOM_TaskDep_voidfunc(list<tuple<Task,list<Integer>>> odeTasks, list<tuple<Task,list<Integer>>> daeTasks, list<tuple<Task,list<Integer>>> zeroFuncTasks, list<SimEqSystem> allEquationsPlusWhen, | |
| 1483 | String iType, Absyn.Path name, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1484 | ::= | ||
| 1485 | let funcTasksOde = odeTasks |> t => function_HPCOM_TaskDep_voidfunc0(t,allEquationsPlusWhen,iType, "Ode", name, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1486 | let funcTasksDae = daeTasks |> t => function_HPCOM_TaskDep_voidfunc0(t,allEquationsPlusWhen,iType, "All", name, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1487 | let funcTasksZeroFunc = zeroFuncTasks |> t => function_HPCOM_TaskDep_voidfunc0(t,allEquationsPlusWhen,iType, "ZeroFunc", name, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1488 | << | ||
| 1489 | <%funcTasksOde%> | ||
| 1490 | <%funcTasksDae%> | ||
| 1491 | <%funcTasksZeroFunc%> | ||
| 1492 | >> | ||
| 1493 | end function_HPCOM_TaskDep_voidfunc; | ||
| 1494 | |||
| 1495 | ✗ | template function_HPCOM_TaskDep_voidfunc0(tuple<Task,list<Integer>> taskIn, list<SimEqSystem> allEquationsPlusWhen, String iType, String funcSuffix, Absyn.Path name, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1496 | ::= | ||
| 1497 | match taskIn | ||
| 1498 | case ((task as CALCTASK(__),parents)) then | ||
| 1499 | let &tempvarDecl = buffer "" /*BUFD*/ | ||
| 1500 | let taskEqs = taskCode(allEquationsPlusWhen, task, iType, "", &tempvarDecl, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace,useFlatArrayNotation); separator="\n" | ||
| 1501 | << | ||
| 1502 | void <%lastIdentOfPath(name)%>::taskFunc<%funcSuffix%>_<%task.index%>() | ||
| 1503 | { | ||
| 1504 | <%tempvarDecl%> | ||
| 1505 | <%taskEqs%> | ||
| 1506 | } | ||
| 1507 | >> | ||
| 1508 | end match | ||
| 1509 | end function_HPCOM_TaskDep_voidfunc0; | ||
| 1510 | |||
| 1511 | /* | ||
| 1512 | template function_HPCOM_Thread(list<SimEqSystem> allEquationsPlusWhen, array<list<Task>> threadTasksOde, array<list<Task>> threadTasksDae, array<list<Task>> threadTasksZeroFunc, String iType,Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1513 | ::= | ||
| 1514 | let odeEqs = arrayList(threadTasksOde) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,iType,"_lockOde",&varDecls,simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateODE", useFlatArrayNotation); separator="\n" | ||
| 1515 | let daeEqs = arrayList(threadTasksDae) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,iType,"_lockDae",&varDecls,simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateAll", useFlatArrayNotation); separator="\n" | ||
| 1516 | let zeroFuncEqs = arrayList(threadTasksDae) |> tt hasindex i0 => parallelThreadCodeWithSplit(allEquationsPlusWhen,tt,i0,iType,"_lockZeroFunc",&varDecls,simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateZeroFunc", useFlatArrayNotation); separator="\n" | ||
| 1517 | match iType | ||
| 1518 | case ("mpi") then | ||
| 1519 | << | ||
| 1520 | int world_rank; | ||
| 1521 | MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); | ||
| 1522 | if(_evaluateMode == 0) | ||
| 1523 | { | ||
| 1524 | <%odeEqs%> | ||
| 1525 | } | ||
| 1526 | else if(_evaluateMode < 0) | ||
| 1527 | { | ||
| 1528 | <%daeEqs%> | ||
| 1529 | } | ||
| 1530 | else | ||
| 1531 | { | ||
| 1532 | <%zeroFuncEqs%> | ||
| 1533 | } | ||
| 1534 | >> | ||
| 1535 | else | ||
| 1536 | << | ||
| 1537 | if(_evaluateMode == 0) | ||
| 1538 | { | ||
| 1539 | <%generateMeasureTimeStartCode("measuredSchedulerStartValues", "evaluateODE_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1540 | <%odeEqs%> | ||
| 1541 | <%generateMeasureTimeEndCode("measuredSchedulerStartValues", "measuredSchedulerEndValues", "(*measureTimeThreadArrayOdeHpcom)[threadNum]", "evaluateODE_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1542 | } | ||
| 1543 | else if(_evaluateMode < 0) | ||
| 1544 | { | ||
| 1545 | <%generateMeasureTimeStartCode("measuredSchedulerStartValues", "evaluateDAE_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1546 | <%daeEqs%> | ||
| 1547 | <%generateMeasureTimeEndCode("measuredSchedulerStartValues", "measuredSchedulerEndValues", "(*measureTimeThreadArrayDaeHpcom)[threadNum]", "evaluateDAE_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1548 | } | ||
| 1549 | else | ||
| 1550 | { | ||
| 1551 | <%generateMeasureTimeStartCode("measuredSchedulerStartValues", "evaluateZeroFunc_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1552 | <%zeroFuncEqs%> | ||
| 1553 | <%generateMeasureTimeEndCode("measuredSchedulerStartValues", "measuredSchedulerEndValues", "(*measureTimeThreadArrayZeroFuncHpcom)[threadNum]", "evaluateZeroFunc_threads", "MEASURETIME_MODELFUNCTIONS")%> | ||
| 1554 | } | ||
| 1555 | >> | ||
| 1556 | end match | ||
| 1557 | end function_HPCOM_Thread; | ||
| 1558 | */ | ||
| 1559 | ✗ | template generateThreadFunc(list<SimEqSystem> allEquationsPlusWhen, list<Task> threadTasksOde, list<Task> threadTasksDae, list<Task> threadTasksZeroFunc, String iType, Integer iThreadIdx, String modelNamePrefixStr, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Text& mainThreadCode, Boolean useFlatArrayNotation) | |
| 1560 | ::= | ||
| 1561 | let &varDeclsLoc = buffer "" /*BUFD*/ | ||
| 1562 | let taskEqsOde = parallelThreadCode(allEquationsPlusWhen, threadTasksOde, iThreadIdx, iType, "_lockOde", &varDeclsLoc, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateODE", useFlatArrayNotation); separator="\n" | ||
| 1563 | let taskEqsDae = parallelThreadCode(allEquationsPlusWhen, threadTasksDae, iThreadIdx, iType, "_lockDae", &varDeclsLoc, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateAll", useFlatArrayNotation); separator="\n" | ||
| 1564 | let taskEqsZeroFunc = parallelThreadCode(allEquationsPlusWhen, threadTasksZeroFunc, iThreadIdx, iType, "_lockZeroFunc", &varDeclsLoc, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, "evaluateZeroFunc", useFlatArrayNotation); separator="\n" | ||
| 1565 | let assLock = assignLockByLockName(iThreadIdx, "th_lock", iType); separator="\n" | ||
| 1566 | let relLock = releaseLockByLockName(iThreadIdx, "th_lock1", iType); separator="\n" | ||
| 1567 | let &extraFuncsDecl += | ||
| 1568 | << | ||
| 1569 | void evaluateThreadFuncODE_<%iThreadIdx%>(); | ||
| 1570 | void evaluateThreadFuncAll_<%iThreadIdx%>(); | ||
| 1571 | void evaluateThreadFuncZeroFunc_<%iThreadIdx%>(); | ||
| 1572 | >> | ||
| 1573 | |||
| 1574 | if (intGt(iThreadIdx, 0)) then | ||
| 1575 | << | ||
| 1576 | void <%modelNamePrefixStr%>::evaluateThreadFuncODE_<%iThreadIdx%>() | ||
| 1577 | { | ||
| 1578 | <%taskEqsOde%> | ||
| 1579 | } | ||
| 1580 | |||
| 1581 | void <%modelNamePrefixStr%>::evaluateThreadFuncAll_<%iThreadIdx%>() | ||
| 1582 | { | ||
| 1583 | <%taskEqsDae%> | ||
| 1584 | } | ||
| 1585 | |||
| 1586 | void <%modelNamePrefixStr%>::evaluateThreadFuncZeroFunc_<%iThreadIdx%>() | ||
| 1587 | { | ||
| 1588 | <%taskEqsZeroFunc%> | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | void <%modelNamePrefixStr%>::evaluateThreadFunc<%iThreadIdx%>() | ||
| 1592 | { | ||
| 1593 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 1594 | MeasureTimeValues *measuredSchedulerStartValues = measuredSchedulerStartValues_<%intSub(iThreadIdx,1)%>; | ||
| 1595 | MeasureTimeValues *measuredSchedulerEndValues = measuredSchedulerEndValues_<%intSub(iThreadIdx,1)%>; | ||
| 1596 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 1597 | <%&varDeclsLoc%> | ||
| 1598 | while(1) | ||
| 1599 | { | ||
| 1600 | <%assLock%> | ||
| 1601 | if(_terminateThreads) | ||
| 1602 | return; | ||
| 1603 | |||
| 1604 | if(_evaluateMode == 0) | ||
| 1605 | { | ||
| 1606 | evaluateThreadFuncODE_<%iThreadIdx%>(); | ||
| 1607 | } | ||
| 1608 | else if(_evaluateMode < 0) | ||
| 1609 | { | ||
| 1610 | evaluateThreadFuncAll_<%iThreadIdx%>(); | ||
| 1611 | } | ||
| 1612 | else | ||
| 1613 | { | ||
| 1614 | evaluateThreadFuncZeroFunc_<%iThreadIdx%>(); | ||
| 1615 | } | ||
| 1616 | <%relLock%> | ||
| 1617 | } | ||
| 1618 | } | ||
| 1619 | >> | ||
| 1620 | else | ||
| 1621 | let &mainThreadCode += &varDeclsLoc | ||
| 1622 | let &mainThreadCode += | ||
| 1623 | << | ||
| 1624 | #ifdef MEASURETIME_MODELFUNCTIONS | ||
| 1625 | MeasureTimeValues *measuredSchedulerStartValues = measuredSchedulerStartValues_0; | ||
| 1626 | MeasureTimeValues *measuredSchedulerEndValues = measuredSchedulerEndValues_0; | ||
| 1627 | #endif //MEASURETIME_MODELFUNCTIONS | ||
| 1628 | if(_evaluateMode == 0) | ||
| 1629 | { | ||
| 1630 | evaluateThreadFuncODE_<%iThreadIdx%>(); | ||
| 1631 | } | ||
| 1632 | else if(_evaluateMode < 0) | ||
| 1633 | { | ||
| 1634 | evaluateThreadFuncAll_<%iThreadIdx%>(); | ||
| 1635 | } | ||
| 1636 | else | ||
| 1637 | { | ||
| 1638 | evaluateThreadFuncZeroFunc_<%iThreadIdx%>(); | ||
| 1639 | } | ||
| 1640 | >> | ||
| 1641 | << | ||
| 1642 | void <%modelNamePrefixStr%>::evaluateThreadFuncODE_<%iThreadIdx%>() | ||
| 1643 | { | ||
| 1644 | <%taskEqsOde%> | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | void <%modelNamePrefixStr%>::evaluateThreadFuncAll_<%iThreadIdx%>() | ||
| 1648 | { | ||
| 1649 | <%taskEqsDae%> | ||
| 1650 | } | ||
| 1651 | |||
| 1652 | void <%modelNamePrefixStr%>::evaluateThreadFuncZeroFunc_<%iThreadIdx%>() | ||
| 1653 | { | ||
| 1654 | <%taskEqsZeroFunc%> | ||
| 1655 | } | ||
| 1656 | >> | ||
| 1657 | end generateThreadFunc; | ||
| 1658 | |||
| 1659 | ✗ | template function_HPCOM_assignThreadLocks(list<Task> iThreadTasks, String iLockPrefix, Integer iThreadNum, String iType) | |
| 1660 | ::= | ||
| 1661 | let lockAssign = iThreadTasks |> tt => '<%( | ||
| 1662 | match(tt) | ||
| 1663 | case(task as DEPTASK(outgoing=true)) then | ||
| 1664 | assignLockByDepTask(task, iLockPrefix, iType) | ||
| 1665 | else "" | ||
| 1666 | end match)%>'; separator="\n" | ||
| 1667 | << | ||
| 1668 | <%if intNe(iThreadNum, 0) then 'else ' else ''%>if(threadNum == <%iThreadNum%>) | ||
| 1669 | { | ||
| 1670 | <%lockAssign%> | ||
| 1671 | } | ||
| 1672 | >> | ||
| 1673 | end function_HPCOM_assignThreadLocks; | ||
| 1674 | |||
| 1675 | ✗ | template function_HPCOM_releaseThreadLocks(list<Task> iThreadTasks, String iLockPrefix, Integer iThreadNum, String iType) | |
| 1676 | ::= | ||
| 1677 | let lockAssign = iThreadTasks |> tt => '<%( | ||
| 1678 | match(tt) | ||
| 1679 | case(DEPTASK(outgoing=false)) then | ||
| 1680 | releaseLockByDepTask(tt, iLockPrefix, iType) | ||
| 1681 | else "" | ||
| 1682 | end match)%>'; separator="\n" | ||
| 1683 | << | ||
| 1684 | <%if intNe(iThreadNum, 0) then 'else ' else ''%>if(threadNum == <%iThreadNum%>) | ||
| 1685 | { | ||
| 1686 | <%lockAssign%> | ||
| 1687 | } | ||
| 1688 | >> | ||
| 1689 | end function_HPCOM_releaseThreadLocks; | ||
| 1690 | |||
| 1691 | ✗ | template parallelThreadCodeWithSplit(list<SimEqSystem> allEquationsPlusWhen, list<Task> threadTaskList, Integer iThreadNum, Integer iMaxThreadNumber, | |
| 1692 | String iType, String lockPrefix, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, | ||
| 1693 | Text extraFuncsNamespace, String extraFunctionName, Boolean useFlatArrayNotation) | ||
| 1694 | ::= | ||
| 1695 | let functionCalls = List.partition(threadTaskList, 100) |> tt hasindex i0 => parallelThreadCode(allEquationsPlusWhen,tt,i0,iType,lockPrefix,&varDecls,simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, '<%extraFunctionName%>_Th<%iThreadNum%>', useFlatArrayNotation); separator="\n" | ||
| 1696 | match iType | ||
| 1697 | case ("openmp") then | ||
| 1698 | << | ||
| 1699 | <%if intEq(iThreadNum, 0) then 'switch(threadNum) <%\n%>{<%\n%>' else '' %>case <%iThreadNum%>: | ||
| 1700 | <%functionCalls%> | ||
| 1701 | break; | ||
| 1702 | <%if intEq(iThreadNum, iMaxThreadNumber) then '<%\n%>}' else ''%> | ||
| 1703 | >> | ||
| 1704 | case ("mpi") then | ||
| 1705 | << | ||
| 1706 | if (world_rank == <%iThreadNum%>) | ||
| 1707 | { | ||
| 1708 | <%functionCalls%> | ||
| 1709 | } | ||
| 1710 | >> | ||
| 1711 | else | ||
| 1712 | << | ||
| 1713 | <%functionCalls%> | ||
| 1714 | >> | ||
| 1715 | end match | ||
| 1716 | end parallelThreadCodeWithSplit; | ||
| 1717 | |||
| 1718 | ✗ | template parallelThreadCode(list<SimEqSystem> allEquationsPlusWhen, list<Task> threadTaskList, Integer iPartitionIndex, | |
| 1719 | String iType, String lockPrefix, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, String extraFunctionName, Boolean useFlatArrayNotation) | ||
| 1720 | ::= | ||
| 1721 | let threadTasks = threadTaskList |> tt => taskCode(allEquationsPlusWhen,tt,iType,lockPrefix,&varDecls,simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace,useFlatArrayNotation); separator="\n" | ||
| 1722 | let &extraFuncs += | ||
| 1723 | << | ||
| 1724 | void <%extraFuncsNamespace%>::<%extraFunctionName%>_<%iPartitionIndex%>() | ||
| 1725 | { | ||
| 1726 | <%threadTasks%> | ||
| 1727 | }<%\n%><%\n%> | ||
| 1728 | >> | ||
| 1729 | let &extraFuncsDecl += 'void <%extraFunctionName%>_<%iPartitionIndex%>();' | ||
| 1730 | |||
| 1731 | << | ||
| 1732 | <%extraFunctionName%>_<%iPartitionIndex%>(); | ||
| 1733 | >> | ||
| 1734 | end parallelThreadCode; | ||
| 1735 | |||
| 1736 | 102 | template taskCode(list<SimEqSystem> allEquationsPlusWhen, Task iTask, String iType, String lockPrefix, Text &varDecls, | |
| 1737 | SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | ||
| 1738 | ::= | ||
| 1739 | match iTask | ||
| 1740 | case (task as CALCTASK(__)) then | ||
| 1741 | let odeEqs = task.eqIdc |> eq => equationNamesHPCOM_(eq,allEquationsPlusWhen,contextSimulationNonDiscrete,&varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1742 | let &varDeclsLocal = buffer "" /*BUFL*/ | ||
| 1743 | << | ||
| 1744 | // Task <%task.index%> | ||
| 1745 | <%odeEqs%> | ||
| 1746 | // End Task <%task.index%> | ||
| 1747 | >> | ||
| 1748 | case (task as CALCTASK_LEVEL(__)) then | ||
| 1749 | let odeEqs = task.eqIdc |> eq => equationNamesHPCOM_(eq,allEquationsPlusWhen,contextSimulationNonDiscrete,&varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation); separator="\n" | ||
| 1750 | let taskStr = task.nodeIdc |> task => '<%task%>';separator="," | ||
| 1751 | let &varDeclsLocal = buffer "" /*BUFL*/ | ||
| 1752 | << | ||
| 1753 | // Tasks <%taskStr%> | ||
| 1754 | <%odeEqs%> | ||
| 1755 | >> | ||
| 1756 | case(task as DEPTASK(outgoing=false)) then | ||
| 1757 | let assLck = assignLockByDepTask(task, lockPrefix, iType); separator="\n" | ||
| 1758 | << | ||
| 1759 | <%assLck%> | ||
| 1760 | >> | ||
| 1761 | case(task as DEPTASK(outgoing=true)) then | ||
| 1762 | let relLck = releaseLockByDepTask(task, lockPrefix, iType); separator="\n" | ||
| 1763 | << | ||
| 1764 | <%relLck%> | ||
| 1765 | >> | ||
| 1766 | end match | ||
| 1767 | end taskCode; | ||
| 1768 | |||
| 1769 | 171 | template equationNamesHPCOM_(Integer idx, list<SimEqSystem> allEquationsPlusWhen, Context context, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1770 | ::= | ||
| 1771 | let eq = equationHPCOM_(getSimCodeEqByIndex(allEquationsPlusWhen, idx), idx, context, &varDecls, simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, useFlatArrayNotation) | ||
| 1772 | << | ||
| 1773 | <%eq%> | ||
| 1774 | >> | ||
| 1775 | end equationNamesHPCOM_; | ||
| 1776 | |||
| 1777 | 171 | template equationHPCOM_(SimEqSystem eq, Integer idx, Context context, Text &varDecls, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Boolean useFlatArrayNotation) | |
| 1778 | ::= | ||
| 1779 | equation_function_call(eq, context, simCode, "evaluate") | ||
| 1780 | end equationHPCOM_; | ||
| 1781 | |||
| 1782 | ✗ | template function_HPCOM_joinThread(String threadIdx, String iType) | |
| 1783 | ::= | ||
| 1784 | match iType | ||
| 1785 | case ("openmp") then | ||
| 1786 | << | ||
| 1787 | >> | ||
| 1788 | else | ||
| 1789 | << | ||
| 1790 | evaluateThread<%threadIdx%>->join(); | ||
| 1791 | >> | ||
| 1792 | end match | ||
| 1793 | end function_HPCOM_joinThread; | ||
| 1794 | |||
| 1795 | ✗ | template function_HPCOM_destroyThread(String threadIdx, String iType) | |
| 1796 | ::= | ||
| 1797 | match iType | ||
| 1798 | case ("openmp") then | ||
| 1799 | << | ||
| 1800 | >> | ||
| 1801 | else | ||
| 1802 | << | ||
| 1803 | delete evaluateThread<%threadIdx%>; | ||
| 1804 | >> | ||
| 1805 | end match | ||
| 1806 | end function_HPCOM_destroyThread; | ||
| 1807 | |||
| 1808 | ✗ | template generateThread(Integer threadIdx, String iType, String modelNamePrefixStr, String funcName) | |
| 1809 | ::= | ||
| 1810 | match iType | ||
| 1811 | case ("openmp") then | ||
| 1812 | << | ||
| 1813 | >> | ||
| 1814 | else | ||
| 1815 | << | ||
| 1816 | evaluateThread<%threadIdx%> = new thread(bind(&<%modelNamePrefixStr%>::<%funcName%><%threadIdx%>, this)); | ||
| 1817 | >> | ||
| 1818 | end match | ||
| 1819 | end generateThread; | ||
| 1820 | |||
| 1821 | ✗ | template getLockNameByDepTask(Task depTask) | |
| 1822 | ::= | ||
| 1823 | match depTask | ||
| 1824 | case(task as DEPTASK(__)) then | ||
| 1825 | '[<%task.id%>]' | ||
| 1826 | else | ||
| 1827 | 'invalidLockTask' | ||
| 1828 | end match | ||
| 1829 | end getLockNameByDepTask; | ||
| 1830 | |||
| 1831 | ✗ | template initializeLockByDepTask(Task depTask, String lockPrefix, String iType) | |
| 1832 | ::= | ||
| 1833 | let lockName = getLockNameByDepTask(depTask) | ||
| 1834 | << | ||
| 1835 | <%initializeLockByLockName(lockName, lockPrefix, iType)%> | ||
| 1836 | >> | ||
| 1837 | end initializeLockByDepTask; | ||
| 1838 | |||
| 1839 | ✗ | template initializeLockByLockName(String lockName, String lockPrefix, String iType) | |
| 1840 | ::= | ||
| 1841 | match iType | ||
| 1842 | case ("openmp") then | ||
| 1843 | << | ||
| 1844 | omp_init_lock(&<%lockPrefix%>_<%lockName%>); | ||
| 1845 | >> | ||
| 1846 | case ("pthreads") then | ||
| 1847 | << | ||
| 1848 | <%lockPrefix%>_<%lockName%> = new alignedLock(); | ||
| 1849 | >> | ||
| 1850 | case ("pthreads_spin") then | ||
| 1851 | << | ||
| 1852 | <%lockPrefix%>_<%lockName%> = new alignedSpinlock(); | ||
| 1853 | >> | ||
| 1854 | end match | ||
| 1855 | end initializeLockByLockName; | ||
| 1856 | |||
| 1857 | 1 | template initializeBarrierByName(String lockName, String lockPrefix, Integer numberOfThreads, String iType) | |
| 1858 | ::= | ||
| 1859 | match iType | ||
| 1860 | case ("pthreads") | ||
| 1861 | case ("pthreads_spin") then | ||
| 1862 | << | ||
| 1863 | <%lockPrefix%>_<%lockName%>(<%numberOfThreads%>) | ||
| 1864 | >> | ||
| 1865 | end match | ||
| 1866 | end initializeBarrierByName; | ||
| 1867 | |||
| 1868 | ✗ | template createLockByDepTask(Task depTask, String lockPrefix, String iType) | |
| 1869 | ::= | ||
| 1870 | let lockName = getLockNameByDepTask(depTask) | ||
| 1871 | << | ||
| 1872 | <%createLockByLockName(lockName, lockPrefix, iType)%> | ||
| 1873 | >> | ||
| 1874 | end createLockByDepTask; | ||
| 1875 | |||
| 1876 | 2 | template createLockByLockName(String lockName, String lockPrefix, String iType) | |
| 1877 | ::= | ||
| 1878 | match iType | ||
| 1879 | case ("openmp") then | ||
| 1880 | << | ||
| 1881 | omp_lock_t <%lockPrefix%>_<%lockName%>; | ||
| 1882 | >> | ||
| 1883 | case ("pthreads") then | ||
| 1884 | << | ||
| 1885 | alignedLock* <%lockPrefix%>_<%lockName%>; | ||
| 1886 | >> | ||
| 1887 | case ("pthreads_spin") then | ||
| 1888 | << | ||
| 1889 | alignedSpinlock* <%lockPrefix%>_<%lockName%>; | ||
| 1890 | >> | ||
| 1891 | end match | ||
| 1892 | end createLockByLockName; | ||
| 1893 | |||
| 1894 | 1 | template createBarrierByName(String lockName, String lockPrefix, Integer numOfThreads, String iType) | |
| 1895 | ::= | ||
| 1896 | match iType | ||
| 1897 | case ("pthreads") | ||
| 1898 | case ("pthreads_spin") then | ||
| 1899 | << | ||
| 1900 | busywaiting_barrier <%lockPrefix%>_<%lockName%>; | ||
| 1901 | >> | ||
| 1902 | end match | ||
| 1903 | end createBarrierByName; | ||
| 1904 | |||
| 1905 | ✗ | template destroyLockByDepTask(Task depTask, String lockPrefix, String iType) | |
| 1906 | ::= | ||
| 1907 | let lockName = getLockNameByDepTask(depTask) | ||
| 1908 | << | ||
| 1909 | <%destroyLockByLockName(lockName, lockPrefix, iType)%> | ||
| 1910 | >> | ||
| 1911 | end destroyLockByDepTask; | ||
| 1912 | |||
| 1913 | ✗ | template destroyLockByLockName(String lockName, String lockPrefix, String iType) | |
| 1914 | ::= | ||
| 1915 | match iType | ||
| 1916 | case ("openmp") then | ||
| 1917 | << | ||
| 1918 | omp_destroy_lock(&<%lockPrefix%>_<%lockName%>); | ||
| 1919 | >> | ||
| 1920 | case ("pthreads") | ||
| 1921 | case ("pthreads_spin") then | ||
| 1922 | << | ||
| 1923 | delete <%lockPrefix%>_<%lockName%>; | ||
| 1924 | >> | ||
| 1925 | else | ||
| 1926 | << | ||
| 1927 | >> | ||
| 1928 | end match | ||
| 1929 | end destroyLockByLockName; | ||
| 1930 | |||
| 1931 | ✗ | template assignLockByDepTask(Task depTask, String lockPrefix, String iType) | |
| 1932 | ::= | ||
| 1933 | match(depTask) | ||
| 1934 | case(DEPTASK(__)) then | ||
| 1935 | let lockName = getLockNameByDepTask(depTask) | ||
| 1936 | //let commInfoStr = printCommunicationInfoVariables(depTask.communicationInfo) | ||
| 1937 | << | ||
| 1938 | <%assignLockByLockName(lockName, lockPrefix, iType)%> | ||
| 1939 | >> | ||
| 1940 | end match | ||
| 1941 | end assignLockByDepTask; | ||
| 1942 | |||
| 1943 | ✗ | template printCommunicationInfoVariables(CommunicationInfo commInfo) | |
| 1944 | ::= | ||
| 1945 | "" | ||
| 1946 | /* | ||
| 1947 | match(commInfo) | ||
| 1948 | case(COMMUNICATION_INFO(__)) then | ||
| 1949 | let floatVarsStr = floatVars |> v => '<%CodegenCpp.MemberVariableDefine2(v, "", false, true)%>' ;separator="\n" | ||
| 1950 | let intVarsStr = intVars |> v => '<%CodegenCpp.MemberVariableDefine2(v, "", false, true)%>' ;separator="\n" | ||
| 1951 | let boolVarsStr = boolVars |> v => '<%CodegenCpp.MemberVariableDefine2(v, "", false, true)%>' ;separator="\n" | ||
| 1952 | << | ||
| 1953 | <%floatVarsStr%> | ||
| 1954 | >> | ||
| 1955 | else | ||
| 1956 | << | ||
| 1957 | //unsupported communcation info | ||
| 1958 | >> | ||
| 1959 | end match | ||
| 1960 | */ | ||
| 1961 | end printCommunicationInfoVariables; | ||
| 1962 | |||
| 1963 | ✗ | template assignLockByLockName(String lockName, String lockPrefix, String iType) | |
| 1964 | ::= | ||
| 1965 | match iType | ||
| 1966 | case ("openmp") then | ||
| 1967 | << | ||
| 1968 | omp_set_lock(&<%lockPrefix%>_<%lockName%>); | ||
| 1969 | >> | ||
| 1970 | case ("pthreads") | ||
| 1971 | case ("pthreads_spin") then | ||
| 1972 | << | ||
| 1973 | <%lockPrefix%>_<%lockName%>->lock(); | ||
| 1974 | >> | ||
| 1975 | end match | ||
| 1976 | end assignLockByLockName; | ||
| 1977 | |||
| 1978 | ✗ | template releaseLockByDepTask(Task depTask, String lockPrefix, String iType) | |
| 1979 | ::= | ||
| 1980 | let lockName = getLockNameByDepTask(depTask) | ||
| 1981 | << | ||
| 1982 | <%releaseLockByLockName(lockName, lockPrefix, iType)%> | ||
| 1983 | >> | ||
| 1984 | end releaseLockByDepTask; | ||
| 1985 | |||
| 1986 | |||
| 1987 | ✗ | template releaseLockByLockName(String lockName, String lockPrefix, String iType) | |
| 1988 | ::= | ||
| 1989 | match iType | ||
| 1990 | case ("openmp") then | ||
| 1991 | << | ||
| 1992 | omp_unset_lock(&<%lockPrefix%>_<%lockName%>); | ||
| 1993 | >> | ||
| 1994 | case ("pthreads") then | ||
| 1995 | << | ||
| 1996 | <%lockPrefix%>_<%lockName%>->unlock(); | ||
| 1997 | >> | ||
| 1998 | case ("pthreads_spin") then | ||
| 1999 | << | ||
| 2000 | <%lockPrefix%>_<%lockName%>->unlock(); | ||
| 2001 | >> | ||
| 2002 | end match | ||
| 2003 | end releaseLockByLockName; | ||
| 2004 | |||
| 2005 | |||
| 2006 | ✗ | template mpiFinalize() | |
| 2007 | "Finalize the MPI environment in main function." | ||
| 2008 | ::= | ||
| 2009 | << | ||
| 2010 | } // End sequential | ||
| 2011 | MPI_Finalize(); | ||
| 2012 | >> | ||
| 2013 | end mpiFinalize; | ||
| 2014 | |||
| 2015 | ✗ | template mpiInit() | |
| 2016 | "Initialize the MPI environment in main function." | ||
| 2017 | ::= | ||
| 2018 | << | ||
| 2019 | char** argvNotConst = const_cast<char**>(argv); | ||
| 2020 | MPI_Init(&argc, &argvNotConst); | ||
| 2021 | int world_rank, world_size; | ||
| 2022 | MPI_Comm_size(MPI_COMM_WORLD, &world_size); | ||
| 2023 | MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); | ||
| 2024 | std::cout << "Hello world! This is MPI process " << world_rank | ||
| 2025 | << " of " << world_size << " processes." << endl; | ||
| 2026 | |||
| 2027 | // Run simulation in sequential | ||
| 2028 | if (0 == world_rank) { | ||
| 2029 | std::cout << "Remark: Simulation is not (yet) MPI parallel!\n"; | ||
| 2030 | >> | ||
| 2031 | end mpiInit; | ||
| 2032 | |||
| 2033 | 1 | template mpiRunCommandInRunScript(String type, Text &getNumOfProcs, Text &execCommandLinux) | |
| 2034 | "If MPI is used: | ||
| 2035 | - Add the run execution command 'mpirun -np $NPROCESSORS', | ||
| 2036 | - number of MPI processors can be passed as command line argument to simulation | ||
| 2037 | run script." | ||
| 2038 | ::= | ||
| 2039 | match type | ||
| 2040 | case "mpi" then | ||
| 2041 | let &execCommandLinux += "mpirun -np ${NPROCESSORS}" | ||
| 2042 | let &getNumOfProcs += "\nif [ $# -gt 0 ]; then\n NPROCESSORS=$1\n shift \nelse\n NPROCESSORS=1\nfi\n\n" | ||
| 2043 | "" | ||
| 2044 | else | ||
| 2045 | let &execCommandLinux += "exec" | ||
| 2046 | "" | ||
| 2047 | end match | ||
| 2048 | end mpiRunCommandInRunScript; | ||
| 2049 | |||
| 2050 | 1 | template simulationMainRunScript(SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) | |
| 2051 | "Generates code for header file for simulation target." | ||
| 2052 | ::= | ||
| 2053 | let type = if Flags.isSet(Flags.USEMPI) then "mpi" else '' | ||
| 2054 | let &preRunCommandLinux = buffer "" | ||
| 2055 | let &execCommandLinux = buffer "" | ||
| 2056 | let _ = mpiRunCommandInRunScript(type, &preRunCommandLinux, &execCommandLinux) | ||
| 2057 | let preRunCommandWindows = "" | ||
| 2058 | |||
| 2059 | CodegenCpp.simulationMainRunScript(simCode, extraFuncs, extraFuncsDecl, extraFuncsNamespace, preRunCommandLinux, preRunCommandWindows, execCommandLinux) | ||
| 2060 | end simulationMainRunScript; | ||
| 2061 | |||
| 2062 | 1 | template getAdditionalMakefileFlags(Text& additionalLinkerFlags_GCC, Text& additionalLinkerFlags_MSVC, Text& additionalCFlags_GCC, Text& additionalCFlags_MSVC) | |
| 2063 | ::= | ||
| 2064 | let type = getConfigString(HPCOM_CODE) | ||
| 2065 | |||
| 2066 | let &additionalCFlags_GCC += if stringEq(type,"openmp") then " -fopenmp" else "" | ||
| 2067 | let &additionalCFlags_GCC += if stringEq(type,"tbb") then ' -I"$(INTEL_TBB_INCLUDE)"' else "" | ||
| 2068 | |||
| 2069 | let &additionalCFlags_MSVC += if stringEq(type,"openmp") then "/openmp" else "" | ||
| 2070 | |||
| 2071 | let &additionalLinkerFlags_GCC += if stringEq(type,"tbb") then "-L$(INTEL_TBB_LIBS) $(INTEL_TBB_LIBRARIES) " else "" | ||
| 2072 | let &additionalLinkerFlags_GCC += if stringEq(type,"openmp") then " -fopenmp" else "" | ||
| 2073 | << | ||
| 2074 | >> | ||
| 2075 | end getAdditionalMakefileFlags; | ||
| 2076 | |||
| 2077 | 1 | template simulationMakefile(String target, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace) | |
| 2078 | "Adds specific compiler flags for HPCOM mode to simulation makefile." | ||
| 2079 | ::= | ||
| 2080 | let &additionalCFlags_GCC = buffer "" | ||
| 2081 | let &additionalCFlags_MSVC = buffer "" | ||
| 2082 | let &additionalLinkerFlags_GCC = buffer "" | ||
| 2083 | let &additionalLinkerFlags_MSVC = buffer "" | ||
| 2084 | |||
| 2085 | << | ||
| 2086 | <%getAdditionalMakefileFlags(additionalLinkerFlags_GCC, additionalLinkerFlags_MSVC, additionalCFlags_GCC, additionalCFlags_MSVC)%> | ||
| 2087 | <%CodegenCpp.simulationMakefile(target, simCode, extraFuncs ,extraFuncsDecl, extraFuncsNamespace, additionalLinkerFlags_GCC, | ||
| 2088 | additionalLinkerFlags_MSVC, additionalCFlags_GCC, additionalCFlags_MSVC, | ||
| 2089 | Flags.isSet(Flags.USEMPI))%> | ||
| 2090 | >> | ||
| 2091 | end simulationMakefile; | ||
| 2092 | |||
| 2093 | 1 | template numPreVarsHpcom(ModelInfo modelInfo, Option<MemoryMap> hpcOmMemoryOpt) | |
| 2094 | ::= | ||
| 2095 | match(hpcOmMemoryOpt) | ||
| 2096 | case(SOME(hpcomMemory as MEMORYMAP_ARRAY(floatArraySize=floatArraySize,intArraySize=intArraySize,boolArraySize=boolArraySize))) then | ||
| 2097 | '<%floatArraySize%> + <%intArraySize%> + <%boolArraySize%>' | ||
| 2098 | else | ||
| 2099 | CodegenCpp.getPreVarsCount(modelInfo) | ||
| 2100 | end numPreVarsHpcom; | ||
| 2101 | |||
| 2102 | 1 | template numRealvarsHpcom(ModelInfo modelInfo, Option<MemoryMap> hpcOmMemoryOpt) | |
| 2103 | ::= | ||
| 2104 | match(hpcOmMemoryOpt) | ||
| 2105 | case(SOME(hpcomMemory as MEMORYMAP_ARRAY(floatArraySize=floatArraySize))) then | ||
| 2106 | '<%floatArraySize%>' | ||
| 2107 | else | ||
| 2108 | '<%CodegenCpp.numRealvars(modelInfo)%>' | ||
| 2109 | end numRealvarsHpcom; | ||
| 2110 | |||
| 2111 | 1 | template numIntvarsHpcom(ModelInfo modelInfo, Option<MemoryMap> hpcOmMemoryOpt) | |
| 2112 | ::= | ||
| 2113 | match(hpcOmMemoryOpt) | ||
| 2114 | case(SOME(hpcomMemory as MEMORYMAP_ARRAY(intArraySize=intArraySize))) then | ||
| 2115 | '<%intArraySize%>' | ||
| 2116 | else | ||
| 2117 | CodegenCpp.numIntvars(modelInfo) | ||
| 2118 | end numIntvarsHpcom; | ||
| 2119 | |||
| 2120 | 1 | template numBoolvarsHpcom(ModelInfo modelInfo, Option<MemoryMap> hpcOmMemoryOpt) | |
| 2121 | ::= | ||
| 2122 | match(hpcOmMemoryOpt) | ||
| 2123 | case(SOME(hpcomMemory as MEMORYMAP_ARRAY(boolArraySize=boolArraySize))) then | ||
| 2124 | '<%boolArraySize%>' | ||
| 2125 | else | ||
| 2126 | CodegenCpp.numBoolvars(modelInfo) | ||
| 2127 | end numBoolvarsHpcom; | ||
| 2128 | |||
| 2129 | ✗ | template numStringvarsHpcom(ModelInfo modelInfo, Option<MemoryMap> hpcOmMemoryOpt) | |
| 2130 | ::= | ||
| 2131 | match(hpcOmMemoryOpt) | ||
| 2132 | case(SOME(hpcomMemory as MEMORYMAP_ARRAY(stringArraySize=stringArraySize))) then | ||
| 2133 | '<%stringArraySize%>' | ||
| 2134 | else | ||
| 2135 | CodegenCpp.numStringvars(modelInfo) | ||
| 2136 | end numStringvarsHpcom; | ||
| 2137 | |||
| 2138 | annotation(__OpenModelica_Interface="codegen_cpp_ext"); | ||
| 2139 | end CodegenCppHpcom; | ||
| 2140 |