kdsymm.c
Go to the documentation of this file.
#include "../include/lass.h"
/**
*
* @file kdsymm.c
*
* @brief LASs-DDSs kdsymm routine.
*
* LASs-DDSs is a software package provided by:
* Barcelona Supercomputing Center - Centro Nacional de Supercomputacion
*
* @author Pedro Valero-Lara pedro.valero@bsc.es
* @date 2017-08-11
* @reviewer
* @modified
*
**/
/**
*
* @ingroup DDSS
*
* Performs one of the matrix-matrix operations:
*
* C = ALPHA * A * B + BETA * C
* or
*
* C = ALPHA * B * A + BETA * C
*
*
* where op( X ) is one of:
*
* op( X ) = X or
* op( X ) = X**T
*
* ALPHA and BETA are scalars, A is a symmetric matrix, and B and C
* are M by N matrices.
*
**/
/**
*
* @param[in]
* SIDE enum DDSS_SIDE.
* UPLO specifies the position of the symmetric A matrix in
* the operation:
* - Left: C = ALPHA * A * B + BETA * C
* - Right: C = ALPHA * B * A + BETA * C
*
* @param[in]
* UPLO enum DDSS_UPLO.
* UPLO specifies the form of A is stored:
* - Lower: Lower triangle of A is stored. The upper traingular part is
* not referenced.
* - Upper: Upper triangle of A is stored. The lower triangular part is
* not referenced.
*
* @param[in]
* M int.
* M specifies the number of rows of the matrix C.
* M must be equal or greater than zero.
*
* @param[in]
* N int.
* N specifies the number of columns of the matrix C.
* N must be equal or greater than zero.
*
* @param[in]
* ALPHA double.
*
* @param[in]
* A double *.
* A is a pointer to a matrix of dimension Ma ( rows ) by Na
* (columns), where Ma is M and Na is M when SIDE = Left, and
* Ma is N and Na is N when SIDE = Right
*
*
* @param[in]
* LDA int.
* LDA specifies the number of columns of A ( row-major order ).
* LDA must be at least max( 1, Na ).
*
* @param[in]
* B double *.
* B is a pointer to a matrix of dimension M by N.
*
* @param[in]
* LDB int.
* LDB specifies the number of columns of B ( row-major order ).
* LDB must be at least max( 1, N ).
*
* @param[in]
* BETA double.
*
* @param[in,out]
* C double *.
* C is a pointer to a matrix of dimension M by N.
* On exit, C is overwritten by the M by N matrix.
*
* @param[in]
* LDC int.
* LDC specifies the number of columns of C ( row-major order ).
* LDC must be at least max( 1, N ).
*
**/
/**
*
* @retval Success sucessful exit
* @retval NoSuccess unsucessful exit
*
**/
/**
*
* @sa ddss_dgemm
* @sa ddss_tile
* @sa ddss_flat2tiled
* @sa ddss_symflat2tiled
* @sa ddss_tiled2flat
* @sa ddss_symtiled2flat
*
**/
enum LASS_RETURN kdsymm( enum DDSS_SIDE SIDE, enum DDSS_UPLO UPLO,
int M, int N,
const double ALPHA, double *A, int LDA,
double *B, int LDB,
const double BETA, double *C, int LDC )
{
// Local variables
int mt, kt, nt;
int mi, ki, ni;
int Am, An;
int Amt, Ant;
int tile_size_m;
int tile_size_n;
int tile_size_k;
int k_check;
double betat;
// Number of tiles
if ( M % TILE_SIZE == 0 )
{
mt = M / TILE_SIZE;
}
else
{
mt = ( M / TILE_SIZE ) + 1;
}
if ( N % TILE_SIZE == 0 )
{
nt = N / TILE_SIZE;
}
else
{
nt = ( N / TILE_SIZE ) + 1;
}
if ( SIDE == Left )
{
if ( M % TILE_SIZE == 0 )
{
kt = M / TILE_SIZE;
}
else
{
kt = ( M / TILE_SIZE ) + 1;
}
}
else
{
if ( N % TILE_SIZE == 0 )
{
kt = N / TILE_SIZE;
}
else
{
kt = ( N / TILE_SIZE ) + 1;
}
}
/****************************
--Tile matrices declaration--
****************************/
if ( SIDE == Left )
{
Am = M;
An = M;
Amt = mt;
Ant = mt;
}
else
{
Am = N;
An = N;
Amt = nt;
Ant = nt;
}
/***************************
--Tile matrices allocation--
***************************/
double (*TILE_A)[Ant][TILE_SIZE * TILE_SIZE] = malloc ( Amt * Ant *
TILE_SIZE * TILE_SIZE * sizeof( double ) );
if ( TILE_A == NULL)
{
fprintf( stderr, "Failure in kdsymm for matrix TILE_A\n" );
return NoSuccess;
}
double (*TILE_B)[nt][TILE_SIZE * TILE_SIZE] = malloc ( mt * nt *
TILE_SIZE * TILE_SIZE * sizeof( double ) );
if ( TILE_B == NULL)
{
fprintf( stderr, "Failure in kdsymm for matrix TILE_B\n" );
return NoSuccess;
}
double (*TILE_C)[nt][TILE_SIZE * TILE_SIZE] = malloc ( mt * nt *
TILE_SIZE * TILE_SIZE * sizeof( double ) );
if ( TILE_C == NULL)
{
fprintf( stderr, "Failure in kdsymm for matrix TILE_C\n" );
return NoSuccess;
}
/************************************************
// --From flat data layout to tiled data layout--
************************************************/
// From flat and symmetric matrix A to tile matrix TILE_A
ddss_dsymflat2tiled( Am, An, A, LDA, Amt, Ant, TILE_A, UPLO );
// From flat matrix B to tile matrix TILE_B
ddss_dflat2tiled( M, N, B, LDB, mt, nt, TILE_B );
// From flat matrix C to tile matrix TILE_C
ddss_dflat2tiled( M, N, C, LDC, mt, nt, TILE_C );
/*************
--DSYMM tile--
*************/
for ( mi = 0; mi < mt; mi++ )
{
tile_size_m = ddss_tile_size( M, mi );
for ( ni = 0; ni < nt; ni++ )
{
tile_size_n = ddss_tile_size( N, ni );
if ( SIDE == Left )
{
// --SIDE = Left & UPLO = Lower--
if ( UPLO == Lower)
{
for ( ki = 0; ki < kt; ki++ )
{
if (ki == 0)
{
betat = BETA;
}
else
{
betat = 1.0;
}
tile_size_k = ddss_tile_size( M, ki );
if ( ki < mi )
{
#pragma oss task in( TILE_A[mi][ki] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_A[mi][ki], tile_size_k,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni], tile_size_n );
}
else
{
if ( ki == mi )
{
#pragma oss task in( TILE_A[ki][ki] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dsymm( CblasRowMajor,
( CBLAS_SIDE ) SIDE,
( CBLAS_UPLO ) UPLO,
tile_size_m, tile_size_n,
ALPHA, TILE_A[ki][ki], tile_size_k,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni],
tile_size_n );
}
else
{
#pragma oss task in( TILE_A[ki][mi] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) Trans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_A[ki][mi], tile_size_m,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni],
tile_size_n );
}
}
}
}
// --SIDE = Left & UPLO = Upper--
else
{
for ( ki = 0; ki < kt; ki++ )
{
if (ki == 0)
{
betat = BETA;
}
else
{
betat = 1.0;
}
tile_size_k = ddss_tile_size( M, ki );
if ( ki < mi )
{
#pragma oss task in( TILE_A[ki][mi] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) Trans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_A[ki][mi], tile_size_m,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni], tile_size_n );
}
else
{
if ( ki == mi )
{
#pragma oss task in( TILE_A[ki][ki] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dsymm( CblasRowMajor,
( CBLAS_SIDE ) SIDE,
( CBLAS_UPLO ) UPLO,
tile_size_m, tile_size_n,
ALPHA, TILE_A[ki][ki], tile_size_k,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni],
tile_size_n );
}
else
{
#pragma oss task in( TILE_A[mi][ki] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_A[mi][ki], tile_size_k,
TILE_B[ki][ni], tile_size_n,
betat, TILE_C[mi][ni],
tile_size_n );
}
}
}
}
}
else
{
// --SIDE = Right & UPLO = Lower--
if ( UPLO == Lower)
{
for ( ki = 0; ki < kt; ki++ )
{
if (ki == 0)
{
betat = BETA;
}
else
{
betat = 1.0;
}
tile_size_k = ddss_tile_size( N, ki );
if ( ki < ni )
{
#pragma oss task in( TILE_B[mi][ki] ) \
in( TILE_A[ni][ki] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) Trans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_B[mi][ki], tile_size_k,
TILE_A[ni][ki], tile_size_k,
betat, TILE_C[mi][ni], tile_size_n );
}
else
{
if ( ki == ni )
{
#pragma oss task in( TILE_A[ki][ki] ) \
in( TILE_B[mi][ki] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dsymm( CblasRowMajor,
( CBLAS_SIDE ) SIDE,
( CBLAS_UPLO ) UPLO,
tile_size_m, tile_size_n,
ALPHA, TILE_A[ki][ki], tile_size_k,
TILE_B[mi][ki], tile_size_k,
betat, TILE_C[mi][ni],
tile_size_n );
}
else
{
#pragma oss task in( TILE_B[mi][ki] ) \
in( TILE_A[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_B[mi][ki], tile_size_k,
TILE_A[ki][ni], tile_size_n,
betat, TILE_C[mi][ni],
tile_size_n );
}
}
}
}
// --SIDE = Right & UPLO = Upper--
else
{
for ( ki = 0; ki < kt; ki++ )
{
if (ki == 0)
{
betat = BETA;
}
else
{
betat = 1.0;
}
tile_size_k = ddss_tile_size( N, ki );
if ( ki < ni )
{
#pragma oss task in( TILE_B[mi][ki] ) \
in( TILE_A[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) NoTrans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_B[mi][ki], tile_size_k,
TILE_A[ki][ni], tile_size_n,
betat, TILE_C[mi][ni], tile_size_n );
}
else
{
if ( ki == ni )
{
#pragma oss task in( TILE_A[ki][ki] ) \
in( TILE_B[ki][ni] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dsymm( CblasRowMajor,
( CBLAS_SIDE ) SIDE,
( CBLAS_UPLO ) UPLO,
tile_size_m, tile_size_n,
ALPHA, TILE_A[ki][ki], tile_size_k,
TILE_B[mi][ki], tile_size_k,
betat, TILE_C[mi][ni],
tile_size_n );
}
else
{
#pragma oss task in( TILE_B[mi][ki] ) \
in( TILE_A[ni][ki] ) \
inout( TILE_C[mi][ni] ) \
shared( TILE_A, TILE_B, TILE_C ) \
firstprivate( mi, ni, ki, betat )
cblas_dgemm( CblasRowMajor,
( CBLAS_TRANSPOSE ) NoTrans,
( CBLAS_TRANSPOSE ) Trans,
tile_size_m,
tile_size_n,
tile_size_k,
ALPHA, TILE_B[mi][ki], tile_size_k,
TILE_A[ni][ki], tile_size_k,
betat, TILE_C[mi][ni],
tile_size_n );
}
}
}
}
}
}
}
// From tile matrix TILE_C to flat matrix C
ddss_dtiled2flat( M, N, C, LDC, mt, nt, TILE_C );
// --Tile matrices free--
free( TILE_A );
free( TILE_B );
free( TILE_C );
return Success;
}
ddss_dflat2tiled
void ddss_dflat2tiled(int M, int N, double *A, int LDA, int MT, int NT, double(*TILE_A)[NT][TILE_SIZE *TILE_SIZE])
Definition: ddss_flat2tiled.c:68
ddss_dsymflat2tiled
void ddss_dsymflat2tiled(int M, int N, double *A, int LDA, int MT, int NT, double(*TILE_A)[NT][TILE_SIZE *TILE_SIZE], enum DDSS_UPLO UPLO)
Definition: ddss_flat2tiled.c:147
kdsymm
enum LASS_RETURN kdsymm(enum DDSS_SIDE SIDE, enum DDSS_UPLO UPLO, int M, int N, const double ALPHA, double *A, int LDA, double *B, int LDB, const double BETA, double *C, int LDC)
Definition: kdsymm.c:125
ddss_dtiled2flat
void ddss_dtiled2flat(int M, int N, double *A, int LDA, int MT, int NT, double(*TILE_A)[NT][TILE_SIZE *TILE_SIZE])
Definition: ddss_tiled2flat.c:68
ddss_tile_size
int ddss_tile_size(int M, int MT)
Definition: ddss_tile.c:52