gemm(3)

πŸŽ€ gemm(3) πŸŽ€

okay bestie, welcome to the gemm(3) page from the Library Functions Manual β€” yes the whole thing is literally called gemm, and it's giving main character energy in the BLAS cinematic universe πŸ’…


✨ NAME ✨

gemm β€” gemm: general matrix-matrix multiply πŸ”₯


🌸 SYNOPSIS 🌸

🫢 Functions 🫢

  • subroutine cgemm (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc) β€” CGEMM πŸ’–
  • subroutine dgemm (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc) β€” DGEMM πŸ’–
  • subroutine sgemm (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc) β€” SGEMM πŸ’–
  • subroutine zgemm (transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc) β€” ZGEMM πŸ’–

🌈 Detailed Description 🌈

this part is just vibes β€” the actual tea is in Function Documentation right below, so keep scrolling 🧚

πŸ¦‹ Function Documentation πŸ¦‹

πŸ’œ subroutine cgemm (character transa, character transb, integer m, integer n, integer k, complex alpha, complex, dimension(lda,*) a, integer lda, complex, dimension(ldb,*) b, integer ldb, complex beta, complex, dimension(ldc,*) c, integer ldc)

⭐ CGEMM ⭐

🌟 Purpose: 🌟

okay so CGEMM performs one of the matrix-matrix operations, and it's literally this:

C := alpha*op( A )*op( B ) + beta*C,

where op( X ) is one of

op( X ) = X   or   op( X ) = X**T   or   op( X ) = X**H,

and alpha and beta are scalars, and A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. no cap, that's the whole bit 🫢

πŸŽ€ Parameters πŸŽ€

  • TRANSA β€” TRANSA is CHARACTER*1. on entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication, like this:
    • TRANSA = 'N' or 'n', op( A ) = A.
    • TRANSA = 'T' or 't', op( A ) = A**T.
    • TRANSA = 'C' or 'c', op( A ) = A**H.
  • TRANSB β€” TRANSB is CHARACTER*1. on entry, TRANSB specifies the form of op( B ) to be used in the matrix multiplication, like this:
    • TRANSB = 'N' or 'n', op( B ) = B.
    • TRANSB = 'T' or 't', op( B ) = B**T.
    • TRANSB = 'C' or 'c', op( B ) = B**H.
  • M β€” M is INTEGER. on entry, M specifies the number of rows of the matrix op( A ) and of the matrix C. M must be at least zero. lowkey non-negotiable 🫠
  • N β€” N is INTEGER. on entry, N specifies the number of columns of the matrix op( B ) and the number of columns of the matrix C. N must be at least zero.
  • K β€” K is INTEGER. on entry, K specifies the number of columns of the matrix op( A ) and the number of rows of the matrix op( B ). K must be at least zero.
  • ALPHA β€” ALPHA is COMPLEX. on entry, ALPHA specifies the scalar alpha.
  • A β€” A is COMPLEX array, dimension ( LDA, ka ), where ka is k when TRANSA = 'N' or 'n', and is m otherwise. before entry with TRANSA = 'N' or 'n', the leading m by k part of the array A must contain the matrix A, otherwise the leading k by m part of the array A must contain the matrix A. the way this array reshapes itself depending on TRANSA?? iconic πŸ¦‹
  • LDA β€” LDA is INTEGER. on entry, LDA specifies the first dimension of A as declared in the calling (sub) program. when TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ).
  • B β€” B is COMPLEX array, dimension ( LDB, kb ), where kb is n when TRANSB = 'N' or 'n', and is k otherwise. before entry with TRANSB = 'N' or 'n', the leading k by n part of the array B must contain the matrix B, otherwise the leading n by k part of the array B must contain the matrix B.
  • LDB β€” LDB is INTEGER. on entry, LDB specifies the first dimension of B as declared in the calling (sub) program. when TRANSB = 'N' or 'n' then LDB must be at least max( 1, k ), otherwise LDB must be at least max( 1, n ).
  • BETA β€” BETA is COMPLEX. on entry, BETA specifies the scalar beta. when BETA is supplied as zero then C need not be set on input. free real estate, we love a shortcut πŸ’…
  • C β€” C is COMPLEX array, dimension ( LDC, N ). before entry, the leading m by n part of the array C must contain the matrix C, except when beta is zero, in which case C need not be set on entry. on exit, the array C is overwritten by the m by n matrix ( alpha*op( A )*op( B ) + beta*C ). ⚠️ she gets overwritten, so don't come crying when your old C is gone fr fr.
  • LDC β€” LDC is INTEGER. on entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, m ).

