uBlas bug or compiler bug?

View: New views
3 Messages — Rating Filter:   Alert me  

uBlas bug or compiler bug?

by Marco Guazzone :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear all,

Today I've found a strange behavior with uBlas.
I've tried both Boost 1.37.0 (pre-installed on my Linux Fedora 11
system) and Boost 1.40.0 (compiled by myself).

I've attached the code (ublas.cpp) and the related makefile (ublas.mk)
used for compiling (actually usable for gcc and alike). For people
having the "make" command, simply run:

$ make -f ublas.mk clean all

You need the Boost.Test compiled libraries (see flag
-lboost_unit_test_framework)

Well, the problem.
The code simply test some matrix operations: matrix-scalar product,
matrix sum, matrix product.
For each test, the computed value is checked against the expected
value, with a certain tolerance TOL (=1.0e-5).

When I run the code I get the seventeen errors in the matrix product
test suite like the one below (the other sixteen are the same since
the error always occurs a the same line):
--- [snip] ---
ublas.cpp(144): error in "matrix_matrix_prod": check std::fabs(*col_it
- T(row,col)) <= TOL failed
--- [/snip] ---

But, and here is the *strange* behavior, if I comment both the
"matrix_scalar_prod" and the "matrix_matrix_sum" test suites (lines
from 22 to 94) the matrix product test suite (matrix_matrix_prod) is
OK!!!

Moreover commenting only the "matrix_matrix_sum" I get another
different behavior, that is only four errors (with Boost 1.37) and two
errors (with Boost 1.40); and if I comment only th
"matrix_scalar_prod" the errors returns to be seventeen:

Wow!! :(

So I don't understand if this is a uBlas bug or a compiler bug ...or
maybe something I do wrong with uBlas.
My compiler is: GCC 4.4.1

Can you try to run the attached code and give me a feedback?

Many many thanks!!!

Cheers,

-- Marco

[ublas.cpp]

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/version.hpp>
#include <iostream>

#define BOOST_TEST_MODULE "ublas matrix test suite"
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

#define MY_EXPAND(x) x
#define MY_TRACE(x) std::cerr << MY_EXPAND(x) << std::endl;

static const double TOL(1.0e-5);


BOOST_AUTO_TEST_CASE( boost_version )
{
        MY_TRACE( "Using Boost: " << (BOOST_VERSION / 100000) << "." << (BOOST_VERSION / 100 % 1000) << "." << (BOOST_VERSION % 100) );
}


BOOST_AUTO_TEST_CASE( matrix_scalar_prod )
{
    MY_TRACE( "Test Case: <<matrix-scalar prod>>" );

    typedef double real_type;
    typedef boost::numeric::ublas::matrix<real_type> matrix_type;

    matrix_type A(5,4);

    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

    real_type b(0.5);

    matrix_type C(5,4);

    C = b*A;

    for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
    {
        for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            matrix_type::size_type row(col_it.index1());
            matrix_type::size_type col(col_it.index2());

            MY_TRACE( "C(" << row << "," << col << ") = " << *col_it << " ==> " << (b*A(row,col)) );

            BOOST_CHECK( std::fabs(*col_it - (b*A(row,col))) <= TOL );
        }
    }
}


BOOST_AUTO_TEST_CASE( matrix_matrix_sum )
{
        typedef double real_type;
        typedef boost::numeric::ublas::matrix<real_type> matrix_type;

        matrix_type A(5,4);

        A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
        A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
        A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
        A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
        A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

        matrix_type B(5,4);

        B(0,0) = 0.555950; B(0,1) = 0.274690; B(0,2) = 0.540605; B(0,3) = 0.798938;
        B(1,0) = 0.108929; B(1,1) = 0.830123; B(1,2) = 0.891726; B(1,3) = 0.895283;
        B(2,0) = 0.948014; B(2,1) = 0.973234; B(2,2) = 0.216504; B(2,3) = 0.883152;
        B(3,0) = 0.023787; B(3,1) = 0.675382; B(3,2) = 0.231751; B(3,3) = 0.450332;
        B(4,0) = 1.023787; B(4,1) = 1.675382; B(4,2) = 1.231751; B(4,3) = 1.450332;

        matrix_type C(5,4);

        C = A + B;

        for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
        {
                for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
                {
                        matrix_type::size_type row(col_it.index1());
                        matrix_type::size_type col(col_it.index2());

                        MY_TRACE( "C(" << row << "," << col << ") = " << A(row,col) << " + " << B(row,col) << " ==> " << (A(row,col) + B(row,col)) << " = " << *col_it );
                        BOOST_CHECK( std::fabs(*col_it - (A(row,col)+B(row,col))) <= TOL );
                }
        }
}


