1 |
/* |
2 |
***************************************************************************** |
3 |
* * |
4 |
* COPYRIGHT ACcESS - All Rights Reserved * |
5 |
* * |
6 |
* This software is the property of ACcESS. No part of this code * |
7 |
* may be copied in any form or by any means without the expressed written * |
8 |
* consent of ACcESS. Copying, use or modification of this software * |
9 |
* by any unauthorised person is illegal unless that person has a software * |
10 |
* license agreement with ACcESS. * |
11 |
* * |
12 |
***************************************************************************** |
13 |
*/ |
14 |
#include "escript/Data/DataArrayView.h" |
15 |
#include "escript/Data/DataArray.h" |
16 |
#include "DataArrayViewTestCase.h" |
17 |
#include "esysUtils/EsysException.h" |
18 |
|
19 |
#include <iostream> |
20 |
|
21 |
using namespace CppUnitTest; |
22 |
using namespace esysUtils; |
23 |
using namespace escript; |
24 |
using namespace std; |
25 |
|
26 |
void DataArrayViewTestCase::setUp() { |
27 |
// |
28 |
// This is called before each test is run |
29 |
|
30 |
} |
31 |
|
32 |
void DataArrayViewTestCase::tearDown() { |
33 |
// |
34 |
// This is called after each test has been run |
35 |
|
36 |
} |
37 |
|
38 |
void DataArrayViewTestCase::testSlicing() { |
39 |
|
40 |
// Test some arbitrary slicing |
41 |
|
42 |
cout << endl; |
43 |
|
44 |
{ |
45 |
DataArrayView::RegionType region; |
46 |
region.push_back(DataArrayView::RegionType::value_type(1,5)); |
47 |
DataArrayView::ShapeType resultShape; |
48 |
resultShape.push_back(4); |
49 |
assert(DataArrayView::getResultSliceShape(region)==resultShape); |
50 |
region.push_back(DataArrayView::RegionType::value_type(2,5)); |
51 |
resultShape.push_back(3); |
52 |
assert(DataArrayView::getResultSliceShape(region)==resultShape); |
53 |
} |
54 |
|
55 |
{ |
56 |
// Say an empty region can select a scalar |
57 |
DataArrayView::RegionType region; |
58 |
DataArrayView::ShapeType sourceShape; |
59 |
DataArray source(sourceShape,2.0); |
60 |
DataArray target; |
61 |
target.getView().copySlice(source.getView(),region); |
62 |
assert(source.getView()==target.getView()); |
63 |
} |
64 |
|
65 |
{ |
66 |
// try a slice from a 1 dimensional array |
67 |
DataArrayView::RegionType region; |
68 |
region.push_back(DataArrayView::RegionType::value_type(2,4)); |
69 |
DataArrayView::ShapeType sourceShape; |
70 |
sourceShape.push_back(6); |
71 |
DataArray source(sourceShape); |
72 |
for (int i=0;i<sourceShape[0];++i) { |
73 |
source.getView()(i)=i; |
74 |
} |
75 |
DataArray target(DataArrayView::getResultSliceShape(region)); |
76 |
target.getView().copySlice(source.getView(),region); |
77 |
for (int i=region[0].first;i<region[0].second;++i) { |
78 |
assert(source.getView()(i)==target.getView()(i-2)); |
79 |
} |
80 |
} |
81 |
|
82 |
{ |
83 |
// try a slice from a 2 dimensional array |
84 |
DataArrayView::RegionType region; |
85 |
region.push_back(DataArrayView::RegionType::value_type(2,4)); |
86 |
region.push_back(DataArrayView::RegionType::value_type(0,2)); |
87 |
DataArrayView::ShapeType sourceShape; |
88 |
sourceShape.push_back(6); |
89 |
sourceShape.push_back(3); |
90 |
DataArray source(sourceShape); |
91 |
int val=0; |
92 |
for (int i=0;i<sourceShape[0];++i) { |
93 |
for (int j=0;j<sourceShape[1];++j) { |
94 |
source.getView()(i,j)=val++; |
95 |
} |
96 |
} |
97 |
DataArray target(DataArrayView::getResultSliceShape(region)); |
98 |
target.getView().copySlice(source.getView(),region); |
99 |
for (int i=region[0].first;i<region[0].second;++i) { |
100 |
for (int j=region[1].first;j<region[1].second;++j) { |
101 |
assert(source.getView()(i,j)==target.getView()(i-2,j)); |
102 |
} |
103 |
} |
104 |
} |
105 |
|
106 |
} |
107 |
|
108 |
void DataArrayViewTestCase::testShapeToString() { |
109 |
cout << endl; |
110 |
DataArrayView::ShapeType shape; |
111 |
assert(DataArrayView::shapeToString(shape)=="()"); |
112 |
shape.push_back(5); |
113 |
assert(DataArrayView::shapeToString(shape)=="(5)"); |
114 |
shape.push_back(2); |
115 |
assert(DataArrayView::shapeToString(shape)=="(5,2)"); |
116 |
} |
117 |
|
118 |
void DataArrayViewTestCase::testScalarView() { |
119 |
// |
120 |
// Create a vector containing data for three scalars |
121 |
// and check three scalar views return the appropriate data |
122 |
DataArrayView::ShapeType vShape; |
123 |
DataArrayView::ValueType vData; |
124 |
vData.push_back(0); |
125 |
vData.push_back(1); |
126 |
vData.push_back(2); |
127 |
int sZero=0; |
128 |
int sOne=1; |
129 |
int sTwo=2; |
130 |
DataArrayView zView(vData,vShape,sZero); |
131 |
DataArrayView oView(vData,vShape,sOne); |
132 |
DataArrayView tView(vData,vShape,sTwo); |
133 |
vShape.push_back(3); |
134 |
DataArrayView oneVView(vData,vShape,0); |
135 |
assert(zView()==0); |
136 |
assert(oView()==1); |
137 |
assert(tView()==2); |
138 |
assert(tView.noValues()==1); |
139 |
assert(oView.getRank()==0); |
140 |
// |
141 |
// copy the one view to the zero view |
142 |
zView.copy(oView); |
143 |
assert(zView==oView); |
144 |
zView.checkShape(oView.getShape()); |
145 |
cout << endl << "\tTest shape mismatch functions." << endl; |
146 |
if (!zView.checkShape(oneVView.getShape())) { |
147 |
//cout << zView.createShapeErrorMessage("Error - Shape mismatch.", oneVView.getShape()) << endl; |
148 |
assert(true); |
149 |
} else { |
150 |
assert(false); |
151 |
} |
152 |
zView.unaryOp(negate<double>()); |
153 |
assert(zView()==-1); |
154 |
zView.binaryOp(oView,plus<double>()); |
155 |
assert(zView()==0); |
156 |
// |
157 |
// test view.operator!= |
158 |
assert(zView!=oView); |
159 |
} |
160 |
|
161 |
void DataArrayViewTestCase::testAll() |
162 |
{ |
163 |
|
164 |
{ |
165 |
cout << endl; |
166 |
|
167 |
cout << "\tTest empty DataArrayView." << endl; |
168 |
|
169 |
DataArrayView defView; |
170 |
|
171 |
assert(defView.getOffset()==0); |
172 |
assert(defView.getShape().empty()); |
173 |
assert(defView.noValues()==0); |
174 |
assert(defView.getRank()==0); |
175 |
} |
176 |
|
177 |
{ |
178 |
cout << endl; |
179 |
|
180 |
// define the shape for the data array view |
181 |
cout << "\tTest shape (5):" << endl; |
182 |
DataArrayView::ShapeType shape; |
183 |
shape.push_back(5); |
184 |
int offset=5; |
185 |
|
186 |
// allocate the space external to the DataArrayView |
187 |
DataArrayView::ValueType data(DataArrayView::noValues(shape)+offset,0); |
188 |
|
189 |
// test constructor |
190 |
cout << "\tTest DataArrayView constructor." << endl; |
191 |
DataArrayView dataView(data,shape,offset); |
192 |
|
193 |
// test shape set correctly |
194 |
cout << "\tTest getShape." << endl; |
195 |
assert(dataView.getShape()==shape); |
196 |
|
197 |
// Assign values to the data |
198 |
cout << "\tAssign values via () operator." << endl; |
199 |
for (int i=0;i<shape[0];++i) { |
200 |
//cout << i << ":" << dataView.index(i) << endl; |
201 |
dataView(i)=dataView.index(i); |
202 |
assert(dataView(i)==dataView.index(i)); |
203 |
} |
204 |
|
205 |
// test operator== |
206 |
cout << "\tTest == operator." << endl; |
207 |
assert(dataView==dataView); |
208 |
} |
209 |
|
210 |
{ |
211 |
cout << endl; |
212 |
|
213 |
// define the shape for the data array view |
214 |
cout << "\tTest shape (2,3):" << endl; |
215 |
DataArrayView::ShapeType shape; |
216 |
shape.push_back(2); |
217 |
shape.push_back(3); |
218 |
|
219 |
// allocate the space external to the DataArrayView |
220 |
DataArrayView::ValueType data(DataArrayView::noValues(shape),0); |
221 |
|
222 |
// test constructor |
223 |
cout << "\tTest DataArrayView constructor." << endl; |
224 |
DataArrayView dataView(data,shape); |
225 |
|
226 |
// test shape set correctly |
227 |
cout << "\tTest getShape." << endl; |
228 |
assert(dataView.getShape()==shape); |
229 |
|
230 |
// Assign values to the data |
231 |
cout << "\tAssign values via () operator." << endl; |
232 |
for (int i=0;i<shape[0];++i) { |
233 |
for (int j=0;j<shape[1];++j) { |
234 |
//cout << i << "," << j << ":" << dataView.index(i,j) << endl; |
235 |
dataView(i,j)=dataView.index(i,j); |
236 |
assert(dataView(i,j)==dataView.index(i,j)); |
237 |
} |
238 |
} |
239 |
|
240 |
// test operator== |
241 |
cout << "\tTest == operator." << endl; |
242 |
assert(dataView==dataView); |
243 |
} |
244 |
|
245 |
{ |
246 |
cout << endl; |
247 |
|
248 |
// define the shape for the data array view |
249 |
cout << "\tTest shape (2,3,4):" << endl; |
250 |
DataArrayView::ShapeType shape; |
251 |
shape.push_back(2); |
252 |
shape.push_back(3); |
253 |
shape.push_back(4); |
254 |
|
255 |
// allocate the space external to the DataArrayView |
256 |
DataArrayView::ValueType data(DataArrayView::noValues(shape),0); |
257 |
|
258 |
// test constructor |
259 |
cout << "\tTest DataArrayView constructor." << endl; |
260 |
DataArrayView dataView(data,shape); |
261 |
|
262 |
// test shape set correctly |
263 |
cout << "\tTest getShape." << endl; |
264 |
assert(dataView.getShape()==shape); |
265 |
|
266 |
// Assign values to the data |
267 |
cout << "\tAssign values via () operator." << endl; |
268 |
for (int i=0;i<shape[0];++i) { |
269 |
for (int j=0;j<shape[1];++j) { |
270 |
for (int k=0;k<shape[2];++k) { |
271 |
//cout << i << "," << j << "," << k << ":" << dataView.index(i,j,k) << endl; |
272 |
dataView(i,j,k)=dataView.index(i,j,k); |
273 |
assert(dataView(i,j,k)==dataView.index(i,j,k)); |
274 |
} |
275 |
} |
276 |
} |
277 |
|
278 |
// test operator== |
279 |
cout << "\tTest == operator." << endl; |
280 |
assert(dataView==dataView); |
281 |
} |
282 |
|
283 |
#if defined DOASSERT |
284 |
{ |
285 |
cout << endl; |
286 |
|
287 |
cout << "\tTest too many indices for rank of array exception." << endl; |
288 |
|
289 |
DataArrayView::ShapeType shape; |
290 |
DataArrayView::ValueType data(DataArrayView::noValues(shape),0); |
291 |
DataArrayView dataView(data,shape); |
292 |
|
293 |
// Should be a scalar |
294 |
dataView()=1; |
295 |
|
296 |
try { |
297 |
dataView(1)=1; |
298 |
assert(false); |
299 |
} |
300 |
catch (EsysException& e) { |
301 |
//cout << "\t" << e.what() << endl; |
302 |
assert(true); |
303 |
} |
304 |
|
305 |
try { |
306 |
dataView(1,1)=1; |
307 |
assert(false); |
308 |
} |
309 |
catch (EsysException& e) { |
310 |
//cout << "\t" << e.what() << endl; |
311 |
assert(true); |
312 |
} |
313 |
|
314 |
try { |
315 |
dataView(1,1,1)=1; |
316 |
assert(false); |
317 |
} |
318 |
catch (EsysException& e) { |
319 |
//cout << "\t" << e.what() << endl; |
320 |
assert(true); |
321 |
} |
322 |
} |
323 |
|
324 |
{ |
325 |
cout << endl; |
326 |
|
327 |
cout << "\tTest invalid index exception." << endl; |
328 |
|
329 |
DataArrayView::ShapeType shape; |
330 |
shape.push_back(4); |
331 |
DataArrayView::ValueType data(DataArrayView::noValues(shape),0); |
332 |
DataArrayView dataView(data,shape); |
333 |
|
334 |
try { |
335 |
dataView(4000)=1; |
336 |
assert(false); |
337 |
} |
338 |
catch (EsysException& e) { |
339 |
//cout << "\t" << e.what() << endl; |
340 |
assert(true); |
341 |
} |
342 |
} |
343 |
|
344 |
#endif |
345 |
|
346 |
{ |
347 |
cout << endl; |
348 |
|
349 |
cout << "\tTest insufficient data exception." << endl; |
350 |
|
351 |
DataArrayView::ShapeType shape; |
352 |
DataArrayView::ValueType data; |
353 |
|
354 |
try { |
355 |
DataArrayView dataView(data,shape); |
356 |
assert(false); |
357 |
} |
358 |
catch (EsysException& e) { |
359 |
//cout << "\t" << e.what() << endl; |
360 |
assert(true); |
361 |
} |
362 |
} |
363 |
|
364 |
{ |
365 |
cout << endl; |
366 |
|
367 |
cout << "\tTest matrix multiplication." << endl; |
368 |
|
369 |
DataArrayView::ShapeType leftShape; |
370 |
leftShape.push_back(1); |
371 |
leftShape.push_back(3); |
372 |
DataArrayView::ValueType leftData(DataArrayView::noValues(leftShape),0); |
373 |
DataArrayView leftDataView(leftData,leftShape); |
374 |
|
375 |
DataArrayView::ShapeType rightShape; |
376 |
rightShape.push_back(3); |
377 |
rightShape.push_back(2); |
378 |
DataArrayView::ValueType rightData(DataArrayView::noValues(rightShape),0); |
379 |
DataArrayView rightDataView(rightData,rightShape); |
380 |
|
381 |
DataArrayView::ShapeType resultShape=DataArrayView::determineResultShape(leftDataView,rightDataView); |
382 |
|
383 |
for (int i=0;i<resultShape.size();++i) { |
384 |
cout << "\tDimension: " << i << " size: " << resultShape[i] << endl; |
385 |
} |
386 |
|
387 |
DataArrayView::ValueType resultData(DataArrayView::noValues(resultShape),0); |
388 |
DataArrayView resultDataView(resultData,resultShape); |
389 |
|
390 |
cout << "\tTest result shape." << endl; |
391 |
|
392 |
assert(resultShape.size()==2); |
393 |
assert(resultShape[0]==1); |
394 |
assert(resultShape[1]==2); |
395 |
|
396 |
// Assign some values |
397 |
cout << "\tAssign values." << endl; |
398 |
double aValue=0.0; |
399 |
for (int i=0;i<leftShape[0];++i) { |
400 |
for (int j=0;j<leftShape[1];++j) { |
401 |
leftDataView(i,j)=++aValue; |
402 |
} |
403 |
} |
404 |
aValue=0.0; |
405 |
for (int i=0;i<rightShape[0];++i) { |
406 |
for (int j=0;j<rightShape[1];++j) { |
407 |
rightDataView(i,j)=++aValue; |
408 |
} |
409 |
} |
410 |
|
411 |
cout << "\tDo matrix multiplication." << endl; |
412 |
DataArrayView::matMult(leftDataView,rightDataView,resultDataView); |
413 |
|
414 |
cout << "\tCheck result." << endl; |
415 |
//need to hand build result matrix and compare with generated result here. |
416 |
|
417 |
/* |
418 |
cout << "Create a vector." << endl; |
419 |
DataArray v; |
420 |
DataArray::ShapeType vShape; |
421 |
vShape.push_back(3); |
422 |
v.setShape(vShape); |
423 |
double aValue=0.0; |
424 |
for (int i=0;i<vShape[0];++i) { |
425 |
v(i)=++aValue; |
426 |
} |
427 |
|
428 |
cout << "Create a matrix." << endl; |
429 |
DataArray mat; |
430 |
DataArray::ShapeType mShape; |
431 |
mShape.push_back(3); |
432 |
mShape.push_back(2); |
433 |
mat.setShape(mShape); |
434 |
aValue=0.0; |
435 |
for (int i=0;i<mShape[0];++i) { |
436 |
for (int j=0;j<mShape[1];++j) { |
437 |
mat(i,j)=++aValue; |
438 |
} |
439 |
} |
440 |
|
441 |
// [1,2,3] x |1, 2| = [22,28] |
442 |
// |3, 4| |
443 |
// |5, 6| |
444 |
|
445 |
cout << "Test multiplication of matrix and vector." << endl; |
446 |
DataArray result=DataArray::matMult(v,mat); |
447 |
assert(fabs(result(0) - 22) < 0.1); |
448 |
assert(fabs(result(1) - 28) < 0.1); |
449 |
*/ |
450 |
} |
451 |
|
452 |
} |
453 |
|
454 |
TestSuite* DataArrayViewTestCase::suite () |
455 |
{ |
456 |
// |
457 |
// create the suite of tests to perform. |
458 |
TestSuite *testSuite = new TestSuite ("DataArrayViewTestCase"); |
459 |
|
460 |
testSuite->addTest (new TestCaller< DataArrayViewTestCase>("testAll",&DataArrayViewTestCase::testAll)); |
461 |
testSuite->addTest (new TestCaller< DataArrayViewTestCase>("testShapeToString",&DataArrayViewTestCase::testShapeToString)); |
462 |
testSuite->addTest (new TestCaller< DataArrayViewTestCase>("testScalarView",&DataArrayViewTestCase::testScalarView)); |
463 |
testSuite->addTest (new TestCaller< DataArrayViewTestCase>("testSlicing",&DataArrayViewTestCase::testSlicing)); |
464 |
return testSuite; |
465 |
} |
466 |
|