Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing fmiFlags=s:euler for CMake FMUs #9677

Merged
merged 3 commits into from
Nov 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 1 addition & 6 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Original file line number Diff line number Diff line change
Expand Up @@ -4052,12 +4052,7 @@ algorithm
end if;

// Check flag fmiFlags if we need additional 3rdParty runtime libs and files
fmiFlagsList := Flags.getConfigStringList(Flags.FMI_FLAGS);
if listLength(fmiFlagsList) >= 1 and not stringEqual(List.first(fmiFlagsList), "none") then
needs3rdPartyLibs := true;
else
needs3rdPartyLibs := false;
end if;
needs3rdPartyLibs := SimCodeUtil.cvodeFmiFlagIsSet(SimCodeUtil.createFMISimulationFlags(false));

// Use CMake on Windows when cross-compiling with docker
_ := match (Flags.getConfigString(Flags.FMU_CMAKE_BUILD), needs3rdPartyLibs)
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/SimCode/SimCode.mo
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ public uniontype FmiSimulationFlags
end FMI_SIMULATION_FLAGS_FILE;
end FmiSimulationFlags;

constant FmiSimulationFlags defaultFmiSimulationFlags = FMI_SIMULATION_FLAGS({("solver","euler")});
constant FmiSimulationFlags defaultFmiSimulationFlags = FMI_SIMULATION_FLAGS({("s","euler")});

annotation(__OpenModelica_Interface="backend");
end SimCode;
11 changes: 3 additions & 8 deletions OMCompiler/Compiler/SimCode/SimCodeMain.mo
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,8 @@ algorithm
cminpack_sources := {};
end if;

// Check if the sundials files are needed. Shouldn't this actually check what the flags are
// instead of just checking if flags are set only?
if isSome(simCode.fmiSimulationFlags) then
// Check if the sundials files are needed
if SimCodeUtil.cvodeFmiFlagIsSet(simCode.fmiSimulationFlags) then
// The sundials headers are in the include directory.
copyFiles(RuntimeSources.sundials_headers, source=install_include_omc_dir, destination=fmu_tmp_sources_dir);
copyFiles(RuntimeSources.simrt_c_sundials_sources, source=install_fmu_sources_dir, destination=fmu_tmp_sources_dir);
Expand Down Expand Up @@ -924,13 +923,9 @@ algorithm
Error.addCompilerError("Unsupported value " + Flags.getConfigString(Flags.FMU_RUNTIME_DEPENDS) + "for compiler flag 'fmuRuntimeDepends'.");
then();
end match;
if isSome(simCode.fmiSimulationFlags) then
cmakelistsStr := System.stringReplace(cmakelistsStr, "@WITH_SUNDIALS@", ";WITH_SUNDIALS");
else
cmakelistsStr := System.stringReplace(cmakelistsStr, "@WITH_SUNDIALS@", "");
end if;

// Add external libraries and includes
cmakelistsStr := System.stringReplace(cmakelistsStr, "@NEED_CVODE@", SimCodeUtil.getCmakeSundialsLinkCode(simCode.fmiSimulationFlags));
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_ADDITIONAL_LIBS@", SimCodeUtil.getCmakeLinkLibrariesCode(simCode.makefileParams.libs));
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_ADDITIONAL_INCLUDES@", SimCodeUtil.make2CMakeInclude(simCode.makefileParams.includes));

Expand Down
75 changes: 66 additions & 9 deletions OMCompiler/Compiler/SimCode/SimCodeUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -13706,6 +13706,7 @@ public function createFMISimulationFlags
"Function reads FMI simulation flags from user input --fmiFlags
and creates FmiSimulationFlags record for code generation.
Author: AnHeuermann"
input Boolean printWarning = true;
output Option<SimCode.FmiSimulationFlags> fmiSimulationFlags;
protected
list<String> fmiFlagsList;
Expand All @@ -13730,7 +13731,7 @@ algorithm
fmiSimulationFlags := SOME(SimCode.defaultFmiSimulationFlags);

