1 /* ************************************************************************
2 * Copyright 2013 Advanced Micro Devices, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * ************************************************************************/
16
17 #include <errno.h>
18 #include <assert.h>
19 #include "tile_iter.h"
20
21 // Translate coordiates in physical memory block
22 // into logical tile coordinates
23 static int
iterCalcLogCoords(PhysTileIterator * iter)24 iterCalcLogCoords( PhysTileIterator* iter){
25
26 if( NULL == iter ){
27 return -EINVAL;
28 }
29
30 if ( iter->isLogRowMaj ) {
31
32 iter->row = iter->line;
33 iter->col = iter->vec*iter->vecLen;
34
35 }
36 else {
37
38 iter->col = iter->line;
39 iter->row = iter->vec*iter->vecLen;
40 }
41
42 return 0;
43 }
44
45 //-----------------------------------------------------------------------------
46
47 int
iterInit(PhysTileIterator * iter,const Tile * tile,int vecLen,unsigned int tileIterFlags)48 iterInit(PhysTileIterator *iter,
49 const Tile *tile,
50 int vecLen,
51 unsigned int tileIterFlags)
52 {
53 if( NULL == iter ||
54 NULL == tile ){
55
56 return -EINVAL;
57 }
58
59 memset(iter, 0, sizeof(PhysTileIterator));
60 iter->isLogRowMaj = tile->trans ? 0 : 1;
61 iter->vecLen = vecLen;
62
63 if ( iter->isLogRowMaj ) {
64
65 if ( tile->nrCols % vecLen ) {
66 return -EINVAL;
67 }
68
69 if ( tileIterFlags & TILE_ITER_BACKWARD_ROWS ) {
70 iter->phyIterFlags |= PHY_ITER_BACKWARD_LINES;
71 }
72 if ( tileIterFlags & TILE_ITER_BACKWARD_COLS ) {
73 iter->phyIterFlags |= PHY_ITER_BACKWARD_VECS;
74 }
75
76 iter->nrLines = tile->nrRows;
77 iter->nrVecs = tile->nrCols/vecLen;
78
79 }
80 else {
81
82 if ( tile->nrRows % vecLen ) {
83 return -EINVAL;
84 }
85
86 if ( tileIterFlags & TILE_ITER_BACKWARD_ROWS ) {
87 iter->phyIterFlags |= PHY_ITER_BACKWARD_VECS;
88 }
89 if ( tileIterFlags & TILE_ITER_BACKWARD_COLS ) {
90 iter->phyIterFlags |= PHY_ITER_BACKWARD_LINES;
91 }
92
93 iter->nrLines = tile->nrCols;
94 iter->nrVecs = tile->nrRows/vecLen;
95 }
96
97 switch( iter->phyIterFlags & ( PHY_ITER_BACKWARD_VECS |
98 PHY_ITER_BACKWARD_LINES ) ){
99
100 // lines - forward, vectors - forward
101 case !( PHY_ITER_BACKWARD_LINES | PHY_ITER_BACKWARD_VECS ):
102
103 iter->vec = 0;
104 iter->line = 0;
105 break;
106
107 // lines - forward, vectors - backward
108 case PHY_ITER_BACKWARD_VECS:
109
110 iter->vec = iter->nrVecs-1;
111 iter->line = 0;
112 break;
113
114 // lines - backward, vectors - forward
115 case PHY_ITER_BACKWARD_LINES:
116
117 iter->vec = 0;
118 iter->line = iter->nrLines-1;
119 break;
120
121 // lines - backward, vectors - backward
122 case PHY_ITER_BACKWARD_LINES | PHY_ITER_BACKWARD_VECS:
123
124 iter->vec = iter->nrVecs-1;
125 iter->line = iter->nrLines-1;
126 break;
127
128 }
129
130 iterCalcLogCoords(iter);
131
132 return 0;
133 }
134
135 //-----------------------------------------------------------------------------
136
iterIterate(PhysTileIterator * iter)137 int iterIterate(PhysTileIterator *iter)
138 {
139 if( NULL == iter ){
140 return -EINVAL;
141 }
142
143 //tile end
144 if( iterIsEnd(iter) ){
145 return 1;
146 }
147
148 switch( iter->phyIterFlags & ( PHY_ITER_BACKWARD_LINES |
149 PHY_ITER_BACKWARD_VECS) ){
150
151 // lines - forward, vectors - forward
152 case !( PHY_ITER_BACKWARD_LINES | PHY_ITER_BACKWARD_VECS ):
153
154 if( iter->nrVecs-1 == iter->vec ){
155
156 iter->vec = 0;
157 iter->line++;
158 }
159 else{
160 iter->vec++;
161 }
162 break;
163
164 // lines - forward, vectors - backward
165 case PHY_ITER_BACKWARD_VECS:
166
167 if( 0 == iter->vec ){
168
169 iter->vec = iter->nrVecs-1;
170 iter->line++;
171 }
172 else{
173 iter->vec--;
174 }
175 break;
176
177 // lines - backward, vectors - forward
178 case PHY_ITER_BACKWARD_LINES:
179
180 if( iter->nrVecs-1 == iter->vec ){
181
182 iter->vec = 0;
183 iter->line--;
184 }
185 else{
186 iter->vec++;
187 }
188 break;
189
190 // lines - backward, vectors - backward
191 case ( PHY_ITER_BACKWARD_LINES | PHY_ITER_BACKWARD_VECS ):
192
193 if( 0 == iter->vec ){
194
195 iter->vec = iter->nrVecs-1;
196 iter->line--;
197 }
198 else{
199 iter->vec--;
200 }
201 break;
202 }
203
204 iterCalcLogCoords(iter);
205
206 return 0;
207 }
208
209 //-----------------------------------------------------------------------------
210
211 int
iterSeek(PhysTileIterator * iter,int row,int col)212 iterSeek( PhysTileIterator *iter,
213 int row,
214 int col )
215 {
216 if ( NULL == iter ) {
217 return -EINVAL;
218 }
219
220 iter->row = row;
221 iter->col = col;
222
223 if ( iter->isLogRowMaj ) {
224
225 iter->line = row;
226 iter->vec = col/iter->vecLen;
227 }
228 else {
229
230 iter->line = col;
231 iter->vec = row/iter->vecLen;
232 }
233
234 assert( iter->line < iter->nrLines );
235 assert( iter->vec < iter->nrVecs );
236 return 0;
237 }
238
239 //-----------------------------------------------------------------------------
240
241 int
iterSeekPhys(PhysTileIterator * iter,int line,int vec)242 iterSeekPhys( PhysTileIterator *iter,
243 int line,
244 int vec )
245 {
246 if ( NULL == iter ) {
247 return -EINVAL;
248 }
249
250 iter->line = line;
251 iter->vec = vec;
252
253 if ( iter->isLogRowMaj ) {
254
255 iter->row = line;
256 iter->col = vec * iter->vecLen;
257 }
258 else {
259
260 iter->row = vec * iter->vecLen;
261 iter->col = line;
262 }
263
264 assert( iter->line < iter->nrLines );
265 assert( iter->vec < iter->nrVecs );
266 return 0;
267 }
268
269 //-----------------------------------------------------------------------------
270
271 /*
272 * Check if the entire tile has been iterated. Return true if the iterator is
273 * at the next element beyond the last.
274 */
iterIsEnd(const PhysTileIterator * iter)275 int iterIsEnd(const PhysTileIterator *iter)
276 {
277 int isEnd = false;
278
279 if( NULL == iter ){
280 return -EINVAL;
281 }
282
283 if( iter->phyIterFlags & PHY_ITER_BACKWARD_LINES ){
284 if( iter->line < 0 ){
285 isEnd = true;
286 }
287 }
288 else{
289 if( iter->line >= iter->nrLines ){
290 isEnd = true;
291 }
292 }
293
294 return isEnd;
295
296 }
297