Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScalarTraits_test.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 
44 #include "Teuchos_ScalarTraits.hpp"
49 #include "Teuchos_Version.hpp"
50 
52 
53 namespace {
54 
55 //
56 // Output of the ordinal that will avoid printing non-asci chars.
57 //
58 // The issue is that if you just print a raw char then if it prints non-asci
59 // character, it can not be printed in some cases and causes trouble with
60 // CTest/CDash.
61 //
62 
63 // For general types, just print the type
64 template <class T>
65 T outputOrdinal(const T &t)
66 {
67  return t;
68 }
69 
70 // For char, print the int value (avoid non-ansi chars)
71 int outputOrdinal(const char& t)
72 {
73  return t;
74 }
75 
76 
77 //
78 // Type outputting
79 //
80 
81 template <class T>
82 void TYPE_CHAIN_A(Teuchos::FancyOStream &out) {
83  typedef typename Teuchos::ScalarTraits<T>::doublePrecision double_type;
84 
85  T b;
86  // double_type d; // unused
87  out << Teuchos::typeName (b);
88  if (! std::is_same_v<T, double_type>) {
89  out << " -> ";
90  TYPE_CHAIN_A<double_type>(out);
91  }
92 }
93 
94 template <class T>
95 void TYPE_CHAIN_D(Teuchos::FancyOStream &out) {
96  typedef typename Teuchos::ScalarTraits<T>::halfPrecision half_type;
97 
98  T b;
99  // half_type d; // unused
100  out << Teuchos::typeName (b);
101 
102  if (! std::is_same_v<T, half_type>) {
103  out << " -> ";
104  TYPE_CHAIN_D<half_type>(out);
105  }
106 }
107 
108 
109 inline std::string passfail(bool result)
110 {
111  return ( result ? "passed" : "failed" );
112 }
113 
114 
115 template<class Scalar>
116 bool testScalarTraits(
118  )
119 {
120 
122 
123  bool success = true;
124 
125  out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";
126 
127  Teuchos::OSTab tab(out);
128 
129  const Scalar nan = ST::nan();
130 
131  out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
132  out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";
133 
134  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(ST::one()), false, out, success);
135 
136  out << "\nTesting that squareroot(NaN) == NaN! ...\n";
137  {
138  const Scalar sqrtNan = ST::squareroot(nan);
139  out << "squareroot("<<nan<<") = " << sqrtNan << "\n";
140  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
141  }
142 
143  out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
144  {
145  const Scalar negNan = -nan;
146  const Scalar sqrtNegNan = ST::squareroot(negNan);
147  out << "squareroot("<<negNan<<") = " << sqrtNegNan << "\n";
148  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegNan), true, out, success);
149  }
150 
151  if (ST::isComplex == false)
152  {
153  out << "\nTesting that squareroot(-1) == NaN! ...\n";
154  {
155  const Scalar negOne = -ST::one();
156  const Scalar sqrtNegOne = ST::squareroot(negOne);
157  out << "squareroot("<<negOne<<") = " << sqrtNegOne << "\n";
158  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegOne), true, out, success);
159  }
160  }
161 
162 #ifdef HAVE_NUMERIC_LIMITS
163 
164  out << "\nTesting that squareroot(quiet_NaN) == NaN! ...\n";
165  {
166  const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
167  const Scalar sqrtNan = ST::squareroot(nan);
168  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
169  }
170 
171  out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
172  {
173  const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
174  const Scalar sqrtNan = ST::squareroot(nan);
175  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
176  }
177 
178  out << "\nTesting that squareroot(inf) == NaN! ...\n";
179  {
180  const Scalar inf = std::numeric_limits<Scalar>::infinity();
181  const Scalar sqrtInf = ST::squareroot(inf);
182  TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtInf), true, out, success);
183  }
184 
185 #endif // HAVE_NUMERIC_LIMITS
186 
187  return success;
188 
189 }
190 
191 
192 template<class Ordinal>
193 bool testOrdinalTraits(
195  )
196 {
197 
199 
200  bool success = true;
201  bool result;
202 
203  out << "\nTesting: " << Teuchos::TypeNameTraits<OT>::name() << " ...\n";
204 
205  Teuchos::OSTab tab(out);
206 
207  const Ordinal zero = OT::zero();
208  const Ordinal one = OT::one();
209  const Ordinal max = OT::max();
210  const Ordinal invalid = OT::invalid();
211  out << "\nmax() == " << outputOrdinal(max) << "\n";
212  out << "\ninvalid() == " << outputOrdinal(invalid) << "\n";
213 
214  out << "\nTesting that zero() * one() == zero() ...\n";
215  {
216  const Ordinal zto = zero*one;
217  result = (zto == zero);
218  if (!result) success = false;
219  out
220  << "zero*one = " << outputOrdinal(zto) << " == " << outputOrdinal(zero) << " : "
221  << passfail(result) << "\n";
222  }
223 
224  out << "\nTesting that one() * one() == one() ...\n";
225  {
226  const Ordinal oto = one*one;
227  result = (oto == one);
228  if (!result) success = false;
229  out
230  << "one*one = " << outputOrdinal(oto) << " == " << outputOrdinal(one) << " : "
231  << passfail(result) << "\n";
232  }
233 
234  out << "\nTesting that one() + zero() == zero() + one() == one() ...\n";
235  {
236  const Ordinal opz = one+zero;
237  const Ordinal zpo = zero+one;
238  result = (opz == one) && (zpo == one);
239  if (!result) success = false;
240  out
241  << "one+zero = " << outputOrdinal(opz) << " == zero+one = "
242  << outputOrdinal(zpo) << " == " << outputOrdinal(one) << " : "
243  << passfail(result) << "\n";
244  }
245 
246  out << "\nTesting that one() - one() == zero() ...\n";
247  {
248  const Ordinal omo = one-one;
249  result = (omo == zero);
250  if (!result) success = false;
251  out
252  << "one-one = " << outputOrdinal(omo) << " == " << outputOrdinal(zero) << " : "
253  << passfail(result) << "\n";
254  }
255 
256  out << "\nTesting that zero() < one() <= max() ...\n";
257  {
258  result = (zero < one) && (one <= max) && (zero < max);
259  if (!result) success = false;
260  out
261  << "(zero < one) = " << (zero < one) << " == "
262  << "(one <= max) = " << (one <= max) << " == "
263  << "(zero < max) = " << (zero < max) << " == "
264  << true << " : "
265  << passfail(result) << "\n";
266  }
267 
268  out << "\nTesting that invalid() not in [zero(),max()]...\n";
269  {
270  result = !( (invalid > zero || invalid==zero) && (invalid <= max) );
271  if (!result) success = false;
272  out
273  << "invalid in [zero,max] == false : " << passfail(result) << "\n";
274  }
275 
276  return success;
277 
278 }
279 
280 
281 } // namespace
282 
283 
284 int main( int argc, char* argv[] ) {
285 
287 
288  bool success = true;
289  bool result;
290 
291  Teuchos::GlobalMPISession mpiSession(&argc,&argv);
292  //const int procRank = Teuchos::GlobalMPISession::getRank();
293 
296 
297  try {
298 
299  // Read options from the commandline
300  CommandLineProcessor clp(false); // Don't throw exceptions
301  CommandLineProcessor::EParseCommandLineReturn parse_return = clp.parse(argc,argv);
302  if( parse_return != CommandLineProcessor::PARSE_SUCCESSFUL ) {
303  *out << "\nEnd Result: TEST FAILED" << std::endl;
304  return parse_return;
305  }
306 
307  result = testScalarTraits<float>(*out);
308  if(!result) success = false;
309 
310  result = testScalarTraits<double>(*out);
311  if(!result) success = false;
312 
313  result = testOrdinalTraits<char>(*out);
314  if(!result) success = false;
315 
316  result = testOrdinalTraits<short int>(*out);
317  if(!result) success = false;
318 
319  result = testOrdinalTraits<int>(*out);
320  if(!result) success = false;
321 
322  result = testOrdinalTraits<long int>(*out);
323  if(!result) success = false;
324 
325  result = testOrdinalTraits<size_t>(*out);
326  if(!result) success = false;
327 
328  result = testOrdinalTraits<long long int>(*out);
329  if(!result) success = false;
330 
331 #ifdef HAVE_TEUCHOS___INT64
332  result = testOrdinalTraits<__int64>(*out);
333  if(!result) success = false;
334 
335  result = testOrdinalTraits<unsigned __int64>(*out);
336  if(!result) success = false;
337 #endif
338 
339 #ifdef HAVE_TEUCHOS_COMPLEX
340  result = testScalarTraits<std::complex<double> >(*out);
341  if(!result) success = false;
342 
343  result = testScalarTraits<std::complex<float> >(*out);
344  if(!result) success = false;
345 #endif // HAVE_TEUCHOS_COMPLEX
346 
347 #ifdef HAVE_TEUCHOSCORE_KOKKOS
348  result = testScalarTraits<Kokkos::complex<double> >(*out);
349  if(!result) success = false;
350 
351  result = testScalarTraits<Kokkos::complex<float> >(*out);
352  if(!result) success = false;
353 #endif // HAVE_TEUCHOSCORE_KOKKOS
354 
355 #ifdef HAVE_TEUCHOSCORE_QUADMATH
356  result = testScalarTraits<__float128>(*out);
357  if(!result) success = false;
358 #endif // HAVE_TEUCHOSCORE_QUADMATH
359 
360 #ifdef HAVE_TEUCHOS_QD
361  result = testScalarTraits<dd_real>(*out);
362  if(!result) success = false;
363  result = testScalarTraits<qd_real>(*out);
364  if(!result) success = false;
365 #endif
366 
367  }
368  TEUCHOS_STANDARD_CATCH_STATEMENTS(true,std::cerr,success);
369 
370  if(success)
371  *out << "\nEnd Result: TEST PASSED\n" << std::endl;
372  else
373  *out << "\nEnd Result: TEST FAILED\n" << std::endl;
374 
375  return ( success ? 0 : 1 );
376 
377 }
std::string typeName(const T &t)
Template function for returning the concrete type name of a passed-in object.
#define TEUCHOS_TEST_EQUALITY_CONST(v1, v2, out, success)
Test that an object is equal to a given constant.
Tabbing class for helping to create formated, indented output for a basic_FancyOStream object...
Initialize, finalize, and query the global MPI session.
const std::string passfail(const bool result)
Return &quot;passed&quot; or &quot;failed&quot;.
This structure defines some basic traits for a scalar field type.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
#define TEUCHOS_STANDARD_CATCH_STATEMENTS(VERBOSE, ERR_STREAM, SUCCESS_FLAG)
Simple macro that catches and reports standard exceptions and other exceptions.
static RCP< FancyOStream > getDefaultOStream()
Get the default output stream object.
This structure defines some basic traits for the ordinal field type.
T doublePrecision
Typedef for double precision.
int main(int argc, char *argv[])
Utilities to make writing tests easier.
Defines basic traits for the ordinal field type.
A MPI utilities class, providing methods for initializing, finalizing, and querying the global MPI se...
Basic command line parser for input from (argc,argv[])
Defines basic traits for the scalar field type.
Smart reference counting pointer class for automatic garbage collection.
T halfPrecision
Typedef for half precision.
RCP< basic_FancyOStream< CharT, Traits > > tab(const RCP< basic_FancyOStream< CharT, Traits > > &out, const int tabs=1, const std::basic_string< CharT, Traits > linePrefix="")
Create a tab for an RCP-wrapped basic_FancyOStream object to cause the indentation of all output auto...
Class that helps parse command line input arguments from (argc,argv[]) and set options.