// User supplied file
// --fmiFlags=none
// --fmiFlags=path/to/*.json
elseif listLength(fmiFlagsList) == 1 and stringEqual( List.last(Util.stringSplitAtChar(List.first(fmiFlagsList),".")) , "json" ) then
pathToFile := List.first(fmiFlagsList);
if System.regularFileExists(pathToFile) then
Expand All @@ -13740,8 +13741,10 @@ algorithm
fmiSimulationFlags := SOME(SimCode.FMI_SIMULATION_FLAGS_FILE(path=Util.absoluteOrRelative(pathToFile)));
return;
else
msg := "Could not find file \"" + pathToFile + "\nIgnoring \"--fmiFlags=" + pathToFile + "\" and using default setting.\n";
Error.addCompilerWarning(msg);
if printWarning then
msg := "Could not find file \"" + pathToFile + "\nIgnoring \"--fmiFlags=" + pathToFile + "\" and using default setting.\n";
Error.addCompilerWarning(msg);
end if;
fmiSimulationFlags := SOME(SimCode.defaultFmiSimulationFlags);
return;
end if;
Expand All @@ -13753,8 +13756,10 @@ algorithm
// Check each flag
tmpSplitted := Util.stringSplitAtChar(flag,":");
if not listLength(tmpSplitted) == 2 then
msg := "Can't process flag \"" + flag + "\".\nSeperate flag name and flag value with \":\".\n";
Error.addCompilerWarning(msg);
if printWarning then
msg := "Can't process flag \"" + flag + "\".\nSeperate flag name and flag value with \":\".\n";
Error.addCompilerWarning(msg);
end if;
fmiSimulationFlags := SOME(SimCode.defaultFmiSimulationFlags);
return;
end if;
Expand All @@ -13763,12 +13768,16 @@ algorithm
// Save value
if stringEqual(tmpName, "s") then
if not stringEqual(tmpValue, "euler") and not stringEqual(tmpValue, "cvode") then
msg := "Unknown value \"" + tmpValue + "\" for flag \"s\".";
Error.addCompilerWarning(msg);
if printWarning then
msg := "Unknown value \"" + tmpValue + "\" for flag \"s\".";
Error.addCompilerWarning(msg);
end if;
end if;
else
msg := "Adding unknown FMU simulation flag \"" + tmpName + "\" .";
Error.addCompilerWarning(msg);
if printWarning then
msg := "Adding unknown FMU simulation flag \"" + tmpName + "\" .";
Error.addCompilerWarning(msg);
end if;
end if;
nameValueTuples := (tmpName, tmpValue) :: nameValueTuples;
end for;
Expand Down Expand Up @@ -15604,6 +15613,54 @@ algorithm
end for;
end getCmakeLinkLibrariesCode;

public function getCmakeSundialsLinkCode
"Code for FMU CMakeLists.txt to specify if CVODE is needed."
input Option<SimCode.FmiSimulationFlags> fmiSimulationFlags;
output String code = "";
algorithm
if not cvodeFmiFlagIsSet(fmiSimulationFlags) then
code := "set(NEED_CVODE FALSE)";
else
code := "set(NEED_CVODE TRUE)\n" +
"set(CVODE_DIRECTORY \"" + Settings.getInstallationDirectoryPath() + "/lib/omc\")";
end if;
end getCmakeSundialsLinkCode;

public function cvodeFmiFlagIsSet
"Checks if s:cvode is part of FMI_FLAGS.
If a *.json exists we don't check and assume cvode will be needed at some point."
input Option<SimCode.FmiSimulationFlags> fmiSimulationFlags;
output Boolean needsCvode = false;
algorithm
_ := match fmiSimulationFlags
local
list<tuple<String,String>> nameValueTuples;
String setting, value;
String configFile;
String fileContent;
case SOME(SimCode.FMI_SIMULATION_FLAGS(nameValueTuples))
algorithm
if listLength(nameValueTuples) >= 1 then
for tpl in nameValueTuples loop
(setting, value) := tpl;
if stringEqual(setting, "s") and stringEqual(value, "cvode") then
needsCvode := true;
break;
end if;
end for;
end if;
then();
case SOME(SimCode.FMI_SIMULATION_FLAGS_FILE(configFile))
algorithm
fileContent := System.readFile(configFile);
if not -1 == System.stringFind(fileContent, "\"cvode\"") then
needsCvode := true;
end if;
then();
else then();
end match;
end cvodeFmiFlagIsSet;

