Content |
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
#define FLENS_DEBUG_CLOSURES
#endif
#include <cxxstd/iostream.h>
#include <flens/flens.cxx>
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 = 1, 2, 3;
y = 2, 3, 4;
z = 3, 4, 5;
GEMatrix A(3,3);
A = 1, 2, 3,
5, 6, 7,
5, 4, 3;
verbose::ClosureLog::start("mylogfile");
y = beta*y + alpha*transpose(A)*x + z;
cout << "y = " << y << endl;
verbose::ClosureLog::stop();
return 0;
}
Comments on Example Code
Define the macro for debugging 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.
Compute \(y = \beta y + \alpha A^T 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 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) * x2)) + x3); flens::assign((((2.5 * x1) + ((1.5 * (A1)^T) * x2)) + x3), x1); flens::blas::copy(??1, (((2.5 * x1) + ((1.5 * (A1)^T) * x2)) + x3), x1); flens::blas::copy(??2, ((2.5 * x1) + ((1.5 * (A1)^T) * x2)), x1); --> flens::blas::mv(Trans, 1.5, A1, x2, 2.5, x1); --> flens::blas::axpy(1, x3, 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).