Using FLENS-BLAS through Overloaded Operators

Toy Example

We use the same example as before, i.e. we compute \(y = \beta y + \alpha\,A^T x + z\) where \(\alpha, \beta\) are scalars, \(x, y, z\) are (dense) vectors and \(A\) is a (general) matrix (with full storage).

This time we just code it the natural way, i.e. as y = beta*y + alpha*transpose(A)*x + z and hope the best.

However, afterwards we want to check how FLENS-BLAS was internally utilized for the evaluation of the linear algebra expression. We therefore log the evaluation.

Example Code


#include <flens/flens.cxx>
#include <iostream>

using namespace flens;
using namespace std;

    typedef double                               T;
    typedef DenseVector<Array<T> >               DEVector;
    typedef GeMatrix<FullStorage<T, ColMajor> >  GEMatrix;

    const T  alpha = 1.5,
             beta = 2.5;

    DEVector x(3), y(3), z(3);
    x = 123;
    y = 234;
    z = 345;

    GEMatrix A(3,3);
    A = 123,


    y = beta*y + alpha*transpose(A)*x + z;

    cout << "y = " << y << endl;


    return 0;

Comments on Example Code

Define the macro for debugging closures


We turn on logging of the closure evaluation, i.e. the evaluation of linear algebra expressions that are coded through overloaded operators.


Compute \(y = \beta y + \alpha A^T x + z\)

    y = beta*y + alpha*transpose(A)*x + z;

Stop logging.


Compile, Run and Examining the Log-File

Compiling the code becomes slightly more complex. But we hope the comments give enough glues to see what need to be done.

$shell> cd flens/examples                                                     
$shell> #                                                                     
$shell> # cleanup old object files and compile some stuff needed for logging  
$shell> #                                                                     
$shell> rm -f *.o                                                             
$shell> g++ -Wall -std=c++11 -I../.. -c ../../flens/debug/auxiliary/*.cc      
$shell> #                                                                     
$shell> # compile with -DFLENS_DEBUG_CLOSURES and link against the log stuff  
$shell> #                                                                     
$shell> g++ -Wall -std=c++11 -I../.. *.o              
$shell> ./a.out                                                               
y = 
           47           50.5             54 
$shell> #                                                                     
$shell> # look what is in the log file                                        
$shell> #                                                                     
$shell> cat mylogfile                                                         
x1 = (((2.5 * x1) + ((1.5 * (A1)^T) * x3)) + x2);
flens::assign((((2.5 * x1) + ((1.5 * (A1)^T) * x3)) + x2), x1);
    flens::blas::copy((((2.5 * x1) + ((1.5 * (A1)^T) * x3)) + x2), x1);
        flens::blas::copy(((2.5 * x1) + ((1.5 * (A1)^T) * x3)), x1);
            --> flens::blas::mv(Trans, 1.5, A1, x3, 2.5, x1);
        --> flens::blas::axpy(1, x2, x1);

In the log files you see a complete trace of function calls. If you compile with -DNDEBUG instead most of these functions get inlined and only the functions marked with the arrows --> actually get called. Not that this means that in non-debug mode the resulting code is equivalent to calling CXXBLAS directly.

Note: The logging mechanism in FLENS gives different matrix/vector objects unique names. The letter represents the matrix/vector types:


Matrix/Vector Type









Further, vectors and matrices of same type receive subsequent numbers (like in this example vectors receive names x1, x2, x3).