public function make2CMakeInclude
"Convert makefile include directories to CMake include directories"
input list<String> includes;
Expand Down
1 change: 0 additions & 1 deletion OMCompiler/Compiler/Template/CodegenFMU.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,6 @@ template settingsfile(SimCode simCode)
#define OMC_MODEL_PREFIX "<%modelNamePrefix(simCode)%>"
#define OMC_MINIMAL_RUNTIME 1
#define OMC_FMI_RUNTIME 1
<%if isSome(fmiSimulationFlags) then "#define WITH_SUNDIALS 1"%>
#endif
>>
end settingsfile;
Expand Down
11 changes: 0 additions & 11 deletions OMCompiler/SimulationRuntime/c/simulation/solver/sundials_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -949,15 +949,4 @@ void kinsolInfoHandlerFunction(const char *module, const char *function,
throwStreamPrint(NULL, "No sundials/kinsol support activated.");
}

/**
* @brief Function not supported without WITH_SUNDIALS
*
* @param A
* @param name
* @param logLevel
*/
void sundialsPrintSparseMatrix(SUNMatrix A, const char* name, const int logLevel) {
throwStreamPrint(NULL, "No sundials/kinsol support activated.");
}

#endif /* WITH_SUNDIALS */
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ set(FMU_NAME @FMU_NAME_IN@)

project(${FMU_NAME})

# CVODE needed
@NEED_CVODE@

# Test if RUNTIME_DEPENDENCIES is needed and available
set(RUNTIME_DEPENDENCIES_LEVEL @RUNTIME_DEPENDENCIES_LEVEL@)
if(${CMAKE_VERSION} VERSION_LESS "3.21" AND NOT ${RUNTIME_DEPENDENCIES_LEVEL} STREQUAL "none")
Expand Down Expand Up @@ -36,7 +39,10 @@ file(GLOB_RECURSE FMU_RUNTIME_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/external_solve
${CMAKE_CURRENT_SOURCE_DIR}/meta/*.c
${CMAKE_CURRENT_SOURCE_DIR}/simulation/*.c
${CMAKE_CURRENT_SOURCE_DIR}/util/*.c)

if (NOT ${NEED_CVODE})
list(REMOVE_ITEM FMU_RUNTIME_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/simulation/solver/sundials_error.c
${CMAKE_CURRENT_SOURCE_DIR}/simulation/solver/cvode_solver.c)
endif()
file(GLOB FMU_GENERATED_MODEL_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
Expand Down Expand Up @@ -78,12 +84,26 @@ if(NOT ${CMAKE_VERSION} VERSION_LESS "3.13")
endif()
target_link_libraries(${FMU_NAME} PRIVATE m Threads::Threads)
@FMU_ADDITIONAL_LIBS@
if(${NEED_CVODE})
find_library(SUNDIALS_CVODE_LIBRARY sundials_cvode
PATHS ${CVODE_DIRECTORY}
NO_DEFAULT_PATH)
find_library(SUNDIALS_NVSERIAL_LIBRARY sundials_nvecserial
PATHS ${CVODE_DIRECTORY}
NO_DEFAULT_PATH)
target_link_libraries(${FMU_NAME} PRIVATE ${SUNDIALS_CVODE_LIBRARY} ${SUNDIALS_NVSERIAL_LIBRARY})
target_include_directories(${FMU_NAME} PRIVATE sundials)
set(WITH_SUNDIALS ";WITH_SUNDIALS")
message(STATUS "CVODE: ${SUNDIALS_CVODE_LIBRARY} ${SUNDIALS_NVSERIAL_LIBRARY}")
else()
message(STATUS "CVODE: Not linked")
endif()

target_include_directories(${FMU_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(${FMU_NAME} PRIVATE ${FMI_INTERFACE_HEADER_FILES_DIRECTORY}
sundials@FMU_ADDITIONAL_INCLUDES@)

target_compile_definitions(${FMU_NAME} PRIVATE OMC_MINIMAL_RUNTIME=1;OMC_FMI_RUNTIME=1;CMINPACK_NO_DLL)
target_compile_definitions(${FMU_NAME} PRIVATE OMC_MINIMAL_RUNTIME=1;OMC_FMI_RUNTIME=1;CMINPACK_NO_DLL${WITH_SUNDIALS})

if(RUNTIME_DEPENDENCIES_LEVEL STREQUAL "all")
install(TARGETS ${FMU_NAME}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ val(v, 1.0, "BouncingBallFMI20_res.mat"); getErrorString();
// 0
// ""
// "{
// \"solver\" : \"euler\"
// \"s\" : \"euler\"
// }"
// ""
// true
Expand Down