Wiki source code of V2 Simulation
Version 1.1 by aas2 on 2017/08/03 13:23
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | = Simulation of Models in KIELER = | ||
2 | |||
3 | |||
4 | |||
5 | {{toc/}} | ||
6 | |||
7 | == Overview == | ||
8 | |||
9 | After a model has been created, it is reasonable to test if the model does what is expected. This can be achieved by simulating the model. The simulation must | ||
10 | |||
11 | * Receive inputs for the next tick | ||
12 | * Execute a tick | ||
13 | * Send generated outputs | ||
14 | |||
15 | Thus the simulation can be seen as a black box, which receives a state for the model, somehow computes a reaction, and communicates its new state to the outside. The communication for receiving and sending the state of the model is done using JSON. For example, in KIELER a simulation can be started by starting an executable file. The JSON communication is then done on stdin and stdout of the running process. | ||
16 | |||
17 | Within KIELER a single state of a simulation is represented as a //Data Pool//. A data pool can have multiple models. Each model can have multiple variables. Thus a representation of a complete run of a simulation can be implemented as list of data pools. | ||
18 | |||
19 | == Starting a Simulation == | ||
20 | |||
21 | Besides the explicit configuration of a simulation using a kisim file, it is possible to start simulations directly on models, executables or trace files. This will start a pre-defined configuration depending on the selected files. The following table shows which files can be started as simulation and what simulation configuration is created for it. | ||
22 | |||
23 | (% class="relative-table" style="width: 99.9453%;" %) | ||
24 | |=((( | ||
25 | Selection | ||
26 | )))|=(% colspan="1" %)(% colspan="1" %) | ||
27 | ((( | ||
28 | Example Selection | ||
29 | )))|=((( | ||
30 | Macro Tick Configuration of Simulation | ||
31 | ))) | ||
32 | |(% colspan="1" %)(% colspan="1" %) | ||
33 | ((( | ||
34 | executable | ||
35 | )))|(% colspan="1" %)(% colspan="1" %) | ||
36 | ((( | ||
37 | Sim_ModelA.exe | ||
38 | )))|(% colspan="1" %)(% colspan="1" %) | ||
39 | ((( | ||
40 | Performs a single tick and updates the pool with the received data from the process | ||
41 | ))) | ||
42 | |(% colspan="1" %)(% colspan="1" %) | ||
43 | ((( | ||
44 | 2 executables | ||
45 | )))|(% colspan="1" %)(% colspan="1" %) | ||
46 | ((( | ||
47 | Sim_ModelA.exe, Sim_ModelB.exe | ||
48 | )))|(% colspan="1" %)(% colspan="1" %) | ||
49 | ((( | ||
50 | Starts two executable data handlers with bidirectional redirection of inputs/outputs between the models. So the performed steps are: | ||
51 | |||
52 | Execute tick of A, redirect A→B, execute tick of B, redirect B → A | ||
53 | ))) | ||
54 | |(% colspan="1" %)(% colspan="1" %) | ||
55 | ((( | ||
56 | kisim file | ||
57 | )))|(% colspan="1" %)(% colspan="1" %) | ||
58 | ((( | ||
59 | ComplexSimulation.kisim | ||
60 | )))|(% colspan="1" %)(% colspan="1" %) | ||
61 | ((( | ||
62 | Uses the explicit configuration from the file | ||
63 | ))) | ||
64 | |(% colspan="1" %)(% colspan="1" %) | ||
65 | ((( | ||
66 | 1 executable, 1 trace file | ||
67 | )))|(% colspan="1" %)(% colspan="1" %) | ||
68 | ((( | ||
69 | Sim_ModelA.exe, TraceOfModelA.eso | ||
70 | )))|(% colspan="1" %)(% colspan="1" %) | ||
71 | ((( | ||
72 | The trace will first set inputs for the model that are read from the trace file. Then the tick is performed. Afterwards the generated outputs are compared to the outputs of the trace file and events are fired in case of a mismatch. | ||
73 | ))) | ||
74 | |(% colspan="1" %)(% colspan="1" %) | ||
75 | ((( | ||
76 | simin file | ||
77 | )))|(% colspan="1" %)(% colspan="1" %) | ||
78 | ((( | ||
79 | process_output.simin | ||
80 | )))|(% colspan="1" %)(% colspan="1" %) | ||
81 | ((( | ||
82 | The simin file must contain a JSON object for some model. The data pool of the simulation is then updated with its contents. | ||
83 | ))) | ||
84 | |(% colspan="1" %)(% colspan="1" %) | ||
85 | ((( | ||
86 | simout file | ||
87 | )))|(% colspan="1" %)(% colspan="1" %) | ||
88 | ((( | ||
89 | simulation_output.simout | ||
90 | )))|(% colspan="1" %)(% colspan="1" %) | ||
91 | ((( | ||
92 | The current pool of the simulation is written as JSON object to the simout file. | ||
93 | ))) | ||
94 | |||
95 | == Data Handlers == | ||
96 | |||
97 | A simulation consists of a list of //data handlers//, that can read or write the current data pool. Which handlers are available are explained in the following. | ||
98 | |||
99 | === Executable === | ||
100 | |||
101 | For instance, there exists a data handler for the simulation of an executable. The write operation of this data handler will send the inputs of the model as JSON object on stdin of the process. Afterwards the tick is triggered, and finally the data pool is updated with the JSON object received from stdout of the running process. | ||
102 | |||
103 | |=((( | ||
104 | Attribute | ||
105 | )))|=(% colspan="1" %)(% colspan="1" %) | ||
106 | ((( | ||
107 | Domain | ||
108 | )))|=(% colspan="1" %)(% colspan="1" %) | ||
109 | ((( | ||
110 | Example | ||
111 | )))|=((( | ||
112 | Description | ||
113 | ))) | ||
114 | |(% colspan="1" %)(% colspan="1" %) | ||
115 | ((( | ||
116 | executable | ||
117 | )))|(% colspan="1" %)(% colspan="1" %) | ||
118 | ((( | ||
119 | String, absolute workspace path or project relative path | ||
120 | )))|(% colspan="1" %)(% colspan="1" %) | ||
121 | ((( | ||
122 | /MyProject/kieler-gen/sim/bin/Sim_MyModel.exe | ||
123 | )))|(% colspan="1" %)(% colspan="1" %) | ||
124 | ((( | ||
125 | The path to the executable | ||
126 | ))) | ||
127 | |||
128 | === Redirect === | ||
129 | |||
130 | Multiple models may interact with each other as some can have inputs that are generated as outputs of other models. To implement this behaviour in the simulation, the redirect data handler has been created. It sets the inputs of a model to the outputs of some other model in the data pool. Thus the outputs of a some model A can be used as inputs of some model B. | ||
131 | |||
132 | |=((( | ||
133 | Attribute | ||
134 | )))|=((( | ||
135 | Domain | ||
136 | )))|=((( | ||
137 | Example | ||
138 | )))|=((( | ||
139 | Description | ||
140 | ))) | ||
141 | |((( | ||
142 | from | ||
143 | )))|((( | ||
144 | String, name of a model in the simulation | ||
145 | )))|((( | ||
146 | Sim_ModelA.exe | ||
147 | MyModelA | ||
148 | )))|((( | ||
149 | The name of the model of which the outputs are read | ||
150 | ))) | ||
151 | |((( | ||
152 | to | ||
153 | )))|((( | ||
154 | String, name of a model in the simulation | ||
155 | )))|((( | ||
156 | Sim_ModelB.exe | ||
157 | MyModelB | ||
158 | )))|((( | ||
159 | The name of the model of which the inputs are set | ||
160 | ))) | ||
161 | |||
162 | === Trace === | ||
163 | |||
164 | A trace data handler can read a trace file, set the inputs of a model with the inputs from the trace file as well as comparing the outputs of a model to the outputs of the trace file. If the outputs of the trace do not match the outputs of the current simulation, an event is fired and the data pool view will display a trace mismatch. | ||
165 | |||
166 | The typical setup to use a trace data handler for a model A is: | ||
167 | |||
168 | * Read inputs for model from trace | ||
169 | * Perform the tick of the model A | ||
170 | * Compare the outputs of the trace and the model A | ||
171 | |||
172 | |=((( | ||
173 | Attribute | ||
174 | )))|=((( | ||
175 | Domain | ||
176 | )))|=((( | ||
177 | Example | ||
178 | )))|=((( | ||
179 | Description | ||
180 | ))) | ||
181 | |((( | ||
182 | file | ||
183 | )))|((( | ||
184 | String, project relative path | ||
185 | )))|((( | ||
186 | MyTrace.eso | ||
187 | )))|((( | ||
188 | The trace file to be used | ||
189 | ))) | ||
190 | |((( | ||
191 | modelName | ||
192 | )))|((( | ||
193 | String, name of a model in the simulation | ||
194 | )))|((( | ||
195 | Sim_ModelA.exe | ||
196 | |||
197 | MyModelA | ||
198 | )))|((( | ||
199 | The model in the simulation for which the trace is for | ||
200 | ))) | ||
201 | |(% colspan="1" %)(% colspan="1" %) | ||
202 | ((( | ||
203 | checkOutputs | ||
204 | )))|(% colspan="1" %)(% colspan="1" %) | ||
205 | ((( | ||
206 | Boolean | ||
207 | )))|(% colspan="1" %)(% colspan="1" %) | ||
208 | ((( | ||
209 | true | ||
210 | false | ||
211 | )))|(% colspan="1" %)(% colspan="1" %) | ||
212 | ((( | ||
213 | If false, the outputs of the trace and simulation are not compared and the next tick is loaded after inputs have been set. | ||
214 | Use this option when only the //write// method of the data handler is used, but not its //read// method. | ||
215 | ))) | ||
216 | |(% colspan="1" %)(% colspan="1" %) | ||
217 | ((( | ||
218 | traceNumber | ||
219 | )))|(% colspan="1" %)(% colspan="1" %) | ||
220 | ((( | ||
221 | Integer | ||
222 | )))|(% colspan="1" %)(% colspan="1" %) | ||
223 | ((( | ||
224 | 0 | ||
225 | )))|(% colspan="1" %)(% colspan="1" %) | ||
226 | ((( | ||
227 | In case there are multiple traces in the eso file, determines which trace should be used. | ||
228 | Default is 0 | ||
229 | ))) | ||
230 | |(% colspan="1" %)(% colspan="1" %) | ||
231 | ((( | ||
232 | tickNumber | ||
233 | )))|(% colspan="1" %)(% colspan="1" %) | ||
234 | ((( | ||
235 | Integer | ||
236 | )))|(% colspan="1" %)(% colspan="1" %) | ||
237 | ((( | ||
238 | 0 | ||
239 | )))|(% colspan="1" %)(% colspan="1" %) | ||
240 | ((( | ||
241 | The tick of which the input is set. This can be used to skip some ticks of the trace. | ||
242 | Default is 0 | ||
243 | ))) | ||
244 | |||
245 | \\ | ||
246 | |||
247 | === Simulation Input Files === | ||
248 | |||
249 | The simulation can communicate with executables via stdin and stdout. To use this, the executable has to be started from within KIELER. | ||
250 | |||
251 | To get information about a model that is running outside of KIELER, simulation input files can be used. A simin file contains a single JSON object with the state of a model that can be used to feed the simulation with data. Thus any program that can write a JSON object to a file can interact with the simulation. | ||
252 | |||
253 | In combination with redirects, a simin file can be used to set the inputs of a model with data that is produced from another application. | ||
254 | |||
255 | Simulation input files can also be used to feed the simulation with data to be visualized via the simulation visualization. | ||
256 | |||
257 | (% class="relative-table" style="width: 81.5545%;" %) | ||
258 | |=((( | ||
259 | Attribute | ||
260 | )))|=((( | ||
261 | Domain | ||
262 | )))|=((( | ||
263 | Example | ||
264 | )))|=((( | ||
265 | Description | ||
266 | ))) | ||
267 | |((( | ||
268 | fileLocation | ||
269 | )))|((( | ||
270 | String, absolute file system path | ||
271 | )))|((( | ||
272 | /home/myuser/process_output.simin | ||
273 | )))|((( | ||
274 | The file location of the file containing the JSON object | ||
275 | ))) | ||
276 | |((( | ||
277 | modelName | ||
278 | )))|((( | ||
279 | String, name of a model | ||
280 | )))|((( | ||
281 | MyModel | ||
282 | )))|((( | ||
283 | Name of the model in the simulation that the data in the simin file is for. | ||
284 | ))) | ||
285 | |||
286 | \\ | ||
287 | |||
288 | === Simulation Outputs Files === | ||
289 | |||
290 | This data handler writes the output of the model in the simulation to the specified file. | ||
291 | |||
292 | (% class="relative-table" style="width: 81.7734%;" %) | ||
293 | |=((( | ||
294 | Attribute | ||
295 | )))|=((( | ||
296 | Domain | ||
297 | )))|=((( | ||
298 | Example | ||
299 | )))|=((( | ||
300 | Description | ||
301 | ))) | ||
302 | |((( | ||
303 | fileLocation | ||
304 | )))|((( | ||
305 | String, absolute file system path | ||
306 | )))|((( | ||
307 | /home/myuser/process_output.simout | ||
308 | )))|((( | ||
309 | The file location of the target file | ||
310 | ))) | ||
311 | |((( | ||
312 | modelName | ||
313 | )))|((( | ||
314 | String, name of a model | ||
315 | )))|((( | ||
316 | MyModel | ||
317 | )))|((( | ||
318 | Name of the model in the simulation that will be written as JSON object to the simout file | ||
319 | ))) | ||
320 | |||
321 | == KiSim == | ||
322 | |||
323 | Which data handlers are used and which actions are performed on them can be configured using a DSL, namely **KiSim**. | ||
324 | |||
325 | A kisim file contains two main parts: | ||
326 | |||
327 | * Configuration of data handlers | ||
328 | * Actions to be performed on the data handlers for each a macro tick | ||
329 | |||
330 | Besides these, an optional initialization part can be used to perform actions on data handlers once at startup. | ||
331 | |||
332 | === Examples === | ||
333 | |||
334 | The following shows examples of kisim files. | ||
335 | |||
336 | Configuration to simulate a single executable: | ||
337 | |||
338 | {{code title="Single Executable"}} | ||
339 | configure sim Test { | ||
340 | executable: kielger-gen/sim/bin/Sim_Test | ||
341 | } | ||
342 | |||
343 | execution { | ||
344 | write sim Test | ||
345 | } | ||
346 | {{/code}} | ||
347 | |||
348 | \\ | ||
349 | |||
350 | Configuration for two executables with redirection between both: | ||
351 | |||
352 | {{code}} | ||
353 | configure sim A { | ||
354 | executable: kielger-gen/sim/bin/Sim_Test | ||
355 | } | ||
356 | configure sim B { | ||
357 | executable: kielger-gen/sim/bin/Sim_Test2 | ||
358 | } | ||
359 | |||
360 | configure redirect A_to_B{ | ||
361 | from: A | ||
362 | to: B | ||
363 | } | ||
364 | |||
365 | configure redirect B_to_A{ | ||
366 | from: B | ||
367 | to: A | ||
368 | } | ||
369 | |||
370 | execution { | ||
371 | write sim A | ||
372 | write redirect A_to_B | ||
373 | write sim B | ||
374 | write redirect B_to_A | ||
375 | } | ||
376 | {{/code}} | ||
377 | |||
378 | Using a trace for a model: | ||
379 | |||
380 | {{code}} | ||
381 | configure sim A { | ||
382 | executable: kielger-gen/sim/bin/Sim_Test | ||
383 | } | ||
384 | |||
385 | configure trace A { | ||
386 | file: MyTrace.eso | ||
387 | modelName: A | ||
388 | } | ||
389 | |||
390 | execution { | ||
391 | write trace A // Set inputs of model to values from trace | ||
392 | write sim A // Perform tick of model | ||
393 | read trace A // Compare outputs of model with values from trace | ||
394 | } | ||
395 | {{/code}} | ||
396 | |||
397 | Feeding inputs of a model from a simin file: | ||
398 | |||
399 | {{code}} | ||
400 | configure sim A { | ||
401 | executable: kielger-gen/sim/bin/Sim_Test | ||
402 | } | ||
403 | |||
404 | configure simin SimInput { | ||
405 | file: process_output.simin | ||
406 | } | ||
407 | |||
408 | configure redirect SimInput_to_A{ | ||
409 | from: SimInput | ||
410 | to: A | ||
411 | } | ||
412 | |||
413 | execution { | ||
414 | write simin SimIn | ||
415 | write redirect SimInput_to_A | ||
416 | write sim A | ||
417 | } | ||
418 | {{/code}} | ||
419 | |||
420 | \\ | ||
421 | |||
422 | \\ |