ug4
Loading...
Searching...
No Matches
vm.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013-2014: G-CSC, Goethe University Frankfurt
3 * Author: Martin Rupp
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef VM_H_
34#define VM_H_
35
36#include "common/log.h"
37#include <vector>
38#include "parser_node.h"
39#include "common/assert.h"
40#include "parser.hpp"
41#include "common/error.h"
42
43namespace ug{
44
48class VMAdd
49{
50private:
51 std::vector<char> vmBuf;
52 std::string m_name;
53 std::vector<double> variables;
54 size_t m_nrOut, m_nrIn;
55 std::vector<SmartPtr<VMAdd> > subfunctions;
56
69
70
71
73 {
74 int i=inst;
75 serializeInt(i);
76 }
77
78
79 inline void deserializeVMInstr(size_t &p, VMInstruction &instr)
80 {
81 int i = *((int*)&vmBuf[p]);
82 instr = (VMInstruction) i;
83 p += sizeof(int);
84 }
85
86 inline void serializeChar(char c)
87 {
88 vmBuf.push_back(c);
89 }
90
91 inline void serializeInt(int d)
92 {
93 char *tmp = (char*)&d;
94 for(size_t i=0; i<sizeof(d); i++)
95 serializeChar(tmp[i]);
96 }
97
98 inline void deserializeInt(size_t &p, int &i)
99 {
100 i = *((int*)&vmBuf[p]);
101 p += sizeof(int);
102 }
103
104 inline void serializeDouble(double d)
105 {
106 char *tmp = (char*)&d;
107 for(size_t i=0; i<sizeof(d); i++)
108 serializeChar(tmp[i]);
109 }
110
111 inline void deserializeDouble(size_t &p, double &d)
112 {
113 d = *((double*)&vmBuf[p]);
114 p += sizeof(double);
115 }
116
117
118 void print_unaryDouble(const char *desc, size_t &i)
119 {
120 double t;
121 deserializeDouble(i, t);
122 UG_LOG(desc << " " << t << "\n");
123 }
124 void print_unaryInt(const char *desc, size_t &i)
125 {
126 int t;
127 deserializeInt(i, t);
128 UG_LOG(desc << " " << t << "\n");
129 }
130
131 void print_op(size_t &i)
132 {
133 int op;
134 deserializeInt(i, op);
135 switch(op)
136 {
137 case LUAPARSER_MATH_COS: UG_LOG("cos\n"); break;
138 case LUAPARSER_MATH_SIN: UG_LOG("sin\n"); break;
139 case LUAPARSER_MATH_EXP: UG_LOG("exp\n"); break;
140 case LUAPARSER_MATH_ABS: UG_LOG("abs\n"); break;
141 case LUAPARSER_MATH_LOG: UG_LOG("log\n"); break;
142 case LUAPARSER_MATH_LOG10: UG_LOG("log10\n"); break;
143 case LUAPARSER_MATH_SQRT: UG_LOG("sqrt\n"); break;
144 case LUAPARSER_MATH_FLOOR: UG_LOG("floor\n"); break;
145 case LUAPARSER_MATH_CEIL: UG_LOG("ceil\n"); break;
146 case '+': UG_LOG("+\n"); break;
147 case '-': UG_LOG("-\n"); break;
148 case '*': UG_LOG("*\n"); break;
149 case '/': UG_LOG("/\n"); break;
150 case '<': UG_LOG("<\n"); break;
151 case '>': UG_LOG(">\n"); break;
152 case LUAPARSER_GE: UG_LOG("GE >=\n"); break;
153 case LUAPARSER_LE: UG_LOG("LE <=\n"); break;
154 case LUAPARSER_NE: UG_LOG("NE ~=\n"); break;
155 case LUAPARSER_EQ: UG_LOG("EQ ==\n"); break;
156 case LUAPARSER_AND: UG_LOG("AND\n"); break;
157 case LUAPARSER_OR: UG_LOG("OR\n"); break;
158 case LUAPARSER_MATH_POW: UG_LOG("pow\n"); break;
159 case LUAPARSER_MATH_MIN: UG_LOG("min\n"); break;
160 case LUAPARSER_MATH_MAX: UG_LOG("max\n"); break;
161 }
162 }
163
164public:
166 {
167 m_name = "unknown";
168 }
169 void set_name(std::string name)
170 {
171 m_name = name;
172 }
173
174 void push(double constant)
175 {
176// UG_LOG("POS " << get_pos() << "\n");
177// UG_LOG("PUSH_CONSTANT " << constant << "\n");
179 serializeDouble(constant);
180 }
181
182 void push_var(int i)
183 {
184// UG_LOG("PUSH_VAR " << i << "\n");
186 serializeInt(i);
187// UG_LOG("POS " << get_pos() << "\n");
188 }
189
191 {
192// UG_LOG("JMP_IF_FALSE\n");
193 return jump(JMP_IF_FALSE);
194 }
195
196 int jmp()
197 {
198// UG_LOG("JMP\n");
199 return jump(JMP);
200 }
201
203 {
204 return vmBuf.size();
205 }
206
207 void unary(int oper)
208 {
209// UG_LOG("UNARY OP " << oper << "\n");
211 serializeInt(oper);
212// UG_LOG("POS " << get_pos() << "\n");
213 }
214
215 void binary(int oper)
216 {
217// UG_LOG("BINARY OP " << oper << "\n");
219 serializeInt(oper);
220// UG_LOG("POS " << get_pos() << "\n");
221 }
222
223 void assign(int v)
224 {
225// UG_LOG("ASSIGN " << v << "\n");
227 serializeInt(v);
228// UG_LOG("POS " << get_pos() << "\n");
229 }
230
231 void call(SmartPtr<VMAdd> subfunction)
232 {
233 size_t i;
234 for(i=0; i<subfunctions.size(); i++)
235 if(subfunctions[i] == subfunction)
236 break;
237 if(i == subfunctions.size())
238 subfunctions.push_back(subfunction);
240 serializeInt(i);
241 }
242
243 void adjust_jmp_pos(int iPos, int jmpPos)
244 {
245// UG_LOG("adjusting jmp pos in " << iPos << " to " << jmpPos << "\n");
246 int *p = (int *)&vmBuf[iPos];
247 *p = jmpPos;
248 }
249
250 void ret()
251 {
253 }
254
256 {
257 UG_LOG("function " << m_name << ", " << m_nrIn << " inputs, " << m_nrOut <<
258 " outputs, "<< variables.size() << " variables, " << subfunctions.size() << " subfunctions");
259 }
260
261 void print()
262 {
263 print_rec(0);
264 }
265
266 void print_rec(int level)
267 {
268 if(level > 5) { UG_LOG("\n... aborting recursion (potential infinite loop)\n"); }
269 print_short();
270 UG_LOG("\n");
271 for(size_t i=0; i<vmBuf.size(); )
272 {
273 UG_ASSERT(i<vmBuf.size(), i);
274 UG_LOG(i << " ");
275 VMInstruction instr;
276 deserializeVMInstr(i, instr);
277
278 switch(instr)
279 {
280 case PUSH_CONSTANT:
281 print_unaryDouble("PUSH_CONSTANT", i);
282 break;
283
284 case PUSH_VAR:
285 print_unaryInt("PUSH_VAR", i);
286 break;
287
288 case JMP_IF_FALSE:
289 print_unaryInt("JMP_IF_FALSE", i);
290 break;
291 case JMP:
292 print_unaryInt("JMP", i);
293 break;
294
295 case OP_UNARY:
296 UG_LOG("OP_UNARY "); print_op(i);
297 break;
298 case OP_BINARY:
299 UG_LOG("OP_BINARY "); print_op(i);
300 break;
301 case ASSIGN:
302 print_unaryInt("ASSIGN", i);
303 break;
304 case OP_RETURN:
305 UG_LOG("RETURN\n");
306 break;
307
308 case OP_CALL:
309 {
310 int varI;
311 deserializeInt(i, varI);
312
313 UG_COND_THROW(varI >= (int)subfunctions.size(), i);
314 UG_LOG("CALL to subfunction " << varI << ": ");
315 subfunctions[varI]->print_short();
316 UG_LOG("\n");
317 break;
318 }
319
320 default:
321 UG_LOG(((int)instr) << "?\n");
322 }
323 }
324 if(subfunctions.size() > 0)
325 {
326 UG_LOG("<< SUBFUNCTIONS OF " << m_name << ":\n");
327 for(size_t i=0; i<subfunctions.size(); i++)
328 {
329 UG_LOG("---- SUBFUNCTION " << i << " of " << m_name << " ----\n");
330 subfunctions[i]->print_rec(level+1);
331 }
332 UG_LOG(" SUBFUNCTIONS OF " << m_name << " >>\n");
333 }
334 }
335
337 {
338 serializeVMInstr(instr);
339 int jmpPos = get_pos();
340 serializeInt(jmpPos);
341// UG_LOG("jump pos is " << jmpPos << "\n");
342 return jmpPos;
343 }
344
345
346
347 void set_in_out(size_t nrIn,size_t nrOut)
348 {
349 m_nrOut = nrOut;
350 m_nrIn = nrIn;
351 }
352 void set_nr_of_variables(size_t nr)
353 {
354 variables.resize(nr);
355 }
356
357 inline void execute_unary(size_t &i, double &v)
358 {
359 int op;
360// UG_LOG("unary op " << v << "\n");
361 deserializeInt(i, op);
362 switch(op)
363 {
364 case LUAPARSER_MATH_COS: v = cos(v); break;
365 case LUAPARSER_MATH_SIN: v = sin(v); break;
366 case LUAPARSER_MATH_EXP: v = exp(v); break;
367 case LUAPARSER_MATH_ABS: v = fabs(v); break;
368 case LUAPARSER_MATH_LOG: v = log(v); break;
369 case LUAPARSER_MATH_LOG10: v = log10(v); break;
370 case LUAPARSER_MATH_SQRT: v = sqrt(v); break;
371 case LUAPARSER_MATH_FLOOR: v = floor(v); break;
372 case LUAPARSER_MATH_CEIL: v = ceil(v); break;
373 }
374 }
375
376 inline void execute_binary(size_t &i, double *stack, int SP)
377 {
378 double &a = stack[SP-2];
379 double &b = stack[SP-1];
380// UG_LOG("binary op " << a << " op " << b << "\n");
381
382 int op;
383 deserializeInt(i, op);
384 switch(op)
385 {
386 case '+': a = b+a; break;
387 case '-': a = b-a; break;
388 case '*': a = b*a; break;
389 case '/': a = b/a; break;
390 case '<': a = (b < a) ? 1.0 : 0.0; break;
391 case '>': a = (b > a) ? 1.0 : 0.0; break;
392 case LUAPARSER_GE: a = (b >= a) ? 1.0 : 0.0; break;
393 case LUAPARSER_LE: a = (b <= a) ? 1.0 : 0.0; break;
394 case LUAPARSER_NE: a = (b != a) ? 1.0 : 0.0; break;
395 case LUAPARSER_EQ: a = (b == a) ? 1.0 : 0.0; break;
396 case LUAPARSER_AND: a = (a != 0.0 && b != 0.0) ? 1.0 : 0.0; break;
397 case LUAPARSER_OR: a = (a != 0 || b != 0) ? 1.0 : 0.0; break;
398 case LUAPARSER_MATH_POW: a = pow(b, a); break;
399 case LUAPARSER_MATH_MIN: a = (b < a) ? a : b; break;
400 case LUAPARSER_MATH_MAX: a = (b > a) ? a : b; break;
401 }
402 }
403
404 double call(double *stack, int &SP)
405 {
406// for(int j=0; j<variables.size(); j++)
407// {UG_LOG("var[[" << j << "] = " << variables[j] << "\n");}
408
409 double varD;
410 int varI;
411 size_t i=0;
412 VMInstruction instr;
413 while(1)
414 {
415// UG_LOG("IP = " << i << ", SP = " << SP);
416 deserializeVMInstr(i, instr);
417// UG_LOG("OP = " << (int)instr << "\n");
418// for(int j=0; j<SP; j++)
419// {UG_LOG("SP[" << j << "] = " << stack[j] << ", ");}
420// UG_LOG("\n");
421
422 switch(instr)
423 {
424 case PUSH_CONSTANT:
425
426 deserializeDouble(i, varD);
427// UG_LOG("PUSH CONSTANT " << varD << "\n");
428 stack[SP++] = varD;
429 break;
430
431 case PUSH_VAR:
432 deserializeInt(i, varI);
433 stack[SP++] = variables[varI-1];
434// UG_LOG("PUSH VAR " << varI << "\n");
435 break;
436
437 case JMP_IF_FALSE:
438 deserializeInt(i, varI);
439// UG_LOG("JMP IF FALSE " << varI << "\n");
440 SP--;
441 if(stack[SP] == 0.0)
442 i = varI;
443 break;
444 case JMP:
445 deserializeInt(i, varI);
446// UG_LOG("JMP " << varI << "\n");
447 i = varI;
448 break;
449
450 case OP_UNARY:
451 UG_ASSERT(SP>0, SP);
452 execute_unary(i, stack[SP-1]);
453 break;
454
455 case OP_BINARY:
456 UG_ASSERT(SP>1, SP);
457 execute_binary(i, stack, SP);
458 SP--;
459 break;
460
461 case ASSIGN:
462 deserializeInt(i, varI);
463 SP--;
464// UG_LOG("ASSIGN " << varI << " = " << stack[SP] << "\n");
465 variables[varI-1] = stack[SP];
466 break;
467
468 case OP_RETURN:
469// UG_LOG("RETURN\n");
470 UG_ASSERT(SP == (int)m_nrOut, "stack pointer is not nrOut =" << m_nrOut << ", instead " << SP << " ?")
471 return stack[0];
472 break;
473
474 case OP_CALL:
475 {
476 deserializeInt(i, varI);
477// UG_LOG("call IP = " << i << ", SP = " << SP << "\n");
478 SmartPtr<VMAdd> sub = subfunctions[varI];
479 sub->call_sub(stack, SP);
480// UG_LOG("call IP = " << i << ", SP = " << SP << "\n");
481 break;
482 }
483 default:
484 UG_ASSERT(0, "IP: " << i << " op " << ((int)instr) << " ?\n");
485 }
486 }
487 }
488
489 double call_sub(double *stack, int &SP)
490 {
491 for(size_t i=0; i<m_nrIn; i++)
492 variables[i] = stack[SP+i-1];
493 SP -= m_nrIn;
494 return call(stack, SP);
495 }
496
497 int execute(double *ret, const double *in)
498 {
499 double stack[255];
500 int SP=0;
501
502 for(size_t i=0;i<m_nrIn; i++)
503 variables[i] = in[i];
504 call(stack, SP);
505 UG_ASSERT(SP == (int)m_nrOut, SP << " != " << m_nrOut);
506 for(size_t i=0; i<m_nrOut; i++)
507 ret[i] = stack[i];
508
509 return 1;
510 }
511
512 double call()
513 {
514 double stack[255];
515 int SP=0;
516 return call(stack, SP);
517 }
518
519 double call(double a, double b, double c)
520 {
522 UG_ASSERT(m_nrIn == 3, m_nrIn);
523 variables[0] = a;
524 variables[1] = b;
525 variables[2] = c;
526 return call();
527 }
528
529 double call(double a, double b)
530 {
532 UG_ASSERT(m_nrIn == 2, m_nrIn);
533 variables[0] = a;
534 variables[1] = b;
535 return call();
536 }
537
538 double call(double a)
539 {
541 UG_ASSERT(m_nrIn == 1, m_nrIn);
542 variables[0] = a;
543 return call();
544 }
545
546 size_t num_out()
547 {
548 return m_nrOut;
549 }
550 size_t num_in()
551 {
552 return m_nrIn;
553 }
554};
555
556}
557#endif /* VM_H_ */
parameterString p
location name
Definition checkpoint_util.lua:128
Definition smart_pointer.h:108
--> documentation in vm.doxygen <–///
Definition vm.h:49
std::vector< SmartPtr< VMAdd > > subfunctions
Definition vm.h:55
int jump(VMInstruction instr)
Definition vm.h:336
double call(double a, double b, double c)
Definition vm.h:519
void deserializeDouble(size_t &p, double &d)
Definition vm.h:111
std::vector< char > vmBuf
Definition vm.h:51
size_t num_out()
Definition vm.h:546
double call(double a, double b)
Definition vm.h:529
void serializeInt(int d)
Definition vm.h:91
int jmp()
Definition vm.h:196
std::string m_name
Definition vm.h:52
double call()
Definition vm.h:512
void print_op(size_t &i)
Definition vm.h:131
void print_rec(int level)
Definition vm.h:266
void deserializeVMInstr(size_t &p, VMInstruction &instr)
Definition vm.h:79
VMInstruction
Definition vm.h:58
@ OP_CALL
Definition vm.h:67
@ JMP_IF_FALSE
Definition vm.h:61
@ ASSIGN
Definition vm.h:65
@ PUSH_VAR
Definition vm.h:60
@ OP_UNARY
Definition vm.h:63
@ PUSH_CONSTANT
Definition vm.h:59
@ JMP
Definition vm.h:62
@ OP_BINARY
Definition vm.h:64
@ OP_RETURN
Definition vm.h:66
void serializeDouble(double d)
Definition vm.h:104
void print_unaryDouble(const char *desc, size_t &i)
Definition vm.h:118
void push(double constant)
Definition vm.h:174
void serializeChar(char c)
Definition vm.h:86
void call(SmartPtr< VMAdd > subfunction)
Definition vm.h:231
int execute(double *ret, const double *in)
Definition vm.h:497
void unary(int oper)
Definition vm.h:207
void binary(int oper)
Definition vm.h:215
int get_pos()
Definition vm.h:202
void set_nr_of_variables(size_t nr)
Definition vm.h:352
void print_short()
Definition vm.h:255
double call(double a)
Definition vm.h:538
size_t m_nrOut
Definition vm.h:54
double call(double *stack, int &SP)
Definition vm.h:404
int jmp_if_false()
Definition vm.h:190
size_t num_in()
Definition vm.h:550
void ret()
Definition vm.h:250
void execute_binary(size_t &i, double *stack, int SP)
Definition vm.h:376
void print()
Definition vm.h:261
void print_unaryInt(const char *desc, size_t &i)
Definition vm.h:124
void set_name(std::string name)
Definition vm.h:169
double call_sub(double *stack, int &SP)
Definition vm.h:489
void adjust_jmp_pos(int iPos, int jmpPos)
Definition vm.h:243
void serializeVMInstr(VMInstruction inst)
Definition vm.h:72
size_t m_nrIn
Definition vm.h:54
void set_in_out(size_t nrIn, size_t nrOut)
Definition vm.h:347
void push_var(int i)
Definition vm.h:182
VMAdd()
Definition vm.h:165
void execute_unary(size_t &i, double &v)
Definition vm.h:357
void deserializeInt(size_t &p, int &i)
Definition vm.h:98
std::vector< double > variables
Definition vm.h:53
void assign(int v)
Definition vm.h:223
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_LOG(msg)
Definition log.h:367
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition error.h:61
the ug namespace
#define LUAPARSER_MATH_CEIL
Definition parser.cpp:134
#define LUAPARSER_NE
Definition parser.cpp:144
#define LUAPARSER_MATH_SQRT
Definition parser.cpp:132
#define LUAPARSER_MATH_MAX
Definition parser.cpp:136
#define LUAPARSER_MATH_COS
Definition parser.cpp:127
#define LUAPARSER_MATH_LOG
Definition parser.cpp:130
#define LUAPARSER_MATH_FLOOR
Definition parser.cpp:133
#define LUAPARSER_MATH_EXP
Definition parser.cpp:128
#define LUAPARSER_MATH_SIN
Definition parser.cpp:126
#define LUAPARSER_MATH_POW
Definition parser.cpp:135
#define LUAPARSER_OR
Definition parser.cpp:142
#define LUAPARSER_EQ
Definition parser.cpp:145
#define LUAPARSER_AND
Definition parser.cpp:143
#define LUAPARSER_GE
Definition parser.cpp:147
#define LUAPARSER_MATH_LOG10
Definition parser.cpp:131
#define LUAPARSER_MATH_ABS
Definition parser.cpp:129
#define LUAPARSER_MATH_MIN
Definition parser.cpp:137
#define LUAPARSER_LE
Definition parser.cpp:146