Belos Version of the Day
Loading...
Searching...
No Matches
BelosDenseMatTester.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Belos: Block Linear Solvers Package
4//
5// Copyright 2004-2016 NTESS and the Belos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9//
10#ifndef BELOS_DENSETRAITS_TESTER_HPP
11#define BELOS_DENSETRAITS_TESTER_HPP
12
17#include "BelosConfigDefs.hpp"
18#include "BelosTypes.hpp"
19
22
23#include "Teuchos_RCP.hpp"
24#include "Teuchos_SetScientific.hpp"
25
26namespace Belos {
27
44 template< class ScalarType, class DM >
45 bool
47 {
48 using Teuchos::SetScientific;
49 using Teuchos::RCP;
50 using std::endl;
52 typedef Teuchos::ScalarTraits<ScalarType> STS;
53
54 // Make sure that all floating-point numbers are printed with the
55 // right precision.
57
58 // Arbitrary tolerance in case
59 // norms are not computed deterministically (which is possible
60 // even with MPI only, and more likely with threads).
61
62 /* Dense Traits Contract:
63
64 //Example:
65 CloneCopy(MV,vector<int>)
66 USER: will request positive number of vectors
67 MV: will return a multivector with exactly the number of
68 requested vectors.
69 vectors are the same dimension as the cloned MV
70
71
72 *********************************************************************/
73
74 //TODO const ScalarType one = STS::one();
75 const ScalarType zero = STS::zero();
76
77 /*********** Basic Functions: *****************************************
78 Verify:
79 1) Can call DM constructor.
80 2) Number of rows and cols matches requested.
81 3) Init to zero if requested.
82 4) Call constructor with no init to zero.
83 5) Can randomize matrix values.
84 6) Can change a matrix value.
85 7) Const value access is const.
86 8)
87 Basic tester: Just call all the functions.
88 *********************************************************************/
89 { //begin test scope
90 int numrows = 4;
91 int numcols = 3;
92 RCP<DM> dm1 = DMT::Create(numrows,numcols);
93
94 //Check number of rows and cols.
95 int checknumrows = DMT::GetNumRows(*dm1);
96 int checknumcols = DMT::GetNumCols(*dm1);
98 om->stream(Warnings)
99 << "*** ERROR *** DenseMatTraits::GetNumRows or GetNumCols" << endl
100 << "Returned incorrect value." << endl;
101 return false;
102 }
103
104 DMT::SyncDeviceToHost(*dm1);
105 //Check init to zero on create.
106 for(int i = 0; i<numrows; i++){
107 for(int j = 0; j<numcols; j++){
108 ScalarType val = DMT::ValueConst(*dm1,i,j);
109 if(val != zero){
110 om->stream(Warnings)
111 << "*** ERROR *** DenseMatTraits::Create(-,-,true)" << endl
112 << "Did not initialize to zero!" << endl;
113 return false;
114 }
115 }
116 }
117
118 //Try to change a value.
119 DMT::Value(*dm1,0,0) = (ScalarType)5.0;
120 if(DMT::ValueConst(*dm1,0,0) != (ScalarType)5.0){
121 om->stream(Warnings)
122 << "*** ERROR *** DenseMatTraits::Value" << endl
123 << "Does not give write access to matrix values!!" << endl;
124 return false;
125 }
126
127 //Try to sync to host and vice-versa
128 DMT::SyncHostToDevice(*dm1);
129
130 //Call create with non-default third arg.
131 RCP<DM> dm2 = DMT::Create(numrows, numcols, false);
132 DMT::PutScalar(*dm2,(ScalarType)47.2);
133 DMT::SyncDeviceToHost(*dm2);
134 if( DMT::ValueConst(*dm2,0,0) != (ScalarType)47.2){
135 om->stream(Warnings)
136 << "*** ERROR *** DenseMatTraits::PutScalar " << endl
137 << "Value at dm2 0,0 is: " << DMT::ValueConst(*dm2,0,0) << endl;
138 return false;
139 }
140 DMT::PutScalar(*dm2);
141 DMT::SyncDeviceToHost(*dm2);
142 if( DMT::ValueConst(*dm2,0,0) != zero){
143 om->stream(Warnings)
144 << "*** ERROR *** DenseMatTraits::" << endl
145 << "PutScalar default args failed" << endl;
146 return false;
147 }
148
149 //get stride
150 int stride = DMT::GetStride(*dm2);
151 if (stride != numrows) {
152 om->stream(Warnings)
153 << "*** ERROR *** DenseMatTraits::" << endl
154 << "Stride failed" << endl;
155 return false;
156 }
157
158 //randomize and add
159 DMT::Randomize(*dm2);
160 DMT::SyncDeviceToHost(*dm2);
161 ScalarType tmpVal = DMT::ValueConst(*dm1,numrows-1,numcols-1) + DMT::ValueConst(*dm2,numrows-1,numcols-1);
162 ScalarType tmpVal2 = DMT::ValueConst(*dm1,0,0) + DMT::ValueConst(*dm2,0,0);
163 DMT::Add(*dm1,*dm2);
164 DMT::SyncDeviceToHost(*dm1);
165 if(DMT::ValueConst(*dm1,numrows-1,numcols-1) != tmpVal ||
166 DMT::ValueConst(*dm1,0,0) != tmpVal2){
167 om->stream(Warnings)
168 << "*** ERROR *** DenseMatTraits::" << endl
169 << "Add failed" << endl;
170 return false;
171 }
172
173 //Test assign and scale:
174 DMT::Assign(*dm1,*dm2);
175 DMT::Scale(*dm1,2.0);
176 DMT::SyncDeviceToHost(*dm1);
177 if(DMT::ValueConst(*dm1,1,1) != (ScalarType)DMT::ValueConst(*dm2,1,1)*(ScalarType)2.0){
178 om->stream(Warnings)
179 << "*** ERROR *** DenseMatTraits::" << endl
180 << "Assign or scale failed" << endl;
181 return false;
182 }
183
184 RCP<DM> dm3 = DMT::Subview(*dm1, numrows-1, numcols-1, 1, 1);
185 DMT::SyncDeviceToHost(*dm3);
186 if(DMT::ValueConst(*dm3,0,0) != DMT::ValueConst(*dm1,1,1)){
187 om->stream(Warnings)
188 << "*** ERROR *** DenseMatTraits::" << endl
189 << "Subview failed" << endl;
190 return false;
191 }
192 if(DMT::GetNumRows(*dm3) != numrows-1 ||
193 DMT::GetNumCols(*dm3) != numcols-1){
194 om->stream(Warnings)
195 << "*** ERROR *** DenseMatTraits::" << endl
196 << "Subview gives wrong dimensions." << endl;
197 return false;
198 }
199 // Try to change a value in the subview.
200 ScalarType testVal = 237.1;
201 DMT::Value(*dm3,0,0) = testVal;
202 if(DMT::ValueConst(*dm3,0,0) != DMT::ValueConst(*dm1,1,1) ||
203 DMT::ValueConst(*dm3,0,0) != testVal){
204 om->stream(Warnings)
205 << "*** ERROR *** DenseMatTraits::" << endl
206 << "Subview did not edit value or did not edit original." << endl;
207 return false;
208 }
209
210 RCP<DM> dm4 = DMT::SubviewCopy(*dm1, numrows-2, numcols-2, 2, 2);
211 if(DMT::ValueConst(*dm4,0,0) != DMT::ValueConst(*dm1,2,2)){
212 om->stream(Warnings)
213 << "*** ERROR *** DenseMatTraits::" << endl
214 << "SubviewCopy failed" << endl;
215 return false;
216 }
217 if(DMT::GetNumRows(*dm4) != numrows-2 ||
218 DMT::GetNumCols(*dm4) != numcols-2){
219 om->stream(Warnings)
220 << "*** ERROR *** DenseMatTraits::" << endl
221 << "SubviewCopy gives wrong dimensions." << endl;
222 return false;
223 }
224 // Try to change a value in the subview.
225 DMT::Value(*dm4,0,0) = testVal-(ScalarType)5;
226 if(DMT::ValueConst(*dm4,0,0) == DMT::ValueConst(*dm1,2,2) ||
227 DMT::ValueConst(*dm4,0,0) != testVal-(ScalarType)5){
228 om->stream(Warnings)
229 << "*** ERROR *** DenseMatTraits::" << endl
230 << "SubviewCopy is incorrect. Possible view but not copy." << endl;
231 return false;
232 }
233 // Try to take a subview of a subview
234 RCP<DM> dm5 = DMT::Subview(*dm3, 1, 1);
235 DMT::Value(*dm5,0,0) = testVal-(ScalarType)10;
236 if (DMT::ValueConst(*dm3,0,0) != DMT::ValueConst(*dm5,0,0) ||
237 DMT::ValueConst(*dm1,1,1) != (testVal-(ScalarType)10)) {
238 om->stream(Warnings)
239 << "*** ERROR *** DenseMatTraits::" << endl
240 << "Subview of a subview is incorrect. Possibly can't take hierarchical subviews." << endl;
241 return false;
242 }
243
244
245 //TODO: Try to add matrices of mismatched size (eg dm3, dm4) and make sure it throws error.
246 //
247 //Try reshaping:
248 //TODO: What should happen if reshape is called on a subview?
249 //Increase Dimensions
250 DMT::Reshape(*dm2, numrows+5, numcols+5);
251 if(DMT::GetNumRows(*dm2) != numrows+5 ||
252 DMT::GetNumCols(*dm2) != numcols+5){
253 om->stream(Warnings)
254 << "*** ERROR *** DenseMatTraits::" << endl
255 << "Reshape test 1 gives wrong dimensions." << endl;
256 return false;
257 }
258 //Decrease dimensions.
259 DMT::Reshape(*dm2, numrows-2, numcols-2);
260 if(DMT::GetNumRows(*dm2) != numrows-2 ||
261 DMT::GetNumCols(*dm2) != numcols-2){
262 om->stream(Warnings)
263 << "*** ERROR *** DenseMatTraits::" << endl
264 << "Reshape test 2 gives wrong dimensions." << endl;
265 return false;
266 }
267 //Increase Dimensions and init to zeros.
268 DMT::Reshape(*dm2, numrows+5, numcols+5, true);
269 if(DMT::GetNumRows(*dm2) != numrows+5 ||
270 DMT::GetNumCols(*dm2) != numcols+5){
271 om->stream(Warnings)
272 << "*** ERROR *** DenseMatTraits::" << endl
273 << "Reshape test 3 gives wrong dimensions." << endl;
274 return false;
275 }
276 if(DMT::ValueConst(*dm2,0,0) != zero || DMT::ValueConst(*dm2,numrows+4,numcols+4) != zero){
277 om->stream(Warnings)
278 << "*** ERROR *** DenseMatTraits::" << endl
279 << "Reshape test 3 does not init to zero." << endl;
280 return false;
281 }
282
283 // Check that we can get a raw pointer from a non-const and const object for BLAS/LAPACK calls
284 DMT::SyncDeviceToHost( *dm2 );
285 ScalarType * testPtr = DMT::GetRawHostPtr(*dm2);
286 if (testPtr == 0) {
287 om->stream(Warnings)
288 << "*** ERROR *** DenseMatTraits::" << endl
289 << "GetRawHostPtr returns NULL." << endl;
290 return false;
291 }
292 RCP<const DM> cdm2 = DMT::SubviewConst(*dm2, DMT::GetNumRows(*dm2), DMT::GetNumCols(*dm2));
293 if(DMT::GetNumRows(*cdm2) != numrows+5 ||
294 DMT::GetNumCols(*cdm2) != numcols+5){
295 om->stream(Warnings)
296 << "*** ERROR *** DenseMatTraits::" << endl
297 << "SubviewConst did not create the right size matrix." << endl;
298 return false;
299 }
300 const ScalarType * testPtr2 = DMT::GetConstRawHostPtr(*cdm2);
301 if (testPtr2 == 0) {
302 om->stream(Warnings)
303 << "*** ERROR *** DenseMatTraits::" << endl
304 << "GetConstRawHostPtr returns NULL." << endl;
305 return false;
306 }
307 //
308 //Compute Frobenius norm. //TODO: Do Frob norm of a matrix we know the answer for and check it.
309 DMT::NormFrobenius(*dm2);
310
311 //TODO: Definitely need testing to check host/device sync semantics.
312 return true;
313 } //end test scope
314 } //end test function
315} //namespace Belos
316
317#endif
Belos header file which uses auto-configuration information to include necessary C++ headers.
Class which manages the output and verbosity of the Belos solvers.
Collection of types and exceptions used within the Belos solvers.
Alternative run-time polymorphic interface for operators.
bool TestDenseMatTraits(const Teuchos::RCP< OutputManager< ScalarType > > &om)
Test correctness of a MultiVecTraits specialization and multivector implementation.

Generated for Belos by doxygen 1.9.8