sum<rowwise> of DynamicMatrix<bool> producing error output

Issue #414 resolved
GK Palem created an issue

Consider the below code:

blaze::DynamicMatrix<bool> A{ { 1, 0, 1 }, { 1, 1, 1 } };
blaze::DynamicVector<int, blaze::columnVector> rowsum1 = blaze::sum<blaze::rowwise>(A);

It produces (1, 1) as output where as I would expect the row sums to be (2, 3)

Even an explicit function such as blaze::Add() with reduce returns the same (1,1) instead of the correct sum values.

blaze::DynamicMatrix<bool> A{ { 1, 0, 1 }, { 1, 1, 1 } };
blaze::DynamicVector<int, blaze::columnVector> rowsum2 = blaze::reduce<blaze::rowwise>(A, blaze::Add());

Note that the return type is expected to be DynamicVector<int>> while the sum and reduce seem to be basing the return value calculations on the input type DynamicMatrix<bool> thus clamping the outputs to be just 0 or 1.

While that may be useful in some cases, often times the sum is expected to be int and not just bool.

Is there anyway we could ask the sum or reduce to return the int values ?

As of now the balze::Add is working same as blaze::Or which is confusing.

Comments (6)

  1. GK Palem reporter

    Even an explicit lambda function that adds the values explicitly is not giving the correct return values.

    blaze::DynamicMatrix<bool> A{ { 1, 0, 1 }, { 1, 1, 1 } };
    
    blaze::DynamicVector<int, blaze::columnVector> rowsum2 = 
        blaze::reduce<blaze::rowwise>(A, [](int a, int b) { return a + b; });
    

    Not sure how to return the summed value as integers correctly.

  2. GK Palem reporter

    After digging into the code, came across this dvecreduce that is defined as below:

    template< typename VT    // Type of the dense vector
            , bool TF        // Transpose flag
            , typename OP >  // Type of the reduction operation
    inline auto dvecreduce( const DenseVector<VT,TF>& dv, OP op )
       -> EnableIf_t< DVecReduceExprHelper<VT,OP>::value, ElementType_t<VT> >
    {
       using CT = CompositeType_t<VT>;
       using ET = ElementType_t<VT>;
       ...
       ET redux{};
       ...
       return redux;
    }
    

    Note that the return type of the reduce method is governed by the input element type ET rather than the output type of the op

    For example, an input vector of strings that is being reduced to an int by an op function that counts how many strings in the vector start with the letter a

    Such function is not possible to implement when the return type is expected to be same as the input element type of the vector

    How to overcome this situation? Any help is really appreciated.

  3. Klaus Iglberger

    Hi GK!

    Thanks a lot for reporting this issue. You are correct, the correct answer would be {2,3} instead of {1,1}. Also, you have already identified the source of the issue. Indeed, the dvecreduce() operations do not return the type returned by the reduction operation, but the element type of the vector expression. Will provide a fix as quickly as possible. In the meantime, you can easily work around this by using the rowwise reduction operation on a column-major matrix:

    blaze::DynamicMatrix<bool,blaze::columnMajor> A{ { 1, 0, 1 }, { 1, 1, 1 } };  // Note: Column-major matrix!
    
    // Will produce (2,3) instead of (1,1)
    blaze::DynamicVector<int, blaze::columnVector> rowsum2 = 
        blaze::reduce<blaze::rowwise>(A, [](int a, int b) { return a + b; });
    

    We apologize for the inconvenience,

    Best regards,

    Klaus!

  4. Klaus Iglberger

    Commit cb70dcb fixes the return type of non-vectorized reduction operations for dense and sparse vectors and dense and sparse matrices. The fix is immediately available via cloning the Blaze repository and will be officially released in Blaze 3.9.

  5. Log in to comment