BOOST_AUTO_TEST_CASE( matrix_matrix_prod )
{
    MY_TRACE( "Test Case: <<matrix-matrix prod>>" );

    typedef double real_type;
    typedef boost::numeric::ublas::matrix<real_type> matrix_type;

    matrix_type A(5,4);

    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

    matrix_type B(4,5);

    B(0,0) = 0.555950; B(0,1) = 0.108929; B(0,2) = 0.948014; B(0,3) = 0.023787; B(0,4) = 1.023787;
    B(1,0) = 0.274690; B(1,1) = 0.830123; B(1,2) = 0.973234; B(1,3) = 0.675382; B(1,4) = 1.675382;
    B(2,0) = 0.540605; B(2,1) = 0.891726; B(2,2) = 0.216504; B(2,3) = 0.231751; B(2,4) = 1.231751;
    B(3,0) = 0.798938; B(3,1) = 0.895283; B(3,2) = 0.883152; B(3,3) = 0.450332; B(3,4) = 1.450332;

    matrix_type T(A.size1(),B.size2());

    for (matrix_type::iterator1 row_it = T.begin1(); row_it != T.end1(); ++row_it)
    {
        for (matrix_type::iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            for (matrix_type::size_type i = 0; i < A.size2(); ++i)
            {
                    *col_it += A(col_it.index1(), i) * B(i, col_it.index2());
            }
        }
    }

    matrix_type C(A.size1(),B.size2());

    C = boost::numeric::ublas::prod(A, B);

    for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
    {
        for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            matrix_type::size_type row(col_it.index1());
            matrix_type::size_type col(col_it.index2());

            MY_TRACE( "C(" << row << "," << col << ") = " << *col_it << " ==> " << T(row,col) );

            BOOST_CHECK( std::fabs(*col_it - T(row,col)) <= TOL );
        }
    }
}



_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

ublas.mk (462 bytes) Download Attachment

Re: uBlas bug or compiler bug?

by Nasos Iliopoulos :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
Marco,
Try to initialize matrix "T" in your multiplication algorithm to zeros. I attach a test run on your example without the boost unit test and with
matrix_type T=boost::numeric::ublas::zero_matrix<real_type>(A.size1(), B.size2());

compiled with:
g++ -O3 ublas_no_boost_unit_test.cpp -o test;

Very Best
Nasos Iliopoulos


