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
AllPairsTests.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 <cstdio>
39 #include <cstdlib>
40 #include <vector>
41 
42 #include <pvsutil/Logger.h>
43 
44 #include <SkelCL/SkelCL.h>
45 #include <SkelCL/Vector.h>
46 #include <SkelCL/AllPairs.h>
47 #include <SkelCL/Zip.h>
48 #include <SkelCL/Reduce.h>
49 
50 #include "Test.h"
53 
54 void testAllPairsWithMatrices(const unsigned int, const unsigned int, const unsigned int);
55 
56 class AllPairsTest : public ::testing::Test {
57 protected:
58  AllPairsTest() {
59  //pvsutil::defaultLogger.setLoggingLevel(pvsutil::Logger::Severity::DebugInfo);
61 
62  srand(1);
63  }
64 
65  ~AllPairsTest() {
67  }
68 };
69 
70 // Tests Constructor
71 TEST_F(AllPairsTest, ConstructorWithZipAndReduce) {
72  skelcl::Zip<float(float, float)> zip("float func(float x, float y){ return x*y; }");
73  skelcl::Reduce<float(float)> reduce("float func(float x, float y){ return x+y; }");
74  skelcl::AllPairs<float(float, float)> allpairs(reduce, zip);
75 }
76 
77 // Tests kernel with matrixmultiplication of two 64x64 matrices
78 TEST_F(AllPairsTest, SquareMatrices64x64) {
79  testAllPairsWithMatrices(64, 64, 64);
80 }
81 
82 // Tests kernel with matrixmultiplication with one 32x128 matrix and one 128x32 matrix
83 TEST_F(AllPairsTest, NoSquareMatrices32x128Simple) {
84  testAllPairsWithMatrices(32, 128, 32);
85 }
86 
87 // Tests kernel with matrixmultiplication with two arbitrary matrices
88 TEST_F(AllPairsTest, ArbitraryMatrices) {
89  testAllPairsWithMatrices(100, 60, 11);
90 }
91 
92 // M * N = D
93 //----------------
94 // M: height x dim
95 // N: dim x width
96 // D: height x width
97 void testAllPairsWithMatrices(const unsigned int height, const unsigned int dim, const unsigned int width) {
98  skelcl::Zip<float(float, float)> zip("float func(float x, float y){ return x*y; }");
99  skelcl::Reduce<float(float)> reduce("float func(float x, float y){ return x+y; }");
100  skelcl::AllPairs<float(float, float)> allpairs(reduce, zip);
101 
102  std::vector<float> tmpleft(height*dim);
103  for (size_t i = 0; i < tmpleft.size(); ++i)
104  tmpleft[i] = rand() % 100;
105  EXPECT_EQ(height*dim, tmpleft.size());
106 
107  std::vector<float> tmpright(dim*width);
108  for (size_t i = 0; i < tmpright.size(); ++i)
109  tmpright[i] = rand() % 101;
110  EXPECT_EQ(dim*width, tmpright.size());
111 
112  skelcl::Matrix<float> left(tmpleft, dim);
113  EXPECT_EQ(height, left.rowCount());
114  EXPECT_EQ(dim, left.columnCount());
115 
116  skelcl::Matrix<float> right(tmpright, width);
117  EXPECT_EQ(dim, right.rowCount());
118  EXPECT_EQ(width, right.columnCount());
119 
120  skelcl::Matrix<float> output = allpairs(left, right);
121  EXPECT_EQ(height, output.rowCount());
122  EXPECT_EQ(width, output.columnCount());
123 
124  for (size_t i = 0; i < output.rowCount(); ++i) {
125  for (size_t j = 0; j < output.columnCount(); ++j) {
126  float tmp = 0;
127  for (size_t k = 0; k < left.columnCount(); ++k) {
128  tmp += left[i][k] * right[k][j];
129  }
130  EXPECT_EQ(tmp, output[i][j]);
131  }
132  }
133 }
134 
135 // Test additional arguments
136 TEST_F(AllPairsTest, AdditionalArguments) {
137  skelcl::Zip<float(float, float)> zip("float func(float x, float y, float a){ return x*y+a; }");
138  skelcl::Reduce<float(float)> reduce("float func(float x, float y, float b){ return x+y+b; }");
139  skelcl::AllPairs<float(float, float)> allpairs(reduce, zip);
140 
141  std::vector<float> tmpleft(4096);
142  for (size_t i = 0; i < tmpleft.size(); ++i)
143  tmpleft[i] = rand() % 100;
144  EXPECT_EQ(4096, tmpleft.size());
145 
146  std::vector<float> tmpright(4096);
147  for (size_t i = 0; i < tmpright.size(); ++i)
148  tmpright[i] = rand() % 101;
149  EXPECT_EQ(4096, tmpright.size());
150 
151  skelcl::Matrix<float> left(tmpleft, 64);
152  EXPECT_EQ(64, left.rowCount());
153  EXPECT_EQ(64, left.columnCount());
154 
155  skelcl::Matrix<float> right(tmpright, 64);
156  EXPECT_EQ(64, right.rowCount());
157  EXPECT_EQ(64, right.columnCount());
158 
159  float a = 5.0f; float b = 6.0f;
160  skelcl::Matrix<float> output = allpairs(left, right, b, a);
161  EXPECT_EQ(64, output.rowCount());
162  EXPECT_EQ(64, output.columnCount());
163 
164  for (size_t i = 0; i < output.rowCount(); ++i) {
165  for (size_t j = 0; j < output.columnCount(); ++j) {
166  float tmp = 0;
167  for (size_t k = 0; k < left.columnCount(); ++k) {
168  tmp += (left[i][k] * right[k][j] + a) + b;
169  }
170  EXPECT_EQ(tmp, output[i][j]);
171  }
172  }
173 }
174 
175 // Tests alternative kernel-constructor
176 TEST_F(AllPairsTest, AlternativeKernelConstructor) {
177  skelcl::AllPairs<float(float, float)> allpairs("float func(lmatrix_t* row, rmatrix_t* col, const unsigned int dim){return 1;}");
178 }
179 
180 // Tests alternative kernel
181 TEST_F(AllPairsTest, AlternativeKernel) {
182  skelcl::AllPairs<float(float, float)> allpairs("float func(lmatrix_t* row, rmatrix_t* col, const unsigned int dim) {" \
183  "float res = 0;" \
184  "for (int i = 0; i < dim; ++i) {" \
185  " res += getElementFromRow(row, i) * getElementFromColumn(col, i); }" \
186  "return res; }");
187 
188  const unsigned int height = 100;
189  const unsigned int dim = 55;
190  const unsigned int width = 23;
191 
192  std::vector<float> tmpleft(height*dim);
193  for (size_t i = 0; i < tmpleft.size(); ++i)
194  tmpleft[i] = rand() % 99;
195  EXPECT_EQ(height*dim, tmpleft.size());
196 
197  std::vector<float> tmpright(dim*width);
198  for (size_t i = 0; i < tmpright.size(); ++i)
199  tmpright[i] = rand() % 101;
200  EXPECT_EQ(dim*width, tmpright.size());
201 
202  skelcl::Matrix<float> left(tmpleft, dim);
203  EXPECT_EQ(height, left.rowCount());
204  EXPECT_EQ(dim, left.columnCount());
205 
206  skelcl::Matrix<float> right(tmpright, width);
207  EXPECT_EQ(dim, right.rowCount());
208  EXPECT_EQ(width, right.columnCount());
209 
210  skelcl::Matrix<float> output = allpairs(left, right);
211  EXPECT_EQ(height, output.rowCount());
212  EXPECT_EQ(width, output.columnCount());
213 
214  for (size_t i = 0; i < output.rowCount(); ++i) {
215  for (size_t j = 0; j < output.columnCount(); ++j) {
216  float tmp = 0;
217  for (size_t k = 0; k < left.columnCount(); ++k) {
218  tmp += left[i][k] * right[k][j];
219  }
220  EXPECT_EQ(tmp, output[i][j]);
221  }
222  }
223 }
224 
225 // Tests alternative kernel with additional arguments
226 TEST_F(AllPairsTest, AltKernelAddArguments) {
227  skelcl::AllPairs<float(float, float)> allpairs("float func(lmatrix_t* row, rmatrix_t* col, const unsigned int dim, int start) {" \
228  "float res = start;" \
229  "for (int i = 0; i < dim; ++i) {" \
230  " res += getElementFromRow(row, i) * getElementFromColumn(col, i); }" \
231  "return res; }");
232 
233  const unsigned int height = 10;
234  const unsigned int dim = 55;
235  const unsigned int width = 23;
236 
237  std::vector<float> tmpleft(height*dim);
238  for (size_t i = 0; i < tmpleft.size(); ++i)
239  tmpleft[i] = rand() % 98;
240  EXPECT_EQ(height*dim, tmpleft.size());
241 
242  std::vector<float> tmpright(dim*width);
243  for (size_t i = 0; i < tmpright.size(); ++i)
244  tmpright[i] = rand() % 107;
245  EXPECT_EQ(dim*width, tmpright.size());
246 
247  skelcl::Matrix<float> left(tmpleft, dim);
248  EXPECT_EQ(height, left.rowCount());
249  EXPECT_EQ(dim, left.columnCount());
250 
251  skelcl::Matrix<float> right(tmpright, width);
252  EXPECT_EQ(dim, right.rowCount());
253  EXPECT_EQ(width, right.columnCount());
254 
255  int start = 100;
256  skelcl::Matrix<float> output = allpairs(left, right, start);
257  EXPECT_EQ(height, output.rowCount());
258  EXPECT_EQ(width, output.columnCount());
259 
260  for (size_t i = 0; i < output.rowCount(); ++i) {
261  for (size_t j = 0; j < output.columnCount(); ++j) {
262  float tmp = start;
263  for (size_t k = 0; k < left.columnCount(); ++k) {
264  tmp += left[i][k] * right[k][j];
265  }
266  EXPECT_EQ(tmp, output[i][j]);
267  }
268  }
269 }
270 
272 
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
SKELCL_DLL void terminate()
Frees all resources allocated internally by SkelCL.
Definition: SkelCL.cpp:81