MicroModelicaCCompiler  4.5.3
model_matrix_gen.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 "model_matrix_gen.hpp"
21 
22 #include <sstream>
23 
24 #include <ast/parser/parse.hpp>
25 #include <deps/builders/eq_graph_builder.hpp>
26 #include <deps/sbg_graph/build_from_exps.hpp>
27 #include <deps/sb_dependencies.hpp>
28 #include <ir/derivative.hpp>
29 #include <ir/helpers.hpp>
30 #include <ir/index.hpp>
31 #include <util/model_config.hpp>
32 #include <util/util.hpp>
33 #include <util/symbol_table.hpp>
34 
35 namespace MicroModelica {
36 using namespace Deps;
37 using namespace SB;
38 using namespace Util;
39 namespace IR {
40 
41 template <typename NT, typename N, typename Config>
42 ModelMatrixGenerator<NT, N, Config>::ModelMatrixGenerator() : _model_matrix_def(), _tabs(0), _deps(), _post_process_eval(false), _config()
43 {
44 }
45 
46 template <typename NT, typename N, typename Config>
48 {
49  _config = config;
50 }
51 
52 template <typename NT, typename N, typename Config>
54 {
55  return _config;
56 }
57 
58 template <typename NT, typename N, typename Config>
59 void ModelMatrixGenerator<NT, N, Config>::addCode(MatrixCode dep_code, std::stringstream& code)
60 {
61  int size = dep_code.code.size();
62  for (int i = 0; i < size; i++) {
63  code << dep_code.begin[i];
64  code << dep_code.code[i];
65  if (!dep_code.end[i].empty()) {
66  code << dep_code.end[i] << endl;
67  }
68  }
69 }
70 
71 template <typename NT, typename N, typename Config>
73 {
74  stringstream buffer;
75  string component = _config.component[0];
76  bool use_component = _config.use_component[mode];
77  if (method == MATRIX::Init) {
78  component = _config.component[1];
79  }
80  if (!component.empty() && use_component) {
81  buffer << "." << component;
82  }
83  return buffer.str();
84 }
85 
86 template <typename NT, typename N, typename Config>
88 {
89  map<string, MatrixCode> deps_code;
90  NT nodes = _config.selector.getNodes();
92  std::stringstream code;
93  FunctionPrinter printer;
94  for (auto variable : _deps) {
95  list<DepData> var_deps = variable.second;
96  Option<Variable> ifr = variables[variable.first];
97  assert(ifr);
98  for (DepData var_dep : var_deps) {
99  string matrix = _config.names[method + mode];
100  string access = _config.access[mode];
101  std::stringstream begin;
102  std::stringstream end;
103  std::stringstream buffer;
104  N node = _config.selector.getNode(var_dep.id);
105  Expression use_exp = getUseExp(ifr.get(), var_dep);
106  Option<Range> range = getUseRange<N>(ifr.get(), var_dep, node, _config.selector.multipleNodes());
107  Index ifr_idx(use_exp);
108  string ifr_id = ifr_idx.identifier();
109  N ifr_node = _config.selector.setUsage(ifr_idx, node, range);
110  ifr_node = _config.selector.getScalarUsage(var_dep.var_dep.equations(), use_exp, ifr_node, ifr_idx);
111  Index ife_idx(_config.selector.exp(ifr_node));
112  Index ife_orig_idx = ife_idx;
113  Index ifr_orig_idx = ifr_idx;
114  if (mode == MATRIX::Transpose) {
115  Index swap = ifr_idx;
116  ifr_idx = ife_idx;
117  ife_idx = swap;
118  }
119  Index ifr_range_idx = ifr_idx;
120  Index ife_range_idx = ife_idx;
121  ifr_idx = ifr_idx.replace(range);
122  ife_idx = ife_idx.replace(range);
123  if (deps_code.find(ifr_id) == deps_code.end()) {
124  MatrixCode dep_code;
125  deps_code[ifr_id] = dep_code;
126  }
127  MatrixCode dep_code = deps_code[ifr_id];
128  if (range) {
129  if (!var_dep.var_dep.isRecursive()) {
130  range->replace(ife_range_idx, ifr_range_idx);
131  }
132  dep_code.begin.push_back(range->print());
133  dep_code.end.push_back(range->end());
134  buffer << range->block();
135  } else {
136  if (ifr_orig_idx.isConstant() && ifr_node.hasRange()) {
137  Range der_range = ifr_node.range().get();
138  der_range.replace(ife_orig_idx);
139  dep_code.begin.push_back(der_range.print());
140  dep_code.end.push_back(der_range.end());
141  buffer << der_range.block();
142  } else {
143  dep_code.begin.push_back("");
144  dep_code.end.push_back("");
145  }
146  }
147  if (method == MATRIX::Alloc) {
148  buffer << _config.container << matrix << "[" << ifr_idx << "]" << component(MATRIX::Alloc, mode) << "++;" << endl;
149  } else {
150  buffer << _config.container << matrix << "[" << ifr_idx << "]" << component(MATRIX::Init, mode) << "[" << access << "[" << ifr_idx
151  << "]++] = " << ife_idx << ";" << endl;
152  }
153  dep_code.code.push_back(buffer.str());
154  deps_code[ifr_id] = dep_code;
155  }
156  }
157  for (auto dc : deps_code) {
158  MatrixCode dep_code = dc.second;
159  addCode(dep_code, code);
160  }
161  if (method == MATRIX::Alloc) {
162  _model_matrix_def.alloc[mode] = code.str();
163  } else {
164  _model_matrix_def.init[mode] = code.str();
165  }
166 }
167 
168 template <typename NT, typename N, typename Config>
169 void ModelMatrixGenerator<NT, N, Config>::postProcess(SB::Deps::SetVertex vertex)
170 {
171  if (_post_process_eval) {
172  return;
173  }
174  printMatrix(MATRIX::Alloc, MATRIX::Normal);
175  printMatrix(MATRIX::Alloc, MATRIX::Transpose);
176  printMatrix(MATRIX::Init, MATRIX::Normal);
177  printMatrix(MATRIX::Init, MATRIX::Transpose);
178  _post_process_eval = true;
179 }
180 
181 template <typename NT, typename N, typename Config>
182 void ModelMatrixGenerator<NT, N, Config>::init(SB::Deps::SetVertex vertex)
183 {
184 }
185 
186 template <typename NT, typename N, typename Config>
188 {
189 }
190 
191 template <typename NT, typename N, typename Config>
192 void ModelMatrixGenerator<NT, N, Config>::visitF(SB::Deps::SetVertex vertex, SB::Deps::VariableDep var_dep)
193 {
194  if (!_config.selector.isAlgebraic(vertex)) {
195  string var_name = var_dep.var().name();
196  DepData dep_data(_config.selector.id(vertex), var_dep);
197  if (!findDep(_deps, dep_data, _config.selector.multipleNodes())) {
198  list<DepData> deps = _deps[var_name];
199  deps.push_back(dep_data);
200  _deps[var_name] = deps;
201  }
202  }
203 }
204 
205 template <typename NT, typename N, typename Config>
206 void ModelMatrixGenerator<NT, N, Config>::visitF(SB::Deps::SetVertex vertex, SB::Deps::VariableDep var_dep, SB::Deps::SetVertex gen_vertex)
207 {
208 }
209 
210 template <typename NT, typename N, typename Config>
211 void ModelMatrixGenerator<NT, N, Config>::visitG(SB::Deps::SetVertex v_vertex, SB::Deps::SetVertex g_vertex, SB::Deps::VariableDep var_dep,
212  int index_shift)
213 {
214  list<SB::Deps::VariableDep> pure_recursive_deps = g_vertex.desc().pureRecursiveDeps();
215  if (!_config.selector.isAlgebraic(v_vertex) && !var_dep.var().isAlgebraic()) {
216  string var_name = var_dep.var().name();
217  const bool FROM_ALG = true;
218  const bool REC_DEPS = pure_recursive_deps.size() > 0 || var_dep.isRecursive();
219  SB::Deps::VariableDep dep = var_dep;
220  dep.setRecursive(REC_DEPS);
221  DepData dep_data(_config.selector.id(v_vertex), dep, FROM_ALG);
222  if (!findDep(_deps, dep_data, _config.selector.multipleNodes())) {
223  list<DepData> deps = _deps[var_name];
224  deps.push_back(dep_data);
225  _deps[var_name] = deps;
226  }
227  }
228 }
229 
230 template <typename NT, typename N, typename Config>
231 void ModelMatrixGenerator<NT, N, Config>::visitG(SB::Deps::SetVertex v_vertex, SB::Deps::SetVertex g_vertex, SB::PWLMap use_map,
232  SB::Deps::LMapExp use_map_exp, Expression use_exp, SB::PWLMap def_map,
233  SB::Deps::LMapExp def_map_exp, SB::Set intersection)
234 {
235 }
236 
237 template <typename NT, typename N, typename Config>
238 void ModelMatrixGenerator<NT, N, Config>::initG(SB::Deps::SetVertex vertex, SB::Deps::SetEdge edge)
239 {
240 }
241 
242 template <typename NT, typename N, typename Config>
244 {
245  return _model_matrix_def;
246 }
247 
248 namespace MATRIX {
249 
250 template class MatrixConfig<Deps::EQSelector>;
251 
252 template class MatrixConfig<Deps::EVSelector>;
253 
254 } // namespace MATRIX
255 
257 
259 
260 } // namespace IR
261 } // namespace MicroModelica
MicroModelica::IR::ModelMatrixGenerator::postProcess
void postProcess(SB::Deps::SetVertex vertex)
Definition: model_matrix_gen.cpp:186
MicroModelica::IR::FunctionPrinter
Definition: helpers.hpp:147
MicroModelica::IR::MATRIX::Normal
@ Normal
Definition: model_matrix_gen.hpp:103
MicroModelica::IR::MatrixCode::begin
vector< std::string > begin
Definition: model_matrix_gen.hpp:112
MicroModelica::Util::VarSymbolTable
Definition: symbol_table.hpp:184
MicroModelica::Util::ModelConfig::symbols
VarSymbolTable & symbols()
Definition: model_config.hpp:122
index.hpp
MicroModelica::IR::findDep
bool findDep(DepsMap deps, DepData dep_data, bool multiple_nodes)
Definition: compute_deps.cpp:65
MicroModelica::IR::getUseExp
Expression getUseExp(Variable variable, DepData dep_data)
Definition: compute_deps.cpp:48
MicroModelica::IR::ModelMatrixGenerator::init
void init(SB::Deps::SetVertex vertex)
Definition: model_matrix_gen.cpp:199
MicroModelica::IR::ModelMatrixGenerator::ModelMatrixGenerator
ModelMatrixGenerator()
Definition: model_matrix_gen.cpp:59
symbol_table.hpp
helpers.hpp
Option
Definition: util_types.hpp:32
MicroModelica::IR::MatrixCode::code
vector< std::string > code
Definition: model_matrix_gen.hpp:114
MicroModelica::IR::ModelMatrixGenerator::addCode
void addCode(MatrixCode dep_code, std::stringstream &code)
Definition: model_matrix_gen.cpp:76
model_config.hpp
MicroModelica::IR::MATRIX::Method
Method
Definition: model_matrix_gen.hpp:88
MicroModelica::IR::MatrixCode
Definition: model_matrix_gen.hpp:111
MicroModelica::IR::ModelMatrixGenerator::end
void end()
Definition: model_matrix_gen.cpp:204
MicroModelica::IR::MatrixCode::end
vector< std::string > end
Definition: model_matrix_gen.hpp:113
MicroModelica::IR::Expression
Definition: expression.hpp:64
MicroModelica::IR::MATRIX::Transpose
@ Transpose
Definition: model_matrix_gen.hpp:103
model_matrix_gen.hpp
MicroModelica::IR::ModelMatrixGenerator::setup
void setup(Config config)
Definition: model_matrix_gen.cpp:64
MicroModelica::IR::Index::isConstant
bool isConstant() const
Definition: index.cpp:134
MicroModelica::IR::ModelMatrixGenerator::def
ModelMatrixDef def()
Definition: model_matrix_gen.cpp:260
MicroModelica::Util::ModelConfig::instance
static ModelConfig & instance()
Definition: model_config.hpp:87
MicroModelica::IR::MATRIX::Mode
Mode
Definition: model_matrix_gen.hpp:86
MicroModelica::IR::ModelMatrixGenerator::printMatrix
void printMatrix(MATRIX::Method method, MATRIX::Mode mode)
Definition: model_matrix_gen.cpp:104
MicroModelica::IR::Index
Definition: index.hpp:92
derivative.hpp
MicroModelica::Generator::MODEL_INSTANCE::Component::Deps
@ Deps
MicroModelica::IR::Index::replace
Index replace(bool range_idx=false) const
Definition: index.cpp:175
MicroModelica
Definition: files.cpp:45
MicroModelica::IR::ModelMatrixGenerator::config
Config config()
Definition: model_matrix_gen.cpp:70
MicroModelica::IR::ModelMatrixGenerator::visitF
void visitF(SB::Deps::SetVertex vertex, SB::Deps::VariableDep var_dep)
Definition: model_matrix_gen.cpp:209
MicroModelica::IR::ModelMatrixGenerator
Definition: model_matrix_gen.hpp:118
MicroModelica::IR::ModelMatrixGenerator::component
std::string component(MATRIX::Method method, MATRIX::Mode mode) const
Definition: model_matrix_gen.cpp:89
MicroModelica::IR::DepData
Definition: compute_deps.hpp:149
MicroModelica::IR::ModelMatrixGenerator::visitG
void visitG(SB::Deps::SetVertex v_vertex, SB::Deps::SetVertex g_vertex, SB::Deps::VariableDep var_dep, int index_shift)
Definition: model_matrix_gen.cpp:228
MicroModelica::IR::ModelMatrixGenerator::initG
void initG(SB::Deps::SetVertex vertex, SB::Deps::SetEdge edge)
Definition: model_matrix_gen.cpp:255
MicroModelica::IR::MATRIX::Alloc
@ Alloc
Definition: model_matrix_gen.hpp:88
util.hpp
MicroModelica::IR::MATRIX::Init
@ Init
Definition: model_matrix_gen.hpp:88