Merge branch 'fix-vector-analysis-failure' into 'master'

Fix issues with UnitTestVectorAnalysis for MSVC.

We have been having a problem with one of the MSVC dashboards failing
the UnitTestVectorAnalysis test. The test just dies in the middle with
no indication of what problematic thing was run.

After playing with this for quite a while, I found that it could by
triggered exclusively in the Lerp test. I further found that if I
switched the order of the test and check Lerp the test worked. This is
strange behavior and leads me to believe one of the following is going
on:

1. There is an error such as an invalid memory access happening in
the VTK-m code that is sometimes corrupting the stack.
2. Somewhere there is an expression that has undefined behavior. Usually
it works OK, but some optimization sequence causes it to fail.
3. There is a bug in one of the compiler's optimizations.

It concerns me that I cannot identify exactly where the problem lies.
I've looked very hard at the vtkm::Vec and vtkm::Lerp code to try to find
possible problems, but I have not been able to find anything.

See merge request !399
This commit is contained in:
Kenneth Moreland 2016-04-20 12:05:31 -04:00
commit eede71f918
2 changed files with 19 additions and 12 deletions

@ -347,10 +347,8 @@ bool test_equal(VectorType1 vector1,
{
continue;
}
vtkm::Float64 ratio;
// The following condition is redundant since the previous check
// guarantees neither value will be zero, but the MSVC compiler
// sometimes complains about it.
if ((vtkm::Abs(value2) > tolerance) && (value2 != 0))
{
ratio = value1 / value2;

@ -50,11 +50,6 @@ template<typename VectorType>
VectorType MyNormal(const VectorType& vt)
{
typedef vtkm::VecTraits<VectorType> Traits;
double total = 0.0;
for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; ++index)
{
total += Traits::GetComponent(vt,index) * Traits::GetComponent(vt,index);
}
typename Traits::ComponentType mag = internal::MyMag(vt);
VectorType temp = vt;
for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; ++index)
@ -81,25 +76,30 @@ void TestVector(const VectorType& vector)
//to do have to implement a norm and normalized call to verify the math ones
//against
std::cout << " Magnitude" << std::endl;
ComponentType magnitude = vtkm::Magnitude(vector);
ComponentType magnitudeCompare = internal::MyMag(vector);
VTKM_TEST_ASSERT(test_equal(magnitude, magnitudeCompare),
"Magnitude failed test.");
std::cout << " Magnitude squared" << std::endl;
ComponentType magnitudeSquared = vtkm::MagnitudeSquared(vector);
VTKM_TEST_ASSERT(test_equal(magnitude*magnitude, magnitudeSquared),
"Magnitude squared test failed.");
if (magnitudeSquared > 0)
{
std::cout << " Reciprocal magnitude" << std::endl;
ComponentType rmagnitude = vtkm::RMagnitude(vector);
VTKM_TEST_ASSERT(test_equal(1/magnitude, rmagnitude),
"Reciprical magnitude failed.");
std::cout << " Normal" << std::endl;
VTKM_TEST_ASSERT(test_equal(vtkm::Normal(vector),
internal::MyNormal(vector)),
"Normalized vector failed test.");
std::cout << " Normalize" << std::endl;
VectorType normalizedVector = vector;
vtkm::Normalize(normalizedVector);
VTKM_TEST_ASSERT(test_equal(normalizedVector, internal::MyNormal(vector)),
@ -113,11 +113,15 @@ void TestLerp(const VectorType& a,
const VectorType& w,
const typename vtkm::VecTraits<VectorType>::ComponentType& wS)
{
VectorType lhs = internal::MyLerp(a,b,w);
VectorType rhs = vtkm::Lerp(a,b,w);
VTKM_TEST_ASSERT(test_equal(lhs, rhs),
std::cout << "Linear interpolation: " << a << "-" << b << ": " << w
<< std::endl;
VectorType vtkmLerp = vtkm::Lerp(a, b, w);
VectorType otherLerp = internal::MyLerp(a, b, w);
VTKM_TEST_ASSERT(test_equal(vtkmLerp, otherLerp),
"Vectors with Vector weight do not lerp() correctly");
std::cout << "Linear interpolation: " << a << "-" << b << ": " << wS
<< std::endl;
VectorType lhsS = internal::MyLerp(a,b,wS);
VectorType rhsS = vtkm::Lerp(a,b,wS);
VTKM_TEST_ASSERT(test_equal(lhsS, rhsS),
@ -127,17 +131,21 @@ void TestLerp(const VectorType& a,
template<typename T>
void TestCross(const vtkm::Vec<T,3> &x, const vtkm::Vec<T,3> &y)
{
std::cout << "Testing " << x << " x " << y << std::endl;
typedef vtkm::Vec<T,3> Vec3;
Vec3 cross = vtkm::Cross(x, y);
std::cout << "Testing " << x << " x " << y << " = " << cross << std::endl;
std::cout << " = " << cross << std::endl;
std::cout << " Orthogonality" << std::endl;
// The cross product result should be perpendicular to input vectors.
VTKM_TEST_ASSERT(test_equal(vtkm::dot(cross,x), T(0.0)),
"Cross product not perpendicular.");
VTKM_TEST_ASSERT(test_equal(vtkm::dot(cross,y), T(0.0)),
"Cross product not perpendicular.");
std::cout << " Length" << std::endl;
// The length of cross product should be the lengths of the input vectors
// times the sin of the angle between them.
T sinAngle =
@ -152,6 +160,7 @@ void TestCross(const vtkm::Vec<T,3> &x, const vtkm::Vec<T,3> &y)
VTKM_TEST_ASSERT(test_equal(sinAngle*sinAngle + cosAngle*cosAngle, T(1.0)),
"Bad cross product length.");
std::cout << " Triangle normal" << std::endl;
// Test finding the normal to a triangle (similar to cross product).
Vec3 normal = vtkm::TriangleNormal(x, y, Vec3(0, 0, 0));
VTKM_TEST_ASSERT(test_equal(vtkm::dot(normal, x-y), T(0.0)),