Skip to content

Commit

Permalink
- changed the -r" flag of the cpp-runtime to "-F" to have a consisten…
Browse files Browse the repository at this point in the history
…t flag-behaviour

- added some asserts to array-classes of c++ runtime
- fixed Kinsol-FMU support
- some typos
- added the possibility to overwrite flags in the c++ simulation runtime -- we can now replace "-r=file" with "-F=file" and "-w" with "-V all=warning"
  • Loading branch information
Marcus Walther committed Sep 2, 2015
1 parent 44eef17 commit c242492
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Compiler/Template/CodegenCpp.tpl
Expand Up @@ -2276,7 +2276,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
opts["-I"] = "<%solver%>";
opts["-R"] = "<%simulationLibDir(simulationCodeTarget(),simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace)%>";
opts["-M"] = "<%moLib%>";
opts["-r"] = "<%simulationResults(getRunningTestsuite(),simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace)%>";
opts["-F"] = "<%simulationResults(getRunningTestsuite(),simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace)%>";
<%if (stringEq(settings.outputFormat, "empty")) then 'opts["-O"] = "none";' else ""%>
<%
match(getConfigString(PROFILING_LEVEL))
Expand Down
3 changes: 2 additions & 1 deletion Compiler/Template/CodegenFMUCpp.tpl
Expand Up @@ -740,7 +740,6 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
$(eval CFLAGS=$(CFLAGS) -DUSE_LOGGER)
endif

CPPFLAGS = $(CFLAGS)
LDFLAGS=-L"$(OMHOME)/lib/<%getTriple()%>/omc/cpp" -L"$(BOOST_LIBS)" <%additionalLinkerFlags_GCC%>
PLATFORM="<%platformstr%>"

Expand All @@ -752,6 +751,8 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
$(eval OMCPP_SOLVER_LIBS=$(OMCPP_SOLVER_LIBS) -lOMCppKinsol_static $(SUNDIALS_LIBRARIES))
endif

CPPFLAGS = $(CFLAGS)

OMCPP_LIBS=-Wl,--start-group -lOMCppOMCFactory_FMU_static -lOMCppSystem_static -lOMCppSimController_static -Wl,--end-group -lOMCppDataExchange_static -lOMCppSimulationSettings_static $(OMCPP_SOLVER_LIBS) -lOMCppSolver_static -lOMCppMath_static -lOMCppModelicaUtilities_static -lOMCppExtensionUtilities_static -lOMCppFMU_static
MODELICA_EXTERNAL_LIBS=-lModelicaExternalC -lModelicaStandardTables -L$(LAPACK_LIBS) $(LAPACK_LIBRARIES)
BOOST_LIBRARIES = -l$(BOOST_SYSTEM_LIB) -l$(BOOST_FILESYSTEM_LIB) -l$(BOOST_PROGRAM_OPTIONS_LIB)
Expand Down
2 changes: 1 addition & 1 deletion SimulationRuntime/cpp/CMakeLists.txt
Expand Up @@ -135,7 +135,7 @@ ENDIF(RUNTIME_PROFILING)

# Handle FMU kinsol support
IF(FMU_KINSOL)
ADD_DEFINITIONS(-DFMU_KINSOL)
ADD_DEFINITIONS(-DENABLE_KINSOL_STATIC)
SET(USE_FMU_KINSOL_ "ON")
MESSAGE(STATUS "FMU kinsol enabled")
ELSE(FMU_KINSOL)
Expand Down
12 changes: 12 additions & 0 deletions SimulationRuntime/cpp/Include/Core/Math/Array.h
Expand Up @@ -277,6 +277,7 @@ class RefArray : public BaseArray<T>
*/
virtual void getDataCopy(T data[], size_t n) const
{
assert(n <= nelems);
const T* const * simvars_data = _ref_array.begin();
std::transform(simvars_data, simvars_data + n, data, RefArray2CArray<T>());
}
Expand Down Expand Up @@ -349,6 +350,7 @@ class RefArrayDim1 : public RefArray<T, size>
*/
virtual const T& operator()(const vector<size_t>& idx) const
{
assert(size > (idx[0] - 1));
return *(RefArray<T, size>::_ref_array[idx[0]-1]);
}

Expand All @@ -358,6 +360,7 @@ class RefArrayDim1 : public RefArray<T, size>
*/
virtual T& operator()(const vector<size_t>& idx)
{
assert(size > (idx[0] - 1));
return *(RefArray<T, size>::_ref_array[idx[0]-1]);
}

