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 
18 //#include <stdlib.h>             // srand()
19 //#include <string.h>             // memcpy()
20 #include <gtest/gtest.h>
21 #include <clBLAS.h>
22 //
23 //#include "common.h"
24 //#include "blas.h"
25 #include "blas-wrapper.h"
26 #include "clBLAS-wrapper.h"
27 #include "BlasBase.h"
28 #include "blas-random.h"
29 #include "timer.h"
30 #include "func.h"
31 
32 #include <stdio.h>
33 
34 template <typename M>
35 class ImagesClass
36 {
37     enum
38     {
39         I_DEFAULT = -1,
40         I_BUFERS,
41         I_IMAGES,
42         I_CASHES
43     };
44 
45     M metod;
46 protected:
47     bool generateData();
48     void setImplementation(int i);
49 public:
50     void images();
51     nano_time_t runRepeat(int rep, cl_int* err);
52 };
53 template <typename T> void
setImplementation(int i)54 ImagesClass<T>::setImplementation(int i)
55 {
56     char str[100];
57     clMath::BlasBase *base = clMath::BlasBase::getInstance();
58 
59 
60     if (i != I_IMAGES) {
61         if (base->useImages()) {
62             base->removeScratchImages();
63         }
64         base->setUseImages(false);
65     }
66 
67 #if WIN32
68     if (i == I_DEFAULT) {
69         sprintf (str, "%s=", metod.env);
70     }
71     else {
72         sprintf (str, "%s=%i",metod.env, i);
73     }
74     _putenv(str);
75 #else
76     if (i == I_DEFAULT) {
77         str[0] = '\0';
78     }
79     else {
80         sprintf (str, "%i", i);
81     }
82 
83     setenv(metod.env, str, 1);
84 #endif
85 
86     if (i == I_IMAGES) {
87         base->setUseImages(true);
88         if (base->useImages()) {
89             if (base->addScratchImages()) {
90                 std::cerr << ">> FATAL ERROR, CANNOT CREATE SCRATCH IMAGES!"
91                           << std::endl
92                           << ">> Test skipped." << ::std::endl;
93                 SUCCEED();
94             }
95         }
96    }
97 
98 }
99 
100 template <typename T> bool
generateData()101 ImagesClass<T>::generateData()
102 {
103     metod.generateData();
104     bool ret = metod.prepareDataToRun();
105 
106     if (!ret) {
107         ::std::cerr << ">> Failed to create/enqueue buffer for a matrix."
108             << ::std::endl
109             << ">> Can't execute the test, because data is not transfered to GPU."
110             << ::std::endl
111             << ">> Test skipped." << ::std::endl;
112         SUCCEED();
113     }
114     return ret;
115 }
116 
117 template <typename M> nano_time_t
runRepeat(int rep,cl_int * err)118 ImagesClass<M>::runRepeat(int rep, cl_int* err)
119 {
120     nano_time_t time1 = getCurrentTime();
121     for (int i= 0; i < rep; i++) {
122         nano_time_t time = getCurrentTime();
123         *err = metod.run();
124         if (*err != CL_SUCCESS) {
125             return 0;
126         }
127         *err = clFinish(metod.queues[0]);
128         if (*err != CL_SUCCESS) {
129             return 0;
130         }
131         time = getCurrentTime() - time;
132         time1 = (time < time1)?time:time1 ;
133     }
134     return time1;
135 }
136 
137 template <typename M> void
images()138 ImagesClass<M>::images()
139 {
140     cl_int err;
141     int i= 6;
142     int iMax = 30;
143     nano_time_t maxTime = 1000;
144     nano_time_t minTime = 100;
145     bool next = true;
146 
147     do {
148         nano_time_t time;
149 
150         metod.initDefault(256*i, 1);
151         bool b = generateData();
152         ASSERT_EQ(b, true) << "generateData()";
153         setImplementation(I_BUFERS);
154         metod.initOutEvent();
155         time = runRepeat(2, &err);
156         ASSERT_EQ(err, CL_SUCCESS) << "clFinish()";
157         //std::cerr << "size = " << 256*i << "/" << i << " time = " << conv2millisec(time) << std::endl;
158         if (conv2millisec(time) < minTime) {
159             i += (((int)minTime - (int)conv2millisec(time)) /20) + 1;
160 			metod.destroy();
161             continue;
162         }
163         if (conv2millisec(time) > maxTime) {
164             i = iMax;
165 			metod.destroy();
166             continue;
167         }
168 		next = false;
169 
170 		nano_time_t time1 = runRepeat(5, &err);
171         ASSERT_EQ(err, CL_SUCCESS) << "clFinish()";
172 
173         setImplementation(I_IMAGES);
174 
175         nano_time_t time2 = runRepeat(5, &err);
176         ASSERT_EQ(err, CL_SUCCESS) << "clFinish()";
177 
178         setImplementation(I_DEFAULT);
179 
180         //nano_time_t time3 = runRepeat(5, & err);
181         //ASSERT_EQ(err, CL_SUCCESS) << "clFinish()";
182 
183         double d = (double)(time1) / time2;
184         std::cerr << "size = " << 256*i
185                   << "  timeBufer = " << conv2millisec(time1)
186                   << "  timeImage = " << conv2millisec(time2)
187                   << "  t1/t2 = " << d << std::endl;
188 
189         if (d < 1.2) {
190             next = true;
191             i++;
192         }
193         metod.destroy();
194 
195     } while (i < iMax && next);
196 
197     ASSERT_TRUE(!next) ;
198 
199 }
200 
201 // Instantiate the test
202 
203 //******************************************************/
TEST(IMAGES,sgemm)204 TEST(IMAGES, sgemm) {
205     ImagesClass<GemmMetod<float> > ec;
206     ec.images();
207 }
208 
TEST(IMAGES,cgemm)209 TEST(IMAGES, cgemm) {
210     ImagesClass<GemmMetod<FloatComplex> > ec;
211     ec.images();
212 }
213 
TEST(IMAGES,dgemm)214 TEST(IMAGES, dgemm) {
215     CHECK_DOUBLE;
216     ImagesClass<GemmMetod<cl_double> > ec;
217     ec.images();
218 }
219 
TEST(IMAGES,zgemm)220 TEST(IMAGES, zgemm) {
221     CHECK_DOUBLE;
222     ImagesClass<GemmMetod<DoubleComplex> > ec;
223     ec.images();
224 }//******************************************************/
TEST(IMAGES,strmm)225 TEST(IMAGES, strmm) {
226     ImagesClass<TrmmMetod<float> > ec;
227     ec.images();
228 }
229 
TEST(IMAGES,ctrmm)230 TEST(IMAGES, ctrmm) {
231     ImagesClass<TrmmMetod<FloatComplex> > ec;
232     ec.images();
233 }
234 
TEST(IMAGES,dtrmm)235 TEST(IMAGES, dtrmm) {
236     CHECK_DOUBLE;
237     ImagesClass<TrmmMetod<cl_double> > ec;
238     ec.images();
239 }
240 
TEST(IMAGES,ztrmm)241 TEST(IMAGES, ztrmm) {
242     CHECK_DOUBLE;
243     ImagesClass<TrmmMetod<DoubleComplex> > ec;
244     ec.images();
245 }
246 //******************************************************/
TEST(IMAGES,strsm)247 TEST(IMAGES, strsm) {
248     ImagesClass<TrsmMetod<float> > ec;
249     ec.images();
250 }
251 
TEST(IMAGES,ctrsm)252 TEST(IMAGES, ctrsm) {
253     ImagesClass<TrsmMetod<FloatComplex> > ec;
254     ec.images();
255 }
256 
TEST(IMAGES,dtrsm)257 TEST(IMAGES, dtrsm) {
258     CHECK_DOUBLE;
259     ImagesClass<TrsmMetod<cl_double> > ec;
260     ec.images();
261 }
262 
TEST(IMAGES,ztrsm)263 TEST(IMAGES, ztrsm) {
264     CHECK_DOUBLE;
265     ImagesClass<TrsmMetod<DoubleComplex> > ec;
266     ec.images();
267 }
268 //******************************************************/
269