From 5560adcf27410fa1946b390c97e542a3428dfbf7 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Fri, 19 Apr 2024 09:44:19 -0700 Subject: [PATCH 1/9] Fix for issue #1210 (I hope.) Also, re-enable test, and add new one for loading from scratch. The savedState files are different on different OSes because the size of things is different (notably 'unsigned long'). --- source/llvm/LLJit.cpp | 4 +- source/llvm/MCJit.cpp | 66 ++++++++++-------- .../StateSavingTests/savedState_linux.rr | Bin 0 -> 13262 bytes .../StateSavingTests/savedState_windows.rr | Bin 0 -> 12286 bytes test/serialization/state_saving.cpp | 19 +++-- 5 files changed, 51 insertions(+), 38 deletions(-) create mode 100644 test/models/StateSavingTests/savedState_linux.rr create mode 100644 test/models/StateSavingTests/savedState_windows.rr diff --git a/source/llvm/LLJit.cpp b/source/llvm/LLJit.cpp index ab07765f0b..5ff3b1e2d9 100644 --- a/source/llvm/LLJit.cpp +++ b/source/llvm/LLJit.cpp @@ -73,7 +73,9 @@ namespace rrllvm { } LLJit::LLJit(std::uint32_t options) - : Jit(options) { + : Jit(options) + , llJit() + { // todo, can we cross compile providing a different host arch? diff --git a/source/llvm/MCJit.cpp b/source/llvm/MCJit.cpp index f96aa2ac42..1913789c59 100644 --- a/source/llvm/MCJit.cpp +++ b/source/llvm/MCJit.cpp @@ -44,7 +44,7 @@ namespace rrllvm { * file type. */ #if LLVM_VERSION_MAJOR == 6 - llvm::LLVMTargetMachine::CodeGenFileType getCodeGenFileType(){ + llvm::LLVMTargetMachine::CodeGenFileType getCodeGenFileType() { return llvm::TargetMachine::CGFT_ObjectFile; } #elif LLVM_VERSION_MAJOR >= 12 @@ -57,25 +57,29 @@ namespace rrllvm { MCJit::MCJit(std::uint32_t opt) - : Jit(opt), - engineBuilder(EngineBuilder(std::move(module))) { + : Jit(opt) + , engineBuilder(EngineBuilder(std::move(module))) + , executionEngine() + , functionPassManager() + , errString() + { compiledModuleBinaryStream = std::make_unique(moduleBuffer); engineBuilder - .setErrorStr(errString.get()) - .setMCJITMemoryManager(std::make_unique()); - executionEngine = std::unique_ptr(engineBuilder.create()); + .setErrorStr(errString.get()) + .setMCJITMemoryManager(std::make_unique()); + executionEngine.reset(engineBuilder.create()); MCJit::mapFunctionsToJitSymbols(); MCJit::initFunctionPassManager(); } - ExecutionEngine *MCJit::getExecutionEngineNonOwning() const { + ExecutionEngine* MCJit::getExecutionEngineNonOwning() const { return executionEngine.get(); } - std::string MCJit::mangleName(const std::string &unmangledName) const { + std::string MCJit::mangleName(const std::string& unmangledName) const { std::string mangledName; llvm::raw_string_ostream mangledNameStream(mangledName); llvm::Mangler::getNameWithPrefix(mangledNameStream, unmangledName, getDataLayout()); @@ -86,9 +90,9 @@ namespace rrllvm { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); // for symbols in current process - for (auto [fnName, fnTy_addr_pair] : externalFunctionSignatures()){ + for (auto [fnName, fnTy_addr_pair] : externalFunctionSignatures()) { auto [fnTy, addr] = fnTy_addr_pair; - rrLogDebug << "Creating function \"" << fnName << "\"; fn type: " << toStringRef(fnTy).str() << "; at addr: " < modelResources) { @@ -112,12 +116,12 @@ namespace rrllvm { } - std::uint64_t MCJit::lookupFunctionAddress(const std::string &name) { - void *v = executionEngine->getPointerToNamedFunction(mangleName(name)); - return (std::uint64_t) v; + std::uint64_t MCJit::lookupFunctionAddress(const std::string& name) { + void* v = executionEngine->getPointerToNamedFunction(mangleName(name)); + return (std::uint64_t)v; } - llvm::TargetMachine *MCJit::getTargetMachine() { + llvm::TargetMachine* MCJit::getTargetMachine() { return executionEngine->getTargetMachine(); } @@ -138,7 +142,7 @@ namespace rrllvm { llvm::Expected > objectFileExpected = - llvm::object::ObjectFile::createObjectFile(obj->getMemBufferRef()); + llvm::object::ObjectFile::createObjectFile(obj->getMemBufferRef()); if (!objectFileExpected) { throw std::invalid_argument("Failed to load object data"); } @@ -147,11 +151,11 @@ namespace rrllvm { } - const llvm::DataLayout &MCJit::getDataLayout() const { + const llvm::DataLayout& MCJit::getDataLayout() const { return getExecutionEngineNonOwning()->getDataLayout(); } - void MCJit::addModule(llvm::Module *M) { + void MCJit::addModule(llvm::Module* M) { } @@ -169,7 +173,7 @@ namespace rrllvm { if (compiledModuleBinaryStream->str().empty()) { std::string err = "Attempt to add module before its been written to binary. Make a call to " - "MCJit::writeObjectToBinaryStream() before addModule()"; + "MCJit::writeObjectToBinaryStream() before addModule()"; rrLogErr << err; throw_llvm_exception(err); } @@ -177,8 +181,8 @@ namespace rrllvm { auto memBuffer(llvm::MemoryBuffer::getMemBuffer(compiledModuleBinaryStream->str().str())); llvm::Expected > objectFileExpected = - llvm::object::ObjectFile::createObjectFile( - llvm::MemoryBufferRef(compiledModuleBinaryStream->str(), "id")); + llvm::object::ObjectFile::createObjectFile( + llvm::MemoryBufferRef(compiledModuleBinaryStream->str(), "id")); if (!objectFileExpected) { //LS DEBUG: find a way to get the text out of the error. @@ -196,7 +200,7 @@ namespace rrllvm { getExecutionEngineNonOwning()->finalizeObject(); } - std::unique_ptr MCJit::getCompiledModelFromCache(const std::string &sbmlMD5) { + std::unique_ptr MCJit::getCompiledModelFromCache(const std::string& sbmlMD5) { return nullptr; } @@ -213,8 +217,8 @@ namespace rrllvm { //Write the object file to modBufferOut std::error_code EC; -// llvm::SmallVector modBufferOut; -// postOptimizedModuleStream(modBufferOut); + // llvm::SmallVector modBufferOut; + // postOptimizedModuleStream(modBufferOut); llvm::legacy::PassManager pass; auto FileType = getCodeGenFileType(); @@ -244,10 +248,10 @@ namespace rrllvm { * Note to developers - passes are stored in llvm/Transforms/Scalar.h. */ - // we only support LLVM >= 3.1 + // we only support LLVM >= 3.1 #if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR == 1) //#if (LLVM_VERSION_MAJOR == 6) - functionPassManager->add(new TargetData(*executionEngine->getTargetData())); + functionPassManager->add(new TargetData(*executionEngine->getTargetData())); #elif (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR <= 4) functionPassManager->add(new DataLayout(*executionEngine->getDataLayout())); #elif (LLVM_VERSION_MINOR > 4) @@ -271,7 +275,7 @@ namespace rrllvm { functionPassManager->add(createInstSimplifyLegacyPass()); #else rrLogWarn << "Not using llvm optimization \"OPTIMIZE_INSTRUCTION_SIMPLIFIER\" " - "because llvm version is " << LLVM_VERSION_MAJOR; + "because llvm version is " << LLVM_VERSION_MAJOR; #endif } @@ -300,7 +304,7 @@ namespace rrllvm { // or replaced with createDeadCodeEliminationPass, which we add below anyway #else rrLogWarn << "Not using OPTIMIZE_DEAD_INST_ELIMINATION because you are using" - "LLVM version " << LLVM_VERSION_MAJOR; + "LLVM version " << LLVM_VERSION_MAJOR; #endif } @@ -313,11 +317,11 @@ namespace rrllvm { } } - llvm::legacy::FunctionPassManager *MCJit::getFunctionPassManager() const { + llvm::legacy::FunctionPassManager* MCJit::getFunctionPassManager() const { return functionPassManager.get(); } - llvm::raw_svector_ostream &MCJit::getCompiledModuleStream() { + llvm::raw_svector_ostream& MCJit::getCompiledModuleStream() { return *compiledModuleBinaryStream; } diff --git a/test/models/StateSavingTests/savedState_linux.rr b/test/models/StateSavingTests/savedState_linux.rr new file mode 100644 index 0000000000000000000000000000000000000000..da296743b950825f610daa069dcb8fd50832e251 GIT binary patch literal 13262 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 literal 0 HcmV?d00001 diff --git a/test/serialization/state_saving.cpp b/test/serialization/state_saving.cpp index 696e0c31a5..92a9a002a0 100644 --- a/test/serialization/state_saving.cpp +++ b/test/serialization/state_saving.cpp @@ -46,7 +46,7 @@ static std::mutex SerializationMutex; */ class StateSavingTests : public RoadRunnerTest { public: - path stateSavingModelsDir = rrTestModelsDir_ / "StateSaving"; + path stateSavingModelsDir = rrTestModelsDir_ / "StateSavingTests"; path stateSavingOutputDir = rrTestDir_ / "StateSavingOutput"; path fname_ = stateSavingOutputDir / "state-saving-test.rr"; std::string fname; @@ -430,13 +430,20 @@ bool StateSavingTests::StateRunTestModelFromScratch(void(*generate)(RoadRunner * // accordingly. The reverse can't be tested, since it'll either // exit or throw, depending. TEST_F(StateSavingTests, LOAD_INVALID_FILE) { -// on mac systems this test causes abort signal. We disable on mac. -#if (!defined(__APPLE__)) -# if LLVM_VERSION_PATCH > 1 RoadRunner rri; - EXPECT_THROW(rri.loadState((rrTestModelsDir_ / "wrong-save-state.rr").string()), std::exception); -# endif + EXPECT_THROW(rri.loadState((stateSavingModelsDir / "wrong-save-state.rr").string()), std::exception); +} + +TEST_F(StateSavingTests, LOAD_VALID_FILE) { + RoadRunner rri; +#if defined(_WIN32) + rri.loadState((stateSavingModelsDir / "savedState_windows.rr").string()); + //#elif defined(__unix__) + //#if (defined(__APPLE__)) +#else + rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); #endif + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); } TEST_F(StateSavingTests, LOAD_NONEXISTENT_FILE) { From 55e90da4e2cf5f337bf6d6a41faebf7d53a950c1 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Fri, 19 Apr 2024 10:57:09 -0700 Subject: [PATCH 2/9] Update version number; declare enum type. --- CMakeLists.txt | 2 +- source/rrSelectionRecord.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 107bb71708..fcf6e56f10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.16) set(ROADRUNNER_VERSION_MAJOR 2) set(ROADRUNNER_VERSION_MINOR 6) -set(ROADRUNNER_VERSION_PATCH 0) +set(ROADRUNNER_VERSION_PATCH 1) set(ROADRUNNER_VERSION "${ROADRUNNER_VERSION_MAJOR}.${ROADRUNNER_VERSION_MINOR}.${ROADRUNNER_VERSION_PATCH}") diff --git a/source/rrSelectionRecord.h b/source/rrSelectionRecord.h index 01da75910f..ed3f1d2927 100644 --- a/source/rrSelectionRecord.h +++ b/source/rrSelectionRecord.h @@ -17,7 +17,7 @@ using std::ostream; class RR_DECLSPEC SelectionRecord { public: - enum SelectionType + enum SelectionType : unsigned long { /** * SelectionType for time. From 2e794414c14415562a25cc07580559d84a62f0c0 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Fri, 19 Apr 2024 16:24:45 -0700 Subject: [PATCH 3/9] Comment out read-file test. The test seems to work in some contexts but not others. Committing this version so we can test it on python on other platforms. --- source/llvm/Jit.cpp | 2 +- source/llvm/LLJit.cpp | 5 +++++ source/llvm/LLJit.h | 2 +- source/llvm/MCJit.cpp | 6 +++++- source/llvm/MCJit.h | 8 ++++++++ test/serialization/state_saving.cpp | 6 ++++-- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/source/llvm/Jit.cpp b/source/llvm/Jit.cpp index 72aab7b5e6..d358c03969 100644 --- a/source/llvm/Jit.cpp +++ b/source/llvm/Jit.cpp @@ -67,7 +67,7 @@ namespace rrllvm { } Jit::Jit() - : Jit(LoadSBMLOptions().modelGeneratorOpt) {} + : Jit(LoadSBMLOptions().modelGeneratorOpt) {} llvm::Module *Jit::getModuleNonOwning() { return moduleNonOwning; diff --git a/source/llvm/LLJit.cpp b/source/llvm/LLJit.cpp index 5ff3b1e2d9..b59e938e0e 100644 --- a/source/llvm/LLJit.cpp +++ b/source/llvm/LLJit.cpp @@ -72,6 +72,11 @@ namespace rrllvm { return mangledNameStream.str(); } + LLJit::LLJit() + : LLJit(LoadSBMLOptions().modelGeneratorOpt) + { + } + LLJit::LLJit(std::uint32_t options) : Jit(options) , llJit() diff --git a/source/llvm/LLJit.h b/source/llvm/LLJit.h index 90aba4ed9a..feec0e569c 100644 --- a/source/llvm/LLJit.h +++ b/source/llvm/LLJit.h @@ -42,7 +42,7 @@ namespace rrllvm { class LLJit : public Jit { public: - LLJit() = default; + LLJit(); ~LLJit() override = default; diff --git a/source/llvm/MCJit.cpp b/source/llvm/MCJit.cpp index 1913789c59..baf46628f6 100644 --- a/source/llvm/MCJit.cpp +++ b/source/llvm/MCJit.cpp @@ -63,7 +63,6 @@ namespace rrllvm { , functionPassManager() , errString() { - compiledModuleBinaryStream = std::make_unique(moduleBuffer); engineBuilder @@ -75,10 +74,15 @@ namespace rrllvm { MCJit::initFunctionPassManager(); } + MCJit::MCJit() + : MCJit(LoadSBMLOptions().modelGeneratorOpt) + { + } ExecutionEngine* MCJit::getExecutionEngineNonOwning() const { return executionEngine.get(); } + std::string MCJit::mangleName(const std::string& unmangledName) const { std::string mangledName; llvm::raw_string_ostream mangledNameStream(mangledName); diff --git a/source/llvm/MCJit.h b/source/llvm/MCJit.h index e194d1de40..9094d554a0 100644 --- a/source/llvm/MCJit.h +++ b/source/llvm/MCJit.h @@ -37,6 +37,14 @@ namespace rrllvm { explicit MCJit(std::uint32_t options); + /** + * @brief default constructor. + * @details delegates to MCJit(std::uint32_t options). The options + * argument is the default constructed from LoadSBMLOptions.modelGeneratorOpt. + * Note, that LoadSBMLOptions is influenced by the global Config. + */ + MCJit(); + ~MCJit() override = default; diff --git a/test/serialization/state_saving.cpp b/test/serialization/state_saving.cpp index 92a9a002a0..d86bc7ea50 100644 --- a/test/serialization/state_saving.cpp +++ b/test/serialization/state_saving.cpp @@ -437,13 +437,15 @@ TEST_F(StateSavingTests, LOAD_INVALID_FILE) { TEST_F(StateSavingTests, LOAD_VALID_FILE) { RoadRunner rri; #if defined(_WIN32) + // This only works on Windows, and lord only knows why. rri.loadState((stateSavingModelsDir / "savedState_windows.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); //#elif defined(__unix__) //#if (defined(__APPLE__)) #else - rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + //rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + //EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); #endif - EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); } TEST_F(StateSavingTests, LOAD_NONEXISTENT_FILE) { From e8c75549d5f9143a7644249b54f7be6b9197f66e Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Tue, 23 Apr 2024 14:11:40 -0700 Subject: [PATCH 4/9] Fix! The trick turned out to be that on linux, loading loadBinary into jit->compiledModuleBinaryStream corrupted the compiledModuleBinaryStream. Instead, we now convert to and from a string, and that seems to work. At the same time, I changed the factory to return Jit* objects instead of unique_ptr objects, which also seems to work, though that might be a purely cosmetic change. --- source/llvm/Jit.cpp | 15 +++++++++------ source/llvm/JitFactory.cpp | 22 ++++++++++++++-------- source/llvm/JitFactory.h | 4 ++-- source/llvm/LLVMExecutableModel.cpp | 2 ++ source/llvm/MCJit.cpp | 3 ++- source/llvm/ModelGeneratorContext.cpp | 5 +++-- source/llvm/ModelGeneratorContext.h | 2 +- source/llvm/ModelResources.cpp | 24 +++++++++++++++++------- source/rrRoadRunner.cpp | 13 ++++++++++--- 9 files changed, 60 insertions(+), 30 deletions(-) diff --git a/source/llvm/Jit.cpp b/source/llvm/Jit.cpp index d358c03969..75bd6ddff6 100644 --- a/source/llvm/Jit.cpp +++ b/source/llvm/Jit.cpp @@ -34,13 +34,16 @@ using namespace rr; namespace rrllvm { Jit::Jit(std::uint32_t options) - : options(options), - context(std::make_unique()), - // todo the module name should be the sbmlMD5. Might be cleaner to + : options(options) + , context(std::make_unique()) + // todo the module name should be the sbmlMD5. Might be cleaner to // add this as a parameter to Jit constructor. - module(std::make_unique("LLVM Module", *context)), - moduleNonOwning(module.get()), /*Maintain a weak ref so we don't lose our handle to the module*/ - builder(std::make_unique>(*context)) { + , module(std::make_unique("LLVM Module", *context)) + , moduleNonOwning(module.get()) /*Maintain a weak ref so we don't lose our handle to the module*/ + , builder(std::make_unique>(*context)) + , compiledModuleBinaryStream(nullptr) + , moduleBuffer() + { // IR module is initialized with just a ModuleID and a source filename diff --git a/source/llvm/JitFactory.cpp b/source/llvm/JitFactory.cpp index 139fdd11ae..6d7d16cf8e 100644 --- a/source/llvm/JitFactory.cpp +++ b/source/llvm/JitFactory.cpp @@ -6,22 +6,28 @@ namespace rrllvm { - std::unique_ptr JitFactory::makeJitEngine(std::uint32_t opt) { - std::unique_ptr jit; + Jit* JitFactory::makeJitEngine(std::uint32_t opt) { + rrLog(Logger::LOG_DEBUG) << __FUNC__; + Jit* jit = NULL; if (opt & LoadSBMLOptions::MCJIT) { - jit = std::move(std::make_unique(opt)); + rrLog(Logger::LOG_DEBUG) << "Creating an MCJit object."; + jit = new rrllvm::MCJit(opt); } else if (opt & LoadSBMLOptions::LLJIT) { - jit = std::move(std::make_unique(opt)); + jit = new rrllvm::LLJit(opt); + } + + else { + throw std::invalid_argument("Cannot create JIT object; need to say whether it's MCJit or LLJit in the options."); } - return std::move(jit); + rrLog(Logger::LOG_DEBUG) << "Done creating a Jit object."; + return jit; } - std::unique_ptr JitFactory::makeJitEngine() { + Jit* JitFactory::makeJitEngine() { LoadSBMLOptions opt; - std::unique_ptr j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); - return std::move(j); + return JitFactory::makeJitEngine(opt.modelGeneratorOpt); } } diff --git a/source/llvm/JitFactory.h b/source/llvm/JitFactory.h index a61fdb9b00..4ba533ea64 100644 --- a/source/llvm/JitFactory.h +++ b/source/llvm/JitFactory.h @@ -37,7 +37,7 @@ namespace rrllvm { /** * @brief Create a Jit engine using local options provided by the user */ - static std::unique_ptr makeJitEngine(std::uint32_t opt); + static Jit* makeJitEngine(std::uint32_t opt); /** * @brief Create a Jit engine using the global options in Config. @@ -45,7 +45,7 @@ namespace rrllvm { * This function instantiates the LoadSBMLOptions and provides the default * modelGeneratorOpt to JitFactory::makeJitEngine(opt); */ - static std::unique_ptr makeJitEngine(); + static Jit* makeJitEngine(); }; diff --git a/source/llvm/LLVMExecutableModel.cpp b/source/llvm/LLVMExecutableModel.cpp index 229d97d9a5..1b767e1613 100644 --- a/source/llvm/LLVMExecutableModel.cpp +++ b/source/llvm/LLVMExecutableModel.cpp @@ -274,6 +274,8 @@ LLVMExecutableModel::LLVMExecutableModel(std::istream& in, uint modelGeneratorOp conversionFactor(1.0), flags(defaultFlags()) { + + rrLog(Logger::LOG_DEBUG) << __FUNC__ << std::endl; modelData = LLVMModelData_from_save(in); resources->loadState(in, modelGeneratorOpt); diff --git a/source/llvm/MCJit.cpp b/source/llvm/MCJit.cpp index baf46628f6..29b95e3abe 100644 --- a/source/llvm/MCJit.cpp +++ b/source/llvm/MCJit.cpp @@ -44,7 +44,8 @@ namespace rrllvm { * file type. */ #if LLVM_VERSION_MAJOR == 6 - llvm::LLVMTargetMachine::CodeGenFileType getCodeGenFileType() { + llvm::LLVMTargetMachine::CodeGenFileType getCodeGenFileType() + { return llvm::TargetMachine::CGFT_ObjectFile; } #elif LLVM_VERSION_MAJOR >= 12 diff --git a/source/llvm/ModelGeneratorContext.cpp b/source/llvm/ModelGeneratorContext.cpp index f16edaf5bc..2c87b73f8d 100644 --- a/source/llvm/ModelGeneratorContext.cpp +++ b/source/llvm/ModelGeneratorContext.cpp @@ -106,7 +106,7 @@ namespace rrllvm { #endif ModelGeneratorContext::ModelGeneratorContext(const libsbml::SBMLDocument* doc_, unsigned options, - std::unique_ptr jitEngine) + Jit* jitEngine) : ownedDoc(nullptr), doc(nullptr), @@ -114,7 +114,8 @@ namespace rrllvm { symbols(nullptr), options(options), random(nullptr), - jit(std::move(jitEngine)) { + jit(jitEngine) + { if (useSymbolCache()) { rrLog(Logger::LOG_INFORMATION) << "Using LLVM symbol/value cache"; } else { diff --git a/source/llvm/ModelGeneratorContext.h b/source/llvm/ModelGeneratorContext.h index 7e26483351..6c09a01a24 100644 --- a/source/llvm/ModelGeneratorContext.h +++ b/source/llvm/ModelGeneratorContext.h @@ -101,7 +101,7 @@ namespace rrllvm { ModelGeneratorContext( const libsbml::SBMLDocument *_doc, unsigned options, - std::unique_ptr jitEngine); + Jit* jitEngine); /** * does not attach to any sbml doc, diff --git a/source/llvm/ModelResources.cpp b/source/llvm/ModelResources.cpp index fb6c0984f2..4b640e8432 100644 --- a/source/llvm/ModelResources.cpp +++ b/source/llvm/ModelResources.cpp @@ -55,8 +55,14 @@ using rr::LoadSBMLOptions; namespace rrllvm { /** @cond PRIVATE */ - ModelResources::ModelResources() : - symbols(nullptr), executionEngine(nullptr), context(nullptr), random(nullptr), errStr(nullptr) { + ModelResources::ModelResources() + : symbols(nullptr) + , executionEngine(nullptr) + , context(nullptr) + , random(nullptr) + , errStr(nullptr) + , jit(nullptr) + { // the reset of the ivars are assigned by the generator, // and in an exception they are not, does not matter as // we don't have to delete them. @@ -128,14 +134,13 @@ namespace rrllvm { rr::saveBinary(out, usingCompiledModuleBinaryStream); if (usingCompiledModuleBinaryStream) { - rr::saveBinary(out, jit->compiledModuleBinaryStream.get()); + rr::saveBinary(out, jit->compiledModuleBinaryStream.get()->str().str()); } } void ModelResources::loadState(std::istream &in, uint modelGeneratorOpt) { - - jit = std::move(JitFactory::makeJitEngine(modelGeneratorOpt)); + jit.reset(JitFactory::makeJitEngine(modelGeneratorOpt)); // get rid of sumbols, if not nullptr. // todo make symbols a unique_ptr @@ -164,8 +169,13 @@ namespace rrllvm { * a roadrunner instance cannot saveState. */ if (usingCompiledModuleBinaryStream) { - //Get the object file binary string from the input stream - rr::loadBinary(in, jit->compiledModuleBinaryStream.get()); + //We saved this as a string; convert it back to a 'raw_svector_ostream' + string stream_str; + rr::loadBinary(in, stream_str); + llvm::raw_svector_ostream* binarystream = new llvm::raw_svector_ostream(jit->moduleBuffer); + *binarystream << stream_str; + + jit->compiledModuleBinaryStream.reset(binarystream); } //Set up a buffer to read the object code from diff --git a/source/rrRoadRunner.cpp b/source/rrRoadRunner.cpp index faf290dd15..6b095b2f98 100644 --- a/source/rrRoadRunner.cpp +++ b/source/rrRoadRunner.cpp @@ -259,7 +259,10 @@ namespace rr { simulateOpt(), mInstanceID(0), loadOpt(dict), - compiler(Compiler::New()) { + compiler(Compiler::New()), + model(nullptr), + document(nullptr) + { // have to init integrators the hard way in c++98 //memset((void*)integrators, 0, sizeof(integrators)/sizeof(char)); } @@ -276,7 +279,10 @@ namespace rr { mLS(0), simulateOpt(), mInstanceID(0), - compiler(Compiler::New()) { + compiler(Compiler::New()), + model(nullptr), + document(nullptr) + { loadOpt.setItem("compiler", Setting(_compiler)); loadOpt.setItem("tempDir", Setting(_tempDir)); loadOpt.setItem("supportCodeDir", Setting(_supportCodeDir)); @@ -295,13 +301,13 @@ namespace rr { mSelectionList(rri.mSelectionList), loadOpt(rri.loadOpt), mSteadyStateSelection(rri.mSteadyStateSelection), - //model(NULL), //Create below instead. Constructing with 'NULL' doesn't work. compiler(Compiler::New()), mLS(NULL), //Create only if asked. simulateOpt(rri.simulateOpt), roadRunnerOptions(rri.roadRunnerOptions), configurationXML(rri.configurationXML), simulatedSinceReset(false), + model(nullptr), document(rri.document->clone()) { //There may be an easier way to save and load the model state, but this // is at least straightforward. We call 'saveState', convert it to an @@ -5578,6 +5584,7 @@ namespace rr { } void RoadRunner::loadStateS(std::stringstream *in) { + rrLog(Logger::LOG_DEBUG) << __FUNC__; int inMagicNumber; rr::loadBinary(*in, inMagicNumber); std::string x = in->str(); From 4f129ef4954d527d5dd4be8664ca7968164c7200 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Tue, 23 Apr 2024 14:17:55 -0700 Subject: [PATCH 5/9] Update linux test. Also, bugs appeared only after loading twice, so check that. --- .../StateSavingTests/savedState_linux.rr | Bin 13262 -> 21030 bytes test/serialization/state_saving.cpp | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/test/models/StateSavingTests/savedState_linux.rr b/test/models/StateSavingTests/savedState_linux.rr index da296743b950825f610daa069dcb8fd50832e251..8a405aa0e3387248a89725bf12d030e025510512 100644 GIT binary patch delta 22 ecmX??zHABOhH#b5+gKOKO}@dTuz9}|G1> diff --git a/test/serialization/state_saving.cpp b/test/serialization/state_saving.cpp index d86bc7ea50..6489721e90 100644 --- a/test/serialization/state_saving.cpp +++ b/test/serialization/state_saving.cpp @@ -437,14 +437,21 @@ TEST_F(StateSavingTests, LOAD_INVALID_FILE) { TEST_F(StateSavingTests, LOAD_VALID_FILE) { RoadRunner rri; #if defined(_WIN32) - // This only works on Windows, and lord only knows why. rri.loadState((stateSavingModelsDir / "savedState_windows.rr").string()); EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); - //#elif defined(__unix__) - //#if (defined(__APPLE__)) + rri.loadState((stateSavingModelsDir / "savedState_windows.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); +#elif (defined(__APPLE__)) + //Try the linux one? + rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); + rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); #else - //rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); - //EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); + rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); + rri.loadState((stateSavingModelsDir / "savedState_linux.rr").string()); + EXPECT_EQ(rri.getNumberOfFloatingSpecies(), 2); #endif } From 8cd0c042e02a39fb3a99ae0c5989bca2a6756fef Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Tue, 23 Apr 2024 14:29:54 -0700 Subject: [PATCH 6/9] Update minor version number. Because this changes the save file format slightly. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcf6e56f10..9b56e13368 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 3.16) # Version information and include modules set(ROADRUNNER_VERSION_MAJOR 2) -set(ROADRUNNER_VERSION_MINOR 6) -set(ROADRUNNER_VERSION_PATCH 1) +set(ROADRUNNER_VERSION_MINOR 7) +set(ROADRUNNER_VERSION_PATCH 0) set(ROADRUNNER_VERSION "${ROADRUNNER_VERSION_MAJOR}.${ROADRUNNER_VERSION_MINOR}.${ROADRUNNER_VERSION_PATCH}") From 686888cf5fe34a9f4ee2754662f48f258fe7e94b Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Tue, 23 Apr 2024 14:52:55 -0700 Subject: [PATCH 7/9] Fix Jit factory tests. --- test/llvm_tests/JitFactoryTests.cpp | 8 ++++---- test/llvm_tests/LLVMGeneratedFunctionTests.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/llvm_tests/JitFactoryTests.cpp b/test/llvm_tests/JitFactoryTests.cpp index 928604a82e..7a44cf18c9 100644 --- a/test/llvm_tests/JitFactoryTests.cpp +++ b/test/llvm_tests/JitFactoryTests.cpp @@ -21,26 +21,26 @@ class JitFactoryTests : public ::testing::Test { TEST_F(JitFactoryTests, MCJitFromConfig){ Config::setValue(Config::LLVM_BACKEND, Config::LLVM_BACKEND_VALUES::MCJIT); - std::unique_ptr j = JitFactory::makeJitEngine(); + Jit* j = JitFactory::makeJitEngine(); ASSERT_TRUE(typeid((*j)) == typeid(MCJit)); } TEST_F(JitFactoryTests, LLJitFromConfig){ Config::setValue(Config::LLVM_BACKEND, Config::LLVM_BACKEND_VALUES::LLJIT); - std::unique_ptr j = JitFactory::makeJitEngine(); + Jit* j = JitFactory::makeJitEngine(); ASSERT_TRUE(typeid((*j)) == typeid(LLJit)); } TEST_F(JitFactoryTests, MCJitFromOpt){ LoadSBMLOptions opt; opt.setLLVMBackend(LoadSBMLOptions::MCJIT); - std::unique_ptr j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); + Jit* j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); ASSERT_TRUE(typeid((*j)) == typeid(MCJit)); } TEST_F(JitFactoryTests, LLJitFromOpt){ LoadSBMLOptions opt; opt.setLLVMBackend(LoadSBMLOptions::LLJIT); - std::unique_ptr j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); + Jit* j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); ASSERT_TRUE(typeid((*j)) == typeid(LLJit)); } diff --git a/test/llvm_tests/LLVMGeneratedFunctionTests.cpp b/test/llvm_tests/LLVMGeneratedFunctionTests.cpp index 66ad2df745..4264ca464a 100644 --- a/test/llvm_tests/LLVMGeneratedFunctionTests.cpp +++ b/test/llvm_tests/LLVMGeneratedFunctionTests.cpp @@ -22,8 +22,8 @@ void LLVMGeneratedFunctionTests::checkInitialEvaluationSpecies(int options, int s->setInitialAmount(speciesAmt); // so 4.5 after initial eval? // create the Jit engine and give to ModelGeneratorContext. - std::unique_ptr j = JitFactory::makeJitEngine(options); - ModelGeneratorContext mgc(doc.get() /*borrowed*/, options, std::move(j)); + Jit* j = JitFactory::makeJitEngine(options); + ModelGeneratorContext mgc(doc.get() /*borrowed*/, options, j); // code gen (limited scope, this test only needs a few functions) EvalInitialConditionsCodeGen(mgc).createFunction(); From 63e79035b22b05e7f0c370994ab2191ce60c5da2 Mon Sep 17 00:00:00 2001 From: Lucian Smith Date: Tue, 23 Apr 2024 16:24:40 -0700 Subject: [PATCH 8/9] Updated savedState files for all platforms. --- .../StateSavingTests/savedState_linux.rr | Bin 21030 -> 15374 bytes .../models/StateSavingTests/savedState_mac.rr | Bin 0 -> 11430 bytes .../StateSavingTests/savedState_windows.rr | Bin 12286 -> 12286 bytes test/serialization/state_saving.cpp | 4 ++-- 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 test/models/StateSavingTests/savedState_mac.rr diff --git a/test/models/StateSavingTests/savedState_linux.rr b/test/models/StateSavingTests/savedState_linux.rr index 8a405aa0e3387248a89725bf12d030e025510512..83e9e184b67db3898c6f5080270b4c438dc59d41 100644 GIT binary patch literal 15374 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 literal 21030 zcmeHPZ)_aJ6<_1D7(!zk5TwC^)nQR+75nV8NuaiK4*6qf0w#vE5h3UG-Cn%P-R-fv z7u#u6T$$oTQJbi0RX}NLzLb7xWvN1fHljwZ3RJ2TRVt0DL~_-tpwdbPq!5*q^u3w) zcIW2yVgf<%;a2j^%*gECXGFJj`zx ziyI_u@wZe~v{9BS5Bqap#<9(R7&**~X8MByu22WbmT2_3xZ&xi@OpvDS3@62o~7uK zq|0676yj2*QrPN7AMnNX>j=o&Ijfux(wN1T7ZmJbfE0Eg3)we<0SQ|<6vG*~&nc>1 z_PON%8JQVHaTJhGzu2O2?!e`zV;F2MkCw~yy-6fR%`Vj^>3h3z80<#mL^At9#Z{V) zBQ5S?KK31#Ixq7f&TeHMrq$}pd?r=aC6nv!%&q&1wRTNcE@@?wx$ZSqcX#)?b#}HZ zIkN7_n&1C zQ49s3%i2-Yk*PV^MCb@w@^yeX^Fogp~#wO4Oou_cT*lwXV z4j0=isg0w>wh86H)bCmz?%&g&p3ikO-|{$c!h(3qCPVligb8l~^Yrb=EMovL>Ny%2 zxoetqPA8=fHg?xEDW6`C{VTj#p;72tivFFm!F5ybHH~Srnoe{v`f(oVQ|~v9tvtLq@PY^f zd|YUU43IIup`1PS@LA zbCve#ZSY?k#$)x{&AWux!Vt8knr0io13GK~3R0qYHbM*28GR14Xh;;Fc9h=>K2@{( zr7AtO$d&pqo~x?j*(&CgGz?9_C<^0SMI5P$kwgR4c)|E@K>HFH^9AUJd3O>@5&Kgr zpofn0ZzcA>4IPF3Q2hdwLT3b_B!JNU;i5qPxe@z+3H>AcOFQ0dQ4ul(Qg>JN1k}c3 zqP(?HZ(QCiagB}G;Tw7MOY+SLje}%be zMRID{_Zp90(YU8!h1tJik8=acElM4$NI#)q zas5v#^vy~gtJwd%f|*Jkt4MF-F+=@p2r3uSdldR-6dG2MzFVR5_hDv3`ay*rXaDgf z=qD6JxkDcEA%+|2bZ89SLnU$I4aS9ClvY(G4#_4eR~Z3 zyh7g^LvQ1+H$V%&;uD{Uzd~Od(|@-@kCT5;p~vO-afKe2A14%goPSR%^tk@#6?$C% zHvW4sM*Q3zm{J&eF$IYLE3SIY)rY>wg3pOt^-ntM1N~N*tTb?8~R(unUIy4%3 zRvX6WVNP7D$l-Mlr%FrIHLT4O|0FWNm63(96H1h`NI3id5aBJ9dmQ&?p^f~*gfsu^ zgijK_ndDD_ACUhf;U?jC6aOON?Ds#Dohgbrk32*CgM@P)pnhQw;cQPk;gcG^ljO{3 z@~?z8%9+)0pZMnpXT7%)|4EJiCgNYva9kHq{-P#ln)o^NEdOP~TPXKg+fO*>?@!3jE#zQcHzo)lB%Ifa_elOR!dcE4!WRhVJb94hBtHubaB*BZ zSw7)BUVN|-an$&qA$(HfZ=i7DI{EUL5Jt@N9QE(i}B;l(m57_=;!nr^kUD!n9=QuNN63%gE{0_o7 z&Wv{xZju7VPmv!v&W!()aE>$MZxPOMX8b(iDNX(xG=7dJ^BXjNjwj<+5zcXA{93|? zHTmla=eRNd7Q#7hj6Xm)$BpsbgqtKE{YNP*kYNp<#Ex)HiciB}e!joWXgJ^B<}`em zlq_iYBr7L9EI+)zX*l2CQW~D3xDRVM-`{u~EPt5zXEgpv!sj%6hVTUq=ldHwk>$@3 zze(d`obPWb4PPMsVGZZ|+oXo`{cT3W`TjPi;e3Bv&~U!L8Kj@>oTEH9HJtBnDGlfQ z+pvc7{cTdi`TjPe;e3Ca)9^u>Uke&OOgQ_4?dSWON#kJr81bhxe3tNG4L?cvq=xhT z&B*v(x?lyKGoJSCAYD9Q?6rf<`(a0E&~seR2_`~dlbyFFj1CWqj=&xd4Ct`YEf=$v zH!)PQGmh=|7oZ(rk9Y#~*phdxz$xyn>Jd+<)^ShK38WrBMv+Rb)}~UyNKK_mwf9?j zY&%x|Znv0)id*z!MvOebkO7BzFfL@O9(@c`ylvHzVocPS(9#{Yl|kh@tibjSfk16X zId4k@wA~%;6{0yi-F&$KykKk%3Q7T0`)$t$$y-2y>!Aa-=G_r1KWKSY!47N>CFqci z`SYOX?A4dR17l4rIqw*Z&uQ)V_iuX2KW2Ev$tq;6y3n? z*m~bXtNp;r>=WJuZ$WVL_E6wDnb8<82$x#fpqwa(QcOtC&02v4vs08E89!K0x2lg+{0i19TCytSoV!sr&uB!t zy@b5$poSPPb4*B4WiQ>&8RzFDZsW-ZTDlk#rP(T*e80XLns{sA=Pz6@@xuER>c3XB zqK}`G-a`>2YTTd8SExVTc0%qXF-(SttZ+Yu=b?X`{Ym-)G)WFa`|;72`?LM{9IpEm zWzRArHk3=}{juy{((UK|Pin^LVxO#G|1A9gI{m3y)UfAfDEm{qL0I3Qeq5|0!XLVS^bJJ4UEiRtZ&2fw>nTVf zxdB_b0eq<&&X>wx-=MC&QOz6ET#8w4)aH+;OZ1cYtZz_DubZ0laRahVc}nFU-kD8o zP%3o#J($V$4QlYjZsmzu`~D>Sb8rdzafQwsN$lYI1~qKZ)0YzTNt}P{8`Lse>KoLC zQQx4JxlrGrmVS5!3f#EnAMknosBch9|I|0Ar61}W)Y1>@Wg&j##K)5Q2DSXbw7x+t z{ZQYamVT&jP}eu8ecVapt#90(#ddvzy1qeeN^c=xOeS=zhVv-#~C2!C&T;HJn zXdBe*$66)-ewo=1FQbs}wTMn5;K_}^*>9%<7v4o-!6_mP&v*ax+|0YbpY7u_3)YAa zhjjvttMy;2zx~vY9_?iXe&FQ9so(}W8etTyai>r&q(`#3wCiPU4}aD|c0PQ~3|7`E z_z??QsmmyW96zv2KFToft7gDASqKg_!9pocQCM-xhAyV3R4%mW>?~A|-2AhVL9F)pI+H=RmIA)$`5dJ`NF>gQG&06@!d#fC{ z>4NLn!9?0BTKNgz5jq>#gH}H8j-^YU?ZfymmTs}arV5G}S>&EwDV9>rP7<)Qf$|BHU5SPpg=#Vqvagp}j3N+r*gZ*<^uI1-A_&(KSv z8=NAP=@u$z`GNuO29Ouafh-9<0H$(^$4>-KapqzT4jem^XYDW>aU5ZgDbXOIOK`>z zRo%Mr``0{k{N=B5Y)3qIB5N1ZaCmLh&GIk3S4lICyi>FxkAev#;2-~flXJZ>%geGN zHYwil`V6jK3)ugceFk%?7TuzZUK*B5IJJnINIZp#_E_K+IcUCJ^kJ>p4`HS>Kwh2; zVk!q#(RRx|r^TiR6h=;9Jo9OLcD9|kdi;?>-W)IFi+*onGzdy}b#{)8jddX0;d*;J zvC^4`vxfOKoph|St25(zcES{BZ(>ctBtmbZE75ngY4#N0zL7T}TP-Ksn;1`+vOpS8 z^Nt_fpHoh7`jP-7<>fG@KjJ=UdxhS_(8l}kO2YN!uB4O{^D3Ey>6c)7S@}&cTftLs zrd3#mODdXWW&i;P1-*&DE8B@qvZb?@F=Qp3_zey8<(XkIpdlePe49;gBGxXtMO2*K z>`lN(MlJvTVt!(%Jc5R0?1$i90!HVoybsPDp+m~hPafnADbYwID-8v_S7BT?j``DK zTo3uV!ky&e@KkP;2JnI)c~DpQ8D9GXDTW7CFA_-@zSb)jc1m{COn~ZcaKBYL3NOZG zPIbo-rCYM5LiU6{YH|i2ijI8Y(J^V^3V0V#!t`J^!ue)+YzT8AXZeuXG9Nfs!9tnb zgK)mKoC!jaViHoW?67mN96_$C^tfS zI;++9bh0~{uZIEhFAV-t{VQSyOUuXY;21q0GQyD6pXLa|gI9in0~E#`pRxULu?u05 z4!NpqK)Ohkp{^KOPiK{mp39Ox;MtEoeLiIL;?k#jh6ulXvf?V@LT=c!LL~e$}^R0@>Lm{KaAK}4Zx8md$ zoFj&0DL{LYsHXL6tvg62^miT$dG%V&asBI^k~v_xQbt0pEKzhSHOn>yrXpOudc!Se zFz%a`T0&KYLK15HUV~PNQ7$PdYW%gq?%Tt0&+Qxux|U$_0q^|&VAy2v`tZv;9-sT` z%5R+i*iC=g`oJpL-?Qq$7cZVUyQ6KTQe7KO5tz};tB@%4G`_MyDIpmpuW7TZBsTjj z_c5AmMeUKk(p7w-)k7;sb+L#abZCJOwk^5g|Ff%p@G!L}xql(Zfs{EJ9$GrpBUM7G zm!%X?J(L60)c9k}D4AuWZu>e_vElj^v+5I~(x;5vF+>XzP-QZsD)0`g8dbT&srw|T zgvpdz1(HiP715YdQ2mEv8Y)~hTh;3~cM%kl-O-%rH}}vqR2oT=V3mg`KZ+&!grzkl zr*fzIq^y!7zDlc-QP_OCN-oQT6?-#xH+p({R;(~f-CaW~ zp7?|m{Pnx9{u^gs3uT6EFT}HioM-W%U4VxVTR|uPo8Y6jmjhNbou~AuxOLq($3(G8 z3%b7khTGOBt!Y}}OvxjAr29lh(>_J41=<94s_D9I`KD{wy^@o(r|j%yg^9Dn)hCvU zi(yTdd#dQ`_3EfqE$RB|0fkXN!*OMqnZ=PrIr~YQ%o~QWCDV0tSTDPVdiN#cYduRE z8sk9v*&dtM5bm%VQ%`S#C3xie1LbxZdZb9(hd8q6DF~7~47weC=6uA6KuKdQo@iSJ zf*xrziky60*#3_tg`L~lGlgA~QxHEm_m!!G$J(?w+24BbSZ3i8!%}E}DP|3ZC=ZHhF2pRv26B!GCSO zUrs@W-bE&O_2Qv#oK$XmrKyGA#9ls7E|)tNU33q*6UnL(ll{}0%HVQyzjgAXc$b4a|59@&ZHN9JR;uyde&Zu@JejV`9y&lT=F_luZ)p}64g zLd&5ON2%o2DO0m#it0fIL=;s+NYSE%6jj23-OuBu{d+tw<9QvAS|3`hXgvE)2u^JM zj^eOa`J+gtBXm+fNhj?k@g&_nB{+fqBu)96LH)deO@%}u(-~1kZ%`Fo{E7y7%HRy* z1dQD$l3v&~F@>Z+N88uZT%f-d67ls!!r9ltzyU3SaL^_kkj|ou@Fr*)Uq_%G#1}8z zCUMRum=Z6HBi`AaDOE+Eu!5?J<%%XLsw$Qs!KLbI}fo|#q+mF zy~%oS*#DoF+vQ%ofx^n27E88yg3iE@do;@3-8A3J8uPtTSfja;^;rC(TF4inetLZ&_!JwL zo4ZTWC+|m}`O$@)f85-!`u|ohE{97N;>WF-?n$wR>!oNdTi0nVW0{uBIcK!)hU`*s z>6v~LhXk6`2V>y8EdCc*9)00$iI<2OX{5Ue&qIvkiWqBzZ^N^L@p256_V<7{-9&#s z@I#DmNYOt6UhABUFPDNJ2X6`ETT<|)$io=pB7G5=r5NYI9A+E`WULXs3HWV{r_LXE zp$WbRcyAN``+;BD1U~{?%`Yv!de<`YEj`N#_=Yh{Ko@Rd&aJ7DE_%`5b z{ZiK-xQhQXvFK!d><6yqKazqU0ltItGns-P2j2RQtdBJ*_)-Mj%ebC`=Yfwk!8ZYa zf^jEBe;e@DccuTd`q%?}j`cB&HCmtjV9qd}rhf$ZbQAsKzz;E=i&>ZXUAiFDPs@KE zxbmO2e>MRx@cfeb|7xrFth@NnXUP8N+&{oQ-T1LQi#xdg9bzT=Iqq-f{sfrBe~kNk zxbNVePCWcu{7)1x_3hjr$9#!Cf_|B%UGWE|rm$=~9KC z{ln~!-Zw-~FJj43$Fut4Vca=Wsg4!b-PloARSw745ZbMK0x{zmTcQcMu zi*_ac7dX@3W4xc~A2L40^Xp=NdzpTXX^rjI+20iFTdY6J^fcRF%k)c(XW8C1w)b_O z&($nnL%mSDhVAcTe-Nj-3Y%W^T)krWt~I86rmt7GYWfz_zhMM_YhLSGj%)ejA!op} z4UiDL&Z$>RhC4o3GmDn#U0VU|3&D91=-g;KhHq83H0sQQH2V2M)$*k;FU?sDZuA&~ zG0TM87;KIhHZd&2zTT;pFmS5ynH~}(ib$A?=?N*=PNacMC8g2>OiHE4nUtb%*O^9< z0$6AGCPEb~4A<3dlUeY1efV7h#k9e(>lKoQoB1Fz1b-u@>%sbsaN@Wk6F1q;kYTSi z=#Q)+z%!|o*1Oi0Ei55wE6P}FnMHHd^2~tQnB~}f)0RFV(3snVKx0}H0wV5f zJnu5$|`cID#)j@yBJ+ zKFYm|ZR=YjrtUlVF4RD+(s6L#tB>z}`&au`Dk)>gLoxUXskXmgareXDzq3y{@O-OW z#wnw<;7`t?Rg5vKQm^PkrLyk0CDWy|l*HB7SW3Vs85J)Sp(v9!s<7kvX3ZlT*;^Y0 z=$lj_!3P?|B0^SGMAB3UGPJ4nR3ZL)L#yCxH>+k#R~}7QQ)wD8T+0|@NcXI*rhpfb z3>qe@<4d+$-Pc`bRLo=Vy)7ai1XpeI&K~7OeVQ`rzN1$h%k;-}qiWdWo+W&?s00lzvl^$jY88Gc4>?-!)DQTF}!%YMg! ze)<&vwYXWe*ug56AfgIV&cmqHTxU#7AR{bjnq;NdXOJbKhL@Erx4=Q>68U`xnNoI8 zB|!!ds#?4Bji5?gNhuHF8z*t1Q#H~&f<@*+LqXT@LL*npuKVseKi>2FHEL~#TxYyw zR&|_=!%m3|P*eAA+p3zVBY&I#diZ^=l^u7~a7)UO3MoDC|L@?&vq0tll<#0ws#T{d zS5L=riFYDhr_>gznxno`Rg31CRS##)2$q@4fMnHP5L?+ds-{!-R9OssDI%x}m~IxP zYnIwsD(?+d?Ce;@u6ljBVc)M^-Pt)hI@&?(4#(ZnNrO%s?=O3KC%?42JByBM=CXp@ zms_68GSHXn&aFHvo6T47-mtT%R>Law<;HSZ*%1cRwmg4LIdVbpBmgM#VU@3M*R#2MO}~a=u$PbDbPZ z=X}9%lzhDm0`%k+RZM75m<@hS(U(h&i(e733qfBFGZ{9#HC20jus%eA70oZ>U4o#? zhV3D_LwqNOp1dyxNH`NI%2Pr1V!`#$oIfnVbaIM=D_>X!_<@SN1&Tc5XD28z zx(YQ}NlZVXRSuN8I_52aMm4-|BZ?x6X_eEcI22Lqn%AMqL~_=g40Y`ebK&wuT%-cO zMagAd>_*(4acu}{qHK7mY*`PgRuQ2r?zOH{su%shq}YU9E9=ZMjssL5_K*1Rh3$se zJ#j6y9Bg5CylK|qh1a&xO&%*}`c`qZF&YL11$;ytPC0W%mx~jp`>LyYJ8yxA`0tk0 z;z*&GWy=?>m01{uUyQ_w!ayh44LSMFM)&znl};s>R}9WCCjVaZE7lB0%Lkp{6hH5C zg;CWX<`u@p%N|z?6s$YlvAy813)rF@$_>>(xG0su?i4KF+2A98O3DYB{lLrTeXd?w z`84hjk+=VCgEpjA*le Date: Wed, 24 Apr 2024 12:19:21 -0700 Subject: [PATCH 9/9] Updates from Adel's code review. * Move string conversion of compiledModuleBinaryStream to Jit class itself. * Remove spurious endl. * Initialize all object children in ModelGeneratorContext's default constructor. * Clean up Jit objects in factory test. * Describe new state_saving test and how to fix it when it inevitably breaks. --- source/llvm/Jit.cpp | 15 ++++++- source/llvm/Jit.h | 17 +++++++- source/llvm/LLVMExecutableModel.cpp | 2 +- source/llvm/MCJit.cpp | 2 +- source/llvm/ModelGeneratorContext.cpp | 18 ++++---- source/llvm/ModelResources.cpp | 7 +--- test/llvm_tests/JitFactoryTests.cpp | 4 ++ .../llvm_tests/LLVMGeneratedFunctionTests.cpp | 3 +- test/serialization/state_saving.cpp | 42 ++++++++++++------- 9 files changed, 78 insertions(+), 32 deletions(-) diff --git a/source/llvm/Jit.cpp b/source/llvm/Jit.cpp index 75bd6ddff6..8f77cb9d57 100644 --- a/source/llvm/Jit.cpp +++ b/source/llvm/Jit.cpp @@ -36,7 +36,7 @@ namespace rrllvm { Jit::Jit(std::uint32_t options) : options(options) , context(std::make_unique()) - // todo the module name should be the sbmlMD5. Might be cleaner to + // todo the module name should be the sbmlMD5. Might be cleaner to // add this as a parameter to Jit constructor. , module(std::make_unique("LLVM Module", *context)) , moduleNonOwning(module.get()) /*Maintain a weak ref so we don't lose our handle to the module*/ @@ -310,6 +310,19 @@ namespace rrllvm { FunctionType::get(double_type, args_d2, false)); } + std::string Jit::getModuleBinaryStreamAsString() + { + return compiledModuleBinaryStream->str().str(); + } + + void Jit::resetModuleBinaryStream(std::string cmbs) + { + //There might be a way to do this directly, but this is at least clean. + llvm::raw_svector_ostream* binarystream = new llvm::raw_svector_ostream(moduleBuffer); + *binarystream << cmbs; + compiledModuleBinaryStream.reset(binarystream); + } + /** * getProcessTriple() - Return an appropriate target triple for generating * code to be loaded into the current process, e.g. when using the JIT. diff --git a/source/llvm/Jit.h b/source/llvm/Jit.h index 40837297d2..f41e421435 100644 --- a/source/llvm/Jit.h +++ b/source/llvm/Jit.h @@ -328,11 +328,26 @@ namespace rrllvm { */ virtual std::string getModuleAsString(std::string sbmlMD5) = 0; + /** + * @brief Return MCJit's compiled binary stream as a string. + * @details Converts the binary stream to a string. Useful for saving and + * loading state for MCJit objects (LLJit doesn't use it). + */ + virtual std::string getModuleBinaryStreamAsString(); + + /** + * @brief Reset MCJit's compiled binary stream with the given string. + * @details MCJit is the only Jit that uses this. (It's bad interface design + * but works at least.). LLJit uses a caching mechanism which allows us + * to retrieve object files directly, foregoing the need for this function. + */ + virtual void resetModuleBinaryStream(std::string cmbs); + /** * @brief MCJit compiles the generated LLVM IR to this binary stream * which is then used both for adding to the Jit as a module and for * saveState. - * @details MCJit is the only Jit that uses this. (Its bad interface design + * @details MCJit is the only Jit that uses this. (It's bad interface design * but works at least.). LLJit uses a caching mechanism which allows us * to retrieve object files directly, foregoing the need for this variable. */ diff --git a/source/llvm/LLVMExecutableModel.cpp b/source/llvm/LLVMExecutableModel.cpp index 1b767e1613..7f81e4e2a8 100644 --- a/source/llvm/LLVMExecutableModel.cpp +++ b/source/llvm/LLVMExecutableModel.cpp @@ -275,7 +275,7 @@ LLVMExecutableModel::LLVMExecutableModel(std::istream& in, uint modelGeneratorOp flags(defaultFlags()) { - rrLog(Logger::LOG_DEBUG) << __FUNC__ << std::endl; + rrLog(Logger::LOG_DEBUG) << __FUNC__; modelData = LLVMModelData_from_save(in); resources->loadState(in, modelGeneratorOpt); diff --git a/source/llvm/MCJit.cpp b/source/llvm/MCJit.cpp index 29b95e3abe..1ff03d8b6f 100644 --- a/source/llvm/MCJit.cpp +++ b/source/llvm/MCJit.cpp @@ -183,7 +183,7 @@ namespace rrllvm { throw_llvm_exception(err); } - auto memBuffer(llvm::MemoryBuffer::getMemBuffer(compiledModuleBinaryStream->str().str())); + auto memBuffer(llvm::MemoryBuffer::getMemBuffer(getModuleBinaryStreamAsString())); llvm::Expected > objectFileExpected = llvm::object::ObjectFile::createObjectFile( diff --git a/source/llvm/ModelGeneratorContext.cpp b/source/llvm/ModelGeneratorContext.cpp index 2c87b73f8d..c4115a67f1 100644 --- a/source/llvm/ModelGeneratorContext.cpp +++ b/source/llvm/ModelGeneratorContext.cpp @@ -210,13 +210,17 @@ namespace rrllvm { return doc; } - ModelGeneratorContext::ModelGeneratorContext() : - ownedDoc(createEmptyDocument()), - doc(ownedDoc), - mPiecewiseTriggers(), - symbols(new LLVMModelDataSymbols(doc->getModel(), 0)), - modelSymbols(new LLVMModelSymbols(getModel(), *symbols)), - options(0) + ModelGeneratorContext::ModelGeneratorContext() + : ownedDoc(createEmptyDocument()) + , doc(ownedDoc) + , mPiecewiseTriggers() + , symbols(new LLVMModelDataSymbols(doc->getModel(), 0)) + , modelSymbols(new LLVMModelSymbols(doc->getModel(), *symbols)) + , model(doc->getModel()) + , random(NULL) + , options(0) + , jit(nullptr) + , moietyConverter(nullptr) { // initialize LLVM // TODO check result diff --git a/source/llvm/ModelResources.cpp b/source/llvm/ModelResources.cpp index 4b640e8432..b8f6a93464 100644 --- a/source/llvm/ModelResources.cpp +++ b/source/llvm/ModelResources.cpp @@ -134,7 +134,7 @@ namespace rrllvm { rr::saveBinary(out, usingCompiledModuleBinaryStream); if (usingCompiledModuleBinaryStream) { - rr::saveBinary(out, jit->compiledModuleBinaryStream.get()->str().str()); + rr::saveBinary(out, jit->getModuleBinaryStreamAsString()); } } @@ -172,10 +172,7 @@ namespace rrllvm { //We saved this as a string; convert it back to a 'raw_svector_ostream' string stream_str; rr::loadBinary(in, stream_str); - llvm::raw_svector_ostream* binarystream = new llvm::raw_svector_ostream(jit->moduleBuffer); - *binarystream << stream_str; - - jit->compiledModuleBinaryStream.reset(binarystream); + jit->resetModuleBinaryStream(stream_str); } //Set up a buffer to read the object code from diff --git a/test/llvm_tests/JitFactoryTests.cpp b/test/llvm_tests/JitFactoryTests.cpp index 7a44cf18c9..be7f5ef3da 100644 --- a/test/llvm_tests/JitFactoryTests.cpp +++ b/test/llvm_tests/JitFactoryTests.cpp @@ -23,12 +23,14 @@ TEST_F(JitFactoryTests, MCJitFromConfig){ Config::setValue(Config::LLVM_BACKEND, Config::LLVM_BACKEND_VALUES::MCJIT); Jit* j = JitFactory::makeJitEngine(); ASSERT_TRUE(typeid((*j)) == typeid(MCJit)); + delete j; } TEST_F(JitFactoryTests, LLJitFromConfig){ Config::setValue(Config::LLVM_BACKEND, Config::LLVM_BACKEND_VALUES::LLJIT); Jit* j = JitFactory::makeJitEngine(); ASSERT_TRUE(typeid((*j)) == typeid(LLJit)); + delete j; } TEST_F(JitFactoryTests, MCJitFromOpt){ @@ -36,6 +38,7 @@ TEST_F(JitFactoryTests, MCJitFromOpt){ opt.setLLVMBackend(LoadSBMLOptions::MCJIT); Jit* j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); ASSERT_TRUE(typeid((*j)) == typeid(MCJit)); + delete j; } TEST_F(JitFactoryTests, LLJitFromOpt){ @@ -43,4 +46,5 @@ TEST_F(JitFactoryTests, LLJitFromOpt){ opt.setLLVMBackend(LoadSBMLOptions::LLJIT); Jit* j = JitFactory::makeJitEngine(opt.modelGeneratorOpt); ASSERT_TRUE(typeid((*j)) == typeid(LLJit)); + delete j; } diff --git a/test/llvm_tests/LLVMGeneratedFunctionTests.cpp b/test/llvm_tests/LLVMGeneratedFunctionTests.cpp index 4264ca464a..c6d5e6a9fe 100644 --- a/test/llvm_tests/LLVMGeneratedFunctionTests.cpp +++ b/test/llvm_tests/LLVMGeneratedFunctionTests.cpp @@ -22,8 +22,7 @@ void LLVMGeneratedFunctionTests::checkInitialEvaluationSpecies(int options, int s->setInitialAmount(speciesAmt); // so 4.5 after initial eval? // create the Jit engine and give to ModelGeneratorContext. - Jit* j = JitFactory::makeJitEngine(options); - ModelGeneratorContext mgc(doc.get() /*borrowed*/, options, j); + ModelGeneratorContext mgc(doc.get() /*borrowed*/, options, JitFactory::makeJitEngine(options)); // code gen (limited scope, this test only needs a few functions) EvalInitialConditionsCodeGen(mgc).createFunction(); diff --git a/test/serialization/state_saving.cpp b/test/serialization/state_saving.cpp index b7af244a3f..f949da60d0 100644 --- a/test/serialization/state_saving.cpp +++ b/test/serialization/state_saving.cpp @@ -435,6 +435,20 @@ TEST_F(StateSavingTests, LOAD_INVALID_FILE) { } TEST_F(StateSavingTests, LOAD_VALID_FILE) { + //NOTE: This test will fail every time roadrunner comes out with a new minor + // version, and/or the save state format changes. In fact, if the save state + // format changes, the minor version *must* change, so that existing roadrunner + // instances don't try to load new save files and visa versa. These files + // are copied versions of the file generated by the 'FromFile' test, below, so + // when the format changes, run that test on the three platforms, and replace + // the three files with the 'savedState.rr' file for each. + // + // The format is different per platform because things like 'what is the size + // of an unsigned long' can be different per compiler. + // + // At some point, it might be good to auto-generate these files from a different + // run, but issue #1210 was discovered only when loading state from a different + // instance than the one that had saved it, so we need this sort of test. RoadRunner rri; #if defined(_WIN32) rri.loadState((stateSavingModelsDir / "savedState_windows.rr").string()); @@ -455,6 +469,20 @@ TEST_F(StateSavingTests, LOAD_VALID_FILE) { #endif } +TEST_F(StateSavingTests, FromFile) { + std::filesystem::path p = std::filesystem::current_path() / "savedState.rr"; + //std::cout << "saved to " << p << std::endl; + RoadRunner rr(OpenLinearFlux().str()); + rr.saveState(p.string()); + RoadRunner rr2; + rr2.loadState(p.string()); + auto actualDataLsMatrix = *rr2.simulate(0, 10, 11); + auto actualData = rr::Matrix(actualDataLsMatrix); // for almostEquals + auto expectedData = OpenLinearFlux().timeSeriesResult(); + ASSERT_TRUE(expectedData.almostEquals(actualData, 1e-4)); +} + + TEST_F(StateSavingTests, LOAD_NONEXISTENT_FILE) { RoadRunner rri; EXPECT_THROW(rri.loadState((rrTestModelsDir_ / "nonexistent-save-state.rr").string()), std::invalid_argument); @@ -853,20 +881,6 @@ TEST_F(StateSavingTests, FromString) { ASSERT_TRUE(expectedData.almostEquals(actualData, 1e-4)); } -TEST_F(StateSavingTests, FromFile) { - std::filesystem::path p = std::filesystem::current_path() / "savedState.rr"; - //std::cout << "saved to " << p << std::endl; - RoadRunner rr(OpenLinearFlux().str()); - rr.saveState(p.string()); - RoadRunner rr2; - rr2.loadState(p.string()); - auto actualDataLsMatrix = *rr2.simulate(0, 10, 11); - auto actualData = rr::Matrix(actualDataLsMatrix); // for almostEquals - auto expectedData = OpenLinearFlux().timeSeriesResult(); - ASSERT_TRUE(expectedData.almostEquals(actualData, 1e-4)); -} - - class StateSavingTestsModelData : public RoadRunnerTest { public: StateSavingTestsModelData() {