-
Notifications
You must be signed in to change notification settings - Fork 0
/
aliasenv_bobox.h
196 lines (162 loc) · 7.02 KB
/
aliasenv_bobox.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#ifndef aliasenv_BOBOX_GUARD
#define aliasenv_BOBOX_GUARD
#include "defines.h"
#include "writer.h"
#include "aliasenv_bobox.h"
#include <map>
namespace ctb
{
/** see the aliasenv_generator */
class aliasenv_bobox : public aliasenv_generator
{
protected:
typedef map<string, string> aliastab_t;
static aliastab_t aliases;
static void init();
public:
typedef language_cpp language;
static string alias(const string& a, bool* s = NULL);
static string get_name();
template <class G> static writer<aliasenv_bobox> generate(int m, G& generator, string name, stringlist args);
} ;
map<string, string> aliasenv_bobox::aliases;
#define ADD(a,b) aliases.insert(aliastab_t::value_type(a,b))
#define SET(a,b) aliases[a]=b
string aliasenv_bobox::get_name()
{
return "bobox";
}
string aliasenv_bobox::alias(const string& a, bool* s)
{
auto itr = aliases.find(a);
if(itr == aliases.end())
return aliasenv_generator::alias(a, s);
if(s != NULL)
*s = true;
return itr->second;
}
void aliasenv_bobox::init()
{
static bool initialized = false;
if(initialized)
return;
aliasenv_generator::init();
ADD("input", "data_in_$ioindex[pos_in_$ioindex+j+$iindex]");
ADD("output", "data_out_$ioindex[pos_out_$ioindex+j+$iindex]");
ADD("fdeclin", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_decl_in.h")));
ADD("fdeclout", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_decl_out.h")));
ADD("fenvin", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_env_in.h")));
ADD("fenvout", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_env_out.h")));
ADD("fbox", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_box.h")));
ADD("fsend", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_send.h")));
ADD("fcode", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_code.h")));
ADD("falign", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_align.h")));
ADD("fcase", writer<aliasenv_generator>::from_file(string().append(exec_path).append("templates/bobox_case.h")));
initialized = true;
}
template <class G>
writer<aliasenv_bobox> aliasenv_bobox::generate(int granularity, G& generator, string name, stringlist args)
{
typedef imp_contB<writer<aliasenv_bobox>> wrt;
auto opts = generator.option_struct();
init();
wrt ilist;
wrt olist;
string type_string;
//construct box list definitions
for(auto n : generator.graph.in)
ilist.push("input_list_$1, $1", n->data.get_param("ioindex"));
ilist.list_concat(",");
for(auto n : generator.graph.out)
olist.push("output_list_$1, $1", n->data.get_param("ioindex"));
olist.list_concat(",");
//construct declarations
wrt decl;
for(auto n : generator.graph.in)
{
n->data.op->get_type_string(1, type_string);
decl.print("$fdeclin", n->data.get_param("ioindex"), type_string);
}
for(auto n : generator.graph.out)
{
n->data.op->get_type_string(1, type_string);
decl.print("$fdeclout", n->data.get_param("ioindex"), type_string);
}
//accept envelopes
wrt envelopes;
for(auto n : generator.graph.in)
{
n->data.op->get_type_string(1, type_string);
envelopes.print("$fenvin", n->data.get_param("ioindex"), type_string);
}
for(auto n : generator.graph.out)
{
n->data.op->get_type_string(1, type_string);
envelopes.print("$fenvout", n->data.get_param("ioindex"), type_string);
}
//get batch size
wrt minlist;
minlist.print("std::numeric_limits<unsigned>::max()");
for(auto n : generator.graph.in)
minlist = wrt().print("std::min($2, size_in_$1 - pos_in_$1)", n->data.get_param("ioindex"), minlist);
for(auto n : generator.graph.out)
minlist = wrt().print("std::min($2, size_out_$1 - pos_out_$1)", n->data.get_param("ioindex"), minlist);
//alignment code
wrt alignment;
if(generator.graph.in.empty() || generator.graph.out.empty())
{
error("Box without inputs or outputs passed. Cant handle alignment for such boxes. (There does not seem to be a reason to write nontrivial code for cases which should never happen)");
}
else
{
alignment.print("$falign", granularity, generator.graph.in.front()->data.get_param("ioindex"), generator.graph.in.front()->data.get_param("ioindex"));
alignment.print("/*check alignment*/;");
for(auto n : generator.graph.in)
alignment.print("aligned &= align_offset == pos_in_$2 % $1;", granularity, n->data.get_param("ioindex"));
for(auto n : generator.graph.out)
alignment.print("aligned &= output_offset == pos_out_$2 % $1;", granularity, n->data.get_param("ioindex"));
}
//generate actual code
wrt code_simple;
generator.generate(1, code_simple, opts);
wrt code_unaligned;
auto pcu = make_shared<tagmaster_default>("","unalignedio,universal","","");
generator.generate(granularity, code_unaligned, opts, pcu);
wrt code_aligned;
generator.generate(granularity, code_aligned, opts, make_shared<tagmaster_default>("","alignedio,universal","",""));
wrt code_shifted;
for(int i = 1; i < granularity; ++i)
{
SET("alignoffset", wrt().print("$1", i).write_str());
wrt tmpcode;
generator.generate(granularity, tmpcode, opts, make_shared<tagmaster_default>("","shiftedio,universal","",""));
code_shifted.print("$fcase", tmpcode, granularity);
}
wrt code_preload;
/*TODO*/
SET("alignoffset", "(align_offset + output_offset)");
shared_ptr<tagmaster_default> tq = make_shared<tagmaster_default>("","preloadio,universal","","");
shared_ptr<tagmaster_default> tp = make_shared<tagmaster_default>("preloadio","","","");
generator.generate(granularity, code_preload, opts, tq, tp, tp);
wrt code;
code.print("$fcode", code_aligned, code_shifted, code_unaligned, code_simple, code_preload, granularity);
//increment counters
wrt inc;
for(auto n : generator.graph.in)
inc.print("pos_in_$1 += batch_size;", n->data.get_param("ioindex"));
for(auto n : generator.graph.out)
inc.print("pos_out_$1 += batch_size;", n->data.get_param("ioindex"));
//send envelopes
wrt send;
for(auto n : generator.graph.out)
{
n->data.op->get_type_string(1, type_string);
send.print("$fsend", n->data.get_param("ioindex"), type_string);
}
//put everything together
wrt box;
box.print("$fbox", name, ilist, olist,decl, envelopes, minlist, alignment, code, inc, send);
return box;
}
}
#endif