> Date: Sat, 12 Sep 2009 11:15:08 +0200
> From: marco.guazzone@...
> To: ublas@...
> Subject: [ublas] uBlas bug or compiler bug?
>
> Dear all,
>
> Today I've found a strange behavior with uBlas.
> I've tried both Boost 1.37.0 (pre-installed on my Linux Fedora 11
> system) and Boost 1.40.0 (compiled by myself).
>
> I've attached the code (ublas.cpp) and the related makefile (ublas.mk)
> used for compiling (actually usable for gcc and alike). For people
> having the "make" command, simply run:
>
> $ make -f ublas.mk clean all
>
> You need the Boost.Test compiled libraries (see flag
> -lboost_unit_test_framework)
>
> Well, the problem.
> The code simply test some matrix operations: matrix-scalar product,
> matrix sum, matrix product.
> For each test, the computed value is checked against the expected
> value, with a certain tolerance TOL (=1.0e-5).
>
> When I run the code I get the seventeen errors in the matrix product
> test suite like the one below (the other sixteen are the same since
> the error always occurs a the same line):
> --- [snip] ---
> ublas.cpp(144): error in "matrix_matrix_prod": check std::fabs(*col_it
> - T(row,col)) <= TOL failed
> --- [/snip] ---
>
> But, and here is the *strange* behavior, if I comment both the
> "matrix_scalar_prod" and the "matrix_matrix_sum" test suites (lines
> from 22 to 94) the matrix product test suite (matrix_matrix_prod) is
> OK!!!
>
> Moreover commenting only the "matrix_matrix_sum" I get another
> different behavior, that is only four errors (with Boost 1.37) and two
> errors (with Boost 1.40); and if I comment only th
> "matrix_scalar_prod" the errors returns to be seventeen:
>
> Wow!! :(
>
> So I don't understand if this is a uBlas bug or a compiler bug ...or
> maybe something I do wrong with uBlas.
> My compiler is: GCC 4.4.1
>
> Can you try to run the attached code and give me a feedback?
>
> Many many thanks!!!
>
> Cheers,
>
> -- Marco


Your E-mail and More On-the-Go. Get Windows Live Hotmail Free. Sign up now.

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

#define MY_EXPAND(x) x
#define MY_TRACE(x) std::cerr << MY_EXPAND(x) << std::endl;

static const double TOL(1.0e-5);

void test1() {
    typedef double real_type;
    typedef boost::numeric::ublas::matrix<real_type> matrix_type;

    matrix_type A(5,4);

    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

    real_type b(0.5);

    matrix_type C(5,4);

    C = b*A;

    bool problem=0;
    for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
    {
        for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            matrix_type::size_type row(col_it.index1());
            matrix_type::size_type col(col_it.index2());

            MY_TRACE( "C(" << row << "," << col << ") = " << *col_it << " ==> " << (b*A(row,col)) );
            if (!(std::fabs(*col_it - (b*A(row,col))) <= TOL)) problem=1;
            //BOOST_CHECK( std::fabs(*col_it - (b*A(row,col))) <= TOL );
        }
    }
    std::cerr << "scalar*matrix: ";
    if (problem) std::cerr << "PROBLEM!" << std::endl;
    else std::cerr << "NO PROBLEM!" << std::endl;
}

void test2() {
        typedef double real_type;
        typedef boost::numeric::ublas::matrix<real_type> matrix_type;

        matrix_type A(5,4);

        A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
        A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
        A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
        A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
        A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

        matrix_type B(5,4);

        B(0,0) = 0.555950; B(0,1) = 0.274690; B(0,2) = 0.540605; B(0,3) = 0.798938;
        B(1,0) = 0.108929; B(1,1) = 0.830123; B(1,2) = 0.891726; B(1,3) = 0.895283;
        B(2,0) = 0.948014; B(2,1) = 0.973234; B(2,2) = 0.216504; B(2,3) = 0.883152;
        B(3,0) = 0.023787; B(3,1) = 0.675382; B(3,2) = 0.231751; B(3,3) = 0.450332;
        B(4,0) = 1.023787; B(4,1) = 1.675382; B(4,2) = 1.231751; B(4,3) = 1.450332;

        matrix_type C(5,4);

        C = A + B;

    bool problem=0;

        for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
        {
                for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
                {
                        matrix_type::size_type row(col_it.index1());
                        matrix_type::size_type col(col_it.index2());

                        MY_TRACE( "C(" << row << "," << col << ") = " << A(row,col) << " + " << B(row,col) << " ==> " << (A(row,col) + B(row,col)) << " = " << *col_it );
                        if (!( std::fabs(*col_it - (A(row,col)+B(row,col))) <= TOL )) problem=1;
            //BOOST_CHECK( std::fabs(*col_it - (A(row,col)+B(row,col))) <= TOL );
                }
        }
    std::cerr << "matrix+matrix: ";
    if (problem) std::cerr << "PROBLEM!" << std::endl;
    else std::cerr << "NO PROBLEM!" << std::endl;
}