πŸ‘‘ Author πŸ‘‘

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

πŸ“ Further Details: πŸ“

  • Level 3 Blas routine. ✨
  • -- Written on 8-February-1989.
    • Jack Dongarra, Argonne National Laboratory.
    • Iain Duff, AERE Harwell.
    • Jeremy Du Croz, Numerical Algorithms Group Ltd.
    • Sven Hammarling, Numerical Algorithms Group Ltd.

Definition at line 186 of file cgemm.f.


πŸ’œ subroutine dgemm (character transa, character transb, integer m, integer n, integer k, double precision alpha, double precision, dimension(lda,*) a, integer lda, double precision, dimension(ldb,*) b, integer ldb, double precision beta, double precision, dimension(ldc,*) c, integer ldc)

⭐ DGEMM ⭐

🌟 Purpose: 🌟

DGEMM performs one of the matrix-matrix operations, and it's literally this:

C := alpha*op( A )*op( B ) + beta*C,

where op( X ) is one of

op( X ) = X   or   op( X ) = X**T,

and alpha and beta are scalars, and A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. 🫢

heads up bestie: double precision DGEMM lists only X and X**T in its op( X ) lineup β€” no X**H in this one. the conjugate stays with the complex girls πŸ’…

πŸŽ€ Parameters πŸŽ€

  • TRANSA β€” TRANSA is CHARACTER*1. on entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication, like this:
    • TRANSA = 'N' or 'n', op( A ) = A.
    • TRANSA = 'T' or 't', op( A ) = A**T.
    • TRANSA = 'C' or 'c', op( A ) = A**T.
  • TRANSB β€” TRANSB is CHARACTER*1. on entry, TRANSB specifies the form of op( B ) to be used in the matrix multiplication, like this:
    • TRANSB = 'N' or 'n', op( B ) = B.
    • TRANSB = 'T' or 't', op( B ) = B**T.
    • TRANSB = 'C' or 'c', op( B ) = B**T.
  • M β€” M is INTEGER. on entry, M specifies the number of rows of the matrix op( A ) and of the matrix C. M must be at least zero.
  • N β€” N is INTEGER. on entry, N specifies the number of columns of the matrix op( B ) and the number of columns of the matrix C. N must be at least zero.
  • K β€” K is INTEGER. on entry, K specifies the number of columns of the matrix op( A ) and the number of rows of the matrix op( B ). K must be at least zero.
  • ALPHA β€” ALPHA is DOUBLE PRECISION. on entry, ALPHA specifies the scalar alpha.
  • A β€” A is DOUBLE PRECISION array, dimension ( LDA, ka ), where ka is k when TRANSA = 'N' or 'n', and is m otherwise. before entry with TRANSA = 'N' or 'n', the leading m by k part of the array A must contain the matrix A, otherwise the leading k by m part of the array A must contain the matrix A.
  • LDA β€” LDA is INTEGER. on entry, LDA specifies the first dimension of A as declared in the calling (sub) program. when TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ).
  • B β€” B is DOUBLE PRECISION array, dimension ( LDB, kb ), where kb is n when TRANSB = 'N' or 'n', and is k otherwise. before entry with TRANSB = 'N' or 'n', the leading k by n part of the array B must contain the matrix B, otherwise the leading n by k part of the array B must contain the matrix B.
  • LDB β€” LDB is INTEGER. on entry, LDB specifies the first dimension of B as declared in the calling (sub) program. when TRANSB = 'N' or 'n' then LDB must be at least max( 1, k ), otherwise LDB must be at least max( 1, n ).
  • BETA β€” BETA is DOUBLE PRECISION. on entry, BETA specifies the scalar beta. when BETA is supplied as zero then C need not be set on input. πŸŽ€
  • C β€” C is DOUBLE PRECISION array, dimension ( LDC, N ). before entry, the leading m by n part of the array C must contain the matrix C, except when beta is zero, in which case C need not be set on entry. on exit, the array C is overwritten by the m by n matrix ( alpha*op( A )*op( B ) + beta*C ). ⚠️ again: overwritten, so screenshot your C before you call this, iykyk.
  • LDC β€” LDC is INTEGER. on entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, m ).

πŸ‘‘ Author πŸ‘‘

  • Univ. of Tennessee