Expand All @@ -367,6 +370,7 @@ class RefArrayDim1 : public RefArray<T, size>
*/
inline virtual T& operator()(size_t index)
{
assert(size > (index - 1));
return *(RefArray<T, size>::_ref_array[index-1]);
}

Expand Down Expand Up @@ -432,6 +436,7 @@ class RefArrayDim2 : public RefArray<T, size1*size2>
*/
virtual const T& operator()(const vector<size_t>& idx) const
{
assert((size1*size2) > ((idx[0]-1)*size2 + (idx[1]-1)));
return *(RefArray<T, size1*size2>::
_ref_array[(idx[0]-1)*size2 + (idx[1]-1)]);
}
Expand All @@ -442,6 +447,7 @@ class RefArrayDim2 : public RefArray<T, size1*size2>
*/
virtual T& operator()(const vector<size_t>& idx)
{
assert((size1*size2) > ((idx[0]-1)*size2 + (idx[1]-1)));
return *(RefArray<T, size1*size2>::
_ref_array[(idx[0]-1)*size2 + (idx[1]-1)]);
}
Expand All @@ -453,6 +459,7 @@ class RefArrayDim2 : public RefArray<T, size1*size2>
*/
inline virtual T& operator()(size_t i, size_t j)
{
assert((size1*size2) > ((i-1)*size2 + (j-1)));
return *(RefArray<T, size1*size2>::
_ref_array[(i-1)*size2 + (j-1)]);
}
Expand Down Expand Up @@ -557,6 +564,7 @@ class RefArrayDim3 : public RefArray<T, size1*size2*size3>
*/
virtual const T& operator()(const vector<size_t>& idx) const
{
assert((size1*size2*size3) > (size3*(idx[0]-1 + size2*(idx[1]-1)) + idx[2]-1));
return *(RefArray<T, size1*size2*size3>::
_ref_array[size3*(idx[0]-1 + size2*(idx[1]-1)) + idx[2]-1]);
}
Expand All @@ -567,6 +575,7 @@ class RefArrayDim3 : public RefArray<T, size1*size2*size3>
*/
virtual T& operator()(const vector<size_t>& idx)
{
assert((size1*size2*size3) > (size3*(idx[0]-1 + size2*(idx[1]-1)) + idx[2]-1));
return *(RefArray<T, size1*size2*size3>::
_ref_array[size3*(idx[0]-1 + size2*(idx[1]-1)) + idx[2]-1]);
}
Expand All @@ -579,6 +588,7 @@ class RefArrayDim3 : public RefArray<T, size1*size2*size3>
*/
inline virtual T& operator()(size_t i, size_t j, size_t k)
{
assert((size1*size2*size3) > (size3*(i-1 + size2*(j-1)) + (k-1)));
return *(RefArray<T, size1*size2*size3>::
_ref_array[size3*(i-1 + size2*(j-1)) + (k-1)]);
}
Expand Down Expand Up @@ -723,6 +733,7 @@ class StatArray : public BaseArray<T>
if (nelems > 0) {
if (_data == NULL)
throw std::runtime_error("Invalid assign operation to uninitialized StatArray!");
assert(b.getNumElems() == nelems);
b.getDataCopy(_data, nelems);
}
return *this;
Expand Down Expand Up @@ -763,6 +774,7 @@ class StatArray : public BaseArray<T>
if (nelems > 0) {
if (_data == NULL)
throw std::runtime_error("Cannot assign to uninitialized StatArray!");
assert(b.getNumElems() == nelems);
b.getDataCopy(_data, nelems);
}
}
Expand Down
Expand Up @@ -31,7 +31,7 @@ class ModelicaSimulationError : public std::runtime_error
* Create a new modelica error object with the given arguments.
* @param error_id The identifier related to the sender of the error. \see SIMULATION_ERROR for detail.
* @param error_info Error message that should be shown.
* @param description More detailed description of the occurred error i.e. the error-message of the inner exception
* @param description More detailed description of the occurred error e.g. the error-message of the inner exception
* @param suppress Set to true if the error should not appear on std::err and std::out.
*/
ModelicaSimulationError(SIMULATION_ERROR error_id, const std::string& error_info, std::string description = "", bool suppress = false)
Expand Down
Expand Up @@ -32,8 +32,25 @@ class OMCFactory
virtual std::pair<boost::shared_ptr<ISimController>,SimSettings> createSimulation(int argc, const char* argv[], std::map<std::string, std::string> &opts);

