From 5c5966b070197498f1b8d6163537e835e9a2c328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 7 Aug 2026 07:57:06 +0200 Subject: [PATCH 1/2] Apply -alarm to wasm-jit simulations too The wasm-jit runtime honours `-alarm`, but `fixData` only handed the flag to `simCodeTarget=C`, so wasm-jit runs had no wall-clock limit and kept going until the harness' own much larger timeout. Models such as ScalableTestSuite's CocurrentHeatExchangerEquations_N_1280 ran for ten minutes instead of stopping at the configured `ulimitExe` of 300s. Co-authored-by: Claude --- shared.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared.py b/shared.py index 204f369..fa8d328 100644 --- a/shared.py +++ b/shared.py @@ -56,7 +56,7 @@ def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCom data["libraryVersion"] = data.get("libraryVersion") or "default" data["libraryVersionLatestInPackageManager"] = data.get("libraryVersionLatestInPackageManager") or False data["libraryVersionExactMatch"] = data.get("libraryVersionExactMatch") or False - data["alarmFlag"] = data.get("alarmFlag") or (alarmFlag if data["simCodeTarget"]=="C" else "") + data["alarmFlag"] = data.get("alarmFlag") or (alarmFlag if data["simCodeTarget"] in ("C","wasm-jit") else "") data["abortSlowSimulation"] = data.get("abortSlowSimulation") or (abortSimulationFlag if data["simCodeTarget"]=="C" else "") if "changeHash" in data: # Force rebuilding the library due to change in the testing script data["changeHash"] = data["changeHash"] From 20df518cbfe49fd0fefffbe5433a5f6ba1fcb303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 7 Aug 2026 08:03:04 +0200 Subject: [PATCH 2/2] Apply __OpenModelica_simulationFlags to wasm-jit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The annotation was only read for `simCodeTarget=C`, so a model asking for a specific solver got it in the C run and the default `dassl` in the wasm-jit one. That is not a like-for-like comparison, and where the annotation exists it is usually there because the default solver copes badly: ScalableTestSuite's CocurrentHeatExchangerEquations asks for `ida` (sparse, KLU), and dassl's dense factorization made the wasm-jit runs scale cubically instead of linearly. | N | dassl | ida (annotation) | C, ida | | ---- | ------ | ---------------- | ------ | | 320 | 3.7s | 0.34s | 0.4s | | 640 | 31.9s | 1.01s | 0.85s | | 1280 | >600s | 2.82s | 1.9s | The C path validates each flag by running the HelloWorld executable with it. wasm-jit builds no executable — the runtime is inside omc — so probe it there instead, by simulating a trivial model through the session that is already open. Co-authored-by: Claude --- testmodel.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/testmodel.py b/testmodel.py index cad39c4..00230f1 100755 --- a/testmodel.py +++ b/testmodel.py @@ -410,23 +410,33 @@ def sendExpressionOldOrNew(cmd): loadLibraryInNewOM() return omc_new.sendExpression(cmd) +haveFlagCheckModel=False +def wasmJitAcceptsFlag(flagVal): + # There is no HelloWorld executable to probe: the wasm-jit runtime lives in + # omc, so ask it directly whether a trivial model still simulates. + global haveFlagCheckModel + if not haveFlagCheckModel: + sendExpressionOldOrNew('loadString("model OMLibTestFlagCheck Real x(start = 1, fixed = true); equation der(x) = -x; end OMLibTestFlagCheck;")') + haveFlagCheckModel=True + return bool((sendExpressionOldOrNew('simulate(OMLibTestFlagCheck,simflags="%s")' % flagVal) or {}).get("resultFile")) + annotationSimFlags="" (startTime,stopTime,tolerance,numberOfIntervals,stepSize)=sendExpressionOldOrNew('getSimulationOptions(%s,defaultTolerance=%s,defaultNumberOfIntervals=%s)' % (conf["modelName"], conf["defaultTolerance"], max(conf["defaultNumberOfIntervals"], numberOfIntervalsInReference))) -if conf["simCodeTarget"]=="C" and sendExpressionOldOrNew('classAnnotationExists(%s, __OpenModelica_simulationFlags)' % conf["modelName"]): +if conf["simCodeTarget"] in ("C","wasm-jit") and sendExpressionOldOrNew('classAnnotationExists(%s, __OpenModelica_simulationFlags)' % conf["modelName"]): for flag in sendExpressionOldOrNew('getAnnotationNamedModifiers(%s,"__OpenModelica_simulationFlags")' % conf["modelName"]): if flag=="The searched annotation name not found": # Old, stupid API continue val=sendExpressionOldOrNew('getAnnotationModifierValue(%s,"__OpenModelica_simulationFlags","%s")' % (conf["modelName"],flag)) flagVal=" -noemit -%s=%s" % (flag,val) - if shared.simulationAcceptsFlag(flagVal, checkOutput=False, cwd="..", isWin=isWin): + if wasmJitAcceptsFlag("-%s=%s" % (flag,val)) if isWasmJit else shared.simulationAcceptsFlag(flagVal, checkOutput=False, cwd="..", isWin=isWin): annotationSimFlags+=" -%s=%s" % (flag,val) else: with open(errFile, 'a+') as fp: - fp.write("Ignoring simflag %s since it seems broken on HelloWorld\n" % flagVal) + fp.write("Ignoring simflag %s since the simulation runtime does not accept it\n" % flagVal) def simulateCmd(resimulate): - simflags = ("%s %s -lv LOG_STATS" % (conf["simFlags"],emit_protected)).strip() + simflags = ("%s %s %s -lv LOG_STATS" % (annotationSimFlags,conf["simFlags"],emit_protected)).strip() return 'simulate(%s,startTime=%g,stopTime=%g,tolerance=%g,numberOfIntervals=%d,outputFormat="%s",variableFilter="%s",fileNamePrefix="%s",simflags="%s"%s)' % (conf["modelName"],startTime,stopTime,tolerance,numberOfIntervals,outputFormat,variableFilter,conf["fileName"],simflags,(',resimulateExecutable="%s"' % conf["fileName"]) if resimulate else "") # TODO: Detect and handle the case where RT_CLOCK is not available in OMC