Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NativeInterpreter/0.1/NativeInterpreter-0.1/src/interpreter.h @ 16269

Last change on this file since 16269 was 16269, checked in by bburlacu, 6 years ago

#2958: Add C++ source code

File size: 7.2 KB
Line 
1#ifndef NATIVE_TREE_INTERPRETER_CLANG_H
2#define NATIVE_TREE_INTERPRETER_CLANG_H
3
4#include <cstring>
5#include <vector>
6#include <algorithm>
7
8#include "instruction.h"
9#include "vector_operations.h"
10
11inline double evaluate(instruction *code, int len, int row) noexcept
12{
13    for (int i = len - 1; i >= 0; --i)
14    {
15        instruction &in = code[i];
16        switch (in.opcode)
17        {
18            case OpCodes::Var:
19                {
20                    in.value = in.weight * in.data[row];
21                    break;
22                }
23            case OpCodes::Add:
24                {
25                    in.value = code[in.childIndex].value;
26                    for (int j = 1; j < in.narg; ++j)
27                    {
28                        in.value += code[in.childIndex + j].value;
29                    }
30                    break;
31                }
32            case OpCodes::Sub:
33                {
34                    in.value = code[in.childIndex].value;
35                    for (int j = 1; j < in.narg; ++j)
36                    {
37                        in.value -= code[in.childIndex + j].value;
38                    }
39                    if (in.narg == 1)
40                    {
41                        in.value = -in.value;
42                    }
43                    break;
44                }
45            case OpCodes::Mul:
46                {
47                    in.value = code[in.childIndex].value;
48                    for (int j = 1; j < in.narg; ++j)
49                    {
50                        in.value *= code[in.childIndex + j].value;
51                    }
52                    break;
53                }
54            case OpCodes::Div:
55                {
56                    in.value = code[in.childIndex].value;
57                    for (int j = 1; j < in.narg; ++j)
58                    {
59                        in.value /= code[in.childIndex + j].value;
60                    }
61                    if (in.narg == 1)
62                    {
63                        in.value = 1 / in.value;
64                    }
65                    break;
66                }
67            case OpCodes::Exp:
68                {
69                    in.value = std::exp(code[in.childIndex].value);
70                    break;
71                }
72            case OpCodes::Log:
73                {
74                    in.value = std::log(code[in.childIndex].value);
75                    break;
76                }
77            case OpCodes::Sin:
78                {
79                    in.value = std::sin(code[in.childIndex].value);
80                    break;
81                }
82            case OpCodes::Cos:
83                {
84                    in.value = std::cos(code[in.childIndex].value);
85                    break;
86                }
87            case OpCodes::Tan:
88                {
89                    in.value = std::tan(code[in.childIndex].value);
90                    break;
91                }
92            case OpCodes::Power:
93                {
94                    double x = code[in.childIndex].value;
95                    double y = std::round(code[in.childIndex + 1].value);
96                    in.value = std::pow(x, y);
97                    break;
98                }
99            case OpCodes::Root:
100                {
101                    double x = code[in.childIndex].value;
102                    double y = std::round(code[in.childIndex + 1].value);
103                    in.value = std::pow(x, 1 / y);
104                    break;
105                }
106            case OpCodes::Sqrt:
107                {
108                    in.value = std::sqrt(code[in.childIndex].value);
109                    break;
110                }
111        }
112    }
113    return code[0].value;
114}
115
116inline void load_data(instruction &in, int* __restrict rows, int rowIndex, int batchSize) noexcept
117{
118    for (int i = 0; i < batchSize; ++i)
119    {
120        auto row = rows[rowIndex + i];
121        in.buf[i] = in.weight * in.data[row];
122    }
123}
124
125inline void evaluate(instruction* code, int len, int* __restrict rows, int rowIndex, int batchSize) noexcept
126{
127    for (int i = len - 1; i >= 0; --i)
128    {
129        instruction &in = code[i];
130        switch (in.opcode)
131        {
132            case OpCodes::Var:
133                {
134                    load_data(in, rows, rowIndex, batchSize); // buffer data
135                    break;
136                }
137            case OpCodes::Add:
138                {
139                    load(in.buf, code[in.childIndex].buf);
140                    for (int j = 1; j < in.narg; ++j)
141                    {
142                        add(in.buf, code[in.childIndex + j].buf);
143                    }
144                    break;
145                }
146            case OpCodes::Sub:
147                {
148                    load(in.buf, code[in.childIndex].buf);
149                    for (int j = 1; j < in.narg; ++j)
150                    {
151                        sub(in.buf, code[in.childIndex + j].buf);
152                    }
153                    if (in.narg == 1)
154                    {
155                        neg(in.buf);
156                    }
157                    break;
158                }
159            case OpCodes::Mul:
160                {
161                    load(in.buf, code[in.childIndex].buf);
162                    for (int j = 1; j < in.narg; ++j)
163                    {
164                        mul(in.buf, code[in.childIndex + j].buf);
165                    }
166                    break;
167                }
168            case OpCodes::Div:
169                {
170                    load(in.buf, code[in.childIndex].buf);
171                    for (int j = 1; j < in.narg; ++j)
172                    {
173                        div(in.buf, code[in.childIndex + j].buf);
174                    }
175                    if (in.narg == 1)
176                    {
177                        inv(in.buf);
178                    }
179                    break;
180                }
181            case OpCodes::Sin:
182                {
183                    sin(in.buf, code[in.childIndex].buf);
184                    break;
185                }
186            case OpCodes::Cos:
187                {
188                    cos(in.buf, code[in.childIndex].buf);
189                    break;
190                }
191            case OpCodes::Tan:
192                {
193                    tan(in.buf, code[in.childIndex].buf);
194                    break;
195                }
196            case OpCodes::Log:
197                {
198                    log(in.buf, code[in.childIndex].buf);
199                    break;
200                }
201            case OpCodes::Exp:
202                {
203                    exp(in.buf, code[in.childIndex].buf);
204                    break;
205                }
206            case OpCodes::Power:
207                {
208                    load(in.buf, code[in.childIndex].buf);
209                    pow(in.buf, code[in.childIndex + 1].buf);
210                    break;
211                }
212            case OpCodes::Root:
213                {
214                    load(in.buf, code[in.childIndex].buf);
215                    root(in.buf, code[in.childIndex + 1].buf);
216                    break;
217                }
218            case OpCodes::Square:
219                {
220                    square(in.buf, code[in.childIndex].buf);
221                    break;
222                }
223        }
224    }
225}
226
227#endif
Note: See TracBrowser for help on using the repository browser.