…and that's where part 1 leaves us, mid-author-list, on a cliffhanger 🫠 more is literally coming πŸ’œ

🌟 Author

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

🫢 Further Details

Like, here's the receipts, bestie β€” the original header comment, verbatim:

!>
!>  Level 3 Blas routine.
!>
!>  -- Written on 8-February-1989.
!>     Jack Dongarra, Argonne National Laboratory.
!>     Iain Duff, AERE Harwell.
!>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
!>     Sven Hammarling, Numerical Algorithms Group Ltd.
!>

So yeah β€” Level 3 Blas routine, written on 8-February-1989 by Jack Dongarra (Argonne National Laboratory), Iain Duff (AERE Harwell), Jeremy Du Croz (Numerical Algorithms Group Ltd.) and Sven Hammarling (Numerical Algorithms Group Ltd.). Legends. Periodt. πŸ‘‘

Definition at line 186 of file dgemm.f.


πŸ¦‹ subroutine sgemm (character transa, character transb, integer m, integer n, integer k, real alpha, real, dimension(lda,) a, integer lda, real, dimension(ldb,) b, integer ldb, real beta, real, dimension(ldc,*) c, integer ldc)

subroutine sgemm (character transa, character transb, integer m, integer n,
    integer k, real alpha, real, dimension(lda,*) a, integer lda, real,
    dimension(ldb,*) b, integer ldb, real beta, real, dimension(ldc,*) c,
    integer ldc)

SGEMM πŸ’…

✨ Purpose

Okay so SGEMM performs one of the matrix-matrix operations

C := alpha*op( A )*op( B ) + beta*C,

where op( X ) is one of

op( X ) = X   or   op( X ) = X**T,

alpha and beta are scalars, and A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. It's giving "the" matmul, fr fr. πŸ”₯

πŸ”₯ Parameters

  • TRANSA β€” TRANSA is CHARACTER*1. On entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication, as follows:
    • TRANSA = 'N' or 'n', op( A ) = A.
    • TRANSA = 'T' or 't', op( A ) = A**T.
    • TRANSA = 'C' or 'c', op( A ) = A**T.
  • TRANSB β€” TRANSB is CHARACTER*1. On entry, TRANSB specifies the form of op( B ) to be used in the matrix multiplication, as follows:
    • TRANSB = 'N' or 'n', op( B ) = B.
    • TRANSB = 'T' or 't', op( B ) = B**T.
    • TRANSB = 'C' or 'c', op( B ) = B**T.
Not me pointing out that for this real version, 'C' gives you the exact same thing as 'T' β€” both are A**T/B**T up there. That's literally what the page says, don't come for me. πŸ™ˆ
  • M β€” M is INTEGER. On entry, M specifies the number of rows of the matrix op( A ) and of the matrix C. M must be at least zero. Zero is a valid vibe, apparently. πŸ’€
  • N β€” N is INTEGER. On entry, N specifies the number of columns of the matrix op( B ) and the number of columns of the matrix C. N must be at least zero.
  • K β€” K is INTEGER. On entry, K specifies the number of columns of the matrix op( A ) and the number of rows of the matrix op( B ). K must be at least zero.
  • ALPHA β€” ALPHA is REAL. On entry, ALPHA specifies the scalar alpha. Just a little guy. πŸŽ€
  • A β€” A is REAL array, dimension ( LDA, ka ), where ka is k when TRANSA = 'N' or 'n', and is m otherwise. Before entry with TRANSA = 'N' or 'n', the leading m by k part of the array A must contain the matrix A, otherwise the leading k by m part of the array A must contain the matrix A. Yes, that's the shape-swap, iykyk.
  • LDA β€” LDA is INTEGER. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ). That max( 1, ... ) is doing the Lord's work, don't skip it.
  • B β€” B is REAL array, dimension ( LDB, kb ), where kb is n when TRANSB = 'N' or 'n', and is k otherwise. Before entry with TRANSB = 'N' or 'n', the leading k by n part of the array B must contain the matrix B, otherwise the leading n by k part of the array B must contain the matrix B.
  • LDB β€” LDB is INTEGER. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. When TRANSB = 'N' or 'n' then LDB must be at least max( 1, k ), otherwise LDB must be at least max( 1, n ).
  • BETA β€” BETA is REAL. On entry, BETA specifies the scalar beta. When BETA is supplied as zero then C need not be set on input. Big slay β€” you literally don't have to initialize C in that case, the routine's not even gonna look. 🧚
  • C β€” C is REAL array, dimension ( LDC, N ). Before entry, the leading m by n part of the array C must contain the matrix C, except when beta is zero, in which case C need not be set on entry. On exit, the array C is overwritten by the m by n matrix ( alpha*op( A )*op( B ) + beta*C ).
