onnx2versal
Loading...
Searching...
No Matches
graph_pool.h
1#ifndef __POOL_GRAPH_H__
2#define __POOL_GRAPH_H__
3
4#include <adf.h>
5#include "pad.h"
6#include "pool.h"
7#include "graph_split.h"
8#include "graph_concat.h"
9
10
42template <template<typename, int, int, int, int, int, int, int, int, int, int> class POOL,
43 typename TT, int INP_H, int INP_W, int INP_W_PAD, int OUT_H, int OUT_W, int B, int C, int KH, int KW, int STEP_H, int STEP_W,
44 template<typename, int, int, int, int, int, int, int, int> class PAD,
45 int H0 = 0, int H1 = 0, int W0 = 0, int W1 = 0>
46class PoolGraph : public adf::graph {
47
48 private:
49 static constexpr int PAD_H = INP_H + H0 + H1;
50 static constexpr int PAD_W = INP_W + W0 + W1;
51
52 adf::kernel k[1];
53 std::string id;
54 std::vector<adf::kernel> pad;
55
56 public:
57 adf::port<input> pin[1];
58 adf::port<output> pout[1];
59
60 PoolGraph() {
61 k[0] = adf::kernel::create_object<POOL<TT, PAD_H, PAD_W, OUT_H, OUT_W, B, C, KH, KW, STEP_H, STEP_W>>();
62 adf::source(k[0]) = "pool.cc";
63 adf::headers(k[0]) = {"pool.h"};
64 adf::runtime<ratio>(k[0]) = 0.6;
65
66 adf::connect<adf::window<B*OUT_H*OUT_W*C*sizeof(TT)>> (k[0].out[0], pout[0]);
67
68 if (H0+H1+W0+W1 != 0) {
69 pad.push_back(
70 adf::kernel::create_object<PAD<TT, B*C, INP_H, INP_W, INP_W_PAD, H0, H1, W0, W1>>());
71 adf::source(pad[0]) = "pad.cc";
72 adf::headers(pad[0]) = {"pad.h"};
73 adf::runtime<ratio>(pad[0]) = 0.6;
74
75 adf::connect<adf::stream> (pin[0], pad[0].in[0]);
76 adf::connect<adf::window<B*PAD_H*PAD_W*C*sizeof(TT)>> (pad[0].out[0], k[0].in[0]);
77
78 adf::samples_per_iteration(pad[0].in[0]) = B*C*INP_H*INP_W_PAD;
79 adf::samples_per_iteration(pad[0].out[0]) = B*C*PAD_H*PAD_W;
80 } else {
81 adf::connect<adf::window<B*INP_H*INP_W*C*sizeof(TT)>> (pin[0], k[0].in[0]);
82 }
83 }
84
85};
86
87
88template <
89 template<typename, int, int, int, int> class SPLIT,
90 template<typename, int, int, int, int, int, int, int, int, int, int> class POOL,
91 template<typename, int, int, int, int> class CONCAT,
92 int CCHUNK,
93 typename TT, int INP_H, int INP_W, int INP_W_PAD, int OUT_H, int OUT_W, int B, int C, int KH, int KW, int STEP_H, int STEP_W,
94 template<typename, int, int, int, int, int, int, int, int> class PAD,
95 int H0 = 0, int H1 = 0, int W0 = 0, int W1 = 0>
96class PoolChunkCGraph : public adf::graph {
97
98 private:
99 static constexpr int PAD_H = INP_H + H0 + H1;
100 static constexpr int PAD_W = INP_W + W0 + W1;
101
103 mSplitGraph split_graph;
104 static constexpr int LCNT = mSplitGraph::LCNT;
105 ConcatStreamGraph<CONCAT, TT, LCNT, B, CCHUNK*OUT_H*OUT_W, C*OUT_H*OUT_W> concat_graph;
106
107 std::vector<adf::kernel> pad;
108 adf::kernel k[LCNT];
109 std::string id;
110
111 public:
112 adf::port<input> pin[1];
113 adf::port<output> pout[1];
114
115 PoolChunkCGraph(
116 int repeat_cnt = 1
117 ) {
118 static_assert(LCNT <= 8);
119
120 for (int i = 0; i < LCNT; i++) {
121 k[i] = adf::kernel::create_object<POOL<TT, PAD_H, PAD_W, OUT_H, OUT_W, B, CCHUNK, KH, KW, STEP_H, STEP_W>>();
122 adf::source(k[i]) = "pool.cc";
123 adf::headers(k[i]) = {"pool.h"};
124 adf::runtime<ratio>(k[i]) = 0.6;
125 adf::repetition_count(k[i]) = repeat_cnt;
126
127 adf::connect<adf::window<B*CCHUNK*PAD_H*PAD_W*sizeof(TT)>> (split_graph.pout[i], k[i].in[0]);
128 adf::connect<adf::window<B*CCHUNK*OUT_H*OUT_W*sizeof(TT)>> (k[i].out[0], concat_graph.pin[i]);
129 }
130
131 adf::connect<adf::stream> (concat_graph.pout[0], pout[0]);
132
133 if (H0+H1+W0+W1 != 0) {
134 pad.push_back(
135 adf::kernel::create_object<PAD<TT, B*C, INP_H, INP_W, INP_W_PAD, H0, H1, W0, W1>>());
136 adf::source(pad[0]) = "pad.cc";
137 adf::headers(pad[0]) = {"pad.h"};
138 adf::runtime<ratio>(pad[0]) = 0.6;
139 adf::repetition_count(pad[0]) = repeat_cnt;
140
141 adf::connect<adf::stream> (pin[0], pad[0].in[0]);
142 adf::connect<adf::stream> (pad[0].out[0], split_graph.pin[0]);
143
144 adf::samples_per_iteration(pad[0].in[0]) = B*C*INP_H*INP_W_PAD;
145 adf::samples_per_iteration(pad[0].out[0]) = B*C*PAD_H*PAD_W;
146 } else {
147 adf::connect<adf::stream> (pin[0], split_graph.pin[0]);
148 }
149
150 // location constraints
151 for (int i = 0; i < LCNT; i++) {
152 if ((i&0x3) == 1) {
153 adf::location<adf::kernel>(k[i]) = adf::location<adf::kernel>(k[i-1]) + adf::relative_offset({.col_offset=1, .row_offset=1});
154 } else if ((i&0x3) == 3) {
155 adf::location<adf::kernel>(k[i]) = adf::location<adf::kernel>(k[i-1]) + adf::relative_offset({.col_offset=-1, .row_offset=1});
156 } else if ((i&0x3) == 2) {
157 adf::location<adf::kernel>(k[i]) = adf::location<adf::kernel>(k[i-1]) + adf::relative_offset({.col_offset=1, .row_offset=0});
158 } else if (i != 0) {
159 adf::location<adf::kernel>(k[i]) = adf::location<adf::kernel>(k[i-1]) + adf::relative_offset({.col_offset=-1, .row_offset=0});
160 }
161 adf::location<adf::buffer>(k[i].in[0]) = adf::location<adf::kernel>(k[i]);
162 }
163
164 for (int i = 0; i < concat_graph.k1.size(); i++) {
165 adf::location<adf::kernel>(concat_graph.k1[i]) =
166 adf::location<adf::kernel>(k[2*i]) + adf::relative_offset({.col_offset=0, .row_offset=1});
167
168 adf::location_constraint cTilePos = adf::location<adf::kernel>(concat_graph.k1[i]);
169 adf::location<adf::buffer>(k[i*2].out[0]) = cTilePos;
170 adf::location<adf::buffer>(k[i*2].out[0]) = {adf::offset(0), adf::offset(8192)};
171 adf::location<adf::stack>(k[i*2]) = cTilePos;
172 adf::location<adf::buffer>(k[i*2+1].out[0]) = cTilePos;
173 adf::location<adf::buffer>(k[i*2+1].out[0]) = {adf::offset(16384), adf::offset(24576)};
174 adf::location<adf::stack>(k[i*2+1]) = cTilePos;
175 adf::location<adf::stack>(concat_graph.k1[i]) = cTilePos;
176 }
177 }
178
179};
183#endif // __POOL_GRAPH_H__
Single instance graph.
Definition graph_pool.h:46
Graph wrapper for two stream split.
Definition graph_split.h:185