1
0
mirror of https://github.com/TREX-CoE/qmckl.git synced 2024-11-19 12:32:40 +01:00
qmckl/org/qmckl_blas.org
2021-10-14 21:53:00 +02:00

9.3 KiB

BLAS functions

Matrix operations

qmckl_dgemm

Matrix multiply: $C_{ij} = \beta C_{ij} + \alpha \sum_{k} A_{ik} \cdot B_{kj}$ using Fortran matmul function.

TODO: Add description about the external library dependence.

qmckl_context context in Global state
bool TransA in Number of rows of the input matrix
bool TransB in Number of rows of the input matrix
int64_t m in Number of rows of the input matrix
int64_t n in Number of columns of the input matrix
int64_t k in Number of columns of the input matrix
double alpha in Number of columns of the input matrix
double A[][lda] in Array containing the $m \times n$ matrix $A$
int64_t lda in Leading dimension of array A
double B[][ldb] in Array containing the $n \times m$ matrix $B$
int64_t ldb in Leading dimension of array B
double beta in Array containing the $n \times m$ matrix $B$
double C[][ldc] out Array containing the $n \times m$ matrix $B$
int64_t ldc in Leading dimension of array B

Requirements

  • context is not QMCKL_NULL_CONTEXT
  • m > 0
  • n > 0
  • k > 0
  • lda >= m
  • ldb >= n
  • ldc >= n
  • A is allocated with at least $m \times k \times 8$ bytes
  • B is allocated with at least $k \times n \times 8$ bytes
  • C is allocated with at least $m \times n \times 8$ bytes

C header

qmckl_exit_code qmckl_dgemm (
const qmckl_context context,
const bool TransA,
const bool TransB,
const int64_t m,
const int64_t n,
const int64_t k,
const double alpha,
const double* A,
const int64_t lda,
const double* B,
const int64_t ldb,
const double beta,
double* const C,
const int64_t ldc );

Source

integer function qmckl_dgemm_f(context, TransA, TransB, m, n, k, alpha, A, LDA, B, LDB, beta, C, LDC) &
 result(info)
use qmckl
implicit none
integer(qmckl_context)  , intent(in)  :: context
logical*8  , intent(in)  :: TransA, TransB
integer*8  , intent(in)  :: m, n, k
real*8     , intent(in)  :: alpha, beta
integer*8  , intent(in)  :: lda
real*8     , intent(in)  :: A(m,k)
integer*8  , intent(in)  :: ldb
real*8     , intent(in)  :: B(k,n)
integer*8  , intent(in)  :: ldc
real*8     , intent(out) :: C(m,n)
real*8, allocatable      :: AT(:,:), BT(:,:), CT(:,:)

integer*8 :: i,j,l, LDA_2, LDB_2

info = QMCKL_SUCCESS

if (TransA) then
allocate(AT(k,m))
do i = 1, m
  do j = 1, k
    AT(j,i) = A(i,j)
  end do
end do
LDA_2 = M
else
LDA_2 = LDA
endif

if (TransB) then
allocate(BT(n,k))
do i = 1, k
  do j = 1, n
    BT(j,i) = B(i,j)
  end do
end do
LDB_2 = K
else
LDB_2 = LDB
endif

if (context == QMCKL_NULL_CONTEXT) then
 info = QMCKL_INVALID_CONTEXT
 return
endif

if (m <= 0_8) then
 info = QMCKL_INVALID_ARG_4
 return
endif

if (n <= 0_8) then
 info = QMCKL_INVALID_ARG_5
 return
endif

if (k <= 0_8) then
 info = QMCKL_INVALID_ARG_6
 return
endif

if (LDA_2 .ne. m) then
 info = QMCKL_INVALID_ARG_9
 return
endif

if (LDB_2 .ne. k) then
 info = QMCKL_INVALID_ARG_10
 return
endif

if (LDC .ne. m) then
 info = QMCKL_INVALID_ARG_13
 return
endif

if (TransA) then
 if (alpha == 1.d0 && beta == 0.d0) then
   C = matmul(AT,B)
 else
   C = beta*C + alpha*matmul(AT,B)
 endif
else if (TransB) then
 if (alpha == 1.d0 && beta == 0.d0) then
   C = matmul(A,BT)
 else
   C = beta*C + alpha*matmul(A,BT)
 endif
else
 if (alpha == 1.d0 && beta == 0.d0) then
   C = matmul(A,B)
 else
   C = beta*C + alpha*matmul(A,B)
 endif
endif
end function qmckl_dgemm_f