35 #include <type_traits>
37 #include <boost/core/ignore_unused.hpp>
57 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
62 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
64 DataType accum = DataType(0);
65 for (
unsigned int j = 0; j < lhs.GetColumns(); ++j)
67 accum += lhs(i, j) * rhs[j];
73 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
78 int n = lhs.GetRows();
79 for (
unsigned int i = 0; i < n; ++i)
81 result[i] = lhs(i, i) * rhs[i];
85 template <
typename DataType,
typename LhsDataType>
90 int n = lhs.GetRows();
91 const DataType *mat_ptr = lhs.GetRawPtr();
95 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
99 typename std::enable_if<
102 boost::ignore_unused(
p);
104 int m = lhs.GetRows();
105 int n = lhs.GetColumns();
106 int kl = lhs.GetNumberOfSubDiagonals();
107 int ku = lhs.GetNumberOfSuperDiagonals();
108 DataType alpha = lhs.Scale();
109 const DataType *a = lhs.GetRawPtr();
110 int lda = kl + ku + 1;
111 const DataType *x = rhs;
114 DataType *y = result;
116 Blas::Gbmv(
'N', m, n, kl, ku, alpha, a, lda, x, incx,
beta, y, incy);
119 template <
typename DataType,
typename LhsDataType>
123 typename std::enable_if<
127 boost::ignore_unused(result, lhs, rhs,
p);
130 "Banded block matrix multiplication not yet implemented");
133 template <
typename DataType,
typename LhsInnerMatrixType>
139 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
140 unsigned int numberOfBlockColumns = lhs.GetNumberOfBlockColumns();
141 DataType *result_ptr = result.
GetRawPtr();
142 const DataType *rhs_ptr = rhs.
GetRawPtr();
144 for (
unsigned int i = 0; i < result.
GetDimension(); ++i)
146 result_ptr[i] = DataType(0);
149 DataType *temp_ptr = temp.
get();
151 unsigned int curResultRow = 0;
152 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
154 unsigned int rowsInBlock = lhs.GetNumberOfRowsInBlockRow(blockRow);
158 curResultRow += lhs.GetNumberOfRowsInBlockRow(blockRow - 1);
161 if (rowsInBlock == 0)
166 DataType *resultWrapper = result_ptr + curResultRow;
168 unsigned int curWrapperRow = 0;
169 for (
unsigned int blockColumn = 0; blockColumn < numberOfBlockColumns;
172 if (blockColumn != 0)
175 lhs.GetNumberOfColumnsInBlockColumn(blockColumn - 1);
180 const LhsInnerMatrixType *block =
181 lhs.GetBlockPtr(blockRow, blockColumn);
187 unsigned int columnsInBlock =
188 lhs.GetNumberOfColumnsInBlockColumn(blockColumn);
189 if (columnsInBlock == 0)
194 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
195 Multiply(temp_ptr, *block, rhsWrapper);
196 for (
unsigned int i = 0; i < rowsInBlock; ++i)
198 resultWrapper[i] += temp_ptr[i];
204 template <
typename DataType,
typename LhsInnerMatrixType>
210 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
211 DataType *result_ptr = result.
GetRawPtr();
212 const DataType *rhs_ptr = rhs.
GetRawPtr();
216 lhs.GetBlockSizes(rowSizes, colSizes);
218 unsigned int curResultRow = 0;
219 unsigned int curWrapperRow = 0;
220 unsigned int rowsInBlock = 0;
221 unsigned int columnsInBlock = 0;
222 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
224 curResultRow += rowsInBlock;
225 curWrapperRow += columnsInBlock;
228 rowsInBlock = rowSizes[blockRow] + 1;
229 columnsInBlock = colSizes[blockRow] + 1;
233 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
234 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
237 if (rowsInBlock == 0)
241 if (columnsInBlock == 0)
243 std::fill(result.
begin() + curResultRow,
244 result.
begin() + curResultRow + rowsInBlock, 0.0);
248 const LhsInnerMatrixType *block = lhs.GetBlockPtr(blockRow, blockRow);
254 DataType *resultWrapper = result_ptr + curResultRow;
255 const DataType *rhsWrapper = rhs_ptr + curWrapperRow;
256 Multiply(resultWrapper, *block, rhsWrapper);
259 curResultRow += rowsInBlock;
260 if (curResultRow < result.
GetRows())
262 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
270 BlockMatrixTag> &lhs,
273 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
279 lhs.GetBlockSizes(rowSizes, colSizes);
281 unsigned int curResultRow = 0;
282 unsigned int curWrapperRow = 0;
283 unsigned int rowsInBlock = 0;
284 unsigned int columnsInBlock = 0;
285 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
287 curResultRow += rowsInBlock;
288 curWrapperRow += columnsInBlock;
291 rowsInBlock = rowSizes[blockRow] + 1;
292 columnsInBlock = colSizes[blockRow] + 1;
296 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
297 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
300 if (rowsInBlock == 0)
304 if (columnsInBlock == 0)
306 std::fill(result.
begin() + curResultRow,
307 result.
begin() + curResultRow + rowsInBlock, 0.0);
311 const DNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
317 double *resultWrapper = result_ptr + curResultRow;
318 const double *rhsWrapper = rhs_ptr + curWrapperRow;
321 const unsigned int *size = block->GetSize();
322 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
323 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
325 curResultRow += rowsInBlock;
326 if (curResultRow < result.
GetRows())
328 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
336 BlockMatrixTag> &lhs,
339 unsigned int numberOfBlockRows = lhs.GetNumberOfBlockRows();
345 lhs.GetBlockSizes(rowSizes, colSizes);
347 unsigned int curResultRow = 0;
348 unsigned int curWrapperRow = 0;
349 unsigned int rowsInBlock = 0;
350 unsigned int columnsInBlock = 0;
351 for (
unsigned int blockRow = 0; blockRow < numberOfBlockRows; ++blockRow)
353 curResultRow += rowsInBlock;
354 curWrapperRow += columnsInBlock;
357 rowsInBlock = rowSizes[blockRow] + 1;
358 columnsInBlock = colSizes[blockRow] + 1;
362 rowsInBlock = rowSizes[blockRow] - rowSizes[blockRow - 1];
363 columnsInBlock = colSizes[blockRow] - colSizes[blockRow - 1];
366 if (rowsInBlock == 0)
370 if (columnsInBlock == 0)
372 std::fill(result.
begin() + curResultRow,
373 result.
begin() + curResultRow + rowsInBlock, 0.0);
377 const SNekScalMat *block = lhs.GetBlockPtr(blockRow, blockRow);
383 NekSingle *resultWrapper = result_ptr + curResultRow;
384 const NekSingle *rhsWrapper = rhs_ptr + curWrapperRow;
387 const unsigned int *size = block->GetSize();
388 Blas::Gemv(
'N', size[0], size[1], block->Scale(), block->GetRawPtr(),
389 size[0], rhsWrapper, 1, 0.0, resultWrapper, 1);
391 curResultRow += rowsInBlock;
392 if (curResultRow < result.
GetRows())
394 std::fill(result.
begin() + curResultRow, result.
end(), 0.0);
398 template <
typename DataType>
404 std::copy(rhs, rhs + vectorSize, result);
407 DataType *x = result;
413 template <
typename DataType>
422 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
424 result[i] *= lhs.Scale();
428 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
433 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
435 DataType accum = DataType(0);
436 for (
unsigned int j = 0; j <= i; ++j)
438 accum += lhs(i, j) * rhs[j];
444 template <
typename DataType>
450 std::copy(rhs, rhs + vectorSize, result);
453 DataType *x = result;
459 template <
typename DataType>
468 for (
unsigned int i = 0; i < lhs.GetColumns(); ++i)
470 result[i] *= lhs.Scale();
474 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
479 for (
unsigned int i = 0; i < lhs.GetRows(); ++i)
481 DataType accum = DataType(0);
482 for (
unsigned int j = i; j < lhs.GetColumns(); ++j)
484 accum += lhs(i, j) * rhs[j];
490 template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
494 typename std::enable_if<
498 boost::ignore_unused(
p);
500 const unsigned int *size = lhs.GetSize();
502 DataType alpha = lhs.Scale();
503 const DataType *a = lhs.GetRawPtr();
504 const DataType *x = rhs;
507 DataType *y = result;
513 template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
517 typename std::enable_if<
521 boost::ignore_unused(
p);
526 template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
530 typename std::enable_if<
534 boost::ignore_unused(
p);
536 const unsigned int *size = lhs.GetSize();
538 char t = lhs.GetTransposeFlag();
540 DataType alpha = lhs.Scale();
541 const DataType *a = lhs.GetRawPtr();
543 const DataType *x = rhs;
546 DataType *y = result;
549 Blas::Gemv(t, size[0], size[1], alpha, a, lda, x, incx,
beta, y, incy);
552 template <
typename DataType,
typename InnerMatrixType,
typename MatrixTag>
556 typename std::enable_if<
560 boost::ignore_unused(
p);
565 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
569 switch (lhs.GetType())
597 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
604 std::string(
"A left side matrix with column count ") +
605 std::to_string(lhs.GetColumns()) +
606 std::string(
" and a right side vector with row count ") +
607 std::to_string(rhs.
GetRows()) +
608 std::string(
" can't be multiplied."));
619 template <
typename DataType,
typename LhsInnerMatrixType>
641 template <
typename DataType,
typename LhsDataType,
typename MatrixType>
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
#define NEKTAR_STANDARD_AND_SCALED_MATRICES
#define NEKTAR_ALL_MATRIX_TYPES
#define NEKTAR_BLOCK_MATRIX_TYPES
unsigned int GetRows() const
char GetTransposeFlag() const
unsigned int GetColumns() const
const DataType * GetRawPtr() const
unsigned int GetDimension() const
Returns the number of dimensions for the point.
unsigned int GetRows() const
static void Gemv(const char &trans, const int &m, const int &n, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A[m x n].
static void Gbmv(const char &trans, const int &m, const int &n, const int &kl, const int &ku, const double &alpha, const double *a, const int &lda, const double *x, const int &incx, const double &beta, double *y, const int &incy)
static void Tpmv(const char &uplo, const char &trans, const char &diag, const int &n, const double *ap, double *x, const int &incx)
static void Spmv(const char &uplo, const int &n, const double &alpha, const double *a, const double *x, const int &incx, const double &beta, double *y, const int &incy)
BLAS level 2: Matrix vector multiply y = A x where A is symmetric packed.
@ beta
Gauss Radau pinned at x=-1,.
The above copyright notice and this permission notice shall be included.
void NekMultiplyBandedMatrix(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< LhsDataType, MatrixType >>::value >::type *p=0)
SNekMat NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(AddEqualNegatedLhs, NEKTAR_ALL_MATRIX_TYPES,(1,(void)),(1,(DNekMat &)),(0,())) NEKTAR_GENERATE_EXPLICIT_FUNCTION_INSTANTIATION_SINGLE_MATRIX(AddEqualNegatedLhs
void DiagonalBlockMatrixMultiply(NekVector< DataType > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< DataType > &rhs)
NEKTAR_BLOCK_MATRIX_TYPES_SINGLE
void Multiply(NekMatrix< ResultDataType, StandardMatrixTag > &result, const NekMatrix< LhsDataType, LhsMatrixType > &lhs, const ResultDataType &rhs)
void NekMultiplyLowerTriangularMatrix(DataType *result, const NekMatrix< DataType, StandardMatrixTag > &lhs, const DataType *rhs)
NEKTAR_ALL_MATRIX_TYPES_SINGLE
void NekMultiplySymmetricMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag >>::value >::type *p=0)
void NekMultiplyDiagonalMatrix(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs)
void DiagonalBlockFullScalMatrixMultiply(NekVector< double > &result, const NekMatrix< NekMatrix< NekMatrix< NekDouble, StandardMatrixTag >, ScaledMatrixTag >, BlockMatrixTag > &lhs, const NekVector< double > &rhs)
void NekMultiplyUnspecializedMatrixType(DataType *result, const NekMatrix< LhsDataType, MatrixType > &lhs, const DataType *rhs)
void NekMultiplyFullMatrix(DataType *result, const NekMatrix< InnerMatrixType, MatrixTag > &lhs, const DataType *rhs, typename std::enable_if< CanGetRawPtr< NekMatrix< InnerMatrixType, MatrixTag >>::value >::type *p=0)
@ eLOWER_TRIANGULAR_BANDED
@ eUPPER_TRIANGULAR_BANDED
void FullBlockMatrixMultiply(NekVector< DataType > &result, const NekMatrix< LhsInnerMatrixType, BlockMatrixTag > &lhs, const NekVector< DataType > &rhs)
NEKTAR_STANDARD_AND_SCALED_MATRICES_SINGLE
void NekMultiplyUpperTriangularMatrix(DataType *result, const NekMatrix< DataType, StandardMatrixTag > &lhs, const DataType *rhs)
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.