2014-02-10 18:58:41 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
|
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
2014-02-10 18:58:41 +00:00
|
|
|
// Copyright 2014 UT-Battelle, LLC.
|
2015-05-21 12:09:22 +00:00
|
|
|
// Copyright 2014 Los Alamos National Security.
|
2014-02-10 18:58:41 +00:00
|
|
|
//
|
2017-09-20 21:33:44 +00:00
|
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
2014-02-10 18:58:41 +00:00
|
|
|
// the U.S. Government retains certain rights in this software.
|
|
|
|
//
|
|
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
|
|
// this software.
|
|
|
|
//============================================================================
|
2014-03-07 15:19:09 +00:00
|
|
|
#ifndef vtk_m_testing_Testing_h
|
|
|
|
#define vtk_m_testing_Testing_h
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2019-01-01 19:57:54 +00:00
|
|
|
#include <vtkm/Bitset.h>
|
2016-05-26 22:02:30 +00:00
|
|
|
#include <vtkm/Bounds.h>
|
2015-08-16 21:31:36 +00:00
|
|
|
#include <vtkm/CellShape.h>
|
2015-09-24 22:48:03 +00:00
|
|
|
#include <vtkm/Math.h>
|
2016-12-05 21:41:33 +00:00
|
|
|
#include <vtkm/Matrix.h>
|
2015-05-05 18:25:48 +00:00
|
|
|
#include <vtkm/Pair.h>
|
2016-05-26 22:02:30 +00:00
|
|
|
#include <vtkm/Range.h>
|
2014-10-08 22:56:33 +00:00
|
|
|
#include <vtkm/TypeListTag.h>
|
2014-02-10 18:58:41 +00:00
|
|
|
#include <vtkm/TypeTraits.h>
|
2017-05-18 14:51:24 +00:00
|
|
|
#include <vtkm/Types.h>
|
2014-10-07 23:27:31 +00:00
|
|
|
#include <vtkm/VecTraits.h>
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2015-08-28 18:19:46 +00:00
|
|
|
#include <exception>
|
2014-02-10 18:58:41 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
2016-12-05 21:41:33 +00:00
|
|
|
#include <type_traits>
|
2014-02-10 18:58:41 +00:00
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
// Try to enforce using the correct testing version. (Those that include the
|
|
|
|
// control environment have more possible exceptions.) This is not guaranteed
|
|
|
|
// to work. To make it more likely, place the Testing.h include last.
|
2014-06-11 16:43:36 +00:00
|
|
|
#ifdef vtk_m_cont_Error_h
|
2014-03-07 15:19:09 +00:00
|
|
|
#ifndef vtk_m_cont_testing_Testing_h
|
2014-02-10 18:58:41 +00:00
|
|
|
#error Use vtkm::cont::testing::Testing instead of vtkm::testing::Testing.
|
|
|
|
#else
|
|
|
|
#define VTKM_TESTING_IN_CONT
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
/// \def VTKM_STRINGIFY_FIRST(...)
|
|
|
|
///
|
|
|
|
/// A utility macro that takes 1 or more arguments and converts it into the C string version
|
|
|
|
/// of the first argument.
|
|
|
|
|
|
|
|
#define VTKM_STRINGIFY_FIRST(...) VTKM_EXPAND(VTK_M_STRINGIFY_FIRST_IMPL(__VA_ARGS__, dummy))
|
|
|
|
#define VTK_M_STRINGIFY_FIRST_IMPL(first, ...) #first
|
|
|
|
#define VTKM_EXPAND(x) x
|
|
|
|
|
|
|
|
/// \def VTKM_TEST_ASSERT(condition, messages..)
|
2014-02-10 18:58:41 +00:00
|
|
|
///
|
|
|
|
/// Asserts a condition for a test to pass. A passing condition is when \a
|
|
|
|
/// condition resolves to true. If \a condition is false, then the test is
|
2018-10-05 19:00:42 +00:00
|
|
|
/// aborted and failure is returned. If one or more message arguments are
|
|
|
|
/// given, they are printed out by concatinating them. If no messages are
|
|
|
|
/// given, a generic message is given. In any case, the condition that failed
|
|
|
|
/// is written out.
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
#define VTKM_TEST_ASSERT(...) \
|
|
|
|
::vtkm::testing::Testing::Assert( \
|
|
|
|
VTKM_STRINGIFY_FIRST(__VA_ARGS__), __FILE__, __LINE__, __VA_ARGS__)
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
/// \def VTKM_TEST_FAIL(messages..)
|
2014-02-10 18:58:41 +00:00
|
|
|
///
|
2018-10-05 19:00:42 +00:00
|
|
|
/// Causes a test to fail with the given \a messages. At least one argument must be given.
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
#define VTKM_TEST_FAIL(...) ::vtkm::testing::Testing::TestFail(__FILE__, __LINE__, __VA_ARGS__)
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace testing
|
|
|
|
{
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2014-10-08 21:40:20 +00:00
|
|
|
// If you get an error about this class definition being incomplete, it means
|
|
|
|
// that you tried to get the name of a type that is not specified. You can
|
|
|
|
// either not use that type, not try to get the string name, or add it to the
|
|
|
|
// list.
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2014-10-08 21:40:20 +00:00
|
|
|
struct TypeName;
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
#define VTK_M_BASIC_TYPE(type) \
|
|
|
|
template <> \
|
|
|
|
struct TypeName<type> \
|
|
|
|
{ \
|
|
|
|
static std::string Name() { return #type; } \
|
|
|
|
}
|
2014-10-08 21:40:20 +00:00
|
|
|
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Float32);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Float64);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Int8);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::UInt8);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Int16);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::UInt16);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Int32);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::UInt32);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Int64);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::UInt64);
|
|
|
|
|
2019-01-01 19:57:54 +00:00
|
|
|
VTK_M_BASIC_TYPE(vtkm::Bounds);
|
|
|
|
VTK_M_BASIC_TYPE(vtkm::Range);
|
|
|
|
|
2014-10-10 15:53:13 +00:00
|
|
|
#undef VTK_M_BASIC_TYPE
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T, vtkm::IdComponent Size>
|
|
|
|
struct TypeName<vtkm::Vec<T, Size>>
|
2014-10-08 21:40:20 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
static std::string Name()
|
|
|
|
{
|
2014-10-08 21:40:20 +00:00
|
|
|
std::stringstream stream;
|
2017-05-18 14:29:41 +00:00
|
|
|
stream << "vtkm::Vec< " << TypeName<T>::Name() << ", " << Size << " >";
|
2014-10-08 21:40:20 +00:00
|
|
|
return stream.str();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T, typename U>
|
|
|
|
struct TypeName<vtkm::Pair<T, U>>
|
2015-05-05 18:25:48 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
static std::string Name()
|
|
|
|
{
|
2015-05-05 18:25:48 +00:00
|
|
|
std::stringstream stream;
|
2017-05-18 14:29:41 +00:00
|
|
|
stream << "vtkm::Pair< " << TypeName<T>::Name() << ", " << TypeName<U>::Name() << " >";
|
2015-05-05 18:25:48 +00:00
|
|
|
return stream.str();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-01-01 19:57:54 +00:00
|
|
|
template <typename T>
|
|
|
|
struct TypeName<vtkm::Bitset<T>>
|
|
|
|
{
|
|
|
|
static std::string Name()
|
|
|
|
{
|
|
|
|
std::stringstream stream;
|
|
|
|
stream << "vtkm::Bitset< " << TypeName<T>::Name() << " >";
|
|
|
|
return stream.str();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace detail
|
|
|
|
{
|
2015-08-16 21:31:36 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <vtkm::IdComponent cellShapeId>
|
2015-08-16 21:31:36 +00:00
|
|
|
struct InternalTryCellShape
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
|
|
|
void operator()(const FunctionType& function) const
|
|
|
|
{
|
|
|
|
this->PrintAndInvoke(function, typename vtkm::CellShapeIdToTag<cellShapeId>::valid());
|
|
|
|
InternalTryCellShape<cellShapeId + 1>()(function);
|
2015-08-16 21:31:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
|
|
|
void PrintAndInvoke(const FunctionType& function, std::true_type) const
|
|
|
|
{
|
2017-06-23 18:50:34 +00:00
|
|
|
using CellShapeTag = typename vtkm::CellShapeIdToTag<cellShapeId>::Tag;
|
2017-05-18 14:29:41 +00:00
|
|
|
std::cout << "*** " << vtkm::GetCellShapeName(CellShapeTag()) << " ***************"
|
|
|
|
<< std::endl;
|
2015-08-16 21:31:36 +00:00
|
|
|
function(CellShapeTag());
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
|
|
|
void PrintAndInvoke(const FunctionType&, std::false_type) const
|
|
|
|
{
|
2015-08-16 21:31:36 +00:00
|
|
|
// Not a valid cell shape. Do nothing.
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <>
|
2015-08-16 21:31:36 +00:00
|
|
|
struct InternalTryCellShape<vtkm::NUMBER_OF_CELL_SHAPES>
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
|
|
|
void operator()(const FunctionType&) const
|
|
|
|
{
|
2015-08-16 21:31:36 +00:00
|
|
|
// Done processing cell sets. Do nothing and return.
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace detail
|
2014-10-14 16:00:34 +00:00
|
|
|
|
2014-02-10 18:58:41 +00:00
|
|
|
struct Testing
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
class TestFailure
|
|
|
|
{
|
|
|
|
public:
|
2018-10-05 19:00:42 +00:00
|
|
|
template <typename... Ts>
|
|
|
|
VTKM_CONT TestFailure(const std::string& file, vtkm::Id line, Ts&&... messages)
|
2017-05-18 14:29:41 +00:00
|
|
|
: File(file)
|
|
|
|
, Line(line)
|
2014-02-10 18:58:41 +00:00
|
|
|
{
|
2018-10-05 19:00:42 +00:00
|
|
|
std::stringstream messageStream;
|
|
|
|
this->AppendMessages(messageStream, std::forward<Ts>(messages)...);
|
|
|
|
this->Message = messageStream.str();
|
2014-02-10 18:58:41 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT const std::string& GetFile() const { return this->File; }
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT vtkm::Id GetLine() const { return this->Line; }
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT const std::string& GetMessage() const { return this->Message; }
|
2014-02-10 18:58:41 +00:00
|
|
|
private:
|
2018-10-05 19:00:42 +00:00
|
|
|
template <typename T1>
|
|
|
|
VTKM_CONT void AppendMessages(std::stringstream& messageStream, T1&& m1)
|
|
|
|
{
|
|
|
|
messageStream << m1;
|
|
|
|
}
|
|
|
|
template <typename T1, typename T2>
|
|
|
|
VTKM_CONT void AppendMessages(std::stringstream& messageStream, T1&& m1, T2&& m2)
|
|
|
|
{
|
|
|
|
messageStream << m1 << m2;
|
|
|
|
}
|
|
|
|
template <typename T1, typename T2, typename T3>
|
|
|
|
VTKM_CONT void AppendMessages(std::stringstream& messageStream, T1&& m1, T2&& m2, T3&& m3)
|
|
|
|
{
|
|
|
|
messageStream << m1 << m2 << m3;
|
|
|
|
}
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4>
|
|
|
|
VTKM_CONT void AppendMessages(std::stringstream& messageStream,
|
|
|
|
T1&& m1,
|
|
|
|
T2&& m2,
|
|
|
|
T3&& m3,
|
|
|
|
T4&& m4)
|
|
|
|
{
|
|
|
|
messageStream << m1 << m2 << m3 << m4;
|
|
|
|
}
|
|
|
|
template <typename T1, typename T2, typename T3, typename T4, typename... Ts>
|
|
|
|
VTKM_CONT void AppendMessages(std::stringstream& messageStream,
|
|
|
|
T1&& m1,
|
|
|
|
T2&& m2,
|
|
|
|
T3&& m3,
|
|
|
|
T4&& m4,
|
|
|
|
Ts&&... ms)
|
|
|
|
{
|
|
|
|
messageStream << m1 << m2 << m3 << m4;
|
|
|
|
this->AppendMessages(messageStream, std::forward<Ts>(ms)...);
|
|
|
|
}
|
|
|
|
|
2014-02-10 18:58:41 +00:00
|
|
|
std::string File;
|
|
|
|
vtkm::Id Line;
|
|
|
|
std::string Message;
|
|
|
|
};
|
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
template <typename... Ts>
|
|
|
|
static VTKM_CONT void Assert(const std::string& conditionString,
|
2017-05-26 17:53:28 +00:00
|
|
|
const std::string& file,
|
|
|
|
vtkm::Id line,
|
2018-10-05 19:00:42 +00:00
|
|
|
bool condition,
|
|
|
|
Ts&&... messages)
|
2014-02-10 18:58:41 +00:00
|
|
|
{
|
|
|
|
if (condition)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-10 18:58:41 +00:00
|
|
|
// Do nothing.
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
else
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2018-10-05 19:00:42 +00:00
|
|
|
throw TestFailure(file, line, std::forward<Ts>(messages)..., " (", conditionString, ")");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
}
|
|
|
|
|
2018-10-05 19:00:42 +00:00
|
|
|
static VTKM_CONT void Assert(const std::string& conditionString,
|
|
|
|
const std::string& file,
|
|
|
|
vtkm::Id line,
|
|
|
|
bool condition)
|
|
|
|
{
|
|
|
|
Assert(conditionString, file, line, condition, "Test assertion failed");
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename... Ts>
|
|
|
|
static VTKM_CONT void TestFail(const std::string& file, vtkm::Id line, Ts&&... messages)
|
|
|
|
{
|
|
|
|
throw TestFailure(file, line, std::forward<Ts>(messages)...);
|
|
|
|
}
|
|
|
|
|
2014-02-10 18:58:41 +00:00
|
|
|
#ifndef VTKM_TESTING_IN_CONT
|
|
|
|
/// Calls the test function \a function with no arguments. Catches any errors
|
|
|
|
/// generated by VTKM_TEST_ASSERT or VTKM_TEST_FAIL, reports the error, and
|
|
|
|
/// returns "1" (a failure status for a program's main). Returns "0" (a
|
|
|
|
/// success status for a program's main).
|
|
|
|
///
|
|
|
|
/// The intention is to implement a test's main function with this. For
|
|
|
|
/// example, the implementation of UnitTestFoo might look something like
|
|
|
|
/// this.
|
|
|
|
///
|
|
|
|
/// \code
|
|
|
|
/// #include <vtkm/testing/Testing.h>
|
|
|
|
///
|
|
|
|
/// namespace {
|
|
|
|
///
|
|
|
|
/// void TestFoo()
|
|
|
|
/// {
|
|
|
|
/// // Do actual test, which checks in VTKM_TEST_ASSERT or VTKM_TEST_FAIL.
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// } // anonymous namespace
|
|
|
|
///
|
|
|
|
/// int UnitTestFoo(int, char *[])
|
|
|
|
/// {
|
|
|
|
/// return vtkm::testing::Testing::Run(TestFoo);
|
|
|
|
/// }
|
|
|
|
/// \endcode
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <class Func>
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT int Run(Func function)
|
2014-02-10 18:58:41 +00:00
|
|
|
{
|
|
|
|
try
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-10 18:58:41 +00:00
|
|
|
function();
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
catch (TestFailure& error)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
std::cout << "***** Test failed @ " << error.GetFile() << ":" << error.GetLine() << std::endl
|
2014-02-10 18:58:41 +00:00
|
|
|
<< error.GetMessage() << std::endl;
|
|
|
|
return 1;
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
catch (std::exception& error)
|
2015-08-28 18:19:46 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
std::cout << "***** STL exception throw." << std::endl << error.what() << std::endl;
|
2015-08-28 18:19:46 +00:00
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
catch (...)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-10 18:58:41 +00:00
|
|
|
std::cout << "***** Unidentified exception thrown." << std::endl;
|
|
|
|
return 1;
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
2014-10-08 22:56:33 +00:00
|
|
|
struct InternalPrintTypeAndInvoke
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
InternalPrintTypeAndInvoke(FunctionType function)
|
|
|
|
: Function(function)
|
|
|
|
{
|
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2014-10-08 22:56:33 +00:00
|
|
|
void operator()(T t) const
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " ***************" << std::endl;
|
2014-02-10 18:58:41 +00:00
|
|
|
this->Function(t);
|
|
|
|
}
|
2014-10-08 22:56:33 +00:00
|
|
|
|
2014-02-10 18:58:41 +00:00
|
|
|
private:
|
|
|
|
FunctionType Function;
|
|
|
|
};
|
|
|
|
|
2016-08-24 22:02:18 +00:00
|
|
|
/// Runs template \p function on all the types in the given list. If no type
|
|
|
|
/// list is given, then an exemplar list of types is used.
|
2014-02-10 18:58:41 +00:00
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType, typename TypeList>
|
|
|
|
static void TryTypes(const FunctionType& function, TypeList)
|
2014-02-10 18:58:41 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::ListForEach(InternalPrintTypeAndInvoke<FunctionType>(function), TypeList());
|
2014-02-10 18:58:41 +00:00
|
|
|
}
|
2014-10-08 22:56:33 +00:00
|
|
|
|
2016-08-24 22:02:18 +00:00
|
|
|
struct TypeListTagExemplarTypes
|
2017-05-18 14:29:41 +00:00
|
|
|
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Id, vtkm::FloatDefault, vtkm::Vec<vtkm::Float64, 3>>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename FunctionType>
|
|
|
|
static void TryTypes(const FunctionType& function)
|
2014-02-10 18:58:41 +00:00
|
|
|
{
|
2016-08-24 22:02:18 +00:00
|
|
|
TryTypes(function, TypeListTagExemplarTypes());
|
2014-02-10 18:58:41 +00:00
|
|
|
}
|
|
|
|
|
2016-08-24 22:02:18 +00:00
|
|
|
// Disabled: This very long list results is very long compile times.
|
2017-05-18 14:29:41 +00:00
|
|
|
// /// Runs templated \p function on all the basic types defined in VTK-m. This
|
|
|
|
// /// is helpful to test templated functions that should work on all types. If
|
|
|
|
// /// the function is supposed to work on some subset of types, then use
|
|
|
|
// /// \c TryTypes to restrict the call to some other list of types.
|
|
|
|
// ///
|
|
|
|
// template<typename FunctionType>
|
|
|
|
// static void TryAllTypes(const FunctionType &function)
|
|
|
|
// {
|
|
|
|
// TryTypes(function, vtkm::TypeListTagAll());
|
|
|
|
// }
|
2016-08-24 22:02:18 +00:00
|
|
|
|
2015-08-16 21:31:36 +00:00
|
|
|
/// Runs templated \p function on all cell shapes defined in VTK-m. This is
|
|
|
|
/// helpful to test templated functions that should work on all cell types.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FunctionType>
|
|
|
|
static void TryAllCellShapes(const FunctionType& function)
|
2015-08-16 21:31:36 +00:00
|
|
|
{
|
|
|
|
detail::InternalTryCellShape<0>()(function);
|
|
|
|
}
|
2014-02-10 18:58:41 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
} // namespace vtkm::internal
|
|
|
|
|
2016-12-05 21:41:33 +00:00
|
|
|
// Prototype declaration
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename VectorType1, typename VectorType2>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal(VectorType1 vector1,
|
|
|
|
VectorType2 vector2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance = 0.00001);
|
|
|
|
|
|
|
|
namespace detail
|
|
|
|
{
|
|
|
|
|
|
|
|
template <typename VectorType1, typename VectorType2>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal_impl(VectorType1 vector1,
|
|
|
|
VectorType2 vector2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance,
|
|
|
|
vtkm::TypeTraitsVectorTag)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
// If you get a compiler error here, it means you are comparing a vector to
|
|
|
|
// a scalar, in which case the types are non-comparable.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_STATIC_ASSERT_MSG((std::is_same<typename vtkm::TypeTraits<VectorType2>::DimensionalityTag,
|
|
|
|
vtkm::TypeTraitsScalarTag>::type::value == false),
|
|
|
|
"Trying to compare a vector with a scalar.");
|
2016-12-05 21:41:33 +00:00
|
|
|
|
|
|
|
using Traits1 = vtkm::VecTraits<VectorType1>;
|
|
|
|
using Traits2 = vtkm::VecTraits<VectorType2>;
|
|
|
|
|
|
|
|
// If vectors have different number of components, then they cannot be equal.
|
2017-05-18 14:29:41 +00:00
|
|
|
if (Traits1::GetNumberOfComponents(vector1) != Traits2::GetNumberOfComponents(vector2))
|
2015-08-12 23:32:19 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-10-08 22:56:33 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::IdComponent component = 0; component < Traits1::GetNumberOfComponents(vector1);
|
2014-10-07 16:59:34 +00:00
|
|
|
component++)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
bool componentEqual = test_equal(Traits1::GetComponent(vector1, component),
|
2017-05-26 17:53:28 +00:00
|
|
|
Traits2::GetComponent(vector2, component),
|
|
|
|
tolerance);
|
2016-12-05 21:41:33 +00:00
|
|
|
if (!componentEqual)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-10 18:58:41 +00:00
|
|
|
return false;
|
|
|
|
}
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2016-12-05 21:41:33 +00:00
|
|
|
|
2014-02-10 18:58:41 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename MatrixType1, typename MatrixType2>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal_impl(MatrixType1 matrix1,
|
|
|
|
MatrixType2 matrix2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance,
|
|
|
|
vtkm::TypeTraitsMatrixTag)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
// For the purposes of comparison, treat matrices the same as vectors.
|
2017-05-18 14:29:41 +00:00
|
|
|
return test_equal_impl(matrix1, matrix2, tolerance, vtkm::TypeTraitsVectorTag());
|
2016-12-05 21:41:33 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename ScalarType1, typename ScalarType2>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal_impl(ScalarType1 scalar1,
|
|
|
|
ScalarType2 scalar2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance,
|
|
|
|
vtkm::TypeTraitsScalarTag)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
// If you get a compiler error here, it means you are comparing a scalar to
|
|
|
|
// a vector, in which case the types are non-comparable.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_STATIC_ASSERT_MSG((std::is_same<typename vtkm::TypeTraits<ScalarType2>::DimensionalityTag,
|
|
|
|
vtkm::TypeTraitsScalarTag>::type::value),
|
|
|
|
"Trying to compare a scalar with a vector.");
|
2016-12-05 21:41:33 +00:00
|
|
|
|
2018-01-30 00:24:31 +00:00
|
|
|
// Do all comparisons using 64-bit floats.
|
2016-12-05 21:41:33 +00:00
|
|
|
vtkm::Float64 value1 = vtkm::Float64(scalar1);
|
|
|
|
vtkm::Float64 value2 = vtkm::Float64(scalar2);
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
if (vtkm::Abs(value1 - value2) <= tolerance)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We are using a ratio to compare the relative tolerance of two numbers.
|
|
|
|
// Using an ULP based comparison (comparing the bits as integers) might be
|
|
|
|
// a better way to go, but this has been working pretty well so far.
|
|
|
|
vtkm::Float64 ratio;
|
|
|
|
if ((vtkm::Abs(value2) > tolerance) && (value2 != 0))
|
|
|
|
{
|
|
|
|
ratio = value1 / value2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If we are here, it means that value2 is close to 0 but value1 is not.
|
|
|
|
// These cannot be within tolerance, so just return false.
|
|
|
|
return false;
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
if ((ratio > vtkm::Float64(1.0) - tolerance) && (ratio < vtkm::Float64(1.0) + tolerance))
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
// This component is OK. The condition is checked in this way to
|
|
|
|
// correctly handle non-finites that fail all comparisons. Thus, if a
|
|
|
|
// non-finite is encountered, this condition will fail and false will be
|
|
|
|
// returned.
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Special cases of test equal where a scalar is compared with a Vec of size 1,
|
|
|
|
// which we will allow.
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal_impl(vtkm::Vec<T, 1> value1,
|
|
|
|
T value2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance,
|
|
|
|
vtkm::TypeTraitsVectorTag)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
return test_equal(value1[0], value2, tolerance);
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal_impl(T value1,
|
|
|
|
vtkm::Vec<T, 1> value2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance,
|
|
|
|
vtkm::TypeTraitsScalarTag)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
|
|
|
return test_equal(value1, value2[0], tolerance);
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace detail
|
|
|
|
|
|
|
|
/// Helper function to test two quanitites for equality accounting for slight
|
|
|
|
/// variance due to floating point numerical inaccuracies.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename VectorType1, typename VectorType2>
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal(VectorType1 vector1,
|
|
|
|
VectorType2 vector2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance /*= 0.00001*/)
|
2016-12-05 21:41:33 +00:00
|
|
|
{
|
2017-05-26 17:53:28 +00:00
|
|
|
return detail::test_equal_impl(
|
|
|
|
vector1, vector2, tolerance, typename vtkm::TypeTraits<VectorType1>::DimensionalityTag());
|
2016-12-05 21:41:33 +00:00
|
|
|
}
|
|
|
|
|
2014-07-10 16:53:02 +00:00
|
|
|
/// Special implementation of test_equal for strings, which don't fit a model
|
|
|
|
/// of fixed length vectors of numbers.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
static inline VTKM_CONT bool test_equal(const std::string& string1, const std::string& string2)
|
2014-07-10 16:53:02 +00:00
|
|
|
{
|
|
|
|
return string1 == string2;
|
|
|
|
}
|
|
|
|
|
2015-05-07 22:34:06 +00:00
|
|
|
/// Special implementation of test_equal for Pairs, which are a bit different
|
|
|
|
/// than a vector of numbers of the same type.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T1, typename T2, typename T3, typename T4>
|
|
|
|
static inline VTKM_CONT bool test_equal(const vtkm::Pair<T1, T2>& pair1,
|
|
|
|
const vtkm::Pair<T3, T4>& pair2,
|
|
|
|
vtkm::Float64 tolerance = 0.0001)
|
2015-05-07 22:34:06 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return test_equal(pair1.first, pair2.first, tolerance) &&
|
|
|
|
test_equal(pair1.second, pair2.second, tolerance);
|
2015-05-07 22:34:06 +00:00
|
|
|
}
|
|
|
|
|
2016-05-26 22:02:30 +00:00
|
|
|
/// Special implementation of test_equal for Ranges.
|
|
|
|
///
|
2017-05-26 17:53:28 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal(const vtkm::Range& range1,
|
|
|
|
const vtkm::Range& range2,
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 tolerance = 0.0001)
|
2016-05-26 22:02:30 +00:00
|
|
|
{
|
|
|
|
return (test_equal(range1.Min, range2.Min, tolerance) &&
|
|
|
|
test_equal(range1.Max, range2.Max, tolerance));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Special implementation of test_equal for Bounds.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
static inline VTKM_EXEC_CONT bool test_equal(const vtkm::Bounds& bounds1,
|
|
|
|
const vtkm::Bounds& bounds2,
|
|
|
|
vtkm::Float64 tolerance = 0.0001)
|
2016-05-26 22:02:30 +00:00
|
|
|
{
|
|
|
|
return (test_equal(bounds1.X, bounds2.X, tolerance) &&
|
|
|
|
test_equal(bounds1.Y, bounds2.Y, tolerance) &&
|
|
|
|
test_equal(bounds1.Z, bounds2.Z, tolerance));
|
|
|
|
}
|
|
|
|
|
2017-07-11 12:33:56 +00:00
|
|
|
/// Special implementation of test_equal for booleans.
|
|
|
|
///
|
|
|
|
static inline VTKM_EXEC_CONT bool test_equal(bool bool1, bool bool2)
|
|
|
|
{
|
|
|
|
return bool1 == bool2;
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
static inline VTKM_EXEC_CONT T TestValue(vtkm::Id index, T, vtkm::TypeTraitsIntegerTag)
|
2014-10-14 16:00:34 +00:00
|
|
|
{
|
2018-02-22 16:34:08 +00:00
|
|
|
constexpr bool larger_than_2bytes = sizeof(T) > 2;
|
2017-09-21 14:33:17 +00:00
|
|
|
if (larger_than_2bytes)
|
2016-12-16 21:25:09 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return T(index * 100);
|
2016-12-16 21:25:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return T(index + 100);
|
2016-12-16 21:25:09 +00:00
|
|
|
}
|
2014-10-14 16:00:34 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
static inline VTKM_EXEC_CONT T TestValue(vtkm::Id index, T, vtkm::TypeTraitsRealTag)
|
2014-10-14 16:00:34 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
return T(0.01 * static_cast<double>(index) + 1.001);
|
2014-10-14 16:00:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Many tests involve getting and setting values in some index-based structure
|
|
|
|
/// (like an array). These tests also often involve trying many types. The
|
|
|
|
/// overloaded TestValue function returns some unique value for an index for a
|
|
|
|
/// given type. Different types might give different values.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
|
|
|
static inline VTKM_EXEC_CONT T TestValue(vtkm::Id index, T)
|
2014-10-14 16:00:34 +00:00
|
|
|
{
|
|
|
|
return TestValue(index, T(), typename vtkm::TypeTraits<T>::NumericTag());
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T, vtkm::IdComponent N>
|
|
|
|
static inline VTKM_EXEC_CONT vtkm::Vec<T, N> TestValue(vtkm::Id index, vtkm::Vec<T, N>)
|
|
|
|
{
|
|
|
|
vtkm::Vec<T, N> value;
|
2014-10-14 16:00:34 +00:00
|
|
|
for (vtkm::IdComponent i = 0; i < N; i++)
|
|
|
|
{
|
2015-07-30 22:43:19 +00:00
|
|
|
value[i] = T(TestValue(index, T()) + T(i + 1));
|
2014-10-14 16:00:34 +00:00
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2017-10-17 19:50:19 +00:00
|
|
|
template <typename U, typename V>
|
|
|
|
static inline VTKM_EXEC_CONT vtkm::Pair<U, V> TestValue(vtkm::Id index, vtkm::Pair<U, V>)
|
|
|
|
{
|
|
|
|
return vtkm::Pair<U, V>(TestValue(2 * index, U()), TestValue(2 * index + 1, V()));
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
static inline VTKM_CONT std::string TestValue(vtkm::Id index, std::string)
|
|
|
|
{
|
2014-10-14 16:00:34 +00:00
|
|
|
std::stringstream stream;
|
|
|
|
stream << index;
|
|
|
|
return stream.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verifies that the contents of the given array portal match the values
|
|
|
|
/// returned by vtkm::testing::TestValue.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename PortalType>
|
|
|
|
static inline VTKM_CONT void CheckPortal(const PortalType& portal)
|
2014-10-14 16:00:34 +00:00
|
|
|
{
|
2017-06-23 18:50:34 +00:00
|
|
|
using ValueType = typename PortalType::ValueType;
|
2014-10-14 16:00:34 +00:00
|
|
|
|
|
|
|
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
|
|
|
|
{
|
|
|
|
ValueType expectedValue = TestValue(index, ValueType());
|
|
|
|
ValueType foundValue = portal.Get(index);
|
|
|
|
if (!test_equal(expectedValue, foundValue))
|
|
|
|
{
|
|
|
|
std::stringstream message;
|
|
|
|
message << "Got unexpected value in array." << std::endl
|
2017-05-18 14:29:41 +00:00
|
|
|
<< "Expected: " << expectedValue << ", Found: " << foundValue << std::endl;
|
2014-10-14 16:00:34 +00:00
|
|
|
VTKM_TEST_FAIL(message.str().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-15 23:15:17 +00:00
|
|
|
/// Sets all the values in a given array portal to be the values returned
|
|
|
|
/// by vtkm::testing::TestValue. The ArrayPortal must be allocated first.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename PortalType>
|
|
|
|
static inline VTKM_CONT void SetPortal(const PortalType& portal)
|
2016-08-15 23:15:17 +00:00
|
|
|
{
|
2017-06-23 18:50:34 +00:00
|
|
|
using ValueType = typename PortalType::ValueType;
|
2016-08-15 23:15:17 +00:00
|
|
|
|
|
|
|
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
|
|
|
|
{
|
|
|
|
portal.Set(index, TestValue(index, ValueType()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-28 19:40:31 +00:00
|
|
|
/// Verifies that the contents of the two portals are the same.
|
|
|
|
///
|
|
|
|
template <typename PortalType1, typename PortalType2>
|
|
|
|
static inline VTKM_CONT bool test_equal_portals(const PortalType1& portal1,
|
|
|
|
const PortalType2& portal2)
|
|
|
|
{
|
|
|
|
if (portal1.GetNumberOfValues() != portal2.GetNumberOfValues())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (vtkm::Id index = 0; index < portal1.GetNumberOfValues(); index++)
|
|
|
|
{
|
|
|
|
if (!test_equal(portal1.Get(index), portal2.Get(index)))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-06-11 16:43:36 +00:00
|
|
|
#endif //vtk_m_testing_Testing_h
|