Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
tnl-dev
tnl-dev
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 32
    • Issues 32
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 1
    • Merge Requests 1
  • Operations
    • Operations
    • Incidents
  • Analytics
    • Analytics
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
  • TNL
  • tnl-devtnl-dev
  • Issues
  • #79

Closed
Open
Opened Jul 11, 2020 by Tomáš Jakubec@jakubecDeveloper

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.

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking
None
Due date
None
Reference: tnl/tnl-dev#79