protected:
/** merge command line args with built-in args and adapt OMEdit args to Cpp */
std::vector<const char *> preprocessArguments(int argc, const char* argv[], std::map<std::string, std::string> &opts);
/**
* This function handles complex c-runtime arguments like "-override=startTime=0,...". The
* arguments are separated correctly returned as vector. Furthermore the are added to the given
* opts-map (old values are overwritten).
* @param argc Number of arguments in the argv-array.
* @param argv The command line arguments as c-string array.
* @param opts Already parsed command line arguments (as key-value-pairs)
* @return All arguments as simple entries.
*/
std::vector<const char *> handleComplexCRuntimeArguments(int argc, const char* argv[], std::map<std::string, std::string> &opts);

/**
* Replace all argument names that are part of the arguments-to-replace-map.
* @param argc Number of arguments in the argv-array.
* @param argv The command line arguments as c-string array.
* @param opts Already parsed command line arguments (as key-value-pairs)
* @return All arguments including the replaced strings.
*/
std::vector<const char *> handleArgumentsToReplace(int argc, const char* argv[], std::map<std::string, std::string> &opts);

/**
* Evaluate all given command line arguments and store their values into the SimSettings structure.
Expand All @@ -55,14 +72,16 @@ class OMCFactory
pair<string, string> parseIngoredAndWrongFormatOption(const string &s);

void fillArgumentsToIgnore();
void fillArgumentsToReplace();

//boost::shared_ptr<ISimController> _simController;
std::map<string,shared_library> _modules;
std::string _defaultLinSolver;
std::string _defaultNonLinSolver;
map<string,shared_library> _modules;
string _defaultLinSolver;
string _defaultNonLinSolver;
PATH _library_path;
PATH _modelicasystem_path;
boost::unordered_set<string> _argumentsToIgnore; //a set of arguments that should be ignored,
boost::unordered_set<string> _argumentsToIgnore; //a set of arguments that should be ignored
std::map<string, string> _argumentsToReplace; //a mapping to replace arguments (e.g. -r=... -> -F=...)
std::string _overrideOMEdit; // unrecognized options if called from OMEdit
};
/** @} */ // end of simcorefactoryOMCFactory
85 changes: 76 additions & 9 deletions SimulationRuntime/cpp/SimCoreFactory/OMCFactory/OMCFactory.cpp
Expand Up @@ -19,6 +19,7 @@ OMCFactory::OMCFactory(PATH library_path, PATH modelicasystem_path)
, _defaultNonLinSolver("kinsol")
{
fillArgumentsToIgnore();
fillArgumentsToReplace();
}

OMCFactory::OMCFactory()
Expand All @@ -28,6 +29,7 @@ OMCFactory::OMCFactory()
, _defaultNonLinSolver("kinsol")
{
fillArgumentsToIgnore();
fillArgumentsToReplace();
}

OMCFactory::~OMCFactory()
Expand All @@ -48,7 +50,7 @@ pair<string, string> OMCFactory::parseIngoredAndWrongFormatOption(const string &
int sep = s.find("=");
string key = s;
if(sep > 0)
s.substr(0, sep);
key = s.substr(0, sep);

if (_argumentsToIgnore.find(key) != _argumentsToIgnore.end())
return make_pair(string("ignored"), s);
Expand All @@ -59,21 +61,25 @@ pair<string, string> OMCFactory::parseIngoredAndWrongFormatOption(const string &
return make_pair(string(), string());
}

SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[])
SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[])
{
int opt;
int portnum;
std::map<std::string,LogCategory> logCatMap = map_list_of("init", LC_INIT)("nls", LC_NLS)("ls",LC_LS)("solv", LC_SOLV)("output", LC_OUT)("event",LC_EVT)("model",LC_MOD)("other",LC_OTHER);
std::map<std::string,LogLevel> logLvlMap = map_list_of("error", LL_ERROR)("warning", LL_WARNING)("info", LL_INFO)("debug", LL_DEBUG);
std::map<std::string,OutputPointType> outputPointTypeMap = map_list_of("all", OPT_ALL)("step", OPT_STEP)("none", OPT_NONE);
po::options_description desc("Allowed options");

//program options that can be overwritten by OMEdit must be declared as vector
//so that the same value can be set multiple times
//(e.g. 'executable -F arg1 -r=arg2' -> 'executable -F arg1 -F=arg2')
//the variables of OMEdit are always the first elements of the result vectors, if they are set
desc.add_options()
("help", "produce help message")
("nls_continue", po::bool_switch()->default_value(false),"non linear solver will continue if it can not reach the given precision")
("runtime-library,R", po::value<string>(),"path to cpp runtime libraries")
("modelica-system-library,M", po::value<string>(), "path to Modelica library")
("results-file,r", po::value<string>(),"name of results file")
//("config-path,f", po::value< string >(), "path to xml files")
("results-file,F", po::value<vector<string> >(),"name of results file")
("start-time,S", po::value< double >()->default_value(0.0), "simulation start time")
("stop-time,E", po::value< double >()->default_value(1.0), "simulation stop time")
("step-size,H", po::value< double >()->default_value(0.0), "simulation step size")
Expand Down Expand Up @@ -161,7 +167,7 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[])
if (vm.count("results-file"))
{
//cout << "results file: " << vm["results-file"].as<string>() << std::endl;
resultsfilename = vm["results-file"].as<string>();
resultsfilename = vm["results-file"].as<vector<string> >().front();
}
else
throw ModelicaSimulationError(MODEL_FACTORY,"results-filename is not set");
Expand All @@ -183,7 +189,7 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[])
std::vector<std::string> log_vec = vm["log-settings"].as<std::vector<string> >(),tmpvec;
for(unsigned i=0;i<log_vec.size();++i)
{
cout << i << ". " << log_vec[i] << std::endl;
//cout << i << ". " << log_vec[i] << std::endl;
tmpvec.clear();
boost::split(tmpvec,log_vec[i],boost::is_any_of("="));

Expand Down Expand Up @@ -216,7 +222,60 @@ SimSettings OMCFactory::readSimulationParameter(int argc, const char* argv[])
return settings;
}

