# 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

#ifndef FLENS_DEBUG_CLOSURES
#define FLENS_DEBUG_CLOSURES
#endif

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

using namespace flens;
using namespace std;

int
main()
{
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,
567,
543;

verbose::ClosureLog::start("mylogfile");

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

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

verbose::ClosureLog::stop();

return 0;
}

Define the macro for debugging closures

#ifndef FLENS_DEBUG_CLOSURES
#define FLENS_DEBUG_CLOSURES
#endif

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

verbose::ClosureLog::start("mylogfile");

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

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

Stop logging.

verbose::ClosureLog::stop();

## 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 tut02-page03-example.cc
$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:

 Letter Matrix/Vector Type x DenseVector A GeMatrix T TrMatrix S SyMatrix

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