docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
polybench.h
Go to the documentation of this file.
1#pragma once
2
4
6
7using namespace sdfg;
8
9inline std::unique_ptr<StructuredSDFG> correlation() {
10 /***
11 for (i = 0; i < _PB_M-1; i++)
12 {
13 C[i][i] = SCALAR_VAL(1.0);
14 for (j = i+1; j < _PB_M; j++)
15 {
16 C[i][j] = SCALAR_VAL(0.0);
17 for (k = 0; k < _PB_N; k++)
18 C[i][j] += (D[k][i] * D[k][j]);
19 C[j][i] = C[i][j];
20 }
21 }
22 ***/
23
24 /***
25
26 ------>
27
28 for (i = 0; i < _PB_M-1; i++)
29 {
30 C[i][i] = SCALAR_VAL(1.0);
31 }
32
33 for (i=0; i < _PB_M-1; i++)
34 for (j = i+1; j < _PB_M; j++)
35 {
36 C[i][j] = SCALAR_VAL(0.0);
37 }
38 }
39
40 for (i=0; i < _PB_M-1; i++)
41 for (j = i+1; j < _PB_M; j++)
42 for (k = 0; k < _PB_N; k++)
43 {
44 C[i][j] += (D[k][i] * D[k][j]);
45 }
46 }
47 }
48
49 for (i=0; i < _PB_M-1; i++)
50 for (j = i+1; j < _PB_M; j++)
51 {
52 C[j][i] = C[i][j];
53 }
54 }
55 ***/
56
58
60 builder.add_container("M", desc_symbols, true);
61 builder.add_container("N", desc_symbols, true);
62 builder.add_container("i", desc_symbols);
63 builder.add_container("j", desc_symbols);
64 builder.add_container("k", desc_symbols);
65
67 builder.add_container("tmp", desc_element);
68
69 types::Array desc_1d(desc_element, symbolic::symbol("M"));
70 types::Pointer desc_2d(desc_1d);
71 builder.add_container("C", desc_2d, true);
72 builder.add_container("D", desc_2d, true);
73
74 auto& root = builder.subject().root();
75
76 auto& loop_i = builder.add_for(
77 root,
82 );
83 auto& body_i = loop_i.root();
84 {
85 auto& block = builder.add_block(body_i);
86 auto& output_node = builder.add_access(block, "C");
87 auto& one_node = builder.add_constant(block, "1.0", desc_element);
88 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
89 builder.add_computational_memlet(block, one_node, tasklet, "_in", {});
91 .add_computational_memlet(block, tasklet, "_out", output_node, {symbolic::symbol("i"), symbolic::symbol("i")});
92 }
93
94 auto& loop_j = builder.add_for(
95 body_i,
100 );
101 auto& body_j = loop_j.root();
102 {
103 auto& block = builder.add_block(body_j);
104 auto& output_node = builder.add_access(block, "C");
105 auto& one_node = builder.add_constant(block, "1.0", desc_element);
106 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
107 builder.add_computational_memlet(block, one_node, tasklet, "_in", {});
108 builder
109 .add_computational_memlet(block, tasklet, "_out", output_node, {symbolic::symbol("i"), symbolic::symbol("j")});
110 }
111
112 auto& loop_k = builder.add_for(
113 body_j,
114 symbolic::symbol("k"),
118 );
119 auto& body_k = loop_k.root();
120 {
121 auto& block = builder.add_block(body_k);
122 auto& tmp_node = builder.add_access(block, "tmp");
123 auto& D_node = builder.add_access(block, "D");
124 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
125 builder.add_computational_memlet(block, D_node, tasklet, "_in1", {symbolic::symbol("k"), symbolic::symbol("i")});
126 builder.add_computational_memlet(block, D_node, tasklet, "_in2", {symbolic::symbol("k"), symbolic::symbol("j")});
127 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
128
129 auto& C_in_node = builder.add_access(block, "C");
130 auto& C_out_node = builder.add_access(block, "C");
131 auto& tasklet_2 = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
132 builder
133 .add_computational_memlet(block, C_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
134 builder.add_computational_memlet(block, tmp_node, tasklet_2, "_in2", {});
135 builder.add_computational_memlet(
136 block, tasklet_2, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j")}
137 );
138 }
139 {
140 auto& block = builder.add_block(body_j);
141 auto& C_in_node = builder.add_access(block, "C");
142 auto& C_out_node = builder.add_access(block, "C");
143 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
144 builder
145 .add_computational_memlet(block, C_in_node, tasklet, "_in", {symbolic::symbol("i"), symbolic::symbol("j")});
146 builder
147 .add_computational_memlet(block, tasklet, "_out", C_out_node, {symbolic::symbol("j"), symbolic::symbol("i")});
148 }
149
150 return builder.move();
151};
152
153inline std::unique_ptr<StructuredSDFG> covariance() {
154 /***
155 for (i = 0; i < _PB_M; i++)
156 {
157 for (j = i; j < _PB_M; j++)
158 {
159 C[i][j] = SCALAR_VAL(0.0);
160 for (k = 0; k < _PB_N; k++)
161 C[i][j] += (D[k][i] * D[k][j]);
162 C[j][i] = C[i][j];
163 }
164 }
165 ***/
166
168
170 builder.add_container("M", desc_symbols, true);
171 builder.add_container("N", desc_symbols, true);
172 builder.add_container("i", desc_symbols);
173 builder.add_container("j", desc_symbols);
174 builder.add_container("k", desc_symbols);
175
177 builder.add_container("tmp", desc_element);
178
179 types::Array desc_1d(desc_element, symbolic::symbol("M"));
180 types::Pointer desc_2d(desc_1d);
181 builder.add_container("C", desc_2d, true);
182 builder.add_container("D", desc_2d, true);
183
184 auto& root = builder.subject().root();
185
186 auto& loop_i = builder.add_for(
187 root,
188 symbolic::symbol("i"),
192 );
193 auto& body_i = loop_i.root();
194
195 auto& loop_j = builder.add_for(
196 body_i,
197 symbolic::symbol("j"),
199 symbolic::symbol("i"),
201 );
202 auto& body_j = loop_j.root();
203 {
204 auto& block = builder.add_block(body_j);
205 auto& output_node = builder.add_access(block, "C");
206 auto& one_node = builder.add_constant(block, "1.0", desc_element);
207 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
208 builder.add_computational_memlet(block, one_node, tasklet, "_in", {});
209 builder
210 .add_computational_memlet(block, tasklet, "_out", output_node, {symbolic::symbol("i"), symbolic::symbol("j")});
211 }
212
213 auto& loop_k = builder.add_for(
214 body_j,
215 symbolic::symbol("k"),
219 );
220 auto& body_k = loop_k.root();
221 {
222 auto& block = builder.add_block(body_k);
223 auto& tmp_node = builder.add_access(block, "tmp");
224 auto& D_node = builder.add_access(block, "D");
225 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
226 builder.add_computational_memlet(block, D_node, tasklet, "_in1", {symbolic::symbol("k"), symbolic::symbol("i")});
227 builder.add_computational_memlet(block, D_node, tasklet, "_in2", {symbolic::symbol("k"), symbolic::symbol("j")});
228 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
229
230 auto& C_in_node = builder.add_access(block, "C");
231 auto& C_out_node = builder.add_access(block, "C");
232 auto& tasklet_2 = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
233 builder
234 .add_computational_memlet(block, C_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
235 builder.add_computational_memlet(block, tmp_node, tasklet_2, "_in2", {});
236 builder.add_computational_memlet(
237 block, tasklet_2, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j")}
238 );
239 }
240
241 {
242 auto& block = builder.add_block(body_j);
243 auto& C_in_node = builder.add_access(block, "C");
244 auto& C_out_node = builder.add_access(block, "C");
245 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
246 builder
247 .add_computational_memlet(block, C_in_node, tasklet, "_in", {symbolic::symbol("i"), symbolic::symbol("j")});
248 builder
249 .add_computational_memlet(block, tasklet, "_out", C_out_node, {symbolic::symbol("j"), symbolic::symbol("i")});
250 }
251
252 return builder.move();
253};
254
255inline std::unique_ptr<StructuredSDFG> gemm() {
256 /***
257 for (i = 0; i < _PB_N; i++) {
258 for (j = 0; j < _PB_M; j++)
259 C[i][j] *= beta;
260 for (k = 0; k < _PB_K; k++) {
261 for (j = 0; j < _PB_M; j++)
262 C[i][j] += alpha * A[i][k] * B[k][j];
263 }
264 }
265 ***/
267
269 builder.add_container("alpha", desc_element, true);
270 builder.add_container("beta", desc_element, true);
271 builder.add_container("tmp", desc_element);
272
273 types::Array desc_1d(desc_element, symbolic::symbol("M"));
274 types::Pointer desc_2d(desc_1d);
275 builder.add_container("A", desc_2d, true);
276 builder.add_container("B", desc_2d, true);
277 builder.add_container("C", desc_2d, true);
278
280 builder.add_container("N", desc_symbols, true);
281 builder.add_container("M", desc_symbols, true);
282 builder.add_container("K", desc_symbols, true);
283 builder.add_container("i", desc_symbols);
284 builder.add_container("j_1", desc_symbols);
285 builder.add_container("j_2", desc_symbols);
286 builder.add_container("k", desc_symbols);
287
288 auto& root = builder.subject().root();
289
290 auto& loop_i = builder.add_for(
291 root,
292 symbolic::symbol("i"),
296 );
297 auto& body_i = loop_i.root();
298 auto& loop_j_1 = builder.add_for(
299 body_i,
300 symbolic::symbol("j_1"),
304 );
305 auto& body_j = loop_j_1.root();
306 {
307 auto& block = builder.add_block(body_j);
308 auto& C_in_node = builder.add_access(block, "C");
309 auto& C_out_node = builder.add_access(block, "C");
310 auto& beta_node = builder.add_access(block, "beta");
311 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
312 builder
313 .add_computational_memlet(block, C_in_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_1")});
314 builder.add_computational_memlet(block, beta_node, tasklet, "_in2", {});
315 builder.add_computational_memlet(
316 block, tasklet, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_1")}
317 );
318 }
319
320 auto& loop_k = builder.add_for(
321 body_i,
322 symbolic::symbol("k"),
326 );
327 auto& body_k = loop_k.root();
328 auto& loop_j_2 = builder.add_for(
329 body_k,
330 symbolic::symbol("j_2"),
334 );
335 auto& body_j_2 = loop_j_2.root();
336 {
337 auto& block = builder.add_block(body_j_2);
338 auto& A_node = builder.add_access(block, "A");
339 auto& B_node = builder.add_access(block, "B");
340 auto& tmp_node = builder.add_access(block, "tmp");
341 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
342 builder.add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("k")});
343 builder
344 .add_computational_memlet(block, B_node, tasklet, "_in2", {symbolic::symbol("k"), symbolic::symbol("j_2")});
345 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
346
347 auto& tmp_node_2 = builder.add_access(block, "tmp");
348 auto& alpha_node = builder.add_access(block, "alpha");
349 auto& tasklet_2 = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
350 builder.add_computational_memlet(block, tmp_node, tasklet_2, "_in1", {});
351 builder.add_computational_memlet(block, alpha_node, tasklet_2, "_in2", {});
352 builder.add_computational_memlet(block, tasklet_2, "_out", tmp_node_2, {});
353
354 auto& C_in_node = builder.add_access(block, "C");
355 auto& C_out_node = builder.add_access(block, "C");
356 auto& tasklet_3 = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
357 builder.add_computational_memlet(
358 block, C_in_node, tasklet_3, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_2")}
359 );
360 builder.add_computational_memlet(block, tmp_node_2, tasklet_3, "_in2", {});
361 builder.add_computational_memlet(
362 block, tasklet_3, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_2")}
363 );
364 }
365
366 return builder.move();
367};
368
369inline std::unique_ptr<StructuredSDFG> symm() {
370 /***
371 for (i = 0; i < _PB_M; i++)
372 for (j = 0; j < _PB_N; j++ ) {
373 temp2 = 0;
374 for (k = 0; k < i; k++) {
375 C[k][j] += B[i][j] * A[i][k];
376 temp2 += B[k][j] * A[i][k];
377 }
378 C[i][j] = C[i][j] + temp2;
379 }
380 ***/
381
383
385 builder.add_container("i", desc_symbols);
386 builder.add_container("j", desc_symbols);
387 builder.add_container("k", desc_symbols);
388
390 builder.add_container("tmp", desc_element);
391 builder.add_container("tmp2", desc_element);
392 builder.add_container("tmp3", desc_element);
393
394 types::Array desc_1d(desc_element, symbolic::symbol("M"));
395 types::Pointer desc_2d(desc_1d);
396 builder.add_container("A", desc_2d, true);
397 builder.add_container("B", desc_2d, true);
398 builder.add_container("C", desc_2d, true);
399
400 auto& root = builder.subject().root();
401
402 auto& loop_i = builder.add_for(
403 root,
404 symbolic::symbol("i"),
408 );
409 auto& body_i = loop_i.root();
410 auto& loop_j = builder.add_for(
411 body_i,
412 symbolic::symbol("j"),
416 );
417 auto& body_j = loop_j.root();
418 {
419 auto& block = builder.add_block(body_j);
420 auto& temp2_node = builder.add_access(block, "tmp");
421 auto& const_node = builder.add_constant(block, "0.0", desc_element);
422 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
423 builder.add_computational_memlet(block, const_node, tasklet, "_in", {});
424 builder.add_computational_memlet(block, tasklet, "_out", temp2_node, {});
425 }
426 auto& loop_k = builder.add_for(
427 body_j,
428 symbolic::symbol("k"),
432 );
433 {
434 auto& block = builder.add_block(loop_k.root());
435 auto& a_node = builder.add_access(block, "A");
436 auto& b_node = builder.add_access(block, "B");
437 auto& tmp_node = builder.add_access(block, "tmp2");
438 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
439 builder.add_computational_memlet(block, a_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("k")});
440 builder.add_computational_memlet(block, b_node, tasklet, "_in2", {symbolic::symbol("i"), symbolic::symbol("j")});
441 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
442
443 auto& c_in_node = builder.add_access(block, "C");
444 auto& c_node = builder.add_access(block, "C");
445 auto& tasklet_2 = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
446 builder.add_computational_memlet(block, tmp_node, tasklet_2, "_in1", {});
447 builder
448 .add_computational_memlet(block, c_in_node, tasklet_2, "_in2", {symbolic::symbol("k"), symbolic::symbol("j")});
449 builder
450 .add_computational_memlet(block, tasklet_2, "_out", c_node, {symbolic::symbol("k"), symbolic::symbol("j")});
451
452 auto& block2 = builder.add_block(loop_k.root());
453 auto& a2_node = builder.add_access(block2, "A");
454 auto& b2_node = builder.add_access(block2, "B");
455 auto& tmp3_node = builder.add_access(block2, "tmp3");
456 auto& tasklet_3 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
457 builder
458 .add_computational_memlet(block2, b2_node, tasklet_3, "_in1", {symbolic::symbol("k"), symbolic::symbol("j")});
459 builder
460 .add_computational_memlet(block2, a2_node, tasklet_3, "_in2", {symbolic::symbol("i"), symbolic::symbol("k")});
461 builder.add_computational_memlet(block2, tasklet_3, "_out", tmp3_node, {});
462
463 auto& temp2_node = builder.add_access(block2, "tmp");
464 auto& temp2_node_2 = builder.add_access(block2, "tmp");
465 auto& tasklet_4 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
466 builder.add_computational_memlet(block2, temp2_node, tasklet_4, "_in1", {});
467 builder.add_computational_memlet(block2, tmp3_node, tasklet_4, "_in2", {});
468 builder.add_computational_memlet(block2, tasklet_4, "_out", temp2_node_2, {});
469 }
470 {
471 auto& block = builder.add_block(body_j);
472 auto& c_in_node = builder.add_access(block, "C");
473 auto& c_out_node = builder.add_access(block, "C");
474 auto& tmp_node = builder.add_access(block, "tmp");
475 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
476 builder
477 .add_computational_memlet(block, c_in_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
478 builder.add_computational_memlet(block, tmp_node, tasklet, "_in2", {});
479 builder
480 .add_computational_memlet(block, tasklet, "_out", c_out_node, {symbolic::symbol("i"), symbolic::symbol("j")});
481 }
482
483 return builder.move();
484}
485
486inline std::unique_ptr<StructuredSDFG> gemver() {
487 /***
488 for (i = 0; i < _PB_N; i++)
489 for (j = 0; j < _PB_N; j++)
490 A[i][j] = A[i][j] + u1[i] * v1[j] + u2[i] * v2[j];
491
492 for (i = 0; i < _PB_N; i++)
493 for (j = 0; j < _PB_N; j++)
494 x[i] = x[i] + A[j][i] * y[j];
495
496 for (i = 0; i < _PB_N; i++)
497 x[i] = x[i] + z[i];
498
499 for (i = 0; i < _PB_N; i++)
500 for (j = 0; j < _PB_N; j++)
501 w[i] = w[i] + A[i][j] * x[j];
502 */
503
505
507 builder.add_container("i_1", desc_symbols);
508 builder.add_container("i_2", desc_symbols);
509 builder.add_container("i_3", desc_symbols);
510 builder.add_container("i_4", desc_symbols);
511 builder.add_container("j_1", desc_symbols);
512 builder.add_container("j_2", desc_symbols);
513 builder.add_container("j_3", desc_symbols);
514 builder.add_container("j_4", desc_symbols);
515 builder.add_container("N", desc_symbols, true);
516
518 types::Array desc_1d(desc_element, symbolic::symbol("M"));
519 types::Pointer desc_2d(desc_1d);
520 builder.add_container("A", desc_2d, true);
521 builder.add_container("u1", desc_1d, true);
522 builder.add_container("u2", desc_1d, true);
523 builder.add_container("v1", desc_1d, true);
524 builder.add_container("v2", desc_1d, true);
525 builder.add_container("x", desc_1d, true);
526 builder.add_container("y", desc_1d, true);
527 builder.add_container("z", desc_1d, true);
528 builder.add_container("w", desc_1d, true);
529
530 auto& root = builder.subject().root();
531
532 {
533 auto& loop_i_1 = builder.add_for(
534 root,
535 symbolic::symbol("i_1"),
539 );
540 auto& body_i_1 = loop_i_1.root();
541 auto& loop_j_1 = builder.add_for(
542 body_i_1,
543 symbolic::symbol("j_1"),
547 );
548 auto& body_j_1 = loop_j_1.root();
549
550 builder.add_container("tmp_1", desc_element);
551
552 auto& block = builder.add_block(body_j_1);
553 auto& u1_node = builder.add_access(block, "u1");
554 auto& v1_node = builder.add_access(block, "v1");
555 auto& tmp_node = builder.add_access(block, "tmp_1");
556 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
557 builder.add_computational_memlet(block, u1_node, tasklet, "_in1", {symbolic::symbol("i_1")});
558 builder.add_computational_memlet(block, v1_node, tasklet, "_in2", {symbolic::symbol("j_1")});
559 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
560
561 builder.add_container("tmp_2", desc_element);
562
563 auto& block2 = builder.add_block(body_j_1);
564 auto& u2_node = builder.add_access(block2, "u2");
565 auto& v2_node = builder.add_access(block2, "v2");
566 auto& tmp2_node = builder.add_access(block2, "tmp_2");
567 auto& tasklet2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
568 builder.add_computational_memlet(block2, u2_node, tasklet2, "_in1", {symbolic::symbol("i_1")});
569 builder.add_computational_memlet(block2, v2_node, tasklet2, "_in2", {symbolic::symbol("j_1")});
570 builder.add_computational_memlet(block2, tasklet2, "_out", tmp2_node, {});
571
572 builder.add_container("tmp_3", desc_element);
573
574 auto& block3 = builder.add_block(body_j_1);
575 auto& tmp_node_1 = builder.add_access(block3, "tmp_1");
576 auto& tmp2_node_1 = builder.add_access(block3, "tmp_2");
577 auto& tmp3_node = builder.add_access(block3, "tmp_3");
578 auto& tasklet3 = builder.add_tasklet(block3, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
579 builder.add_computational_memlet(block3, tmp_node_1, tasklet3, "_in1", {});
580 builder.add_computational_memlet(block3, tmp2_node_1, tasklet3, "_in2", {});
581 builder.add_computational_memlet(block3, tasklet3, "_out", tmp3_node, {});
582
583 auto& A_node = builder.add_access(block3, "A");
584 auto& A_node_out = builder.add_access(block3, "A");
585 auto& tasklet4 = builder.add_tasklet(block3, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
586 builder.add_computational_memlet(
587 block3, A_node, tasklet4, "_in1", {symbolic::symbol("i_1"), symbolic::symbol("j_1")}
588 );
589 builder.add_computational_memlet(block3, tmp3_node, tasklet4, "_in2", {});
590 builder.add_computational_memlet(
591 block3, tasklet4, "_out", A_node_out, {symbolic::symbol("i_1"), symbolic::symbol("j_1")}
592 );
593 }
594
595 {
596 auto& loop_i_2 = builder.add_for(
597 root,
598 symbolic::symbol("i_2"),
602 );
603 auto& body_i_2 = loop_i_2.root();
604 auto& loop_j_2 = builder.add_for(
605 body_i_2,
606 symbolic::symbol("j_2"),
610 );
611 auto& body_j_2 = loop_j_2.root();
612
613 auto& block = builder.add_block(body_j_2);
614 auto& x_node_in = builder.add_access(block, "x");
615 auto& x_node_out = builder.add_access(block, "x");
616 auto& y_node = builder.add_access(block, "y");
617 auto& A_node = builder.add_access(block, "A");
618 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
619 builder.add_computational_memlet(block, x_node_in, tasklet, "_in3", {symbolic::symbol("i_2")});
620 builder
621 .add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("j_2"), symbolic::symbol("i_2")});
622 builder.add_computational_memlet(block, y_node, tasklet, "_in2", {symbolic::symbol("j_2")});
623 builder.add_computational_memlet(block, tasklet, "_out", x_node_out, {symbolic::symbol("i_2")});
624 }
625
626 {
627 auto& loop_i_3 = builder.add_for(
628 root,
629 symbolic::symbol("i_3"),
633 );
634 auto& body_i_3 = loop_i_3.root();
635
636 auto& block = builder.add_block(body_i_3);
637 auto& x_node_in = builder.add_access(block, "x");
638 auto& x_node_out = builder.add_access(block, "x");
639 auto& z_node = builder.add_access(block, "z");
640 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
641 builder.add_computational_memlet(block, x_node_in, tasklet, "_in1", {symbolic::symbol("i_3")});
642 builder.add_computational_memlet(block, z_node, tasklet, "_in2", {symbolic::symbol("i_3")});
643 builder.add_computational_memlet(block, tasklet, "_out", x_node_out, {symbolic::symbol("i_3")});
644 }
645
646 {
647 auto& loop_i_4 = builder.add_for(
648 root,
649 symbolic::symbol("i_4"),
653 );
654 auto& body_i_4 = loop_i_4.root();
655 auto& loop_j_4 = builder.add_for(
656 body_i_4,
657 symbolic::symbol("j_4"),
661 );
662 auto& body_j_4 = loop_j_4.root();
663
664 auto& block = builder.add_block(body_j_4);
665
666 auto& w_node_in = builder.add_access(block, "w");
667 auto& w_node_out = builder.add_access(block, "w");
668 auto& A_node = builder.add_access(block, "A");
669 auto& x_node = builder.add_access(block, "x");
670 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
671 builder.add_computational_memlet(block, w_node_in, tasklet, "_in3", {symbolic::symbol("i_4")});
672 builder
673 .add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("i_4"), symbolic::symbol("j_4")});
674 builder.add_computational_memlet(block, x_node, tasklet, "_in2", {symbolic::symbol("j_4")});
675 builder.add_computational_memlet(block, tasklet, "_out", w_node_out, {symbolic::symbol("i_4")});
676 }
677
678 return builder.move();
679};
680
681inline std::unique_ptr<StructuredSDFG> gesummv() {
682 /***
683 for (i = 0; i < _PB_N; i++) {
684 tmp[i] = SCALAR_VAL(0.0);
685 y[i] = SCALAR_VAL(0.0);
686 for (j = 0; j < _PB_N; j++) {
687 tmp[i] = A[i][j] * x[j] + tmp[i];
688 y[i] = B[i][j] * x[j] + y[i];
689 }
690 y[i] = tmp[i] + y[i];
691 }
692 */
693
695
697 builder.add_container("i", desc_symbols);
698 builder.add_container("j", desc_symbols);
699 builder.add_container("N", desc_symbols, true);
700
702 types::Array desc_1d(desc_element, symbolic::symbol("M"));
703 types::Pointer desc_2d(desc_1d);
704 builder.add_container("tmp", desc_1d, true);
705 builder.add_container("x", desc_1d, true);
706 builder.add_container("y", desc_1d, true);
707 builder.add_container("A", desc_2d, true);
708 builder.add_container("B", desc_2d, true);
709
710 auto& root = builder.subject().root();
711
712 auto& loop_i = builder.add_for(
713 root,
714 symbolic::symbol("i"),
718 );
719 auto& body_i = loop_i.root();
720
721 {
722 auto& block = builder.add_block(body_i);
723 auto& tmp_node = builder.add_access(block, "tmp");
724 auto& const_node = builder.add_constant(block, "0.0", desc_element);
725 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
726 builder.add_computational_memlet(block, const_node, tasklet, "_in", {});
727 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {symbolic::symbol("i")});
728 }
729
730 {
731 auto& block = builder.add_block(body_i);
732 auto& y_node = builder.add_access(block, "y");
733 auto& const_node = builder.add_constant(block, "0.0", desc_element);
734 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
735 builder.add_computational_memlet(block, const_node, tasklet, "_in", {});
736 builder.add_computational_memlet(block, tasklet, "_out", y_node, {symbolic::symbol("i")});
737 }
738
739 {
740 auto& loop_j = builder.add_for(
741 body_i,
742 symbolic::symbol("j"),
746 );
747 auto& body_j = loop_j.root();
748
749 {
750 auto& block = builder.add_block(body_j);
751 auto& A_node = builder.add_access(block, "A");
752 auto& x_node = builder.add_access(block, "x");
753 auto& tmp_node = builder.add_access(block, "tmp");
754 auto& tmp_node_out = builder.add_access(block, "tmp");
755 auto& tasklet =
756 builder.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
757 builder
758 .add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
759 builder.add_computational_memlet(block, x_node, tasklet, "_in2", {symbolic::symbol("j")});
760 builder.add_computational_memlet(block, tmp_node, tasklet, "_in3", {symbolic::symbol("i")});
761 builder.add_computational_memlet(block, tasklet, "_out", tmp_node_out, {symbolic::symbol("i")});
762 }
763
764 {
765 auto& block = builder.add_block(body_j);
766 auto& B_node = builder.add_access(block, "B");
767 auto& x_node = builder.add_access(block, "x");
768 auto& y_node = builder.add_access(block, "y");
769 auto& y_node_out = builder.add_access(block, "y");
770 auto& tasklet =
771 builder.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
772 builder
773 .add_computational_memlet(block, B_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
774 builder.add_computational_memlet(block, x_node, tasklet, "_in2", {symbolic::symbol("j")});
775 builder.add_computational_memlet(block, y_node, tasklet, "_in3", {symbolic::symbol("i")});
776 builder.add_computational_memlet(block, tasklet, "_out", y_node_out, {symbolic::symbol("i")});
777 }
778 }
779
780 {
781 auto& block = builder.add_block(body_i);
782 auto& tmp_node = builder.add_access(block, "tmp");
783 auto& y_node = builder.add_access(block, "y");
784 auto& y_node_out = builder.add_access(block, "y");
785 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
786 builder.add_computational_memlet(block, tmp_node, tasklet, "_in1", {symbolic::symbol("i")});
787 builder.add_computational_memlet(block, y_node, tasklet, "_in2", {symbolic::symbol("i")});
788 builder.add_computational_memlet(block, tasklet, "_out", y_node_out, {symbolic::symbol("i")});
789 }
790
791 return builder.move();
792};
793
794inline std::unique_ptr<StructuredSDFG> syr2k() {
795 /***
796 for (i = 0; i < _PB_N; i++) {
797 for (j = 0; j <= i; j++) {
798 C[i][j] *= beta;
799 }
800
801 for (k = 0; k < _PB_M; k++) {
802 for (j = 0; j <= i; j++) {
803 C[i][j] += A[j][k]*B[i][k] + B[j][k]*A[i][k];
804 }
805 }
806 }
807 */
808
810
812 builder.add_container("M", desc_symbols, true);
813 builder.add_container("N", desc_symbols, true);
814 builder.add_container("i", desc_symbols);
815 builder.add_container("j_1", desc_symbols);
816 builder.add_container("j_2", desc_symbols);
817 builder.add_container("k", desc_symbols);
818
820 builder.add_container("tmp", desc_element);
821 builder.add_container("tmp2", desc_element);
822 builder.add_container("tmp3", desc_element);
823 builder.add_container("beta", desc_element, true);
824
825 types::Array desc_1d(desc_element, symbolic::symbol("M"));
826 types::Pointer desc_2d(desc_1d);
827 builder.add_container("A", desc_2d, true);
828 builder.add_container("B", desc_2d, true);
829 builder.add_container("C", desc_2d, true);
830
831 auto& root = builder.subject().root();
832
833 auto& loop_i = builder.add_for(
834 root,
835 symbolic::symbol("i"),
839 );
840 auto& body_i = loop_i.root();
841
842 auto& loop_j_1 = builder.add_for(
843 body_i,
844 symbolic::symbol("j_1"),
848 );
849 {
850 auto& block = builder.add_block(loop_j_1.root());
851 auto& C_in_node = builder.add_access(block, "C");
852 auto& C_out_node = builder.add_access(block, "C");
853 auto& beta_node = builder.add_access(block, "beta");
854 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
855 builder
856 .add_computational_memlet(block, C_in_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_1")});
857 builder.add_computational_memlet(block, beta_node, tasklet, "_in2", {});
858 builder.add_computational_memlet(
859 block, tasklet, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_1")}
860 );
861 }
862
863 auto& loop_k = builder.add_for(
864 body_i,
865 symbolic::symbol("k"),
869 );
870 {
871 auto& loop_j_2 = builder.add_for(
872 loop_k.root(),
873 symbolic::symbol("j_2"),
877 );
878
879 auto& block = builder.add_block(loop_j_2.root());
880 auto& A_node = builder.add_access(block, "A");
881 auto& B_node = builder.add_access(block, "B");
882 auto& tmp_node = builder.add_access(block, "tmp");
883 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
884 builder
885 .add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("j_2"), symbolic::symbol("k")});
886 builder.add_computational_memlet(block, B_node, tasklet, "_in2", {symbolic::symbol("i"), symbolic::symbol("k")});
887 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
888
889 auto& block2 = builder.add_block(loop_j_2.root());
890 auto& tmp_node_2 = builder.add_access(block2, "tmp");
891 auto& B_node_2 = builder.add_access(block2, "B");
892 auto& A_node_2 = builder.add_access(block2, "A");
893 auto& tmp2_node = builder.add_access(block2, "tmp2");
894 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
895 builder.add_computational_memlet(
896 block2, B_node_2, tasklet_2, "_in1", {symbolic::symbol("j_2"), symbolic::symbol("k")}
897 );
898 builder
899 .add_computational_memlet(block2, A_node_2, tasklet_2, "_in2", {symbolic::symbol("i"), symbolic::symbol("k")});
900 builder.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in3", {});
901 builder.add_computational_memlet(block2, tasklet_2, "_out", tmp2_node, {});
902
903 auto& block3 = builder.add_block(loop_j_2.root());
904 auto& C_in_node = builder.add_access(block3, "C");
905 auto& C_out_node = builder.add_access(block3, "C");
906 auto& tmp2_node_2 = builder.add_access(block3, "tmp2");
907 auto& tasklet_3 = builder.add_tasklet(block3, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
908 builder.add_computational_memlet(
909 block3, C_in_node, tasklet_3, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_2")}
910 );
911 builder.add_computational_memlet(block3, tmp2_node_2, tasklet_3, "_in2", {});
912 builder.add_computational_memlet(
913 block3, tasklet_3, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_2")}
914 );
915 }
916
917 return builder.move();
918};
919
920inline std::unique_ptr<StructuredSDFG> syrk() {
921 /***
922 for (i = 0; i < _PB_N; i++) {
923 for (j = 0; j <= i; j++)
924 C[i][j] *= beta;
925
926 for (k = 0; k < _PB_M; k++) {
927 for (j = 0; j <= i; j++)
928 C[i][j] += A[i][k] * A[j][k];
929 }
930 }
931 */
932
934
936 sdfg.add_container("M", desc_symbols, true);
937 sdfg.add_container("N", desc_symbols, true);
938 sdfg.add_container("i", desc_symbols);
939 sdfg.add_container("j_1", desc_symbols);
940 sdfg.add_container("j_2", desc_symbols);
941 sdfg.add_container("k", desc_symbols);
942
944 sdfg.add_container("beta", desc_element, true);
945 sdfg.add_container("tmp", desc_element);
946
947 types::Array desc_1d(desc_element, symbolic::symbol("M"));
948 types::Pointer desc_2d(desc_1d);
949 sdfg.add_container("A", desc_2d, true);
950 sdfg.add_container("C", desc_2d, true);
951
952 auto& root = sdfg.subject().root();
953
954 auto& loop_i = sdfg.add_for(
955 root,
956 symbolic::symbol("i"),
960 );
961 auto& body_i = loop_i.root();
962
963 auto& loop_j_1 = sdfg.add_for(
964 body_i,
965 symbolic::symbol("j_1"),
969 );
970 {
971 auto& block = sdfg.add_block(loop_j_1.root());
972 auto& C_in_node = sdfg.add_access(block, "C");
973 auto& C_out_node = sdfg.add_access(block, "C");
974 auto& beta_node = sdfg.add_access(block, "beta");
975 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
976 sdfg.add_computational_memlet(block, C_in_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_1")});
977 sdfg.add_computational_memlet(block, beta_node, tasklet, "_in2", {});
978 sdfg.add_computational_memlet(block, tasklet, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_1")});
979 }
980
981 auto& loop_k = sdfg.add_for(
982 body_i,
983 symbolic::symbol("k"),
987 );
988 {
989 auto& loop_j_2 = sdfg.add_for(
990 loop_k.root(),
991 symbolic::symbol("j_2"),
995 );
996
997 auto& block = sdfg.add_block(loop_j_2.root());
998 auto& A_node = sdfg.add_access(block, "A");
999 auto& tmp_node = sdfg.add_access(block, "tmp");
1000 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
1001 sdfg.add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("j_2"), symbolic::symbol("k")});
1002 sdfg.add_computational_memlet(block, A_node, tasklet, "_in2", {symbolic::symbol("i"), symbolic::symbol("k")});
1003 sdfg.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1004
1005 auto& block2 = sdfg.add_block(loop_j_2.root());
1006 auto& C_in_node = sdfg.add_access(block2, "C");
1007 auto& C_out_node = sdfg.add_access(block2, "C");
1008 auto& tmp_node_2 = sdfg.add_access(block2, "tmp");
1009 auto& tasklet_2 = sdfg.add_tasklet(block2, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
1010 sdfg.add_computational_memlet(
1011 block2, C_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("j_2")}
1012 );
1013 sdfg.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1014 sdfg.add_computational_memlet(
1015 block2, tasklet_2, "_out", C_out_node, {symbolic::symbol("i"), symbolic::symbol("j_2")}
1016 );
1017 }
1018
1019 return sdfg.move();
1020};
1021
1022inline std::unique_ptr<StructuredSDFG> trmm() {
1023 /***
1024 for (i = 0; i < _PB_M; i++) {
1025 for (j = 0; j < _PB_N; j++) {
1026 for (k = i+1; k < _PB_M; k++) {
1027 B[i][j] += A[k][i] * B[k][j];
1028 }
1029
1030 B[i][j] = alpha * B[i][j];
1031 }
1032 }
1033 */
1034
1036
1038 sdfg.add_container("M", desc_symbols, true);
1039 sdfg.add_container("N", desc_symbols, true);
1040 sdfg.add_container("i", desc_symbols);
1041 sdfg.add_container("j", desc_symbols);
1042 sdfg.add_container("k", desc_symbols);
1043
1045 sdfg.add_container("alpha", desc_element, true);
1046 sdfg.add_container("tmp", desc_element);
1047
1048 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1049 types::Pointer desc_2d(desc_1d);
1050 sdfg.add_container("A", desc_2d, true);
1051 sdfg.add_container("B", desc_2d, true);
1052
1053 auto& root = sdfg.subject().root();
1054
1055 auto& loop_i = sdfg.add_for(
1056 root,
1057 symbolic::symbol("i"),
1061 );
1062 auto& body_i = loop_i.root();
1063
1064 auto& loop_j = sdfg.add_for(
1065 body_i,
1066 symbolic::symbol("j"),
1070 );
1071 auto& body_j = loop_j.root();
1072
1073 auto& loop_k = sdfg.add_for(
1074 body_j,
1075 symbolic::symbol("k"),
1079 );
1080 {
1081 auto& block = sdfg.add_block(loop_k.root());
1082 auto& A_node = sdfg.add_access(block, "A");
1083 auto& B_node = sdfg.add_access(block, "B");
1084 auto& tmp_node = sdfg.add_access(block, "tmp");
1085 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
1086 sdfg.add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("k"), symbolic::symbol("i")});
1087 sdfg.add_computational_memlet(block, B_node, tasklet, "_in2", {symbolic::symbol("k"), symbolic::symbol("j")});
1088 sdfg.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1089
1090 auto& block2 = sdfg.add_block(loop_k.root());
1091 auto& B_in_node = sdfg.add_access(block2, "B");
1092 auto& B_out_node = sdfg.add_access(block2, "B");
1093 auto& tmp_node_2 = sdfg.add_access(block2, "tmp");
1094 auto& tasklet_2 = sdfg.add_tasklet(block2, data_flow::TaskletCode::fp_add, "_out", {"_in1", "_in2"});
1095 sdfg.add_computational_memlet(block2, B_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
1096 sdfg.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1097 sdfg.add_computational_memlet(
1098 block2, tasklet_2, "_out", B_out_node, {symbolic::symbol("i"), symbolic::symbol("j")}
1099 );
1100 }
1101
1102 auto& block3 = sdfg.add_block(body_j);
1103 auto& B_in_node = sdfg.add_access(block3, "B");
1104 auto& B_out_node = sdfg.add_access(block3, "B");
1105 auto& alpha_node = sdfg.add_access(block3, "alpha");
1106 auto& tasklet_3 = sdfg.add_tasklet(block3, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
1107 sdfg.add_computational_memlet(block3, B_in_node, tasklet_3, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")});
1108 sdfg.add_computational_memlet(block3, alpha_node, tasklet_3, "_in2", {});
1109 sdfg.add_computational_memlet(block3, tasklet_3, "_out", B_out_node, {symbolic::symbol("i"), symbolic::symbol("j")});
1110
1111 return sdfg.move();
1112};
1113
1114inline std::unique_ptr<StructuredSDFG> atax() {
1115 /***
1116 for (i = 0; i < _PB_N; i++)
1117 y[i] = 0;
1118
1119 for (i = 0; i < _PB_M; i++) {
1120 tmp[i] = SCALAR_VAL(0.0);
1121
1122 for (j = 0; j < _PB_N; j++)
1123 tmp[i] = tmp[i] + A[i][j] * x[j];
1124
1125 for (j = 0; j < _PB_N; j++)
1126 y[j] = y[j] + A[i][j] * tmp[i];
1127 }
1128 */
1129
1131
1133 sdfg.add_container("M", desc_symbols, true);
1134 sdfg.add_container("N", desc_symbols, true);
1135 sdfg.add_container("i_1", desc_symbols);
1136 sdfg.add_container("i_2", desc_symbols);
1137 sdfg.add_container("j_1", desc_symbols);
1138 sdfg.add_container("j_2", desc_symbols);
1139
1141 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1142 types::Pointer desc_2d(desc_1d);
1143 sdfg.add_container("tmp", desc_1d, true);
1144 sdfg.add_container("x", desc_1d, true);
1145 sdfg.add_container("y", desc_1d, true);
1146 sdfg.add_container("A", desc_2d, true);
1147
1148 auto& root = sdfg.subject().root();
1149
1150 {
1151 auto& loop_i_1 = sdfg.add_for(
1152 root,
1153 symbolic::symbol("i_1"),
1157 );
1158 auto& body_i_1 = loop_i_1.root();
1159
1160 auto& block = sdfg.add_block(body_i_1);
1161 auto& y_node = sdfg.add_access(block, "y");
1162 auto& const_node = sdfg.add_constant(block, "0.0", desc_element);
1163 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
1164 sdfg.add_computational_memlet(block, const_node, tasklet, "_in", {});
1165 sdfg.add_computational_memlet(block, tasklet, "_out", y_node, {symbolic::symbol("i_1")});
1166 }
1167
1168 {
1169 auto& loop_i_2 = sdfg.add_for(
1170 root,
1171 symbolic::symbol("i_2"),
1175 );
1176 auto& body_i_2 = loop_i_2.root();
1177
1178 auto& block = sdfg.add_block(body_i_2);
1179 auto& tmp_node = sdfg.add_access(block, "tmp");
1180 auto& const_node = sdfg.add_constant(block, "0.0", desc_element);
1181 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
1182 sdfg.add_computational_memlet(block, const_node, tasklet, "_in", {});
1183 sdfg.add_computational_memlet(block, tasklet, "_out", tmp_node, {symbolic::symbol("i_2")});
1184
1185 auto& loop_j_1 = sdfg.add_for(
1186 body_i_2,
1187 symbolic::symbol("j_1"),
1191 );
1192 auto& body_j_1 = loop_j_1.root();
1193
1194 {
1195 auto& block = sdfg.add_block(body_j_1);
1196 auto& A_node = sdfg.add_access(block, "A");
1197 auto& x_node = sdfg.add_access(block, "x");
1198 auto& tmp_node = sdfg.add_access(block, "tmp");
1199 auto& tmp_node_out = sdfg.add_access(block, "tmp");
1200 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1201 sdfg.add_computational_memlet(
1202 block, A_node, tasklet, "_in1", {symbolic::symbol("i_2"), symbolic::symbol("j_1")}
1203 );
1204 sdfg.add_computational_memlet(block, x_node, tasklet, "_in2", {symbolic::symbol("j_1")});
1205 sdfg.add_computational_memlet(block, tmp_node, tasklet, "_in3", {symbolic::symbol("i_2")});
1206 sdfg.add_computational_memlet(block, tasklet, "_out", tmp_node_out, {symbolic::symbol("i_2")});
1207 }
1208
1209 {
1210 auto& loop_j_2 = sdfg.add_for(
1211 body_i_2,
1212 symbolic::symbol("j_2"),
1216 );
1217 auto& body_j_2 = loop_j_2.root();
1218
1219 auto& block = sdfg.add_block(body_j_2);
1220 auto& A_node = sdfg.add_access(block, "A");
1221 auto& y_node = sdfg.add_access(block, "y");
1222 auto& y_node_out = sdfg.add_access(block, "y");
1223 auto& tmp_node = sdfg.add_access(block, "tmp");
1224 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1225 sdfg.add_computational_memlet(
1226 block, A_node, tasklet, "_in1", {symbolic::symbol("i_2"), symbolic::symbol("j_2")}
1227 );
1228 sdfg.add_computational_memlet(block, tmp_node, tasklet, "_in2", {symbolic::symbol("i_2")});
1229 sdfg.add_computational_memlet(block, y_node, tasklet, "_in3", {symbolic::symbol("j_2")});
1230 sdfg.add_computational_memlet(block, tasklet, "_out", y_node_out, {symbolic::symbol("j_2")});
1231 }
1232 }
1233
1234 return sdfg.move();
1235}
1236
1237inline std::unique_ptr<StructuredSDFG> bicg() {
1238 /***
1239 for (i = 0; i < _PB_M; i++)
1240 s[i] = 0;
1241 for (i = 0; i < _PB_N; i++) {
1242 q[i] = SCALAR_VAL(0.0);
1243 for (j = 0; j < _PB_M; j++) {
1244 s[j] = s[j] + r[i] * A[i][j];
1245 q[i] = q[i] + A[i][j] * p[j];
1246 }
1247 }
1248 */
1249
1251
1253 sdfg.add_container("M", desc_symbols, true);
1254 sdfg.add_container("N", desc_symbols, true);
1255 sdfg.add_container("i_1", desc_symbols);
1256 sdfg.add_container("i_2", desc_symbols);
1257 sdfg.add_container("j", desc_symbols);
1258
1260 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1261 types::Pointer desc_2d(desc_1d);
1262 sdfg.add_container("s", desc_1d, true);
1263 sdfg.add_container("q", desc_1d, true);
1264 sdfg.add_container("r", desc_1d, true);
1265 sdfg.add_container("p", desc_1d, true);
1266 sdfg.add_container("A", desc_2d, true);
1267
1268 auto& root = sdfg.subject().root();
1269
1270 {
1271 auto& loop_i_1 = sdfg.add_for(
1272 root,
1273 symbolic::symbol("i_1"),
1277 );
1278 auto& body_i_1 = loop_i_1.root();
1279
1280 auto& block = sdfg.add_block(body_i_1);
1281
1282 auto& s_node = sdfg.add_access(block, "s");
1283 auto& const_node = sdfg.add_constant(block, "0.0", desc_element);
1284 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
1285 sdfg.add_computational_memlet(block, const_node, tasklet, "_in", {});
1286 sdfg.add_computational_memlet(block, tasklet, "_out", s_node, {symbolic::symbol("i_1")});
1287 }
1288
1289 {
1290 auto& loop_i_2 = sdfg.add_for(
1291 root,
1292 symbolic::symbol("i_2"),
1296 );
1297 auto& body_i_2 = loop_i_2.root();
1298
1299 auto& block = sdfg.add_block(body_i_2);
1300
1301 auto& q_node = sdfg.add_access(block, "q");
1302 auto& zero_node = sdfg.add_constant(block, "0.0", desc_element);
1303 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
1304 sdfg.add_computational_memlet(block, zero_node, tasklet, "_in", {});
1305 sdfg.add_computational_memlet(block, tasklet, "_out", q_node, {symbolic::symbol("i_2")});
1306
1307 auto& loop_j = sdfg.add_for(
1308 body_i_2,
1309 symbolic::symbol("j"),
1313 );
1314 auto& body_j = loop_j.root();
1315
1316 {
1317 auto& block = sdfg.add_block(body_j);
1318
1319 auto& s_node = sdfg.add_access(block, "s");
1320 auto& r_node = sdfg.add_access(block, "r");
1321 auto& A_node = sdfg.add_access(block, "A");
1322 auto& s_node_out = sdfg.add_access(block, "s");
1323 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1324 sdfg.add_computational_memlet(block, r_node, tasklet, "_in1", {symbolic::symbol("i_2")});
1325 sdfg.add_computational_memlet(block, A_node, tasklet, "_in2", {symbolic::symbol("i_2"), symbolic::symbol("j")});
1326 sdfg.add_computational_memlet(block, s_node, tasklet, "_in3", {symbolic::symbol("j")});
1327 sdfg.add_computational_memlet(block, tasklet, "_out", s_node_out, {symbolic::symbol("j")});
1328 }
1329
1330 {
1331 auto& block = sdfg.add_block(body_j);
1332
1333 auto& q_node = sdfg.add_access(block, "q");
1334 auto& A_node = sdfg.add_access(block, "A");
1335 auto& p_node = sdfg.add_access(block, "p");
1336 auto& q_node_out = sdfg.add_access(block, "q");
1337 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1338 sdfg.add_computational_memlet(block, A_node, tasklet, "_in1", {symbolic::symbol("i_2"), symbolic::symbol("j")});
1339 sdfg.add_computational_memlet(block, p_node, tasklet, "_in2", {symbolic::symbol("j")});
1340 sdfg.add_computational_memlet(block, q_node, tasklet, "_in3", {symbolic::symbol("i_2")});
1341 sdfg.add_computational_memlet(block, tasklet, "_out", q_node_out, {symbolic::symbol("i_2")});
1342 }
1343 }
1344
1345 return sdfg.move();
1346};
1347
1348inline std::unique_ptr<StructuredSDFG> doitgen() {
1349 /***
1350 for (r = 0; r < _PB_NR; r++) {}
1351 for (q = 0; q < _PB_NQ; q++) {
1352 for (p = 0; p < _PB_NP; p++) {
1353 sum[p] = SCALAR_VAL(0.0);
1354 for (s = 0; s < _PB_NP; s++)
1355 sum[p] += A[r][q][s] * C4[s][p];
1356 }
1357 for (p = 0; p < _PB_NP; p++)
1358 A[r][q][p] = sum[p];
1359 }
1360 }
1361 */
1362
1364
1366 sdfg.add_container("NP", desc_symbols, true);
1367 sdfg.add_container("NQ", desc_symbols, true);
1368 sdfg.add_container("NR", desc_symbols, true);
1369 sdfg.add_container("p_1", desc_symbols);
1370 sdfg.add_container("p_2", desc_symbols);
1371 sdfg.add_container("q", desc_symbols);
1372 sdfg.add_container("r", desc_symbols);
1373 sdfg.add_container("s", desc_symbols);
1374
1376 types::Array desc_1d(desc_element, symbolic::symbol("NP"));
1377 types::Array desc_2d(desc_1d, symbolic::symbol("NQ"));
1378 types::Pointer desc_3d(desc_2d);
1379 sdfg.add_container("sum", desc_1d, true);
1380 sdfg.add_container("A", desc_3d, true);
1381 sdfg.add_container("C4", desc_2d, true);
1382
1383 auto& root = sdfg.subject().root();
1384
1385 auto& loop_r = sdfg.add_for(
1386 root,
1387 symbolic::symbol("r"),
1391 );
1392 auto& body_r = loop_r.root();
1393
1394 auto& loop_q = sdfg.add_for(
1395 body_r,
1396 symbolic::symbol("q"),
1400 );
1401
1402 {
1403 auto& loop_p_1 = sdfg.add_for(
1404 loop_q.root(),
1405 symbolic::symbol("p_1"),
1409 );
1410 auto& body_p_1 = loop_p_1.root();
1411
1412 auto& block = sdfg.add_block(body_p_1);
1413 auto& sum_node = sdfg.add_access(block, "sum");
1414 auto& const_node = sdfg.add_constant(block, "0.0", desc_element);
1415 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in"});
1416 sdfg.add_computational_memlet(block, const_node, tasklet, "_in", {});
1417 sdfg.add_computational_memlet(block, tasklet, "_out", sum_node, {symbolic::symbol("p_1")});
1418
1419 {
1420 auto& loop_s = sdfg.add_for(
1421 body_p_1,
1422 symbolic::symbol("s"),
1426 );
1427 auto& body_s = loop_s.root();
1428
1429 auto& block = sdfg.add_block(body_s);
1430 auto& A_node = sdfg.add_access(block, "A");
1431 auto& C4_node = sdfg.add_access(block, "C4");
1432 auto& sum_node = sdfg.add_access(block, "sum");
1433 auto& sum_node_out = sdfg.add_access(block, "sum");
1434 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1435 sdfg.add_computational_memlet(
1436 block, A_node, tasklet, "_in1", {symbolic::symbol("r"), symbolic::symbol("q"), symbolic::symbol("s")}
1437 );
1438 sdfg.add_computational_memlet(
1439 block, C4_node, tasklet, "_in2", {symbolic::symbol("s"), symbolic::symbol("p_1")}
1440 );
1441 sdfg.add_computational_memlet(block, sum_node, tasklet, "_in3", {symbolic::symbol("p_1")});
1442 sdfg.add_computational_memlet(block, tasklet, "_out", sum_node_out, {symbolic::symbol("p_1")});
1443 }
1444 }
1445
1446 {
1447 auto& loop_p_2 = sdfg.add_for(
1448 loop_q.root(),
1449 symbolic::symbol("p_2"),
1453 );
1454 auto& body_p_2 = loop_p_2.root();
1455
1456 auto& block = sdfg.add_block(body_p_2);
1457 auto& A_node = sdfg.add_access(block, "A");
1458 auto& sum_node = sdfg.add_access(block, "sum");
1459 auto& A_node_out = sdfg.add_access(block, "A");
1460 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in1"});
1461 sdfg.add_computational_memlet(block, sum_node, tasklet, "_in1", {symbolic::symbol("p_2")});
1462 sdfg.add_computational_memlet(
1463 block,
1464 tasklet,
1465 "_out",
1466 A_node_out,
1467
1469 );
1470 }
1471
1472 return sdfg.move();
1473};
1474
1475inline std::unique_ptr<StructuredSDFG> mvt() {
1476 /*
1477 for (i = 0; i < _PB_N; i++)
1478 for (j = 0; j < _PB_N; j++)
1479 x1[i] = x1[i] + A[i][j] * y_1[j];
1480 for (i = 0; i < _PB_N; i++)
1481 for (j = 0; j < _PB_N; j++)
1482 x2[i] = x2[i] + A[j][i] * y_2[j];
1483 */
1484
1486
1488 sdfg.add_container("N", desc_symbols, true);
1489 sdfg.add_container("i_1", desc_symbols);
1490 sdfg.add_container("i_2", desc_symbols);
1491 sdfg.add_container("j_1", desc_symbols);
1492 sdfg.add_container("j_2", desc_symbols);
1493
1495 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1496 types::Pointer desc_2d(desc_1d);
1497 sdfg.add_container("x1", desc_1d, true);
1498 sdfg.add_container("x2", desc_1d, true);
1499 sdfg.add_container("y_1", desc_1d, true);
1500 sdfg.add_container("y_2", desc_1d, true);
1501 sdfg.add_container("A", desc_2d, true);
1502
1503 auto& root = sdfg.subject().root();
1504
1505 {
1506 auto& loop_i_1 = sdfg.add_for(
1507 root,
1508 symbolic::symbol("i_1"),
1512 );
1513 auto& body_i_1 = loop_i_1.root();
1514
1515 auto& loop_j_1 = sdfg.add_for(
1516 body_i_1,
1517 symbolic::symbol("j_1"),
1521 );
1522 auto& body_j_1 = loop_j_1.root();
1523
1524 auto& block = sdfg.add_block(body_j_1);
1525 auto& x1_node = sdfg.add_access(block, "x1");
1526 auto& A_node = sdfg.add_access(block, "A");
1527 auto& y_1_node = sdfg.add_access(block, "y_1");
1528 auto& x1_node_out = sdfg.add_access(block, "x1");
1529 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1530 sdfg.add_computational_memlet(block, x1_node, tasklet, "_in3", {symbolic::symbol("i_1")});
1531 sdfg.add_computational_memlet(block, A_node, tasklet, "_in2", {symbolic::symbol("i_1"), symbolic::symbol("j_1")});
1532 sdfg.add_computational_memlet(block, y_1_node, tasklet, "_in1", {symbolic::symbol("j_1")});
1533 sdfg.add_computational_memlet(block, tasklet, "_out", x1_node_out, {symbolic::symbol("i_1")});
1534 }
1535
1536 {
1537 auto& loop_i_2 = sdfg.add_for(
1538 root,
1539 symbolic::symbol("i_2"),
1543 );
1544 auto& body_i_2 = loop_i_2.root();
1545
1546 auto& loop_j_2 = sdfg.add_for(
1547 body_i_2,
1548 symbolic::symbol("j_2"),
1552 );
1553 auto& body_j_2 = loop_j_2.root();
1554
1555 auto& block = sdfg.add_block(body_j_2);
1556 auto& x2_node = sdfg.add_access(block, "x2");
1557 auto& A_node = sdfg.add_access(block, "A");
1558 auto& y_2_node = sdfg.add_access(block, "y_2");
1559 auto& x2_node_out = sdfg.add_access(block, "x2");
1560 auto& tasklet = sdfg.add_tasklet(block, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1561 sdfg.add_computational_memlet(block, x2_node, tasklet, "_in3", {symbolic::symbol("i_2")});
1562 sdfg.add_computational_memlet(block, A_node, tasklet, "_in2", {symbolic::symbol("j_2"), symbolic::symbol("i_2")});
1563 sdfg.add_computational_memlet(block, y_2_node, tasklet, "_in1", {symbolic::symbol("j_2")});
1564 sdfg.add_computational_memlet(block, tasklet, "_out", x2_node_out, {symbolic::symbol("i_2")});
1565 }
1566
1567 return sdfg.move();
1568}
1569
1570inline std::unique_ptr<StructuredSDFG> cholesky() {
1571 /***
1572 for (i = 0; i < _PB_N; i++) {
1573 //j<i
1574 for (j = 0; j < i; j++) {
1575 for (k = 0; k < j; k++) {
1576 A[i][j] -= A[i][k] * A[j][k];
1577 }
1578
1579 A[i][j] /= A[j][j];
1580 }
1581 // i==j case
1582 for (k = 0; k < i; k++) {
1583 A[i][i] -= A[i][k] * A[i][k];
1584 }
1585 A[i][i] = sqrt(A[i][i]);
1586 }
1587 */
1588
1590
1592 builder.add_container("N", desc_symbols, true);
1593 builder.add_container("i", desc_symbols);
1594 builder.add_container("j", desc_symbols);
1595 builder.add_container("k_1", desc_symbols);
1596 builder.add_container("k_2", desc_symbols);
1597
1599 builder.add_container("tmp", desc_element);
1600
1601 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1602 types::Pointer desc_2d(desc_1d);
1603 builder.add_container("A", desc_2d, true);
1604
1605 auto& root = builder.subject().root();
1606
1607 auto& loop_i = builder.add_for(
1608 root,
1609 symbolic::symbol("i"),
1613 );
1614 auto& body_i = loop_i.root();
1615 {
1616 auto& loop_j = builder.add_for(
1617 body_i,
1618 symbolic::symbol("j"),
1622 );
1623 auto& body_j = loop_j.root();
1624 {
1625 auto& loop_k_1 = builder.add_for(
1626 body_j,
1627 symbolic::symbol("k_1"),
1631 );
1632 auto& body_k_1 = loop_k_1.root();
1633 {
1634 auto& block = builder.add_block(body_k_1);
1635 auto& A_node = builder.add_access(block, "A");
1636 auto& tmp_node = builder.add_access(block, "tmp");
1637 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
1638 builder.add_computational_memlet(
1639 block, A_node, tasklet, "_in1", {symbolic::symbol("j"), symbolic::symbol("k_1")}
1640 );
1641 builder.add_computational_memlet(
1642 block, A_node, tasklet, "_in2", {symbolic::symbol("i"), symbolic::symbol("k_1")}
1643 );
1644 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1645
1646 auto& block2 = builder.add_block(body_k_1);
1647 auto& A_in_node = builder.add_access(block2, "A");
1648 auto& A_out_node = builder.add_access(block2, "A");
1649 auto& tmp_node_2 = builder.add_access(block2, "tmp");
1650 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1651 builder.add_computational_memlet(
1652 block2, A_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")}
1653 );
1654 builder.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1655 builder.add_computational_memlet(
1656 block2, tasklet_2, "_out", A_out_node, {symbolic::symbol("i"), symbolic::symbol("j")}
1657 );
1658 }
1659
1660 auto& block3 = builder.add_block(body_j);
1661 auto& A_in_node = builder.add_access(block3, "A");
1662 auto& A_out_node = builder.add_access(block3, "A");
1663 auto& tasklet3 = builder.add_tasklet(block3, data_flow::TaskletCode::fp_div, "_out", {"_in1", "_in2"});
1664 builder.add_computational_memlet(
1665 block3, A_in_node, tasklet3, "_in1", {symbolic::symbol("i"), symbolic::symbol("j")}
1666 );
1667 builder.add_computational_memlet(
1668 block3, A_in_node, tasklet3, "_in2", {symbolic::symbol("j"), symbolic::symbol("j")}
1669 );
1670 builder.add_computational_memlet(
1671 block3, tasklet3, "_out", A_out_node, {symbolic::symbol("i"), symbolic::symbol("j")}
1672 );
1673 }
1674
1675 auto& loop_k_2 = builder.add_for(
1676 body_i,
1677 symbolic::symbol("k_2"),
1681 );
1682 auto& body_k_2 = loop_k_2.root();
1683 {
1684 auto& block = builder.add_block(body_k_2);
1685 auto& A_node = builder.add_access(block, "A");
1686 auto& tmp_node = builder.add_access(block, "tmp");
1687 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_mul, "_out", {"_in1", "_in2"});
1688 builder.add_computational_memlet(
1689 block, A_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("k_2")}
1690 );
1691 builder.add_computational_memlet(
1692 block, A_node, tasklet, "_in2", {symbolic::symbol("i"), symbolic::symbol("k_2")}
1693 );
1694 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1695
1696 auto& block2 = builder.add_block(body_k_2);
1697 auto& A_in_node = builder.add_access(block2, "A");
1698 auto& A_out_node = builder.add_access(block2, "A");
1699 auto& tmp_node_2 = builder.add_access(block2, "tmp");
1700 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1701 builder.add_computational_memlet(
1702 block2, A_in_node, tasklet_2, "_in1", {symbolic::symbol("i"), symbolic::symbol("i")}
1703 );
1704 builder.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1705 builder.add_computational_memlet(
1706 block2, tasklet_2, "_out", A_out_node, {symbolic::symbol("i"), symbolic::symbol("i")}
1707 );
1708 }
1709
1710 auto& block3 = builder.add_block(body_i);
1711 auto& A_in_node = builder.add_access(block3, "A");
1712 auto& A_out_node = builder.add_access(block3, "A");
1713 auto& tasklet = builder.add_library_node<math::cmath::CMathNode>(
1715 );
1716 builder.add_computational_memlet(
1717 block3, A_in_node, tasklet, "_in1", {symbolic::symbol("i"), symbolic::symbol("i")}, desc_2d
1718 );
1719 builder.add_computational_memlet(
1720 block3, tasklet, "_out", A_out_node, {symbolic::symbol("i"), symbolic::symbol("i")}, desc_2d
1721 );
1722 }
1723
1724 return builder.move();
1725};
1726
1727inline std::unique_ptr<StructuredSDFG> fdtd_2d() {
1728 /***
1729 for(t = 0; t < _PB_TMAX; t++)
1730 {
1731 for (j = 0; j < _PB_NY; j++)
1732 ey[0][j] = _fict_[t];
1733
1734 for (i = 1; i < _PB_NX; i++)
1735 for (j = 0; j < _PB_NY; j++)
1736 ey[i][j] -= (hz[i][j]-hz[i-1][j]);
1737
1738 for (i = 0; i < _PB_NX; i++)
1739 for (j = 1; j < _PB_NY; j++)
1740 ex[i][j] -= (hz[i][j]-hz[i][j-1]);
1741
1742 for (i = 0; i < _PB_NX - 1; i++)
1743 for (j = 0; j < _PB_NY - 1; j++)
1744 hz[i][j] += (ex[i][j+1] - ex[i][j]) * (ey[i+1][j] - ey[i][j]);
1745 }
1746 */
1747
1749
1751 builder.add_container("TMAX", desc_symbols, true);
1752 builder.add_container("NX", desc_symbols, true);
1753 builder.add_container("NY", desc_symbols, true);
1754 builder.add_container("t", desc_symbols);
1755 builder.add_container("i_1", desc_symbols);
1756 builder.add_container("i_2", desc_symbols);
1757 builder.add_container("i_3", desc_symbols);
1758 builder.add_container("j_1", desc_symbols);
1759 builder.add_container("j_2", desc_symbols);
1760 builder.add_container("j_3", desc_symbols);
1761 builder.add_container("j_4", desc_symbols);
1762
1764 builder.add_container("tmp", desc_element);
1765 builder.add_container("tmp2", desc_element);
1766 builder.add_container("tmp3", desc_element);
1767 builder.add_container("tmp4", desc_element);
1768
1769 types::Array desc_1d(desc_element, symbolic::symbol("M"));
1770 types::Pointer desc_2d(desc_1d);
1771 builder.add_container("_fict_", desc_1d, true);
1772 builder.add_container("ey", desc_2d, true);
1773 builder.add_container("hz", desc_2d, true);
1774 builder.add_container("ex", desc_2d, true);
1775
1776 auto& root = builder.subject().root();
1777
1778 auto& loop_t = builder.add_for(
1779 root,
1780 symbolic::symbol("t"),
1784 );
1785 auto& body_t = loop_t.root();
1786
1787 auto& loop_j_1 = builder.add_for(
1788 body_t,
1789 symbolic::symbol("j_1"),
1793 );
1794 {
1795 auto& block = builder.add_block(loop_j_1.root());
1796 auto& ey_node = builder.add_access(block, "ey");
1797 auto& fict_node = builder.add_access(block, "_fict_");
1798 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::assign, "_out", {"_in1"});
1799 builder.add_computational_memlet(block, fict_node, tasklet, "_in1", {symbolic::symbol("t")});
1800 builder
1801 .add_computational_memlet(block, tasklet, "_out", ey_node, {symbolic::integer(0), symbolic::symbol("j_1")});
1802 }
1803
1809 auto& loop_i_1 = builder.add_for(
1810 body_t,
1811 symbolic::symbol("i_1"),
1815 );
1816 {
1817 auto& loop_j_2 = builder.add_for(
1818 loop_i_1.root(),
1819 symbolic::symbol("j_2"),
1823 );
1824 {
1825 auto& block = builder.add_block(loop_j_2.root());
1826 auto& hz_node = builder.add_access(block, "hz");
1827 auto& tmp_node = builder.add_access(block, "tmp");
1828 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1829 builder.add_computational_memlet(
1830 block, hz_node, tasklet, "_in1", {symbolic::symbol("i_1"), symbolic::symbol("j_2")}
1831 );
1832 builder.add_computational_memlet(
1833 block,
1834 hz_node,
1835
1836 tasklet,
1837 "_in2",
1839 );
1840 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1841
1842 auto& block2 = builder.add_block(loop_j_2.root());
1843 auto& ey_node = builder.add_access(block2, "ey");
1844 auto& ey_node_2 = builder.add_access(block2, "ey");
1845 auto& tmp_node_2 = builder.add_access(block2, "tmp");
1846 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1847 builder.add_computational_memlet(
1848 block2, ey_node, tasklet_2, "_in1", {symbolic::symbol("i_1"), symbolic::symbol("j_2")}
1849 );
1850 builder.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1851 builder.add_computational_memlet(
1852 block2, tasklet_2, "_out", ey_node_2, {symbolic::symbol("i_1"), symbolic::symbol("j_2")}
1853 );
1854 }
1855 }
1856
1857 /*
1858 for (i = 0; i < _PB_NX; i++)
1859 for (j = 1; j < _PB_NY; j++)
1860 ex[i][j] -= (hz[i][j]-hz[i][j-1]);
1861 */
1862 auto& loop_i_2 = builder.add_for(
1863 body_t,
1864 symbolic::symbol("i_2"),
1868 );
1869 {
1870 auto& loop_j_3 = builder.add_for(
1871 loop_i_2.root(),
1872 symbolic::symbol("j_3"),
1876 );
1877 {
1878 auto& block = builder.add_block(loop_j_3.root());
1879 auto& hz_node = builder.add_access(block, "hz");
1880 auto& tmp_node = builder.add_access(block, "tmp2");
1881 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1882 builder.add_computational_memlet(
1883 block, hz_node, tasklet, "_in1", {symbolic::symbol("i_2"), symbolic::symbol("j_3")}
1884 );
1885 builder.add_computational_memlet(
1886 block,
1887 hz_node,
1888
1889 tasklet,
1890 "_in2",
1892 );
1893 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1894
1895 auto& block2 = builder.add_block(loop_j_3.root());
1896 auto& ex_node = builder.add_access(block2, "ex");
1897 auto& ex_node_2 = builder.add_access(block2, "ex");
1898 auto& tmp_node_2 = builder.add_access(block2, "tmp2");
1899 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1900 builder.add_computational_memlet(
1901 block2, ex_node, tasklet_2, "_in1", {symbolic::symbol("i_2"), symbolic::symbol("j_3")}
1902 );
1903 builder.add_computational_memlet(block2, tmp_node_2, tasklet_2, "_in2", {});
1904 builder.add_computational_memlet(
1905 block2, tasklet_2, "_out", ex_node_2, {symbolic::symbol("i_2"), symbolic::symbol("j_3")}
1906 );
1907 }
1908 }
1909
1910 /*
1911 for (i = 0; i < _PB_NX - 1; i++)
1912 for (j = 0; j < _PB_NY - 1; j++)
1913 hz[i][j] += (ex[i][j+1] - ex[i][j]) * (ey[i+1][j] - ey[i][j]);
1914 */
1915 auto& loop_i_3 = builder.add_for(
1916 body_t,
1917 symbolic::symbol("i_3"),
1921 );
1922 {
1923 auto& loop_j_4 = builder.add_for(
1924 loop_i_3.root(),
1925 symbolic::symbol("j_4"),
1929 );
1930 {
1931 auto& block = builder.add_block(loop_j_4.root());
1932 auto& ex_node = builder.add_access(block, "ex");
1933 auto& tmp_node = builder.add_access(block, "tmp3");
1934 auto& tasklet = builder.add_tasklet(block, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1935 builder.add_computational_memlet(
1936 block,
1937 ex_node,
1938
1939 tasklet,
1940 "_in1",
1942 );
1943 builder.add_computational_memlet(
1944 block, ex_node, tasklet, "_in2", {symbolic::symbol("i_3"), symbolic::symbol("j_4")}
1945 );
1946 builder.add_computational_memlet(block, tasklet, "_out", tmp_node, {});
1947
1948 auto& block2 = builder.add_block(loop_j_4.root());
1949 auto& ey_node = builder.add_access(block2, "ey");
1950 auto& tmp_node_2 = builder.add_access(block2, "tmp4");
1951 auto& tasklet_2 = builder.add_tasklet(block2, data_flow::TaskletCode::fp_sub, "_out", {"_in1", "_in2"});
1952 builder.add_computational_memlet(
1953 block2,
1954 ey_node,
1955
1956 tasklet_2,
1957 "_in1",
1959 );
1960 builder.add_computational_memlet(
1961 block2, ey_node, tasklet_2, "_in2", {symbolic::symbol("i_3"), symbolic::symbol("j_4")}
1962 );
1963 builder.add_computational_memlet(block2, tasklet_2, "_out", tmp_node_2, {});
1964
1965 auto& block3 = builder.add_block(loop_j_4.root());
1966 auto& hz_node = builder.add_access(block3, "hz");
1967 auto& hz_node_2 = builder.add_access(block3, "hz");
1968 auto& tmp_node_3 = builder.add_access(block3, "tmp3");
1969 auto& tmp_node_4 = builder.add_access(block3, "tmp4");
1970 auto& tasklet_3 =
1971 builder.add_tasklet(block3, data_flow::TaskletCode::fp_fma, "_out", {"_in1", "_in2", "_in3"});
1972 builder.add_computational_memlet(block3, tmp_node_3, tasklet_3, "_in1", {});
1973 builder.add_computational_memlet(block3, tmp_node_4, tasklet_3, "_in2", {});
1974 builder.add_computational_memlet(
1975 block3, hz_node, tasklet_3, "_in3", {symbolic::symbol("i_3"), symbolic::symbol("j_4")}
1976 );
1977 builder.add_computational_memlet(
1978 block3, tasklet_3, "_out", hz_node_2, {symbolic::symbol("i_3"), symbolic::symbol("j_4")}
1979 );
1980 }
1981 }
1982
1983 return builder.move();
1984}
Note: Even though the class references unique_ptr, it will never delete an SDFG it has a reference to...
Definition structured_sdfg_builder.h:44
Definition cmath_node.h:485
Represents a c-style array type.
Definition array.h:33
Represents a pointer type.
Definition pointer.h:32
Represents a scalar primitive type.
Definition scalar.h:27
Expression add(const Expression lhs, const Expression rhs)
Addition of two expressions.
Expression sub(const Expression lhs, const Expression rhs)
Subtraction of two expressions.
Condition Lt(const Expression lhs, const Expression rhs)
Less-than comparison.
Condition Le(const Expression lhs, const Expression rhs)
Less-than-or-equal comparison.
Integer integer(int64_t value)
Creates an integer constant.
Symbol symbol(const std::string &name)
Creates a symbolic variable with the given name.
Definition function_builder.h:10
@ fp_fma
Floating-point fused multiply-add.
Definition tasklet.h:104
@ fp_mul
Floating-point multiplication.
Definition tasklet.h:101
@ fp_add
Floating-point addition.
Definition tasklet.h:99
@ assign
Assignment/copy operation (can be cast if types differ).
Definition tasklet.h:95
@ fp_div
Floating-point division.
Definition tasklet.h:102
@ fp_sub
Floating-point subtraction.
Definition tasklet.h:100
@ sqrt
Definition cmath_node.h:51
@ Double
64-bit floating-point (IEEE 754 double precision)
Definition type.h:51
@ Int64
64-bit signed integer
Definition type.h:41
Definition analysis.h:7
FunctionType FunctionType_CPU
Definition function.h:38
std::unique_ptr< StructuredSDFG > correlation()
Definition polybench.h:9
std::unique_ptr< StructuredSDFG > covariance()
Definition polybench.h:153
std::unique_ptr< StructuredSDFG > fdtd_2d()
Definition polybench.h:1727
std::unique_ptr< StructuredSDFG > gesummv()
Definition polybench.h:681
std::unique_ptr< StructuredSDFG > trmm()
Definition polybench.h:1022
std::unique_ptr< StructuredSDFG > mvt()
Definition polybench.h:1475
std::unique_ptr< StructuredSDFG > cholesky()
Definition polybench.h:1570
std::unique_ptr< StructuredSDFG > syrk()
Definition polybench.h:920
std::unique_ptr< StructuredSDFG > gemver()
Definition polybench.h:486
std::unique_ptr< StructuredSDFG > symm()
Definition polybench.h:369
std::unique_ptr< StructuredSDFG > doitgen()
Definition polybench.h:1348
std::unique_ptr< StructuredSDFG > bicg()
Definition polybench.h:1237
std::unique_ptr< StructuredSDFG > atax()
Definition polybench.h:1114
std::unique_ptr< StructuredSDFG > syr2k()
Definition polybench.h:794
std::unique_ptr< StructuredSDFG > gemm()
Definition polybench.h:255