MicroModelicaCCompiler  4.5.3
files.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  QSS Solver is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #include <cstdio>
21 #include <cstdlib>
22 #include <iostream>
23 #include <iterator>
24 #include <list>
25 #include <map>
26 #include <set>
27 #include <sstream>
28 #include <sys/stat.h>
29 #include <utility>
30 
31 #include "files.hpp"
32 
33 #include <generator/writer.hpp>
34 #include <ir/annotation.hpp>
35 #include <ir/class.hpp>
36 #include <ir/equation.hpp>
37 #include <ir/expression.hpp>
38 #include <util/compile_flags.hpp>
39 #include <util/symbol_table.hpp>
40 #include <util/util.hpp>
41 #include <util/visitors/partition_interval.hpp>
42 
43 using namespace std;
44 
45 namespace MicroModelica {
46 using namespace IR;
47 using namespace Util;
48 namespace Generator {
49 
50 Files::Files(ModelInstancePtr modelInstance, Model& model, CompileFlags& flags)
51  : _fname(model.name()), _model(model), _modelInstance(modelInstance), _writer(std::make_shared<FileWriter>()), _flags(flags)
52 {
53  if (_flags.hasOutputFile()) {
55  }
56 }
57 
58 Files::Files(string name, CompileFlags& flags) : _fname(name), _model(), _writer(std::make_shared<FileWriter>()), _flags(flags)
59 {
60  if (_flags.hasOutputFile()) {
62  }
63 }
64 
66 {
67  stringstream buffer;
68  stringstream includes;
69  string fname = _fname;
70  SymbolTable include;
71  fname.append(".makefile");
72  _writer->setFile(fname);
73  _writer->print("#Compiler and Linker");
74  _writer->print("CC := gcc");
75  _writer->print("");
76  _writer->print("#The Target Binary Program ");
77  _writer->print("TARGET := " + _fname);
78  _writer->print("");
79  _writer->print("#Flags, Libraries and Includes");
80  includes << "LDFLAGS :=-L " << Utils::instance().environmentVariable("MMOC_LIBS");
83  for (string l = tmp.begin(it); !tmp.end(it); l = tmp.next(it)) {
84  includes << " -L " << l;
85  }
86  includes << " -L " << Utils::instance().environmentVariable("MMOC_PATH") << "/usr/lib";
87  _writer->print(includes);
88  buffer << "LIBS :=" << (_flags.debug() ? " -lqssd -ltimestepd" : " -lqss -ltimestep");
89  _writer->print(buffer);
90  buffer << "INC := -I" + Utils::instance().environmentVariable("MMOC_ENGINE");
91  tmp = _model.includeDirectories();
92  for (string i = tmp.begin(it); !tmp.end(it); i = tmp.next(it)) {
93  include.insert(i, i);
94  }
95  if (_flags.hasObjects()) {
96  list<string> objects = _flags.objects();
97  for (auto obj : objects) {
98  unsigned long f = obj.rfind("/");
99  obj.erase(obj.begin() + f, obj.end());
100  include.insert(obj, obj);
101  }
102  }
103  string pinclude = Utils::instance().environmentVariable("MMOC_INCLUDE");
104  include[pinclude] = pinclude;
105  if (_flags.hasObjects()) {
106  pinclude = Utils::instance().environmentVariable("MMOC_PACKAGES");
107  include.insert(pinclude, pinclude);
108  }
109  for (string i = include.begin(it); !include.end(it); i = include.next(it)) {
110  buffer << " -I" << i;
111  }
112  _writer->print(buffer);
113  if (_flags.debug()) {
114  _writer->print("CFLAGS := -Wall -g -msse2 -mfpmath=sse $(LDFLAGS) $(LIBS)");
115  } else {
116  _writer->print("CFLAGS := -Wall -msse2 -mfpmath=sse -O2 $(LDFLAGS) $(LIBS)");
117  }
118  tmp = _model.linkLibraries();
119  for (string i = tmp.begin(it); !tmp.end(it); i = tmp.next(it)) {
120  includes << " -l" << i;
121  }
122  _writer->print("RMS := rm -rf");
123  _writer->print("");
124  _writer->print("#Source Files");
125  buffer << "TARGET_SRC := " << _fname << ".c";
126  if (!_model.calledFunctions().empty()) {
127  buffer << " " << _fname << "_functions.c";
128  }
129  _writer->print(buffer);
130  if (_flags.hasObjects()) {
131  buffer << "SRC := ";
132  list<string> objects = _flags.objects();
133  for (const auto& obj : objects) {
134  buffer << obj << " ";
135  }
136  _writer->print(buffer);
137  }
138  _writer->print("");
139  if (_flags.hasObjects()) {
140  _writer->print("#Objects");
141  _writer->print("OBJ = $(SRC:.c=.o)");
142  _writer->print("\%.o: \%.c");
143  _writer->print(_writer->indent(1) + "$(CC) $(INC) -c $< -o $@ $(CFLAGS)");
144  _writer->print("");
145  }
146  _writer->print("default: $(TARGET)");
147  _writer->print("");
148  buffer << "$(TARGET):";
149  if (_flags.hasObjects()) {
150  buffer << " $(OBJ)";
151  }
152  _writer->print(buffer);
153  buffer << _writer->indent(1) << "$(CC) $(INC)";
154  if (_flags.hasObjects()) {
155  buffer << " $(OBJ)";
156  }
157  buffer << " $(TARGET_SRC) $(CFLAGS) -o $@ -lm -lgsl -lconfig -lgfortran";
158 #ifdef __linux__
159  buffer << " -lpthread -lmetis -lscotch -lscotcherr -lpatoh -lrt -lsundials_cvode -lsundials_ida -lsundials_nvecserial -llapack -latlas "
160  "-lf77blas -lklu";
161 #endif
162  buffer << " -lgslcblas" << includes.str();
163  if (_model.annotations().parallel()) {
164  buffer << " -DQSS_PARALLEL";
165  }
166  _writer->print(buffer);
167  _writer->print("");
168  _writer->print(".PHONY: clean");
169  _writer->print("");
170  _writer->print("clean:");
171  _writer->print(_writer->indent(1) + "$(RMS) $(TARGET) *.dat *.log");
172  _writer->clearFile();
173 }
174 
176 {
177  string fname = _fname;
178  fname.append(".sh");
179  stringstream buffer;
180  _writer->setFile(fname);
181  _writer->print("cwd=$(pwd)");
182  _writer->print("cd " + Utils::instance().getFilePath(_fname));
183  _writer->print("make -f " + _fname + ".makefile clean");
184  buffer << "make -f " + _fname + ".makefile";
185  _writer->print(buffer);
186  _writer->print("./" + Utils::instance().getFileName(_fname));
187  if (_model.outputNbr()) {
188  _writer->print("echo");
189  _writer->print("gnuplot " + _fname + ".plt");
190  }
191  _writer->print("cd $cwd");
192  _writer->clearFile();
193 #ifdef __linux__
194  chmod(fname.c_str(), S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
195 #endif
196 }
197 
199 {
200  stringstream buffer;
201  /* if(deps->hasStates())
202  {
203  buffer << " with lines title \"" << varName << "\"";
204  }
205  else
206  {
207  buffer << " with steps title \"" << varName << "\"";
208  }*/
209  return buffer.str();
210 }
211 
213 {
214  /* if(!_model.outputNbr()) {
215  return;
216  }
217  stringstream buffer;
218  string fname = _fname;
219  fname.append(".plt");
220  _writer->setFile(fname);
221  _writer->print("set terminal wxt");
222  _writer->print("set title \"" + _fname + "\"");
223  _writer->print("set ylabel \"State Variables\"");
224  _writer->print("set xlabel \"Time\"");
225  _writer->print("set grid");
226  buffer << "plot ";
227  EquationTable outputs = _model.outputs();
228  int outs = 0, total = _model.outputNbr();
229  VarSymbolTable vt = _model.symbols();
230  EquationTable::iterator it;
231  for (Equation out = outputs.begin(it); !outputs.end(it); out = outputs.next(it)) {
232  Index index = outputs->key();
233  string varName;
234  Dependencies deps = eq->exp()->deps();
235  if(out.hasRange()) {
236  Option<Range> range = out.range();
237  for(int i = range-> ex.begin(); i <= index.end(); i++)
238  {
239  varName = eq->exp()->print();
240  buffer << "\"" << varName << ".dat\""
241  << _variableSettings(deps, varName);
242  if(i + 1 <= index.end())
243  {
244  buffer << ",";
245  }
246  }
247  }
248  else
249  {
250  varName = eq->exp()->print("");
251  buffer << "\"" << varName << ".dat\"" << _variableSettings(deps, varName);
252  }
253  outs += index.range();
254  if(outs < total)
255  {
256  buffer << ",";
257  }
258  }
259  _writer->print(&buffer);
260  _writer->print("pause mouse close");
261  _writer->clearFile();*/
262 }
263 
265 {
266  stringstream buffer;
267  string fname = _fname;
268  fname.append(".ini");
269  _writer->setFile(fname);
270  buffer.precision(5);
271  buffer << "minstep=" << scientific << annotation.minStep() << ";";
272  _writer->print(buffer);
273  buffer << "zchyst=" << annotation.ZCHyst() << ";";
274  _writer->print(buffer);
275  buffer << "derdelta=" << annotation.derDelta() << ";";
276  _writer->print(buffer);
277  buffer << "symdiff=" << annotation.symDiff() << ";";
278  _writer->print(buffer);
279  if (annotation.parallel()) {
280  buffer << "lps=" << annotation.lps() << ";";
281  _writer->print(buffer);
282  buffer << "partitionMethod=\"" << annotation.partitionMethodString() << "\";";
283  _writer->print(buffer);
284  buffer << "dt=" << annotation.DT() << ";";
285  _writer->print(buffer);
286  buffer << "dtSynch=\"" << annotation.dtSynchString() << "\";";
287  _writer->print(buffer);
288  } else {
289  _writer->print("lps=0;");
290  }
291  buffer << "nodesize=" << annotation.nodeSize() << ";";
292  _writer->print(buffer);
293  buffer << "jacobian=" << (annotation.jacobian()) << ";";
294  _writer->print(buffer);
295  buffer << "it=" << annotation.initialTime() << ";";
296  _writer->print(buffer);
297  buffer << "ft=" << annotation.finalTime() << ";";
298  _writer->print(buffer);
299  _writer->print("sol=\"" + annotation.solverString() + "\";");
300  list<double> dq = annotation.dqmin();
301  buffer << "dqmin=(";
302  unsigned long count = 0;
303  unsigned long size = dq.size();
304  for (const auto& it : dq) {
305  buffer << it;
306  if (++count < size) {
307  buffer << ",";
308  }
309  }
310  buffer << ");";
311  _writer->print(buffer);
312  dq = annotation.dqrel();
313  buffer << "dqrel=(";
314  count = 0;
315  size = dq.size();
316  for (const auto& it : dq) {
317  buffer << it;
318  if (++count < size) {
319  buffer << ",";
320  }
321  }
322  buffer << ");";
323  _writer->print(buffer);
324  printList(annotation.patohSettings(), "patohOptions");
325  printList(annotation.scotchSettings(), "scotchOptions");
326  printList(annotation.metisSettings(), "metisOptions");
327  buffer << "bdf=";
328  if (annotation.BDFPartition()->empty()) {
329  buffer << "0;";
330  } else {
331  buffer << "1;";
332  }
333  _writer->print(buffer);
334  buffer << "BDFPartitionDepth=" << annotation.BDFPartitionDepth() << ";";
335  _writer->print(buffer);
336  buffer << "BDFMaxStep=" << annotation.BDFMaxStep() << ";";
337  _writer->print(buffer);
338  addAnnotation(annotation, "CVODEMaxOrder", IntegerAnnotations::CVODEMaxOrder);
339  addAnnotation(annotation, "XOutput", IntegerAnnotations::XOutput);
340  _writer->clearFile();
341 }
342 
343 void Files::addAnnotation(const IR::ModelAnnotation& annotation, const string& mmo_name, IntegerAnnotations name)
344 {
345  if (annotation.hasAnnotation(name)) {
346  stringstream buffer;
347  buffer << mmo_name << "=" << annotation.getAnnotation(name) << ";";
348  _writer->print(buffer);
349  }
350 }
351 
352 void Files::printList(const list<string>& ann, const string& tag) const
353 {
354  stringstream buffer;
355  if (ann.empty()) {
356  return;
357  }
358  buffer << tag << "=(";
359  unsigned long count = 0;
360  unsigned long size = ann.size();
361  for (const auto& it : ann) {
362  buffer << it;
363  if (++count < size) {
364  buffer << ",";
365  }
366  }
367  buffer << ");";
368  _writer->print(buffer);
369 }
370 
372 {
373  AST_ExpressionList BDF_exps = _model.annotations().BDFPartition();
374  AST_ExpressionListIterator bdf_exp_it;
375  list<int> variables;
376  foreach (bdf_exp_it, BDF_exps) {
377  PartitionInterval partition_interval;
378  list<int> ret = partition_interval.apply(current_element(bdf_exp_it));
379  variables.splice(variables.end(), ret);
380  }
381  string file_name = _fname + "_BDF.part";
382  ofstream partition(file_name.c_str(), ios::out);
383  unsigned long partition_size = variables.size();
384  partition << partition_size << endl;
385  for (const auto& var_it : variables) {
386  partition << var_it << endl;
387  }
388  partition.close();
389 }
390 
391 } // namespace Generator
392 } // namespace MicroModelica
MicroModelica::Generator::Generator::_writer
WriterPtr _writer
Definition: generator.hpp:103
ModelTable< std::string, std::string >
ModelTable::begin
iterator begin()
Definition: table.hpp:68
MicroModelica::IR::ModelAnnotation::ZCHyst
double ZCHyst()
Definition: annotation.cpp:658
MicroModelica::IR::ModelAnnotation::initialTime
double initialTime()
Definition: annotation.cpp:652
MicroModelica::Generator::Files::_fname
string _fname
Definition: files.hpp:102
MicroModelica::Generator::Files::settings
void settings(IR::ModelAnnotation annotation)
Definition: files.cpp:264
MicroModelica::IR::ModelAnnotation::BDFPartition
AST_ExpressionList BDFPartition()
Definition: annotation.cpp:694
MicroModelica::IR::Model::libraryDirectories
Util::SymbolTable libraryDirectories() const
Definition: class.hpp:187
expression.hpp
MicroModelica::Util::CompileFlags::outputFile
string outputFile()
Definition: compile_flags.cpp:114
MicroModelica::Generator::Generator
Definition: generator.hpp:72
MicroModelica::Generator::Files::run
void run()
Definition: files.cpp:175
MicroModelica::Generator::Files::printList
void printList(const list< string > &ann, const string &tag) const
Definition: files.cpp:352
MicroModelica::IR::ModelAnnotation::BDFPartitionDepth
int BDFPartitionDepth()
Definition: annotation.cpp:696
MicroModelica::IR::IntegerAnnotations
IntegerAnnotations
Definition: annotation.hpp:119
MicroModelica::Generator::Files::_flags
Util::CompileFlags & _flags
Definition: files.hpp:106
MicroModelica::Util::CompileFlags
Definition: compile_flags.hpp:65
MicroModelica::IR::ModelAnnotation::metisSettings
list< string > metisSettings()
Definition: annotation.cpp:692
symbol_table.hpp
writer.hpp
MicroModelica::IR::ModelAnnotation::minStep
double minStep()
Definition: annotation.cpp:656
MicroModelica::IR::ModelAnnotation::nodeSize
int nodeSize()
Definition: annotation.cpp:674
MicroModelica::Generator::Files::plot
void plot()
Definition: files.cpp:212
MicroModelica::Generator::Files::bdfPartition
void bdfPartition()
Definition: files.cpp:371
MicroModelica::Util::CompileFlags::hasOutputFile
bool hasOutputFile()
Definition: compile_flags.cpp:116
MicroModelica::Generator::FileWriter
Definition: writer.hpp:185
MicroModelica::IR::ModelAnnotation::patohSettings
list< string > patohSettings()
Definition: annotation.cpp:688
ModelTable::end
iterator end()
Definition: table.hpp:70
files.hpp
MicroModelica::IR::ModelAnnotation
Definition: annotation.hpp:121
MicroModelica::Generator::Files::addAnnotation
void addAnnotation(const IR::ModelAnnotation &annotation, const string &mmo_name, IR::IntegerAnnotations name)
Definition: files.cpp:343
MicroModelica::IR::ModelAnnotation::symDiff
bool symDiff()
Definition: annotation.cpp:682
MicroModelica::IR::ModelAnnotation::dqrel
list< double > dqrel()
Definition: annotation.cpp:638
MicroModelica::Generator::Files::variablePlotSettings
std::string variablePlotSettings()
Definition: files.cpp:198
MicroModelica::IR::ModelAnnotation::hasAnnotation
bool hasAnnotation(IntegerAnnotations annot) const
Definition: annotation.cpp:627
equation.hpp
MicroModelica::IR::Model::includeDirectories
Util::SymbolTable includeDirectories() const
Definition: class.hpp:186
MicroModelica::IR::ModelAnnotation::dqmin
list< double > dqmin()
Definition: annotation.cpp:634
MicroModelica::Generator::Files::_writer
WriterPtr _writer
Definition: files.hpp:105
MicroModelica::IR::ModelAnnotation::derDelta
double derDelta()
Definition: annotation.cpp:660
MicroModelica::IR::Model::linkLibraries
Util::SymbolTable linkLibraries() const
Definition: class.hpp:185
ModelTable< std::string, std::string >::iterator
std::map< std::string, std::string >::iterator iterator
Definition: table.hpp:61
MicroModelica::IR::ModelAnnotation::getAnnotation
int getAnnotation(IntegerAnnotations annot) const
Definition: annotation.cpp:619
MicroModelica::IR::ModelAnnotation::finalTime
double finalTime()
Definition: annotation.cpp:654
MicroModelica::IR::Model::calledFunctions
FunctionTable calledFunctions() const
Definition: class.hpp:178
MicroModelica::IR::ModelAnnotation::lps
int lps()
Definition: annotation.cpp:672
compile_flags.hpp
MicroModelica::Generator::Generator::_flags
Util::CompileFlags _flags
Definition: generator.hpp:101
MicroModelica::Generator::Files::_model
IR::Model _model
Definition: files.hpp:103
MicroModelica::Generator::Files::makefile
void makefile()
Definition: files.cpp:65
MicroModelica::IR::ModelAnnotation::partitionMethodString
string partitionMethodString()
Definition: annotation.cpp:646
MicroModelica::IR::ModelAnnotation::jacobian
int jacobian()
Definition: annotation.cpp:664
MicroModelica::Generator::Files::Files
Files(ModelInstancePtr modelInstance, IR::Model &model, Util::CompileFlags &flags)
Definition: files.cpp:50
MicroModelica
Definition: files.cpp:45
ModelTable::empty
bool empty()
Definition: table.hpp:108
MicroModelica::IR::Model::outputNbr
int outputNbr() const
Definition: class.hpp:183
MicroModelica::IR::Model
Definition: class.hpp:160
MicroModelica::Util::Utils::instance
static Utils & instance()
Definition: util.hpp:83
MicroModelica::IR::ModelAnnotation::parallel
bool parallel()
Definition: annotation.cpp:700
ModelTable::insert
void insert(Key k, Value v)
Definition: table.hpp:48
MicroModelica::IR::ModelAnnotation::DT
double DT()
Definition: annotation.cpp:636
MicroModelica::Util::Utils::environmentVariable
std::string environmentVariable(std::string ev)
Definition: util.cpp:307
MicroModelica::Util::CompileFlags::objects
list< string > objects()
Definition: compile_flags.cpp:128
MicroModelica::IR::ModelAnnotation::scotchSettings
list< string > scotchSettings()
Definition: annotation.cpp:690
annotation.hpp
MicroModelica::IR::Model::annotations
ModelAnnotation annotations() const
Definition: class.hpp:177
MicroModelica::Util::CompileFlags::debug
int debug()
Definition: compile_flags.cpp:104
class.hpp
current_element
#define current_element(it)
Definition: ast_types.hpp:34
MicroModelica::Util::CompileFlags::hasObjects
bool hasObjects()
Definition: compile_flags.cpp:137
util.hpp
MicroModelica::IR::ModelAnnotation::solverString
string solverString()
Definition: annotation.cpp:642
MicroModelica::IR::ModelAnnotation::BDFMaxStep
double BDFMaxStep()
Definition: annotation.cpp:698
MicroModelica::Generator::ModelInstancePtr
std::shared_ptr< ModelInstance > ModelInstancePtr
Definition: model_instance.hpp:197
ModelTable::next
Value next(iterator &it)
Definition: table.hpp:78
MicroModelica::IR::ModelAnnotation::dtSynchString
string dtSynchString()
Definition: annotation.cpp:650