StaticComparison bug
Testing the following code:
#include <iostream>
#include <GTMesh/Debug/Debug.h>
#include <TNL/Containers/StaticVector.h>
#include <TNL/Containers/Vector.h>
using namespace std;
template<int Dim, typename Real>
struct std::numeric_limits<TNL::Containers::StaticVector<Dim, Real>>{
static constexpr bool is_specialized = true;
static TNL::Containers::StaticVector<Dim, Real> max(){
TNL::Containers::StaticVector<Dim, Real> res;
res = std::numeric_limits<Real>::max();
return res;
}
static TNL::Containers::StaticVector<Dim, Real> lowest(){
TNL::Containers::StaticVector<Dim, Real> res;
res = std::numeric_limits<Real>::lowest();
return res;
}
};
using namespace TNL;
int main()
{
TNL::Containers::Vector<TNL::Containers::StaticVector<3,int>, TNL::Devices::Host, size_t> a;
a.setSize(2);
a[0] = TNL::Containers::StaticVector<3,int>{5,-3,6};
a[1] = TNL::Containers::StaticVector<3,int>{8, 1, -5};
TNL::Containers::StaticVector<3,int> a1 = a[0];
TNL::Containers::StaticVector<3,int> a2 = a[1];
DBGVAR(a); // == ..\lookup_problem\main.cpp << 36 >> [[ a ]] ==> [ [ 5, -3, 6 ], [ 8, 1, -5 ] ]
DBGVAR((a1 < a2), (a2 < a1)); // == ..\lookup_problem\main.cpp << 37 >> [[ (a1 < a2) ]] ==> false
// == ..\lookup_problem\main.cpp << 37 >> [[ (a2 < a1) ]] ==> false
DBGVAR(min(a)); // == ..\lookup_problem\main.cpp << 39 >> [[ min(a) ]] ==> [ 5, -3, -5 ]
DBGVAR(min(a1,a2), min(a2,a1));// == ..\lookup_problem\main.cpp << 40 >> [[ min(a1,a2) ]] ==> [ 5, -3, 6 ]
// == ..\lookup_problem\main.cpp << 40 >> [[ min(a2,a1) ]] ==> [ 8, 1, -5 ]
DBGVAR(TNL::min(a1, a2)); // == ..\lookup_problem\main.cpp << 42 >> [[ TNL::min(a1, a2) ]] ==> [ 5, -3, -5 ]
return 0;
}
The first problem is the comparison of a1
and a2
. If the (a1 < a2)
is false the (a2 < a1)
must be true. However in both cases, the result is false, which is incorrect. The comparison utilizes the StaticCompare::LT
defined as:
__cuda_callable__
static bool LT( const T1& a, const T2& b )
{
TNL_ASSERT_EQ( a.getSize(), b.getSize(), "Sizes of expressions to be compared do not fit." );
for( int i = 0; i < a.getSize(); i++ )
if( ! (a[ i ] < b[ i ]) )
return false;
return true;
}
This function does not realize a suitable comparison, e.g., lexicographical.
Secondly, there is a difference in call of min. Both min(a)
and TNL::min(a1, a2)
utilize StaticBinaryExpressionTemplate< ET1, ET2, Min >
, which results in retuning a vector with minimum in each element separately (which is awesome). However, min(a1, a2)
min
from stl is called (the std::min
is prioritized over TNL::Containers::Expressions::min
) and it employs StaticCompare::LT
through operator<
. This problem is solved by removing using namespace std
(which is partialy my mistake, but worth mentioning). The incorrect implementation of StaticCompare::LT
results in dependency of the result on the order of the arguments of min
.
The macro DBGVAR
is defined in the GTMesh library.