void test3() {
    MY_TRACE( "Test Case: <<matrix-matrix prod>>" );

    typedef double real_type;
    typedef boost::numeric::ublas::matrix<real_type> matrix_type;

    matrix_type A(5,4);

    A(0,0) = 0.555950; A(0,1) = 0.274690; A(0,2) = 0.540605; A(0,3) = 0.798938;
    A(1,0) = 0.108929; A(1,1) = 0.830123; A(1,2) = 0.891726; A(1,3) = 0.895283;
    A(2,0) = 0.948014; A(2,1) = 0.973234; A(2,2) = 0.216504; A(2,3) = 0.883152;
    A(3,0) = 0.023787; A(3,1) = 0.675382; A(3,2) = 0.231751; A(3,3) = 0.450332;
    A(4,0) = 1.023787; A(4,1) = 1.675382; A(4,2) = 1.231751; A(4,3) = 1.450332;

    matrix_type B(4,5);

    B(0,0) = 0.555950; B(0,1) = 0.108929; B(0,2) = 0.948014; B(0,3) = 0.023787; B(0,4) = 1.023787;
    B(1,0) = 0.274690; B(1,1) = 0.830123; B(1,2) = 0.973234; B(1,3) = 0.675382; B(1,4) = 1.675382;
    B(2,0) = 0.540605; B(2,1) = 0.891726; B(2,2) = 0.216504; B(2,3) = 0.231751; B(2,4) = 1.231751;
    B(3,0) = 0.798938; B(3,1) = 0.895283; B(3,2) = 0.883152; B(3,3) = 0.450332; B(3,4) = 1.450332;

    matrix_type T=boost::numeric::ublas::zero_matrix<real_type>(A.size1(), B.size2());


    for (matrix_type::iterator1 row_it = T.begin1(); row_it != T.end1(); ++row_it)
    {
        for (matrix_type::iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            for (matrix_type::size_type i = 0; i < A.size2(); ++i)
            {
                    *col_it += A(col_it.index1(), i) * B(i, col_it.index2());
            }
        }
    }


    matrix_type C(A.size1(),B.size2());

    C = boost::numeric::ublas::prod(A, B);

    bool problem = 0;
    for (matrix_type::const_iterator1 row_it = C.begin1(); row_it != C.end1(); ++row_it)
    {
        for (matrix_type::const_iterator2 col_it = row_it.begin(); col_it != row_it.end(); ++col_it)
        {
            matrix_type::size_type row(col_it.index1());
            matrix_type::size_type col(col_it.index2());

            MY_TRACE( "C(" << row << "," << col << ") = " << *col_it << " ==> " << T(row,col) );
            if (!( std::fabs(*col_it - T(row,col)) <= TOL )) { problem=1; std::cout << "Problem" << std::endl;}
            //BOOST_CHECK( std::fabs(*col_it - T(row,col)) <= TOL );
        }
        }
    std::cerr << "matrix*matrix: ";
    if (problem) std::cerr << "PROBLEM!" << std::endl;
    else std::cerr << "NO PROBLEM!" << std::endl;
    std::cout <<boost::numeric::ublas::trans( C) << std::endl;
    std::cout << T << std::endl;
}



int main() {
   
    test1();
    test2();
    test3();

    return 0;
}


_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...

Re: uBlas bug or compiler bug?

by Marco Guazzone :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Sep 12, 2009 at 8:24 PM, Nasos Iliopoulos <nasos_i@...> wrote:
> Marco,
> Try to initialize matrix "T" in your multiplication algorithm to zeros. I
> attach a test run on your example without the boost unit test and with
> matrix_type T=boost::numeric::ublas::zero_matrix<real_type>(A.size1(),
> B.size2());
>
> compiled with:
> g++ -O3 ublas_no_boost_unit_test.cpp -o test;

OMG, what a stupid error I've done!! :P

Nasos, your code works perfectly.
I really really thank you!!! :)

Cheers!

-- Marco
_______________________________________________
ublas mailing list
ublas@...
http://lists.boost.org/mailman/listinfo.cgi/ublas
Sent to: lists@...