From eb70bf8cb3084bc32b31e3e3e1a49a5fad3047a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Sun, 27 Sep 2026 13:33:56 +0200 Subject: [PATCH] Replace the C+Rust job with a C.old job OpenModelica made the Rust simulation runtime the default for --simCodeTarget=C (OpenModelica/OpenModelica#16913) and removed C+Rust; --simCodeTarget=C.old now links the old libSimulationRuntimeC. The master job therefore tests what c-plus-rust did, and c-old keeps the old runtime covered, differing from master in the runtime alone. It is built like master: the old runtime is on by default (OM_OMC_ENABLE_C_OLD_RUNTIME), so no cmake flags are needed. Its results are a column of the default overview.html rather than a page of their own, and the --new-branch workaround for c-plus-rust is gone. Assisted-by: Claude Opus 5.5 --- .CI/Jenkinsfile | 35 ++++++++++------------------------- README.md | 18 +++++++----------- shared.py | 4 ++-- testmodel.py | 6 +++--- testresults.md | 10 ++++------ 5 files changed, 26 insertions(+), 47 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 7acda0e..029c568 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -38,7 +38,7 @@ pipeline { booleanParam(name: 'wasm_jit', defaultValue: false, description: 'master branch, with --simCodeTarget=wasm-jit (ryzen-9950x). Every model is translated and simulated the way simulate() does, filling wasm-jit. This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'wasm_web', defaultValue: false, description: 'master branch, with --simCodeTarget=wasm-jit (ryzen-9950x), simulated the way the web omc does: the driver and the linear and nonlinear solvers in wasm, the in-wasm libm, and external "C" only from prebuilt wasm libraries. Fills wasm-web. This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'wasm_fmu', defaultValue: false, description: 'master branch, with --simCodeTarget=wasm-jit (ryzen-9950x). Every model is exported once as an unzipped wasm FMU and simulated through both of its FMI 3.0 interfaces, filling wasm-jit-me (Model Exchange) and wasm-jit-cs (Co-Simulation). This is an experimental job that does not run on a fixed schedule.') - booleanParam(name: 'c_plus_rust', defaultValue: false, description: 'master branch, with --simCodeTarget=C+Rust, filling c-plus-rust (ryzen-5950x-1). The C code generator emits what it always did; the executable links libSimulationRuntimeRust instead of libSimulationRuntimeC, so the difference against master is the simulation runtime alone. This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'c_old', defaultValue: false, description: 'master branch, with --simCodeTarget=C.old, filling c-old (ryzen-9950x). The C code generator emits what it does for --simCodeTarget=C; the executable links the old libSimulationRuntimeC instead of libSimulationRuntimeRust, so the difference against master is the simulation runtime alone. This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'heavy_tests', defaultValue: false, description: 'master branch, runs one test at a time. That is, no parallel launching of tests. omc will use multiple threads for each test (-n=1 is not set unlike the other regression tests.), (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') string(name: 'pull_request', defaultValue: '', description: 'Test an OpenModelica pull request rather than a branch: its number, e.g. 16354. omc is built from refs/pull//merge - the pull request as it would land - the results fill a pr- table, and the report compares them against the newest run of pull_request_baseline. Left empty, nothing of this runs.') @@ -387,7 +387,7 @@ pipeline { } } } - stage('C+Rust') { + stage('C.old') { agent { node { label 'ryzen-9950x' @@ -397,15 +397,10 @@ pipeline { options { skipDefaultCheckout() } when { beforeAgent true - expression { params.c_plus_rust } + expression { params.c_old } } steps { - // A cmake build rather than the autotools one every other C target uses: - // libSimulationRuntimeRust is a cmake target (SimulationRuntime/rust), opt-in - // through OM_ENABLE_RUST_SIM_RUNTIME, and without it the generated makefile - // has nothing to link. - runRegressiontest('master', 'c-plus-rust', 'setCommandLineOptions("--simCodeTarget=C+Rust")', '', false, '', '', false, false, 0, 'configs/conf.json', - '-DOM_ENABLE_RUST_SIM_RUNTIME=ON -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache') + runRegressiontest('master', 'c-old', 'setCommandLineOptions("--simCodeTarget=C.old")', '', false, '', '', false, false) } } stage('generateSymbolicJacobian') { @@ -502,7 +497,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_25 || params.v1_26 || params.v1_27 || params.master || params.conversion_script || params.report_ryzen_5950x_1 || params.report_ryzen_5950x_2 || params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests || params.fmi_v1_25 || params.fmi_v1_26 || params.fmi_v1_27 || params.fmi_master || params.fmpy_fmi_v1_25 || params.fmpy_fmi_v1_26 || params.fmpy_fmi_v1_27 || params.fmpy_fmi_master || params.newInst_daeMode || params.newBackend_daeMode || params.oldInst || params.cpp || params.cvode || params.gbode || params.ida || params.wasm_jit || params.wasm_fmu || params.wasm_web || params.c_plus_rust} + expression { params.v1_25 || params.v1_26 || params.v1_27 || params.master || params.conversion_script || params.report_ryzen_5950x_1 || params.report_ryzen_5950x_2 || params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests || params.fmi_v1_25 || params.fmi_v1_26 || params.fmi_v1_27 || params.fmi_master || params.fmpy_fmi_v1_25 || params.fmpy_fmi_v1_26 || params.fmpy_fmi_v1_27 || params.fmpy_fmi_master || params.newInst_daeMode || params.newBackend_daeMode || params.oldInst || params.cpp || params.cvode || params.gbode || params.ida || params.wasm_jit || params.wasm_fmu || params.wasm_web || params.c_old} } environment { GITBRANCHES = 'maintenance/v1.20 maintenance/v1.21 maintenance/v1.22 maintenance/v1.23 maintenance/v1.24 maintenance/v1.25 maintenance/v1.26 maintenance/v1.27 master newInst-newBackend' @@ -512,13 +507,8 @@ pipeline { GITBRANCHES_NEWBACKEND_DAE = 'newBackend-daeMode' GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp v1.23-cpp v1.24-cpp v1.25-cpp cpp v1.26-cpp v1.27-cpp' GITBRANCHES_WASM_JIT = 'wasm-jit-me wasm-jit-cs wasm-jit wasm-web' - GITBRANCHES_C_PLUS_RUST = 'c-plus-rust' + GITBRANCHES_C_OLD = 'c-old' GITBRANCHES_SPECIAL = 'master newInst-newBackend' - // The C+Rust job ran a few times before it was added to this stage, so - // it is past the run count all-reports.py takes for a first report and - // gets no history without being named here. Drop it once the branch has - // one; the run says so in its log. - NEWBRANCHES = '--new-branch=c-plus-rust' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') // A secret file holding one pgpass line; libpq reads the password from @@ -538,8 +528,8 @@ pipeline { ''' sh './clean-empty-omcversion-dates.py' - sh "./all-reports.py --email ${env.NEWBRANCHES} --omcgitdir=OpenModelica ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} ${env.GITBRANCHES_C_PLUS_RUST} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" - sh "./all-plots.py ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} ${env.GITBRANCHES_C_PLUS_RUST} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" + sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} ${env.GITBRANCHES_C_OLD} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" + sh "./all-plots.py ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} ${env.GITBRANCHES_C_OLD} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" // Recorded and announced only once they are up: a report the database // knows about is never generated again, so one that a later failure in @@ -611,18 +601,13 @@ pipeline { // simulation path, the two FMI 3.0 interfaces of one exported wasm FMU, // which share an export and differ only in simulation and verification, // and the web omc's in-wasm path. - sh "./report.py --branches='master ${env.GITBRANCHES_C_PLUS_RUST} ${env.GITBRANCHES_WASM_JIT}' configs/conf.json" + sh "./report.py --branches='master ${env.GITBRANCHES_WASM_JIT}' configs/conf.json" sh "mv overview.html overview-wasm-jit.html" - // Against master, which the job shares a machine and a compiler with: the - // simulation runtime is the only thing that differs. - sh "./report.py --branches='${env.GITBRANCHES_C_PLUS_RUST} master' configs/conf.json" - sh "mv overview.html overview-c-plus-rust.html" - sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json" + sh "./report.py --branches='${env.GITBRANCHES} ${env.GITBRANCHES_C_OLD}' configs/conf.json" sh 'date' sh 'find overview*.html history -type f | wc -l' diff --git a/README.md b/README.md index 211d4fe..35f4684 100644 --- a/README.md +++ b/README.md @@ -370,22 +370,18 @@ entry there (`simflags` is what is appended to the model's simulation flags, `--wasmfmu`, `--fmisimulator` and `--solver` each fan one build out into several result branches, so a job uses one of them, not several. -### The Rust simulation runtime under the C code generator +### The old C simulation runtime -`--simCodeTarget=C+Rust` emits the sources `--simCodeTarget=C` emits and links -`libSimulationRuntimeRust` instead of `libSimulationRuntimeC`, so a run against -master differs in the simulation runtime and nothing else. +`--simCodeTarget=C` links `libSimulationRuntimeRust`; `--simCodeTarget=C.old` +emits the same sources and links the old `libSimulationRuntimeC`, so a run +against master differs in the simulation runtime and nothing else. ```bash -./test.py --branch=c-plus-rust --extraflags='--simCodeTarget=C+Rust' configs/myConf.json -./report.py --branches="c-plus-rust master" -# the overview.html it writes is published as overview-c-plus-rust.html +./test.py --branch=c-old --extraflags='--simCodeTarget=C.old' configs/myConf.json +./report.py --branches="master c-old" ``` -The runtime is a cmake target of the OpenModelica build -(`SimulationRuntime/rust`, `OM_ENABLE_RUST_SIM_RUNTIME`, on by default where -cargo is installed) and has no autotools equivalent, so omc has to be built with -cmake or the generated makefile finds nothing to link. +The Jenkins job lists it as a column of the default overview.html. ### One build, several solvers diff --git a/shared.py b/shared.py index de44073..76c1c7e 100644 --- a/shared.py +++ b/shared.py @@ -76,8 +76,8 @@ 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"] in ("C","C+Rust","wasm-jit") else "") - data["abortSlowSimulation"] = data.get("abortSlowSimulation") or (abortSimulationFlag if data["simCodeTarget"] in ("C","C+Rust","wasm-jit") else "") + data["alarmFlag"] = data.get("alarmFlag") or (alarmFlag if data["simCodeTarget"] in ("C","C.old","wasm-jit") else "") + data["abortSlowSimulation"] = data.get("abortSlowSimulation") or (abortSimulationFlag if data["simCodeTarget"] in ("C","C.old","wasm-jit") else "") data["simFlags"] = simulationFlags(data, data["ulimitExe"]) if "changeHash" in data: # Force rebuilding the library due to change in the testing script data["changeHash"] = data["changeHash"] diff --git a/testmodel.py b/testmodel.py index 9ab087a..c9091e0 100755 --- a/testmodel.py +++ b/testmodel.py @@ -484,7 +484,7 @@ def uncaughtException(exctype, value, tb): with open(errFile, 'a+') as fp: fp.write("Running: %s\n" % " ".join(sys.argv)) -if conf["simCodeTarget"] not in ["Cpp","C","C+Rust","wasm-jit"]: +if conf["simCodeTarget"] not in ["Cpp","C","C.old","wasm-jit"]: with open(errFile, 'a+') as fp: fp.write("Unknown simCodeTarget in %s" % conf["simCodeTarget"]) writeResultAndExit(1) @@ -674,7 +674,7 @@ def wasmJitAcceptsFlag(flagVal): except: # omc answers nothing when the call fails, and nothing else reads the buffer. raise Exception("%s failed:\n%s" % (cmd, omc.sendExpression("getErrorString()", parsed = False))) -if conf["simCodeTarget"] in ("C","C+Rust","wasm-jit") and sendExpressionOldOrNew('classAnnotationExists(%s, __OpenModelica_simulationFlags)' % conf["modelName"]): +if conf["simCodeTarget"] in ("C","C.old","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 @@ -990,7 +990,7 @@ def simulateExecutable(name, solverFlags, resFile, simFile): # sparsity patterns are all read from the build directory, not from here. setupArgument = "-inputPath=.." if runDir else "" cmd = inRunnerDir(runDir, " ".join(x for x in (exe, annotationSimFlags, conf["simFlags"], emit_protected, - "-lv LOG_STATS" if conf["simCodeTarget"] in ("C","C+Rust") else "", + "-lv LOG_STATS" if conf["simCodeTarget"] in ("C","C.old") else "", setupArgument, resultArgument, solverFlags) if x.strip())) with open(simFile,"w") as fp: fp.write("Environment - simulationEnvironment:\n") diff --git a/testresults.md b/testresults.md index 6f27d46..9416357 100644 --- a/testresults.md +++ b/testresults.md @@ -10,7 +10,10 @@ improvements in green. - [Default settings](https://libraries.openmodelica.org/branches/overview.html): - simulation with C runtime and default settings + simulation with the C code generator and default settings. Its `c-old` + column is master with `--simCodeTarget=C.old`: the same generated C sources + linked against the old `libSimulationRuntimeC` instead of the Rust + simulation runtime - [daeMode](https://libraries.openmodelica.org/branches/overview-dae.html): simulation with daeMode (compiler flag [--daeMode](https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html#omcflag-daemode)) @@ -26,11 +29,6 @@ `wasm-jit-me` and `wasm-jit-cs` come from a second job that exports each model once as a wasm FMU and drives that one FMU through its FMI 3.0 Model Exchange and Co-Simulation interfaces - - [C+Rust](https://libraries.openmodelica.org/branches/overview-c-plus-rust.html): - simulation with the Rust runtime under the C code generator (compiler flag - `--simCodeTarget=C+Rust`). The generated sources are the ones the C target - emits; the executable links `libSimulationRuntimeRust` instead of - `libSimulationRuntimeC`, so the difference against master is the runtime alone - **Regression reports and history plots**: Regression reports are periodically generated, using the latest development