std::vector<const char *> OMCFactory::preprocessArguments(int argc, const char* argv[], std::map<std::string, std::string> &opts)
std::vector<const char *> OMCFactory::handleArgumentsToReplace(int argc, const char* argv[], std::map<std::string, std::string> &opts)
{
std::vector<const char *> optv;
optv.push_back(argv[0]);
for(int i = 1; i < argc; i++)
{
string arg = argv[i];

int sep = arg.find("=");
string key = arg;
string value = "";
if(sep > 0)
{
key = arg.substr(0, sep);
value = arg.substr(sep+1);
}

std::map<std::string, std::string>::iterator oldValue = opts.find(key);

map<string,string>::iterator iter = _argumentsToReplace.find(key);
if(iter != _argumentsToReplace.end())
{
//if(opts.find(iter->second) != opts.end()) //if the new key is already part of the argument list, prevent double insertion
// continue;

if(oldValue != opts.end())
{
opts.insert(pair<string,string>(iter->second, oldValue->second));
opts.erase(arg);
}
key = iter->second;
}

if(sep > 0)
arg = key + "=" + value;
else
arg = key;

//maybe we have replaced a simple through a complex value with spaces
std::vector<std::string> strs;
boost::split(strs, arg, boost::is_any_of(" "));
for(int j = 0; j < strs.size(); j++)
{
char *copyStr = new char[strs[j].size() + 1];
strcpy(copyStr, strs[j].c_str());
copyStr[strs[j].size()] = '\0';
optv.push_back(copyStr);
}
}

return optv;
}

std::vector<const char *> OMCFactory::handleComplexCRuntimeArguments(int argc, const char* argv[], std::map<std::string, std::string> &opts)
{
std::map<std::string, std::string>::const_iterator oit;
std::vector<const char *> optv;
Expand Down Expand Up @@ -271,13 +330,21 @@ void OMCFactory::fillArgumentsToIgnore()
_argumentsToIgnore.insert("-emit_protected");
}

void OMCFactory::fillArgumentsToReplace()
{
_argumentsToReplace = map<string, string>();
_argumentsToReplace.insert(std::pair<string,string>("-r","-F"));
_argumentsToReplace.insert(std::pair<string,string>("-w","-V all=warning"));
}

std::pair<boost::shared_ptr<ISimController>,SimSettings>
OMCFactory::createSimulation(int argc, const char* argv[],
std::map<std::string, std::string> &opts)
{
std::vector<const char *> optv = preprocessArguments(argc, argv, opts);
std::vector<const char *> optv = handleComplexCRuntimeArguments(argc, argv, opts);
std::vector<const char *> optv2 = handleArgumentsToReplace(optv.size(), &optv[0], opts);

SimSettings settings = readSimulationParameter(optv.size(), &optv[0]);
SimSettings settings = readSimulationParameter(optv2.size(), &optv2[0]);
type_map simcontroller_type_map;
PATH simcontroller_path = _library_path;
PATH simcontroller_name(SIMCONTROLLER_LIB);
Expand Down

0 comments on commit c242492

Please sign in to comment.