SkelCL
SkelCL is a high level multi GPU skeleton library developed at the university of Münster, Germany.
 All Classes Namespaces Files Functions Variables Typedefs Groups
MapOverlapTests.cpp
1 /*****************************************************************************
2  * Copyright (c) 2011-2012 The skelcl Team as listed in CREDITS.txt *
3  * http://skelcl.uni-muenster.de *
4  * *
5  * This file is part of skelcl. *
6  * skelcl is available under multiple licenses. *
7  * The different licenses are subject to terms and condition as provided *
8  * in the files specifying the license. See "LICENSE.txt" for details *
9  * *
10  *****************************************************************************
11  * *
12  * skelcl is free software: you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation, either version 3 of the License, or *
15  * (at your option) any later version. See "LICENSE-gpl.txt" for details. *
16  * *
17  * skelcl is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  *****************************************************************************
23  * *
24  * For non-commercial academic use see the license specified in the file *
25  * "LICENSE-academic.txt". *
26  * *
27  *****************************************************************************
28  * *
29  * If you are interested in other licensing models, including a commercial- *
30  * license, please contact the author at michel.steuwer@uni-muenster.de *
31  * *
32  *****************************************************************************/
33 
37 
38 #include <fstream>
39 #include <cstdio>
40 
41 #include <pvsutil/Logger.h>
42 
43 #include <SkelCL/SkelCL.h>
44 #include <SkelCL/Matrix.h>
45 #include <SkelCL/Vector.h>
46 #include <SkelCL/MapOverlap.h>
47 
48 #include "Test.h"
51 
52 #include <iostream>
53 
54 class MapOverlapTest : public ::testing::Test {
55 protected:
56  MapOverlapTest() {
57  //pvsutil::defaultLogger.setLoggingLevel(pvsutil::Logger::Severity::DebugInfo);
58  skelcl::init(skelcl::nDevices(1).deviceType(skelcl::device_type::CPU));
59  };
60 
61  ~MapOverlapTest() {
63  };
64 };
65 
66 TEST_F(MapOverlapTest, CreateMapOverlapWithString) {
67  skelcl::MapOverlap<float(float)> m {"float func(input_matrix_t f) \
68  { return -getData(f, 0, 0); }", 1};
69 }
70 
71 #if 0
72 TEST_F(MapOverlapTest, SimpleMapOverlap) {
73  skelcl::MapOverlap<int(int)> m{
74  "int func(__local int* f){ return f[0]; }", 1 };
75 
76  skelcl::Vector<int> input(10);
77  for (size_t i = 0; i < input.size(); ++i) {
78  input[i] = i;
79  }
80  EXPECT_EQ(10, input.size());
81 
82  skelcl::Vector<int> output = m(input);
83 
84  EXPECT_EQ(10, output.size());
85  for (size_t i = 0; i < output.size(); ++i) {
86  EXPECT_EQ(input[i], output[i]);
87  }
88 }
89 
90 TEST_F(MapOverlapTest, SimpleMapOverlap2) {
91  skelcl::MapOverlap<int(int)> m{
92  "int func(__local int* f){ return f[-1]+f[0]+f[1]; }", 1 };
93 
94  skelcl::Vector<int> input(10);
95  for (size_t i = 0; i < input.size(); ++i) {
96  input[i] = i;
97  }
98  EXPECT_EQ(10, input.size());
99 
100  skelcl::Vector<int> output = m(input);
101 
102  EXPECT_EQ(10, output.size());
103  EXPECT_EQ(0+input[0]+input[1], output[0]);
104  for (size_t i = 1; i < output.size() - 1; ++i) {
105  EXPECT_EQ(input[i-1]+input[i]+input[i+1], output[i]);
106  }
107  EXPECT_EQ(input[input.size()-2]+input[input.size()-1]+0, output.back());
108 }
109 
110 TEST_F(MapOverlapTest, SimpleMapOverlapWithZeroOverlap) {
111  skelcl::MapOverlap<float(float)> m{
112  "float func(__local float* f){ return -f[0]; }", 0 };
113 
114  skelcl::Vector<float> input(10);
115  for (size_t i = 0; i < input.size(); ++i) {
116  input[i] = i * 2.5f;
117  }
118  EXPECT_EQ(10, input.size());
119 
120  skelcl::Vector<float> output = m(input);
121 
122  EXPECT_EQ(10, output.size());
123  for (size_t i = 0; i < output.size(); ++i) {
124  EXPECT_EQ(-input[i], output[i]);
125  }
126 }
127 
128 TEST_F(MapOverlapTest, SimpleMultiDeviceMapOverlap) {
131  skelcl::MapOverlap<int(int)> m{
132  "int func(__local int* f){ return f[0]; }", 1 };
133 
134  skelcl::Vector<int> input(10);
135  for (size_t i = 0; i < input.size(); ++i) {
136  input[i] = i;
137  }
138  EXPECT_EQ(10, input.size());
139 
140  skelcl::Vector<int> output = m(input);
141 
142  EXPECT_EQ(10, output.size());
143  for (size_t i = 0; i < output.size(); ++i) {
144  EXPECT_EQ(input[i], output[i]);
145  }
146 }
147 
148 TEST_F(MapOverlapTest, SimpleMultiDeviceMapOverlap2) {
151  skelcl::MapOverlap<int(int)> m{
152  "int func(__local int* f){ return f[-1] + f[0] + f[+1]; }", 1 };
153 
154  skelcl::Vector<int> input(499);
155  for (size_t i = 0; i < input.size(); ++i) {
156  input[i] = i;
157  }
158  EXPECT_EQ(499, input.size());
159 
160  skelcl::Vector<int> output = m(input);
161 
162  EXPECT_EQ(499, output.size());
163  EXPECT_EQ(0+input[0]+input[1], output[0]);
164  for (size_t i = 1; i < output.size() - 1; ++i) {
165  EXPECT_EQ(input[i-1]+input[i]+input[i+1], output[i]);
166  }
167  EXPECT_EQ(input[input.size()-2]+input[input.size()-1]+0, output.back());
168 }
169 #endif
170 
171 
172 #if 0
173 const auto print = [](skelcl::Matrix<int>& m, std::string name) {
174  std::cout << name << "\n";
175  auto i = 0u;
176  for (auto& v : m) {
177  ++i;
178  std::cout << std::setw(2) << v << " ";
179  if (i == m.columnCount()) {
180  i = 0;
181  std::cout << "\n";
182  }
183  }
184 };
185 #endif
186 
187 TEST_F(MapOverlapTest, SimpleMatrixRightShift) {
188  skelcl::MapOverlap<int(int)> m{
189  "int func(input_matrix_t f){ return getData(f, -1, 0); }", 1};
190 
191  size_t size = 1024;
192 
193  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
194  for (size_t i = 0; i < input.size().rowCount(); ++i) { // y direction
195  for (size_t j = 0; j < input.size().columnCount(); ++j) { // x direction
196  input[i][j] = (i*j)+i;
197  }
198  }
199 
200  skelcl::Matrix<int> output = m(input);
201 
202  EXPECT_EQ(size, output.size().rowCount());
203  EXPECT_EQ(size, output.size().columnCount());
204 
205  for (size_t i = 0; i < output.size().rowCount(); ++i) {
206  EXPECT_EQ(input[i][0], output[i][0]);
207  }
208 
209  for (size_t i = 0; i < output.size().rowCount(); ++i) {
210  for (size_t j = 1; j < output.size().columnCount(); ++j) {
211  EXPECT_EQ(input[i][j-1], output[i][j]);
212  }
213  }
214  //print(input, "input");
215  //print(output, "output");
216 }
217 
218 TEST_F(MapOverlapTest, SimpleMatrixTwoRightShift) {
219  auto size = 100u;
220  auto shift = 2u;
221  skelcl::MapOverlap<int(int)> m{
222  "int func(input_matrix_t f){ return getData(f, -2, 0); }", shift};
223 
224  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
225  for (size_t i = 0; i < input.size().rowCount(); ++i) {
226  for (size_t j = 0; j < input.size().columnCount(); ++j) {
227  input[i][j] = j;
228  }
229  }
230 
231  skelcl::Matrix<int> output = m(input);
232 
233  EXPECT_EQ(size, output.size().rowCount());
234  EXPECT_EQ(size, output.size().columnCount());
235 
236  for (size_t i = 0; i < output.size().rowCount(); ++i) {
237  for (size_t j = shift; j < output.size().columnCount(); ++j) {
238  EXPECT_EQ(input[i][j - shift], output[i][j]);
239  }
240  }
241 
242  for (size_t i = 0; i < output.size().rowCount(); ++i) {
243  for (size_t j = 0; j < shift; ++j) {
244  EXPECT_EQ(input[i][0], output[i][j]);
245  }
246  }
247  //print(input, "input");
248  //print(output, "output");
249 }
250 
251 TEST_F(MapOverlapTest, SimpleMatrixLeftShift) {
252  skelcl::MapOverlap<int(int)> m{
253  "int func(input_matrix_t f){ return getData(f, +1, 0); }", 1};
254 
255  size_t size = 100;
256 
257  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
258  for (size_t i = 0; i < input.size().rowCount(); ++i) {
259  for (size_t j = 0; j < input.size().columnCount(); ++j) {
260  input[i][j] = j;
261  }
262  }
263 
264  skelcl::Matrix<int> output = m(input);
265 
266  EXPECT_EQ(size, output.size().rowCount());
267  EXPECT_EQ(size, output.size().columnCount());
268 
269  for (size_t i = 0; i < output.size().rowCount(); ++i) {
270  for (size_t j = 0; j < output.size().columnCount() - 1; ++j) {
271  EXPECT_EQ(input[i][j+1], output[i][j]);
272  }
273  }
274 
275  for (size_t i = 0; i < output.size().rowCount(); ++i) {
276  size_t j = output.size().columnCount() - 1;
277  EXPECT_EQ(input[i][j], output[i][j]);
278  }
279  //print(input, "input");
280  //print(output, "output");
281 }
282 
283 TEST_F(MapOverlapTest, SimpleMatrixTwoLeftShift) {
284  auto size = 100u;
285  auto shift = 2u;
286  skelcl::MapOverlap<int(int)> m{
287  "int func(input_matrix_t f){ return getData(f, +2, 0); }", shift};
288 
289  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
290  for (size_t i = 0; i < input.size().rowCount(); ++i) {
291  for (size_t j = 0; j < input.size().columnCount(); ++j) {
292  input[i][j] = j;
293  }
294  }
295 
296  skelcl::Matrix<int> output = m(input);
297 
298  EXPECT_EQ(size, output.size().rowCount());
299  EXPECT_EQ(size, output.size().columnCount());
300 
301  for (size_t i = 0; i < output.size().rowCount(); ++i) {
302  for (size_t j = 0; j < output.size().columnCount() - shift; ++j) {
303  EXPECT_EQ(input[i][j + shift], output[i][j]);
304  }
305  }
306 
307  for (size_t i = 0; i < output.size().rowCount(); ++i) {
308  for (size_t j = output.size().columnCount() - shift;
309  j < output.size().columnCount(); ++j) {
310  EXPECT_EQ(input[i][output.size().columnCount()-1], output[i][j]);
311  }
312  }
313  //print(input, "input");
314  //print(output, "output");
315 }
316 
317 TEST_F(MapOverlapTest, SimpleMatrixDownShift) {
318  skelcl::MapOverlap<int(int)> m{
319  "int func(input_matrix_t f){ return getData(f, 0, -1); }", 1};
320 
321  size_t size = 1024;
322 
323  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
324  for (size_t i = 0; i < input.size().rowCount(); ++i) {
325  for (size_t j = 0; j < input.size().columnCount(); ++j) {
326  input[i][j] = i;
327  }
328  }
329 
330  skelcl::Matrix<int> output = m(input);
331 
332  EXPECT_EQ(size, output.size().rowCount());
333  EXPECT_EQ(size, output.size().columnCount());
334 
335  for (size_t j = 0; j < output.size().columnCount(); ++j) {
336  EXPECT_EQ(input[0][j], output[0][j]);
337  }
338 
339  for (size_t i = 1; i < output.size().rowCount(); ++i) {
340  for (size_t j = 0; j < output.size().columnCount(); ++j) {
341  EXPECT_EQ(input[i-1][j], output[i][j]);
342  }
343  }
344  //print(input, "input");
345  //print(output, "output");
346 }
347 
348 TEST_F(MapOverlapTest, SimpleMatrixTwoDownShift) {
349  auto size = 100u;
350  auto shift = 2u;
351  skelcl::MapOverlap<int(int)> m{
352  "int func(input_matrix_t f){ return getData(f, 0, -2); }", shift};
353 
354  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
355  for (size_t i = 0; i < input.size().rowCount(); ++i) {
356  for (size_t j = 0; j < input.size().columnCount(); ++j) {
357  input[i][j] = i;
358  }
359  }
360 
361  skelcl::Matrix<int> output = m(input);
362 
363  EXPECT_EQ(size, output.size().rowCount());
364  EXPECT_EQ(size, output.size().columnCount());
365 
366  for (size_t i = 0; i < shift; i++) {
367  for (size_t j = 0; j < output.size().columnCount(); ++j) {
368  EXPECT_EQ(input[0][j], output[i][j]);
369  }
370  }
371 
372  for (size_t i = shift; i < output.size().rowCount(); ++i) {
373  for (size_t j = 0; j < output.size().columnCount(); ++j) {
374  EXPECT_EQ(input[i-shift][j], output[i][j]);
375  }
376  }
377  //print(input, "input");
378  //print(output, "output");
379 }
380 
381 TEST_F(MapOverlapTest, SimpleMatrixUpShift) {
382  auto size = 1024u;
383  auto shift = 1u;
384  skelcl::MapOverlap<int(int)> m{
385  "int func(input_matrix_t f){ return getData(f, 0, +1); }", shift};
386 
387  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
388  for (size_t i = 0; i < input.size().rowCount(); ++i) {
389  for (size_t j = 0; j < input.size().columnCount(); ++j) {
390  input[i][j] = i;
391  }
392  }
393 
394  skelcl::Matrix<int> output = m(input);
395 
396  EXPECT_EQ(size, output.size().rowCount());
397  EXPECT_EQ(size, output.size().columnCount());
398 
399  for (size_t i = 0; i < output.size().rowCount() - shift; ++i) {
400  for (size_t j = 0; j < output.size().columnCount(); ++j) {
401  EXPECT_EQ(input[i + shift][j], output[i][j]);
402  }
403  }
404 
405  for (size_t i = output.size().rowCount() - shift;
406  i < output.size().rowCount(); i++) {
407  for (size_t j = 0; j < output.size().columnCount(); ++j) {
408  EXPECT_EQ(input[i][j], output[i][j]);
409  }
410  }
411  //print(input, "input");
412  //print(output, "output");
413 }
414 
415 TEST_F(MapOverlapTest, SimpleMatrixTwoUpShift) {
416  auto size = 100u;
417  auto shift = 2u;
418  skelcl::MapOverlap<int(int)> m{
419  "int func(input_matrix_t f){ return getData(f, 0, +2); }", shift};
420 
421  skelcl::Matrix<int> input( skelcl::MatrixSize{size, size} );
422  for (size_t i = 0; i < input.size().rowCount(); ++i) {
423  for (size_t j = 0; j < input.size().columnCount(); ++j) {
424  input[i][j] = i;
425  }
426  }
427 
428  skelcl::Matrix<int> output = m(input);
429 
430  EXPECT_EQ(size, output.size().rowCount());
431  EXPECT_EQ(size, output.size().columnCount());
432 
433  for (size_t i = 0; i < output.size().rowCount() - shift; ++i) {
434  for (size_t j = 0; j < output.size().columnCount(); ++j) {
435  EXPECT_EQ(input[i + shift][j], output[i][j]);
436  }
437  }
438 
439  for (size_t i = output.size().rowCount() - shift;
440  i < output.size().rowCount(); i++) {
441  for (size_t j = 0; j < output.size().columnCount(); ++j) {
442  EXPECT_EQ(input[output.size().rowCount()-1][j], output[i][j]);
443  }
444  }
445  //print(input, "input");
446  //print(output, "output");
447 }
448 
449 #if 0
450 TEST_F(MapOverlapTest, SimpleMatrixMapOverlap2) {
451  skelcl::MapOverlap<int(int)> m{
452  "int func(__local int* f){ return f[-1]+f[0]+f[1]; }", 1 };
453 
454  skelcl::Vector<int> input(10);
455  for (size_t i = 0; i < input.size(); ++i) {
456  input[i] = i;
457  }
458  EXPECT_EQ(10, input.size());
459 
460  skelcl::Vector<int> output = m(input);
461 
462  EXPECT_EQ(10, output.size());
463  EXPECT_EQ(0+input[0]+input[1], output[0]);
464  for (size_t i = 1; i < output.size() - 1; ++i) {
465  EXPECT_EQ(input[i-1]+input[i]+input[i+1], output[i]);
466  }
467  EXPECT_EQ(input[input.size()-2]+input[input.size()-1]+0, output.back());
468 }
469 
470 TEST_F(MapOverlapTest, SimpleMatrixMultiDeviceMapOverlap) {
472  skelcl::init(2);
473  skelcl::MapOverlap<int(int)> m{
474  "int func(__local int* f){ return f[0]; }", 1 };
475 
476  skelcl::Vector<int> input(10);
477  for (size_t i = 0; i < input.size(); ++i) {
478  input[i] = i;
479  }
480  EXPECT_EQ(10, input.size());
481 
482  skelcl::Vector<int> output = m(input);
483 
484  EXPECT_EQ(10, output.size());
485  for (size_t i = 0; i < output.size(); ++i) {
486  EXPECT_EQ(input[i], output[i]);
487  }
488 }
489 
490 TEST_F(MapOverlapTest, SimpleMatrixMultiDeviceMapOverlap2) {
492  skelcl::init(2);
493  skelcl::MapOverlap<int(int)> m{
494  "int func(__local int* f){ return f[-1] + f[0] + f[+1]; }", 1 };
495 
496  skelcl::Vector<int> input(499);
497  for (size_t i = 0; i < input.size(); ++i) {
498  input[i] = i;
499  }
500  EXPECT_EQ(499, input.size());
501 
502  skelcl::Vector<int> output = m(input);
503 
504  EXPECT_EQ(499, output.size());
505  EXPECT_EQ(0+input[0]+input[1], output[0]);
506  for (size_t i = 1; i < output.size() - 1; ++i) {
507  EXPECT_EQ(input[i-1]+input[i]+input[i+1], output[i]);
508  }
509  EXPECT_EQ(input[input.size()-2]+input[input.size()-1]+0, output.back());
510 }
511 #endif
512 
514 
The Matrix class is a two dimensional container which makes its data accessible on the host as well a...
Definition: Matrix.h:190
SKELCL_DLL void init(detail::DeviceProperties properties=allDevices())
Initializes the SkelCL library. This function (or another init function) has to be called prior to ev...
Definition: SkelCL.cpp:51
SKELCL_DLL detail::DeviceProperties nDevices(size_t n)
Creates a detail::DeviceProperties object representing n devices. This object should be used as param...
Definition: SkelCL.cpp:66
The Vector class is a one dimensional container which makes its data accessible on the host as well a...
Definition: Vector.h:113
This class defines a two dimensional size for a Matrix.
Definition: Matrix.h:67
size_type rowCount() const
Returns the number of rows.
Definition: MatrixSize.cpp:56
SKELCL_DLL void terminate()
Frees all resources allocated internally by SkelCL.
Definition: SkelCL.cpp:81
size_type columnCount() const
Returns the number of columns.
Definition: MatrixSize.cpp:61