⚠️ Overwritten. C comes in as your matrix and leaves as the answer β€” it's the main character of this whole page, and it does NOT get to keep its old self. If you still needed the original C, copy it first. 😭
  • LDC β€” LDC is INTEGER. On entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, m ).

🌈 Author

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

πŸ“ Further Details

Same iconique header comment, bestie:

!>
!>  Level 3 Blas routine.
!>
!>  -- Written on 8-February-1989.
!>     Jack Dongarra, Argonne National Laboratory.
!>     Iain Duff, AERE Harwell.
!>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
!>     Sven Hammarling, Numerical Algorithms Group Ltd.
!>

Level 3 Blas routine, written on 8-February-1989 by Jack Dongarra (Argonne National Laboratory), Iain Duff (AERE Harwell), Jeremy Du Croz (Numerical Algorithms Group Ltd.) and Sven Hammarling (Numerical Algorithms Group Ltd.). Same squad, single precision this time. πŸ’œ

Definition at line 186 of file sgemm.f.


🧚 subroutine zgemm (character transa, character transb, integer m, integer n, integer k, complex*16 alpha, complex*16, dimension(lda,) a, integer lda, complex16, dimension(ldb,) b, integer ldb, complex16 beta, complex*16, dimension(ldc,*) c, integer ldc)

subroutine zgemm (character transa, character transb, integer m, integer n,
    integer k, complex*16 alpha, complex*16, dimension(lda,*) a, integer
    lda, complex*16, dimension(ldb,*) b, integer ldb, complex*16 beta,
    complex*16, dimension(ldc,*) c, integer ldc)

ZGEMM πŸ‘‘

⭐ Purpose

ZGEMM performs one of the matrix-matrix operations

C := alpha*op( A )*op( B ) + beta*C,

where op( X ) is one of

op( X ) = X   or   op( X ) = X**T   or   op( X ) = X**H,

alpha and beta are scalars, and A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix and C an m by n matrix. And yes β€” X**H is in the building here, that's the conjugate-transpose upgrade, we're in complex land now. πŸ¦‹

πŸ’« Parameters

  • TRANSA β€” TRANSA is CHARACTER*1. On entry, TRANSA specifies the form of op( A ) to be used in the matrix multiplication, as follows:
    • TRANSA = 'N' or 'n', op( A ) = A.
    • TRANSA = 'T' or 't', op( A ) = A**T.
    • TRANSA = 'C' or 'c', op( A ) = A**H.
⚠️ Careful, bestie: for ZGEMM, 'C' means A**H β€” conjugate transpose β€” not plain A**T. That's a whole different vibe from the real-precision versions up the page. πŸ’€
  • TRANSB β€” TRANSB is CHARACTER*1. On entry, TRANSB specifies the form of op( B ) to be used in the matrix multiplication, as follows:
    • TRANSB = 'N' or 'n', op( B ) = B.
    • TRANSB = 'T' or 't', op( B ) = B**T.
    • TRANSB = 'C' or 'c', op( B ) = B**H.
  • M β€” M is INTEGER. On entry, M specifies the number of rows of the matrix op( A ) and of the matrix C. M must be at least zero.
  • N β€” N is INTEGER. On entry, N specifies the number of columns of the matrix op( B ) and the number of columns of the matrix C. N must be at least zero.
  • K β€” K is INTEGER. On entry, K specifies the number of columns of the matrix op( A ) and the number of rows of the matrix op( B ). K must be at least zero.
  • ALPHA β€” ALPHA is COMPLEX*16. On entry, ALPHA specifies the scalar alpha.
  • A β€” A is COMPLEX*16 array, dimension ( LDA, ka ), where ka is k when TRANSA = 'N' or 'n', and is m otherwise. Before entry with TRANSA = 'N' or 'n', the leading m by k part of the array A must contain the matrix A, otherwise the leading k by m part of the array A must contain the matrix A.
  • LDA β€” LDA is INTEGER. On entry, LDA specifies the first dimension of A as declared in the calling (sub) program. When TRANSA = 'N' or 'n' then LDA must be at least max( 1, m ), otherwise LDA must be at least max( 1, k ).
  • B β€” B is COMPLEX*16 array, dimension ( LDB, kb ), where kb is n when TRANSB = 'N' or 'n', and is k otherwise. Before entry with TRANSB = 'N' or 'n', the leading k by n part of the array B must contain the matrix B, otherwise the leading n by k part of the array B must contain the matrix B.
  • LDB β€” LDB is INTEGER. On entry, LDB specifies the first dimension of B as declared in the calling (sub) program. When TRANSB = 'N' or 'n' then LDB must be at least max( 1, k ), otherwise LDB must be at least max( 1, n ).
  • BETA β€” BETA is COMPLEX*16. On entry, BETA specifies the scalar beta. When BETA is supplied as zero then C need not be set on input. Free pass on initializing C, we love to see it. πŸŽ€
  • C β€” C is COMPLEX*16 array, dimension ( LDC, N ). Before entry, the leading m by n part of the array C must contain the matrix C, except when beta is zero, in which case C need not be set on entry. On exit, the array C is overwritten by the m by n matrix ( alpha*op( A )*op( B ) + beta*C ).
⚠️ Again, for the people in the back: C gets overwritten on exit. Whatever was in there before is gone-gone. Save a copy if you need it. 😭
  • LDC β€” LDC is INTEGER. On entry, LDC specifies the first dimension of C as declared in the calling (sub) program. LDC must be at least max( 1, m ).

🌸 Author

  • Univ. of Tennessee
  • Univ. of California Berkeley
  • Univ. of Colorado Denver
  • NAG Ltd.

πŸ’– Further Details

And the header comment, one more time, verbatim:

!>
!>  Level 3 Blas routine.
!>
!>  -- Written on 8-February-1989.
!>     Jack Dongarra, Argonne National Laboratory.
!>     Iain Duff, AERE Harwell.
!>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
!>     Sven Hammarling, Numerical Algorithms Group Ltd.
!>

Level 3 Blas routine, written on 8-February-1989 by Jack Dongarra (Argonne National Laboratory), Iain Duff (AERE Harwell), Jeremy Du Croz (Numerical Algorithms Group Ltd.) and Sven Hammarling (Numerical Algorithms Group Ltd.). Double-complex iconique behavior only. ✨

...and that's literally where the source file itself starts spilling the tea πŸ«– β€” like, before any of the math even happens, the Fortran file opens with a whole little author shoutout baked right into the comments:

!>
!>  Level 3 Blas routine.
!>
!>  -- Written on 8-February-1989.
!>     Jack Dongarra, Argonne National Laboratory.
!>     Iain Duff, AERE Harwell.
!>     Jeremy Du Croz, Numerical Algorithms Group Ltd.
!>     Sven Hammarling, Numerical Algorithms Group Ltd.
!>

okay but the way this is a Level 3 Blas routine and they put it in the very first comment line like a little name tag at a party 😭 iconic behavior honestly. And then the receipt: -- Written on 8-February-1989. bestie that is ancient in computer years and it's still out here doing matrix multiplication for you. Respect the elders πŸ’…

The whole squad, in order, no cap:

  • Jack Dongarra, Argonne National Laboratory
  • Iain Duff, AERE Harwell
  • Jeremy Du Croz, Numerical Algorithms Group Ltd.
  • Sven Hammarling, Numerical Algorithms Group Ltd.

four legends, one subroutine, zero notes πŸŽ€ we simply have to stan.

Also clocking the location details so you can find it yourself, because iykyk:

  • Definition at line 186 of file zgemm.f.

like, line 186, file zgemm.f β€” that's the exact spot in the source, go look, it's right there πŸ¦‹


πŸ‘‘ Author πŸ‘‘

Generated automatically by Doxygen for LAPACK from the source code.

Yeah so nobody hand-wrote this bad boy β€” Doxygen basically scraped it straight out of the LAPACK source code and served it up for us, which is lowkey the most efficient glow-up ever ✨ (no human author to thank for the manpage itself, the tool did all the heavy lifting 🫢).


fr fr reminder before you go: everything above is the vibe and the facts β€” every flag, every argument, every default, every zgemm.f detail stayed exactly where it was. I just gave it a personality πŸ’–

Okay that's the whole page, you made it to the end, slay πŸŽ‰ go forth and multiply your matrices, bestie.

πŸ’œ brought to you by LAPACK, Version 3.12.0, and this little gemm(3) page β€” mwah, see you in the next manpage πŸ§šβ€β™€οΈπŸŒΈ

πŸ“¦ where this page comes from