CBLAS_DROTMG_64(3)

πŸ“¦
version 3.12.1 Β· 3 versions
, in arch rolling

πŸŽ€ CBLAS/include/cblas_64.h β€” Library Functions Manual, section 3 πŸŽ€

okay bestie, listen up πŸ’– this one's a header file, and yes she's that girl. Full path, exactly as she comes: CBLAS/include/cblas_64.h. She lives in the Library Functions Manual and she's section 3, so she's officially in the library-functions club πŸ‘‘ no cap, that's the whole vibe check.


✨ NAME ✨

CBLAS/include/cblas_64.h β€” that's the name, that's the whole name, and we're not adding anything to it 🫢 literally just the path, forehead kiss, moving on.


🌸 SYNOPSIS 🌸

so here's how you slide into her DMs β€” you pull in these three headers first, in this exact order, no freestyling:

#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>

and then, the main character herself πŸ’…

#include 'cblas.h'
bestie, real talk: those first three are angle-bracket includes and that last one is a quoted include β€” 'cblas.h' β€” so don't go "fixing" it into angle brackets, iykyk 😭 copy it exactly, character for character, because that's how she's written and we respect the source πŸ™ˆ

that's the opener, and there's so much more coming β€” do not touch that dial πŸ¦‹βœ¨

πŸ’« Functions πŸ’«

okay bestie, this is the part where the page just starts listing every single function in cblas_64.h and honestly? it's a lot. every int64_t you see is the whole point of this header β€” the _64 suffix means those bad boys are 64-bit ints, and the plain float/double types are doing their usual thing. take a breath, we're going through all of them 🌸

  • double cblas_dcabs1_64 (const void *z) β€” hands you back a double, takes a single const void *z. that's it, that's the whole vibe check.
  • float cblas_scabs1_64 (const void *c) β€” same energy as the one above but float and a const void *c. tiny, cute, doing its job ✨
  • float cblas_sdsdot_64 (const int64_t N, const float alpha, const float *X, const int64_t incX, const float *Y, const int64_t incY) β€” the sdsdot variant, float return, and yes it's got an alpha in there alongside N, X, incX, Y, incY.
  • double cblas_dsdot_64 (const int64_t N, const float *X, const int64_t incX, const float *Y, const int64_t incY) β€” same crew of args minus the alpha, and it comes back as a double. glow up πŸ’…
  • float cblas_sdot_64 (const int64_t N, const float *X, const int64_t incX, const float *Y, const int64_t incY) β€” the classic: N, two float pointers X and Y, two incX/incY strides, float result.
  • double cblas_ddot_64 (const int64_t N, const double *X, const int64_t incX, const double *Y, const int64_t incY) β€” identical shape, but everything's double now. main character energy πŸ”₯
  • void cblas_cdotu_sub_64 (const int64_t N, const void *X, const int64_t incX, const void *Y, const int64_t incY, void *dotu) β€” returns void and writes into that last void *dotu. note the _sub in the name, bestie, it's not giving you a return value.
  • void cblas_cdotc_sub_64 (const int64_t N, const void *X, const int64_t incX, const void *Y, const int64_t incY, void *dotc) β€” exact same lineup, but the output pointer is void *dotc. πŸ¦‹
  • void cblas_zdotu_sub_64 (const int64_t N, const void *X, const int64_t incX, const void *Y, const int64_t incY, void *dotu) β€” the z version, void return, results land in void *dotu.
  • void cblas_zdotc_sub_64 (const int64_t N, const void *X, const int64_t incX, const void *Y, const int64_t incY, void *dotc) β€” and here's its sibling with void *dotc. matching set, obsessed πŸŽ€
  • float cblas_snrm2_64 (const int64_t N, const float *X, const int64_t incX) β€” float back out, just N, const float *X, incX going in. tidy.
  • float cblas_sasum_64 (const int64_t N, const float *X, const int64_t incX) β€” same three args, same float return. the way that incX keeps showing up 😭
  • double cblas_dnrm2_64 (const int64_t N, const double *X, const int64_t incX) β€” same shape, double *X, double result.
  • double cblas_dasum_64 (const int64_t N, const double *X, const int64_t incX) β€” N, const double *X, incX, and a double at the end. periodt.
  • float cblas_scnrm2_64 (const int64_t N, const void *X, const int64_t incX) β€” now X is a const void * and the return is still float. πŸ’–
  • float cblas_scasum_64 (const int64_t N, const void *X, const int64_t incX) β€” same const void *X treatment, float return.
  • double cblas_dznrm2_64 (const int64_t N, const void *X, const int64_t incX) β€” double version of the void * situation. love that for us.
  • double cblas_dzasum_64 (const int64_t N, const void *X, const int64_t incX) β€” and its matching double-returning twin. 🌈

okay now we're getting into the index-returning ones and the return type changes, so keep your eyes on the CBLAS_INDEX bestie πŸ‘€

  • CBLAS_INDEX cblas_isamax_64 (const int64_t N, const float *X, const int64_t incX) β€” returns CBLAS_INDEX, not a float, not a double, an index. const float *X in, incX alongside.
  • CBLAS_INDEX cblas_idamax_64 (const int64_t N, const double *X, const int64_t incX) β€” same CBLAS_INDEX return, but const double *X this time. ⭐
  • CBLAS_INDEX cblas_icamax_64 (const int64_t N, const void *X, const int64_t incX) β€” CBLAS_INDEX out, const void *X in. iconic.
  • CBLAS_INDEX cblas_izamax_64 (const int64_t N, const void *X, const int64_t incX) β€” the z edition, identical args, identical CBLAS_INDEX return. 🫢
  • void cblas_sswap_64 (const int64_t N, float *X, const int64_t incX, float *Y, const int64_t incY) β€” note: X and Y are non-const float * here, because yes, this one's touching both of them. void return, no receipts.
  • void cblas_scopy_64 (const int64_t N, const float *X, const int64_t incX, float *Y, const int64_t incY) β€” source X is const, destination Y is not. the asymmetry is the whole point πŸ’…
  • void cblas_saxpy_64 (const int64_t N, const float alpha, const float *X, const int64_t incX, float *Y, const int64_t incY) β€” float alpha slides in third, then const X, then non-const Y.
  • void cblas_dswap_64 (const int64_t N, double *X, const int64_t incX, double *Y, const int64_t incY) β€” the double swap, same non-const both-sides energy.
  • void cblas_dcopy_64 (const int64_t N, const double *X, const int64_t incX, double *Y, const int64_t incY) β€” const double *X β†’ double *Y. chef's kiss πŸ”₯
  • void cblas_daxpy_64 (const int64_t N, const double alpha, const double *X, const int64_t incX, double *Y, const int64_t incY) β€” double alpha in the third slot, everything else double-ified.
  • void cblas_cswap_64 (const int64_t N, void *X, const int64_t incX, void *Y, const int64_t incY) β€” both void *, both mutable. no const in sight, be aware 🫣
  • void cblas_ccopy_64 (const int64_t N, const void *X, const int64_t incX, void *Y, const int64_t incY) β€” here X is const void * and Y is plain void *. balanced.
  • void cblas_caxpy_64 (const int64_t N, const void *alpha, const void *X, const int64_t incX, void *Y, const int64_t incY) β€” alpha comes in as const void *. yes, a pointer, not a number. read it again, it's fine 😭
  • void cblas_zswap_64 (const int64_t N, void *X, const int64_t incX, void *Y, const int64_t incY) β€” z swap, void * city.
  • void cblas_zcopy_64 (const int64_t N, const void *X, const int64_t incX, void *Y, const int64_t incY) β€” const source, mutable dest. the classic combo 🌸
  • void cblas_zaxpy_64 (const int64_t N, const void *alpha, const void *X, const int64_t incX, void *Y, const int64_t incY) β€” pointer alpha again. void * everything, void return, we move. πŸ’€

  • void cblas_srotmg_64 (float *d1, float *d2, float *b1, const float b2, float *P) β€” no N, no incX β€” just five float things: d1, d2, b1, the lone const float b2, and P. also hi, P is uppercase here πŸ‘‘
  • void cblas_srotm_64 (const int64_t N, float *X, const int64_t incX, float *Y, const int64_t incY, const float *P) β€” and here P is a const float *. different P energy, don't mix them up bestie.
  • void cblas_drotmg_64 (double *d1, double *d2, double *b1, const double b2, double *P) β€” the double glow-up of rotmg. same five-slot layout.
  • void cblas_drotm_64 (const int64_t N, double *X, const int64_t incX, double *Y, const int64_t incY, const double *P) β€” double everything and a const double *P at the end. ⭐
  • void cblas_sscal_64 (const int64_t N, const float alpha, float *X, const int64_t incX) β€” alpha second, float *X third, incX last. small but mighty.
  • void cblas_dscal_64 (const int64_t N, const double alpha, double *X, const int64_t incX) β€” same but double. consistent queen πŸ’…
  • void cblas_cscal_64 (const int64_t N, const void *alpha, void *X, const int64_t incX) β€” pointer alpha again, void *X mutable.
  • void cblas_zscal_64 (const int64_t N, const void *alpha, void *X, const int64_t incX) β€” z version, exactly the same shape. πŸ¦‹
  • void cblas_csscal_64 (const int64_t N, const float alpha, void *X, const int64_t incX) β€” sneaky one: alpha is a plain float here, not a pointer. catch it.
  • void cblas_zdscal_64 (const int64_t N, const double alpha, void *X, const int64_t incX) β€” and this one takes a plain double alpha. matching set πŸŽ€
  • void cblas_srotg_64 (float *a, float *b, float *c, float *s) β€” four lowercase pointer args: a, b, c, s. that's the whole signature, no N invited.
  • void cblas_drotg_64 (double *a, double *b, double *c, double *s) β€” same four, all double. ✨
  • void cblas_crotg_64 (void *a, void *b, float *c, void *s) β€” okay look closely: c is a float * while a, b, s are void *. don't flatten them in your head 🫢
  • void cblas_zrotg_64 (void *a, void *b, double *c, void *s) β€” and here c is double *, others void *. same deal, different precision.
  • void cblas_srot_64 (const int64_t N, float *X, const int64_t incX, float *Y, const int64_t incY, const float c, const float s) β€” and now lowercase c and s are trailing values, not pointers. yes, rot and rotg are different vibes, keep up bestie 😭
  • void cblas_drot_64 (const int64_t N, double *X, const int64_t incX, double *Y, const int64_t incY, const double c, const double s) β€” double everything, trailing const double c, const double s.
  • void cblas_csrot_64 (const int64_t N, void *X, const int64_t incX, void *Y, const int64_t incY, const float c, const float s) β€” void * X and Y, but c and s are float. hybrid moment πŸ”₯
  • void cblas_zdrot_64 (const int64_t N, void *X, const int64_t incX, void *Y, const int64_t incY, const double c, const double s) β€” same, except c and s are double. πŸ’œ

okay now the matrix-vector zone, where the argument lists get long and layout/TransA/Uplo/Diag enter the chat. deep breath, we're doing all of them 🌈

  • void cblas_sgemv_64 (const CBLAS_LAYOUT layout, const CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const float alpha, const float *A, const int64_t lda, const float *X, const int64_t incX, const float beta, float *Y, const int64_t incY) β€” twelve args and not a single one is optional. layout, TransA, M, N, alpha, A, lda, X, incX, beta, Y, incY. copy it exactly, no heroics.
  • void cblas_sgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const float alpha, const float *A, const int64_t lda, const float *X, const int64_t incX, const float beta, float *Y, const int64_t incY) β€” the b version, so KL and KU join between N and alpha. also note layout and TransA drop their const here πŸ‘€
  • void cblas_strmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const float *A, const int64_t lda, float *X, const int64_t incX) β€” now it's Uplo and Diag too, and notice there's no M, no alpha, no beta. different beast.
  • void cblas_stbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const float *A, const int64_t lda, float *X, const int64_t incX) β€” tbmv means interspersed Kright afterN, followed by A, lda, X, incX`.
  • void cblas_stpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const float *Ap, float *X, const int64_t incX) β€” packed version! the arg is Ap (little p, bestie, Ap not A) and there's no lda or K to be found.
  • void cblas_strsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const float *A, const int64_t lda, float *X, const int64_t incX) β€” identical clothes to strmv, but it's a solve. read the name, not the shape πŸ’…
  • void cblas_stbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const float *A, const int64_t lda, float *X, const int64_t incX) β€” the solve with K wedged in after N. yes, exactly like stbmv but s v at the end.
  • void cblas_stpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const float *Ap, float *X, const int64_t incX) β€” packed solve. Ap, X, incX, done. πŸ“
  • void cblas_dgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const double alpha, const double *A, const int64_t lda, const double *X, const int64_t incX, const double beta, double *Y, const int64_t incY) β€” the double gemv, twelve args of pure commitment.
  • void cblas_dgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const double alpha, const double *A, const int64_t lda, const double *X, const int64_t incX, const double beta, double *Y, const int64_t incY) β€” KL/KU back in the middle plus double everything else.
  • void cblas_dtrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const double *A, const int64_t lda, double *X, const int64_t incX) β€” Uplo + Diag + double, no M, no Greek letters. ✨
  • void cblas_dtbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const double *A, const int64_t lda, double *X, const int64_t incX) β€” K after N, double *A, lda, double *X, incX.
  • void cblas_dtpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const double *Ap, double *X, const int64_t incX) β€” packed and double-coded. Ap with the lowercase p, always.
  • void cblas_dtrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const double *A, const int64_t lda, double *X, const int64_t incX) β€” d + tr + sv, the solve, same list as dtrmv. 😌
  • void cblas_dtbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const double *A, const int64_t lda, double *X, const int64_t incX) β€” K present, double present, solve present. all accounted for.
  • void cblas_dtpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const double *Ap, double *X, const int64_t incX) β€” packed double solve, short and sweet. 🧚
  • void cblas_cgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const void *alpha, const void *A, const int64_t lda, const void *X, const int64_t incX, const void *beta, void *Y, const int64_t incY) β€” c means the scalars and vectors are void * now. alpha const, beta const, Y the only mutable one in the party πŸŽ€
  • void cblas_cgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const void *alpha, const void *A, const int64_t lda, const void *X, const int64_t incX, const void *beta, void *Y, const int64_t incY) β€” plus KL and KU, because of course.
  • void cblas_ctrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void *A, const int64_t lda, void *X, const int64_t incX) β€” const void *A in, void *X out, Uplo and Diag along for the ride.
  • void cblas_ctbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void *A, const int64_t lda, void *X, const int64_t incX) β€” K after N, void * for A and X. πŸ’œ
  • void cblas_ctpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void *Ap, void *X, const int64_t incX) β€” packed, Ap, no lda. πŸ¦‹
  • void cblas_ctrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void *A, const int64_t lda, void *X, const int64_t incX) β€” the c solve, const void *A β†’ void *X.
  • void cblas_ctbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void *A, const int64_t lda, void *X, const int64_t incX) β€” banded c solve, K included, all the usuals.
  • void cblas_ctpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void *Ap, void *X, const int64_t incX) β€” packed c solve. shortest of the bunch, still slays. ⭐
  • void cblas_zgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const void *alpha, const void *A, const int64_t lda, const void *X, const int64_t incX, const void *beta, void *Y, const int64_t incY) β€” z flavour, void * everything, twelve args, same deal as c but you know it's the fancy one πŸ‘‘
  • void cblas_zgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, β€” and the page just… stops mid-signature right here 😭 the zgbmv entry is cut off after KU in this chunk, so we pick it back up next part. don't panic, it's not you, it's the page 🫢

…and we're literally starting this part mid-signature, bestie, because that's just how long this list is. Here's the tail of the prototype from last time (you know the one ✨):

           const void *alpha, const void *A, const int64_t lda, const void *X,
           const int64_t incX, const void *beta, void *Y, const int64_t incY)

Cool cool cool, moving on 🫢

πŸ¦‹ the complex triangular girlies (vector edition)

Same vibe check every time: layout, Uplo, TransA, Diag, N, the matrix, lda, the vector X, and incX. Spotted. Noted. Slay.
       void cblas_ztrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void
           *A, const int64_t lda, void *X, const int64_t incX)
       void cblas_ztbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const
           int64_t K, const void *A, const int64_t lda, void *X, const int64_t
           incX)
       void cblas_ztpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void
           *Ap, void *X, const int64_t incX)
       void cblas_ztrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void
           *A, const int64_t lda, void *X, const int64_t incX)
       void cblas_ztbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const
           int64_t K, const void *A, const int64_t lda, void *X, const int64_t
           incX)
       void cblas_ztpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void
           *Ap, void *X, const int64_t incX)

Notice the mv ones (*trmv, *tbmv, *tpmv) and the sv ones (*trsv, *tbsv, *tpsv) are siblings, and the three flavours are the same three flavours every time: full (tr), banded (tb, extra K πŸ‘€), packed (tp, that Ap instead of A + lda). Iconic consistency, honestly.


πŸ“ single precision, symmetric era

       void cblas_ssymv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *A, const int64_t lda, const float
           *X, const int64_t incX, const float beta, float *Y, const int64_t
           incY)
       void cblas_ssbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const int64_t K, const float alpha, const float *A, const int64_t
           lda, const float *X, const int64_t incX, const float beta, float *Y,
           const int64_t incY)
       void cblas_sspmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *Ap, const float *X, const int64_t
           incX, const float beta, float *Y, const int64_t incY)
       void cblas_sger_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const float alpha, const float *X, const int64_t incX, const
           float *Y, const int64_t incY, float *A, const int64_t lda)
       void cblas_ssyr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *X, const int64_t incX, float *A,
           const int64_t lda)
       void cblas_sspr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *X, const int64_t incX, float *Ap)
       void cblas_ssyr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *X, const int64_t incX, const
           float *Y, const int64_t incY, float *A, const int64_t lda)
       void cblas_sspr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const float *X, const int64_t incX, const
           float *Y, const int64_t incY, float *A)

the way that ssymv / ssbmv / sspmv all take alpha, X, incX, beta, Y, incY and only differ in how the matrix shows up (*A + lda, *A + lda + K, *Ap) β€” main character energy from all three tbh πŸ’…

And the rank-updates are out here doing the most: sger takes M and N (it's a rectangle situation), while ssyr, sspr, ssyr2, sspr2 are square-coded with just N and a Uplo. Two vectors for the 2 ones (X and Y, each with their own incX / incY), one vector for the rest. Also note sspr2_64 writes into *A, not *Ap β€” that's literally what the prototype says, don't come for me πŸ‘‘.


🧚 double precision, same energy, more bytes

       void cblas_dsymv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *A, const int64_t lda, const
           double *X, const int64_t incX, const double beta, double *Y, const
           int64_t incY)
       void cblas_dsbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const int64_t K, const double alpha, const double *A, const
           int64_t lda, const double *X, const int64_t incX, const double beta,
           double *Y, const int64_t incY)
       void cblas_dspmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *Ap, const double *X, const
           int64_t incX, const double beta, double *Y, const int64_t incY)
       void cblas_dger_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const double alpha, const double *X, const int64_t incX, const
           double *Y, const int64_t incY, double *A, const int64_t lda)
       void cblas_dsyr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *X, const int64_t incX, double
           *A, const int64_t lda)
       void cblas_dspr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *X, const int64_t incX, double
           *Ap)
       void cblas_dsyr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *X, const int64_t incX, const
           double *Y, const int64_t incY, double *A, const int64_t lda)
       void cblas_dspr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const double *X, const int64_t incX, const
           double *Y, const int64_t incY, double *A)

fr fr it's the exact same shape as the s block, just double everywhere instead of float. iykyk 🌸


πŸ’œ complex, Hermitian-adjacent, doing the absolute most

       void cblas_chemv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *A, const int64_t lda, const void
           *X, const int64_t incX, const void *beta, void *Y, const int64_t
           incY)
       void cblas_chbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const int64_t K, const void *alpha, const void *A, const int64_t
           lda, const void *X, const int64_t incX, const void *beta, void *Y,
           const int64_t incY)
       void cblas_chpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *Ap, const void *X, const int64_t
           incX, const void *beta, void *Y, const int64_t incY)
       void cblas_cgeru_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_cgerc_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_cher_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const void *X, const int64_t incX, void *A,
           const int64_t lda)
       void cblas_chpr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const float alpha, const void *X, const int64_t incX, void *A)
       void cblas_cher2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_chpr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *Ap)
πŸ‘€ stayed up late noticing this: cblas_cher_64 and cblas_chpr_64 take a plain const float alpha, not const void *alpha like all their friends. That's not a typo on my end, bestie β€” that's exactly what the page says. Same deal for zher / zhpr below, which take const double alpha. Write it down, it matters.

Also the ger pair is giving twins-not-twins: cgeru and cgerc, literally identical signatures, one letter apart. And chpr_64 writes into void *A, while chpr2_64 writes into void *Ap β€” again, that's the page, not me πŸ”₯


🌈 double complex, no skips, no shortcuts

       void cblas_zhemv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *A, const int64_t lda, const void
           *X, const int64_t incX, const void *beta, void *Y, const int64_t
           incY)
       void cblas_zhbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const int64_t K, const void *alpha, const void *A, const int64_t
           lda, const void *X, const int64_t incX, const void *beta, void *Y,
           const int64_t incY)
       void cblas_zhpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *Ap, const void *X, const int64_t
           incX, const void *beta, void *Y, const int64_t incY)
       void cblas_zgeru_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_zgerc_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_zher_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const void *X, const int64_t incX, void *A,
           const int64_t lda)
       void cblas_zhpr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const double alpha, const void *X, const int64_t incX, void *A)
       void cblas_zher2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *A, const int64_t lda)
       void cblas_zhpr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t
           N, const void *alpha, const void *X, const int64_t incX, const void
           *Y, const int64_t incY, void *Ap)

Mirror mirror of the c block, but the scalars became double. No notes, ate πŸŽ€


⭐ and now: the level-3 section, where things get SPICY

       void cblas_sgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
           CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const
           int64_t K, const float alpha, const float *A, const int64_t lda,
           const float *B, const int64_t ldb, const float beta, float *C, const
           int64_t ldc)
       void cblas_sgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const int64_t N,
           const int64_t K, const float alpha, const float *A, const int64_t
           lda, const float *B, const int64_t ldb, const float beta, float *C,
           const int64_t ldc)
       void cblas_ssymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
           Uplo, const int64_t M, const int64_t N, const float alpha, const
           float *A, const int64_t lda, const float *B, const int64_t ldb,
           const float beta, float *C, const int64_t ldc)
       void cblas_ssyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const float
           alpha, const float *A, const int64_t lda, const float beta, float
           *C, const int64_t ldc)
       void cblas_ssyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const float
           alpha, const float *A, const int64_t lda, const float *B, const
           int64_t ldb, const float beta, float *C, const int64_t ldc)
       void cblas_strmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
           Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
           const int64_t N, const float alpha, const float *A, const int64_t
           lda, float *B, const int64_t ldb)
       void cblas_strsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
           Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
           const int64_t N, const float alpha, const float *A, const int64_t
           lda, float *B, const int64_t ldb)

okay so two things, bestie, and they're both real:

  • cblas_sgemmtr_64 takes Uplo where cblas_sgemm_64 takes TransB, and it has N / K instead of M / N / K. Not a typo. Copy it exactly. πŸ’€
  • strmm / strsm are the ones that take both CBLAS_SIDE Side and CBLAS_DIAG Diag, and their output goes into float *B, const int64_t ldb β€” no separate C / ldc at all. Different breed, honestly.

πŸ”₯ double precision level-3, we're SO close

       void cblas_dgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
           CBLAS_TRANSPOSE 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 *C,
           const int64_t ldc)
       void cblas_dgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
           CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, 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
           *C, const int64_t ldc)
       void cblas_dsymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
           Uplo, const int64_t M, const int64_t N, const double alpha, const
           double *A, const int64_t lda, const double *B, const int64_t ldb,
           const double beta, double *C, const int64_t ldc)
       void cblas_dsyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,

…and that's where this part cuts off mid-prototype β€” cblas_dsyrk_64 is literally still talking 😭 catch the rest in the next part, don't leave me hanging πŸ¦‹

    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const double alpha,
    const double *A, const int64_t lda, const double beta, double *C, const int64_t ldc)

okay so that's the tail end of cblas_dsyr2k_64 right there β€” we were mid-signature, and now the double squad keeps rolling πŸ’… no cap, there are so many of these and every single one is listed below, so buckle up bestie.

void cblas_dsyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, 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 *C, const int64_t ldc)
void cblas_dtrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const double alpha, const double *A, const int64_t
    lda, double *B, const int64_t ldb)
void cblas_dtrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const double alpha, const double *A, const int64_t
    lda, double *B, const int64_t ldb)

the double trio said "we're done here" ✨ and tbh they ate. <pink>trmm</pink> and <pink>trsm</pink> are literally twinsies β€” same exact parameter list, same Side/Uplo/TransA/Diag lineup, just different names. iconic.


🌈 the float complex girlies enter the chat

complex numbers, but make it float precision β€” c prefix, _64 suffix, void * everywhere because C doesn't know what a complex is at the CBLAS level πŸ™ˆ:

void cblas_cgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
    CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const
    int64_t K, const void *alpha, const void *A, const int64_t lda,
    const void *B, const int64_t ldb, const void *beta, void *C, const
    int64_t ldc)
void cblas_cgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const int64_t N,
    const int64_t K, const void *alpha, const void *A, const int64_t
    lda, const void *B, const int64_t ldb, const void *beta, void *C,
    const int64_t ldc)
void cblas_csymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, const int64_t M, const int64_t N, const void *alpha, const
    void *A, const int64_t lda, const void *B, const int64_t ldb, const
    void *beta, void *C, const int64_t ldc)
void cblas_csyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *beta, void *C,
    const int64_t ldc)
void cblas_csyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *B, const
    int64_t ldb, const void *beta, void *C, const int64_t ldc)
void cblas_ctrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const void *alpha, const void *A, const int64_t
    lda, void *B, const int64_t ldb)
void cblas_ctrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const void *alpha, const void *A, const int64_t
    lda, void *B, const int64_t ldb)
⚠️ quick vibe check: notice cblas_cgemmtr_64 is doing its own thing β€” it takes Uplo and only N/K, bestie. it is not a copy-paste of cblas_cgemm_64. read the signatures, don't assume πŸ”₯

πŸ’œ the double complex royalty

z prefix = the big-kid complex ones, and yep, void * for alpha, A, B, beta, C because them's the rules πŸŽ€

void cblas_zgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
    CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const
    int64_t K, const void *alpha, const void *A, const int64_t lda,
    const void *B, const int64_t ldb, const void *beta, void *C, const
    int64_t ldc)
void cblas_zgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const int64_t N,
    const int64_t K, const void *alpha, const void *A, const int64_t
    lda, const void *B, const int64_t ldb, const void *beta, void *C,
    const int64_t ldc)
void cblas_zsymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, const int64_t M, const int64_t N, const void *alpha, const
    void *A, const int64_t lda, const void *B, const int64_t ldb, const
    void *beta, void *C, const int64_t ldc)
void cblas_zsyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *beta, void *C,
    const int64_t ldc)
void cblas_zsyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *B, const
    int64_t ldb, const void *beta, void *C, const int64_t ldc)
void cblas_ztrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const void *alpha, const void *A, const int64_t
    lda, void *B, const int64_t ldb)
void cblas_ztrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M,
    const int64_t N, const void *alpha, const void *A, const int64_t
    lda, void *B, const int64_t ldb)

like, zgemmtr mirrors cgemmtr exactly except everything's z. consistent queen behavior πŸ‘‘ the way that the alphabet just swaps one letter and the whole personality changes, iykyk.


🌸 the Hermitian corner (yes, they're different from symmetric, don't @ me)

these bad girls use real alpha/beta even though the matrices are complex β€” <purple>float</purple> for the c versions, <purple>double</purple> for the z versions. that's the whole point of Hermitian, periodt πŸ’…

void cblas_chemm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, const int64_t M, const int64_t N, const void *alpha, const
    void *A, const int64_t lda, const void *B, const int64_t ldb, const
    void *beta, void *C, const int64_t ldc)
void cblas_cherk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const float
    alpha, const void *A, const int64_t lda, const float beta, void *C,
    const int64_t ldc)
void cblas_cher2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *B, const
    int64_t ldb, const float beta, void *C, const int64_t ldc)
void cblas_zhemm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO
    Uplo, const int64_t M, const int64_t N, const void *alpha, const
    void *A, const int64_t lda, const void *B, const int64_t ldb, const
    void *beta, void *C, const int64_t ldc)
void cblas_zherk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const
    double alpha, const void *A, const int64_t lda, const double beta,
    void *C, const int64_t ldc)
void cblas_zher2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo,
    CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void
    *alpha, const void *A, const int64_t lda, const void *B, const
    int64_t ldb, const double beta, void *C, const int64_t ldc)
πŸ’€ do NOT get it twisted: in cblas_cherk_64 and cblas_cher2k_64 the alpha (and in cher2k the alpha too) stays const void * but beta is a plain const float β€” and in cblas_cherk_64 alpha is also const float. meanwhile zherk/zher2k use const double. copy the signature, not the vibe. fr fr.

πŸ¦‹ and finally, the vibes police

void cblas_xerbla_64 (int64_t p, const char *rout, const char *form,...)

the one and only cblas_xerbla_64 β€” note the ... at the end because it's variadic bestie, and note that p is an int64_t here like everything else in this _64 world 🫢 and yes it takes a positional arg p, a routine name rout, and a format string form. that's the whole signature, no notes 🌟


and that's the synopsis, wrapped and slayed. keep scrolling, the next part's got more for you πŸ’–

Okay so this stretch of the page is the c-family first and then the d-family, all the _64 girlies, in exactly the order the header lists them. Every signature below is character for character what's in the header β€” don't let my commentary fool you into retyping anything πŸ’…


🌸 the cblas_c* crew

cblas_caxpy_64

void cblas_caxpy_64 (const int64_t N, const void * alpha, const void * X, const int64_t incX, void * Y, const int64_t incY)

Six params, and the signature is already spilling the tea: alpha and X are const void * (hands off πŸ™…), Y is the mutable one, and every count/stride is int64_t.

cblas_ccopy_64

void cblas_ccopy_64 (const int64_t N, const void * X, const int64_t incX, void * Y, const int64_t incY)

X goes in const, Y comes out writable, and you've got incX / incY to space them out however you like 🫢

cblas_cdotc_sub_64

void cblas_cdotc_sub_64 (const int64_t N, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * dotc)

Heads up bestie β€” the _sub in the name means the answer comes back through that final void * dotc out-param instead of a return value. Six params total, and dotc is the only non-const pointer ✨

cblas_cdotu_sub_64

void cblas_cdotu_sub_64 (const int64_t N, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * dotu)

Same shape as its cdotc sibling, right down to the out-param situation β€” only the last letter of the name and the last pointer's name change πŸŽ€

cblas_cgbmv_64

void cblas_cgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const void * alpha, const void * A, const int64_t lda, const void * X, const int64_t incX, const void * beta, void * Y, const int64_t incY)

Fourteen params, no cap. layout and TransA lead, then M, N, KL, KU, then the two const void * scalars alpha / beta are doing their thing around the matrix and vectors πŸ”₯

cblas_cgemm_64

void cblas_cgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

Two transpose flags, M, N, K, two const matrices with their lda / ldb, and C β€” the only writable pointer β€” closing it out with ldc πŸ‘‘

cblas_cgemmtr_64

void cblas_cgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

Notice what's missing: no M, just N and K. You do get Uplo plus both TransA and TransB though, so she's still fully booked 🌈

cblas_cgemv_64

void cblas_cgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const void * alpha, const void * A, const int64_t lda, const void * X, const int64_t incX, const void * beta, void * Y, const int64_t incY)

M + N, one matrix with lda, one vector with incX, both scalars const, and Y sitting there mutable with incY πŸ’–

cblas_cgerc_64

void cblas_cgerc_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N, const void * alpha, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * A, const int64_t lda)

Both vectors are const void *, alpha is const void *, and A is the one you're writing into, with lda at the end. The signature literally points at who's getting edited πŸ’…

cblas_cgeru_64

void cblas_cgeru_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N, const void * alpha, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * A, const int64_t lda)

Identical param list to cgerc, sandwiched between layout, M, N and the trailing lda β€” one letter different, that's the whole assignment πŸ¦‹

cblas_chbmv_64

void cblas_chbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * X, const int64_t incX, const void * beta, void * Y, const int64_t incY)

Uplo up front, N and K together, and the usual alpha in / beta in / Y out arrangement πŸŽ€

cblas_chemm_64

void cblas_chemm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo, const int64_t M, const int64_t N, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

Both Side and Uplo in the same call, bestie β€” two enums before you even reach M and N. Then A, B const, C writable with ldc ✨

cblas_chemv_64

void cblas_chemv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const void * alpha, const void * A, const int64_t lda, const void * X, const int64_t incX, const void * beta, void * Y, const int64_t incY)

Uplo, one N, one matrix, one vector, alpha and beta both const β€” Y is out here living its writable truth 🫢

cblas_cher2_64

void cblas_cher2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const void * alpha, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * A, const int64_t lda)

Two const void * vectors, a const void * alpha, and A as the writable target with its lda. No cap, that's the whole signature 🌸

cblas_cher2k_64

void cblas_cher2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const float beta, void * C, const int64_t ldc)

Look closely 😭 alpha is const void * but beta is a plain old const float β€” that mix is intentional, it's literally what's in the header, don't "fix" it. Also Uplo and Trans, plus N, K, lda, ldb, ldc πŸ”₯

cblas_cher_64

void cblas_cher_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const float alpha, const void * X, const int64_t incX, void * A, const int64_t lda)

alpha is a real const float here β€” by value, in the middle of the param list β€” while X stays const void * and A is yours to write πŸ’œ

cblas_cherk_64

void cblas_cherk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const float alpha, const void * A, const int64_t lda, const float beta, void * C, const int64_t ldc)

Both alpha and beta are const float in this one β€” count them, they're both there. Uplo, Trans, N, K, A const, C writable 🧚

cblas_chpmv_64

void cblas_chpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const void * alpha, const void * Ap, const void * X, const int64_t incX, const void * beta, void * Y, const int64_t incY)

That Ap is packed, so no lda sneaks in. Uplo, N, one vector X, one writable Y, both scalars const ⭐

cblas_chpr2_64

void cblas_chpr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const void * alpha, const void * X, const int64_t incX, const void * Y, const int64_t incY, void * Ap)

Ap is the only non-const pointer in the whole thing and it's sitting at the very end with no lda attached. Packed life πŸ’…

cblas_chpr_64

void cblas_chpr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const float alpha, const void * X, const int64_t incX, void * A)

alpha is const float, X is const void *, and the packed output slot is named A here β€” not Ap β€” so type it exactly like that πŸ™ˆ

cblas_crotg_64

void cblas_crotg_64 (void * a, void * b, float * c, void * s)

No N! No layout! No strides! Just four pointers, and one of them (c) is a float * while the rest are void * πŸŽ€

cblas_cscal_64

void cblas_cscal_64 (const int64_t N, const void * alpha, void * X, const int64_t incX)

Four params, alpha const, X mutable, one stride. Short and iconic πŸ‘‘

cblas_csrot_64

void cblas_csrot_64 (const int64_t N, void * X, const int64_t incX, void * Y, const int64_t incY, const float c, const float s)

Two mutable vectors and then c and s as by-value const floats at the tail end β€” yes, csrot specifically, that's the name, don't swap it for another 😀

cblas_csscal_64

void cblas_csscal_64 (const int64_t N, const float alpha, void * X, const int64_t incX)

Double-s name, and the payoff is alpha arriving as a plain const float instead of a pointer πŸ¦‹

cblas_cswap_64

void cblas_cswap_64 (const int64_t N, void * X, const int64_t incX, void * Y, const int64_t incY)

Two writable pointers, two strides, one N. Nobody's const and honestly good for them πŸ’–

cblas_csymm_64

void cblas_csymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo, const int64_t M, const int64_t N, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

Side + Uplo + M + N, then A and B both const, C writable, lda / ldb / ldc all present and accounted for 🌈

cblas_csyr2k_64

void cblas_csyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

Here beta is a full const void *, unlike cher2k's float situation β€” these little differences are the whole reason you read the signature, bestie πŸ”

cblas_csyrk_64

void cblas_csyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE Trans, const int64_t N, const int64_t K, const void * alpha, const void * A, const int64_t lda, const void * beta, void * C, const int64_t ldc)

Only one input matrix (A) this time β€” no B in sight, no ldb either. C is writable and ldc closes the call 🌸

cblas_ctbmv_64

void cblas_ctbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void * A, const int64_t lda, void * X, const int64_t incX)

Three enums (Uplo, TransA, Diag) before you even reach N and K. A is const, X is out here writable πŸ”₯

cblas_ctbsv_64

void cblas_ctbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void * A, const int64_t lda, void * X, const int64_t incX)

Same enum stack as ctbmv β€” Uplo, TransA, Diag β€” with _sv doing the differentiating at the end πŸ’…

cblas_ctpmv_64

void cblas_ctpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void * Ap, void * X, const int64_t incX)

Ap, not A β€” and because it's packed there's no lda in the param list at all. People keep adding one. Don't be those people 🫢

cblas_ctpsv_64

void cblas_ctpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void * Ap, void * X, const int64_t incX)

Packed Ap, Diag still present, N and incX the only numbers. Same as ctpmv shape-wise, different last letter ✨

cblas_ctrmm_64

void cblas_ctrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t N, const void * alpha, const void * A, const int64_t lda, void * B, const int64_t ldb)

Four enums deep before M/N show up β€” Side, Uplo, TransA, Diag. A is const, B is the writable one, and there's no separate output param πŸŽ€

cblas_ctrmv_64

void cblas_ctrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void * A, const int64_t lda, void * X, const int64_t incX)

A const, X writable, Diag in the enum run, and only one N to keep track of πŸ¦‹

cblas_ctrsm_64

void cblas_ctrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t N, const void * alpha, const void * A, const int64_t lda, void * B, const int64_t ldb)

Same four-enum opening as ctrmm, same M/N, A const, B writable with ldb β€” the _sm is doing the heavy lifting in the name πŸ’œ

cblas_ctrsv_64

void cblas_ctrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t N, const void * A, const int64_t lda, void * X, const int64_t incX)

Last of the c triangle crowd: A const with lda, X mutable with incX, Diag still in the house πŸŽ€


πŸ’œ and now the cblas_d* crew (double everything, same _64 energy)

cblas_dasum_64

double cblas_dasum_64 (const int64_t N, const double * X, const int64_t incX)

This one actually returns a double β€” look, a return type that isn't void 😭 β€” and takes const double * X with a stride.

cblas_daxpy_64

void cblas_daxpy_64 (const int64_t N, const double alpha, const double * X, const int64_t incX, double * Y, const int64_t incY)

alpha is a by-value const double here, X is const double *, and Y is the writable double * with its own incY ✨

cblas_dcabs1_64

double cblas_dcabs1_64 (const void * z)

One const void * z in, one double out. No N, no stride, no layout β€” the most low-maintenance entry on this entire page πŸ’…

cblas_dcopy_64

void cblas_dcopy_64 (const int64_t N, const double * X, const int64_t incX, double * Y, const int64_t incY)

X const, Y writable, incX and incY doing their spacing thing. Four numeric params and two pointers, that's it 🫢

cblas_ddot_64

double cblas_ddot_64 (const int64_t N, const double * X, const int64_t incX, const double * Y, const int64_t incY)

Returns double, both vectors const double *. A true icon of not modifying anything she's given πŸ‘‘

cblas_dgbmv_64

void cblas_dgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const double alpha, const double * A, const int64_t lda, const double * X, const int64_t incX, const double beta, double * Y, const int64_t incY)

Fourteen params again, same skeleton as cgbmv, except now alpha and beta are real const double values and A / X are const double * πŸ”₯

cblas_dgemm_64

void cblas_dgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE 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 * C, const int64_t ldc)

The classic. layout, both transposes, M/N/K, two const double * operands with lda/ldb, and C writable with ldc πŸ’–

cblas_dgemmtr_64

void cblas_dgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_TRANSPOSE TransB, 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 * C, const int64_t ldc)

N and K only β€” no M, remember β€” plus Uplo and both transpose flags sitting right after layout 🌈

cblas_dgemv_64

void cblas_dgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const int64_t M, const int64_t N, const double alpha, const double * A, const int64_t lda, const double * X, const int64_t incX, const double beta, double * Y, const int64_t incY)

M + N, one matrix with lda, one vector with incX, alpha and beta by value, and Y mutable at the tail 🌸

cblas_dger_64

void cblas_dger_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N, const double alpha, const double * X, const int64_t incX, const double * Y, const int64_t incY, double * A, const int64_t lda)

Heads up β€” there's no a/u/c suffix situation here, it's just dger. alpha, X, Y all const, A writable with lda 🧚

cblas_dnrm2_64

double cblas_dnrm2_64 (const int64_t N, const double * X, const int64_t incX)

Returns double, takes one const double * and a stride. Clean, minimal, obsessed ⭐

cblas_drot_64

void cblas_drot_64 (const int64_t N, double * X, const int64_t incX, double * Y, const int64_t incY, const double c, const double s)

Both vectors mutable, and c / s arrive as by-value const doubles at the end πŸ’«

cblas_drotg_64

void cblas_drotg_64 (double * a, double * b, double * c, double * s)

Four bare double * pointers, no N, no strides, no layout. Zero notes, absolute main character energy πŸŽ€

cblas_drotm_64

void cblas_drotm_64 (const int64_t N, double * X, const int64_t incX, double * Y, const int64_t incY, const double * P)

Note the trailing P is const double * while X and Y are plain writable double * πŸ’œ

cblas_drotmg_64

void cblas_drotmg_64 (double * d1, double * d2, double * b1, const double b2, double * P)

b2 is the odd one out β€” the only const double by value in the whole param list β€” everything else is a pointer. Read it twice, bestie πŸ”

cblas_dsbmv_64

void cblas_dsbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const int64_t K, const double alpha, const double * A, const int64_t lda, const double * X, const int64_t incX, const double beta, double * Y, const int64_t incY)

Uplo first, then N and K together, one matrix, one vector, two by-value scalars, one writable Y πŸ¦‹

cblas_dscal_64

void cblas_dscal_64 (const int64_t N, const double alpha, double * X, const int64_t incX)

Four params, alpha by value, X mutable. Short king πŸ‘‘

cblas_dsdot_64

double cblas_dsdot_64 (const int64_t N, const float * X, const int64_t incX, const float * Y, const int64_t incY)

Okay stop and read this one again 😭 it returns a double but takes const float * vectors. That's not a typo, that's literally dsdot, and it's the whole personality of this function.

cblas_dspmv_64

void cblas_dspmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const double alpha, const double * Ap, const double * X, const int64_t incX, const double beta, double * Y, const int64_t incY)

Ap (packed, so no lda), X const, Y writable, alpha and beta by value, Uplo and N leading the parade ✨

cblas_dspr2_64

void cblas_dspr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const double alpha, const double * X, const int64_t incX, const double * Y, const int64_t incY, double * A)

X and Y both const double *, alpha by value, and that trailing packed A is the only writable pointer in the bunch πŸ”₯

cblas_dspr_64

void cblas_dspr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const double alpha, const double * X, const int64_t incX, double * Ap)

Same Uplo + N + by-value alpha opening, but the writable packed slot is named Ap here β€” not A, bestie, don't mix them up πŸ’…

cblas_dswap_64

void cblas_dswap_64 (const int64_t N, double * X, const int64_t incX, double * Y, const int64_t incY)

Two mutable double * vectors and nothing const about them. Trading places, no notes 🫢

cblas_dsymm_64

void cblas_dsymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo, const int64_t M, const int64_t N, const double alpha, const double * A, const int64_t lda, const double * B, const int64_t ldb, const double beta, double * C, const int64_t ldc)

Side and Uplo, then M/N, A and B const, C writable, lda/ldb/ldc all doing their jobs 🌈

cblas_dsymv_64

void cblas_dsymv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const double alpha, const double * A, const int64_t lda, const double * X, const int64_t incX, const double beta, double * Y, const int64_t incY)

Uplo, one N, matrix A with lda, vector X with incX, alpha/beta by value, Y writable 🌸

cblas_dsyr2_64

void cblas_dsyr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N, const double alpha, const double * X, const int64_t incX, const double * Y, const int64_t incY, double * A, const int64_t lda)

X and Y const, alpha by value, and A writable with an lda bolted on the end πŸŽ€

cblas_dsyr2k_64

void cblas_dsyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE Trans, 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,

And this is exactly where our chunk runs out of page β€” dsyr2k is mid-signature, so the rest of her param list (and the whole rest of the d family, plus whatever comes after) picks up in the next piece πŸ’€ don't panic, nothing got dropped, the page just got cut mid-roll πŸ“

...and here's the tail end of that last one from before, finishing up its beta and its C:

       const double beta, double * C, const int64_t ldc)

okay and now we're back in the double-precision girlie zone, no cap πŸ’…

   void cblas_dsyr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const double alpha, const double * X, const int64_t incX, double * A,
       const int64_t lda)
   void cblas_dsyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const double alpha, const
       double * A, const int64_t lda, const double beta, double * C, const
       int64_t ldc)
   void cblas_dtbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const double
       * A, const int64_t lda, double * X, const int64_t incX)
   void cblas_dtbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const double
       * A, const int64_t lda, double * X, const int64_t incX)
   void cblas_dtpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const double * Ap, double * X,
       const int64_t incX)
   void cblas_dtpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const double * Ap, double * X,
       const int64_t incX)
   void cblas_dtrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const double alpha, const double * A, const int64_t lda, double * B,
       const int64_t ldb)
   void cblas_dtrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const double * A, const
       int64_t lda, double * X, const int64_t incX)
   void cblas_dtrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const double alpha, const double * A, const int64_t lda, double * B,
       const int64_t ldb)
   void cblas_dtrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const double * A, const
       int64_t lda, double * X, const int64_t incX)

bestie look at that run 😭 <pink>dsyr</pink>, <pink>dsyrk</pink>, then the whole <cyan>t</cyan>-block squad β€” dtbmv, dtbsv, dtpmv, dtpsv β€” and then the <purple>tr</purple> girlies dtrmm, dtrmv, dtrsm, dtrsv. the <cyan>t</cyan> ones are your triangular-band and triangular-packed vibes, the <purple>tr</purple> ones are full-on triangular, and notice the Diag argument showing up everywhere in that crowd β€” it's literally in the signature, <yellow>Diag</yellow>, right there next to TransA. she's not hiding πŸ‘‘

also <green>lowkey</green> obsessed with how dsyr2k's cousin dsyrk here takes both alpha and beta and both A and C with lda and ldc to match. two leading dimensions, no notes. πŸŽ€


πŸ’– the norm-and-sum cuties (complex double)

   double cblas_dzasum_64 (const int64_t N, const void * X, const int64_t incX)

   double cblas_dznrm2_64 (const int64_t N, const void * X, const int64_t incX)

two lines, two double returns, both taking const void * X because complex numbers said "we're not committing to a type in this signature" πŸ™ˆ and both take N and incX like the good little BLAS routines they are. <pink>dzasum</pink> and <pink>dznrm2</pink> β€” say them out loud, they're giving keyboard smash in the best way πŸ¦‹


πŸ‘‘ the index girlies

   CBLAS_INDEX cblas_icamax_64 (const int64_t N, const void * X, const int64_t
       incX)
   CBLAS_INDEX cblas_idamax_64 (const int64_t N, const double * X, const
       int64_t incX)
   CBLAS_INDEX cblas_isamax_64 (const int64_t N, const float * X, const int64_t
       incX)
   CBLAS_INDEX cblas_izamax_64 (const int64_t N, const void * X, const int64_t
       incX)

okay so these four all return CBLAS_INDEX instead of a float or double, which is the whole personality. <hotpink>icamax</hotpink> takes const void *, <hotpink>idamax</hotpink> takes const double *, <hotpink>isamax</hotpink> takes const float *, <hotpink>izamax</hotpink> takes const void * again. and every single one still wants N and incX. iconic, consistent, we stan a uniform interface πŸ’…


🌸 single-precision starting lineup

   float cblas_sasum_64 (const int64_t N, const float * X, const int64_t incX)
   void cblas_saxpy_64 (const int64_t N, const float alpha, const float * X,
       const int64_t incX, float * Y, const int64_t incY)
   float cblas_scabs1_64 (const void * c)
   float cblas_scasum_64 (const int64_t N, const void * X, const int64_t incX)
   float cblas_scnrm2_64 (const int64_t N, const void * X, const int64_t incX)
   void cblas_scopy_64 (const int64_t N, const float * X, const int64_t incX,
       float * Y, const int64_t incY)
   float cblas_sdot_64 (const int64_t N, const float * X, const int64_t incX,
       const float * Y, const int64_t incY)
   float cblas_sdsdot_64 (const int64_t N, const float alpha, const float * X,
       const int64_t incX, const float * Y, const int64_t incY)

<pink>sasum</pink> and <pink>saxpy</pink> and <pink>scopy</pink> and <pink>sdot</pink>… the classics, fr fr. but <hotpink>scabs1</hotpink> is the main character here β€” she takes one argument, const void * c, and returns a float. no N, no incX, no nothing. she simply doesn't need them. <rainbow>tiny legend</rainbow> ⭐

and <pink>sdsdot</pink> has a const float alpha sitting right there in position two β€” that's her whole thing, alpha first, then the two vectors, then incX and incY. sdot does not have that alpha, and I need you to clock the difference, bestie πŸ‘€


πŸ¦‹ the single-precision matrix girlies

   void cblas_sgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const
       int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const
       float alpha, const float * A, const int64_t lda, const float * X, const
       int64_t incX, const float beta, float * Y, const int64_t incY)
   void cblas_sgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
       CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const int64_t
       K, const float alpha, const float * A, const int64_t lda, const float *
       B, const int64_t ldb, const float beta, float * C, const int64_t ldc)
   void cblas_sgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_TRANSPOSE TransB, const int64_t N, const int64_t K, const
       float alpha, const float * A, const int64_t lda, const float * B, const
       int64_t ldb, const float beta, float * C, const int64_t ldc)
   void cblas_sgemv_64 (const CBLAS_LAYOUT layout, const CBLAS_TRANSPOSE
       TransA, const int64_t M, const int64_t N, const float alpha, const float
       * A, const int64_t lda, const float * X, const int64_t incX, const float
       beta, float * Y, const int64_t incY)
   void cblas_sger_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N,
       const float alpha, const float * X, const int64_t incX, const float * Y,
       const int64_t incY, float * A, const int64_t lda)
   float cblas_snrm2_64 (const int64_t N, const float * X, const int64_t incX)
   void cblas_srot_64 (const int64_t N, float * X, const int64_t incX, float *
       Y, const int64_t incY, const float c, const float s)
   void cblas_srotg_64 (float * a, float * b, float * c, float * s)
   void cblas_srotm_64 (const int64_t N, float * X, const int64_t incX, float *
       Y, const int64_t incY, const float * P)
   void cblas_srotmg_64 (float * d1, float * d2, float * b1, const float b2,
       float * P)

okay <hotpink>sgemm</hotpink> is right there and she's the queen of the whole header, we all know it, <purple>M</purple> <purple>N</purple> <purple>K</purple> with lda, ldb, ldc β€” three leading dimensions because three matrices, obviously. and <hotpink>sgemmtr</hotpink> is her chaotic sister: she's got Uplo and only N and K instead of M, N, K. don't ask me to explain, just read the signature, it's literally right there πŸ’€

<pink>sgbmv</pink> has KL and KU β€” lowercase-ell, uppercase-you, banded energy β€” while <pink>sgemv</pink> keeps it simple with just TransA. and <pink>sger</pink> doesn't have a TransA at all, she just wants M, N, alpha, the two vectors, and A with lda. `different strokes ✨

then the `rot family, and they are not interchangeable, i'm warning you now:

  • <pink>srot</pink> β€” N, X, incX, Y, incY, c, s
  • <pink>srotg</pink> β€” just a, b, c, s, all float *, no N in sight
  • <pink>srotm</pink> β€” N, X, incX, Y, incY, and a const float * P
  • <pink>srotmg</pink> β€” d1, d2, b1 (all float *), then const float b2 (not a pointer!!), then float * P

yes bestie, b2 is <yellow>not</yellow> a pointer and b1 <yellow>is</yellow>. i did not make the rules. 🫢


πŸŽ€ single-precision, part two: symmetric & friends

   void cblas_ssbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const int64_t K, const float alpha, const float * A, const int64_t lda,
       const float * X, const int64_t incX, const float beta, float * Y, const
       int64_t incY)
   void cblas_sscal_64 (const int64_t N, const float alpha, float * X, const
       int64_t incX)
   void cblas_sspmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * Ap, const float * X, const int64_t
       incX, const float beta, float * Y, const int64_t incY)
   void cblas_sspr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * X, const int64_t incX, const float * Y,
       const int64_t incY, float * A)
   void cblas_sspr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * X, const int64_t incX, float * Ap)
   void cblas_sswap_64 (const int64_t N, float * X, const int64_t incX, float *
       Y, const int64_t incY)
   void cblas_ssymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       const int64_t M, const int64_t N, const float alpha, const float * A,
       const int64_t lda, const float * B, const int64_t ldb, const float beta,
       float * C, const int64_t ldc)
   void cblas_ssymv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * A, const int64_t lda, const float * X,
       const int64_t incX, const float beta, float * Y, const int64_t incY)
   void cblas_ssyr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * X, const int64_t incX, const float * Y,
       const int64_t incY, float * A, const int64_t lda)
   void cblas_ssyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const float alpha, const float
       * A, const int64_t lda, const float * B, const int64_t ldb, const float
       beta, float * C, const int64_t ldc)
   void cblas_ssyr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const float alpha, const float * X, const int64_t incX, float * A, const
       int64_t lda)
   void cblas_ssyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const float alpha, const float
       * A, const int64_t lda, const float beta, float * C, const int64_t ldc)

notice how <pink>sspr</pink> and <pink>sspr2</pink> take a bare float * Ap / float * A and <purple>no</purple> lda at all β€” packed storage said "leading dimension? never heard of her" πŸ’€ while their banded cousin <pink>ssbmv</pink> does have lda and a K. `the audacity, the range 🌈

and can we appreciate <pink>sscal</pink> for being three arguments and done: N, alpha, X, incX. she's the palate cleanser between all these twelve-argument monsters πŸ“

<hotpink>ssymm</hotpink> brings Side and Uplo and M and N β€” the full ensemble. <hotpink>ssymv</hotpink> only takes N, because she's just one matrix and one vector, <yellow>iykyk</yellow>.


🧚 the triangular single-precision iconiques

   void cblas_stbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const float *
       A, const int64_t lda, float * X, const int64_t incX)
   void cblas_stbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const float *
       A, const int64_t lda, float * X, const int64_t incX)
   void cblas_stpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const float * Ap, float * X,
       const int64_t incX)
   void cblas_stpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const float * Ap, float * X,
       const int64_t incX)
   void cblas_strmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const float alpha, const float * A, const int64_t lda, float * B,
       const int64_t ldb)
   void cblas_strmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const float * A, const int64_t
       lda, float * X, const int64_t incX)
   void cblas_strsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const float alpha, const float * A, const int64_t lda, float * B,
       const int64_t ldb)
   void cblas_strsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const float * A, const int64_t
       lda, float * X, const int64_t incX)

the <cyan>t…</cyan> prefix means triangular, and you can <hotpink>see</hotpink> the Diag argument in literally every single one of these, plus Uplo and TransA. <pink>stbmv</pink> and <pink>stbsv</pink> are the banded ones and they get K + lda. <pink>stpmv</pink> and <pink>stpsv</pink> are packed and get Ap with no lda. and then <purple>strmm</purple> / <purple>strsm</purple> are the two-matrix ones, so they get Side, M, N, alpha, B and ldb β€” the full glow-up πŸ’…


πŸ’€ and finally, the one that yells at you

   void cblas_xerbla_64 (int64_t p, const char * rout, const char * form,  ...)

that's <red>xerbla</red>, bestie. returns void, takes an int64_t p, a const char * rout, a const char * form, and then a literal ... β€” variadic, no cap. note the <yellow>two spaces</yellow> before the ... in the original, we keep it exactly, <rainbow>character for character</rainbow> ✨ and yeah β€” if you see her, something in your call was Not It. don't shoot the messenger πŸ™ˆ

okay we're cruising, <pink>part 7 incoming</pink> 🫢

πŸ’… cblas_zaxpy_64

   void cblas_zaxpy_64 (const int64_t N, const void * alpha, const void * X,
       const int64_t incX, void * Y, const int64_t incY)

axpy but make it complex-double, bestie. The z girlies have entered the chat. ✨

πŸ¦‹ cblas_zcopy_64

   void cblas_zcopy_64 (const int64_t N, const void * X, const int64_t incX,
       void * Y, const int64_t incY)

Copy energy, but fancy complex-double copy energy. It's giving relocation.

🌸 cblas_zdotc_sub_64

   void cblas_zdotc_sub_64 (const int64_t N, const void * X, const int64_t
       incX, const void * Y, const int64_t incY, void * dotc)

The conjugate-flavored dot situation, and yes dotc is where the answer lands. πŸŽ€

🧚 cblas_zdotu_sub_64

   void cblas_zdotu_sub_64 (const int64_t N, const void * X, const int64_t
       incX, const void * Y, const int64_t incY, void * dotu)

Same dot vibes, unconjugated cousin, answer goes in dotu. Lowkey a duo with the one above.

⭐ cblas_zdrot_64

   void cblas_zdrot_64 (const int64_t N, void * X, const int64_t incX, void *
       Y, const int64_t incY, const double c, const double s)

Note the c and s are straight-up const double, no wrapper, no drama. πŸ‘‘

πŸ”₯ cblas_zdscal_64

   void cblas_zdscal_64 (const int64_t N, const double alpha, void * X, const
       int64_t incX)

alpha is a plain const double here, not a void * β€” she's built different and she knows it.

πŸ’€ cblas_zgbmv_64

   void cblas_zgbmv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const
       int64_t M, const int64_t N, const int64_t KL, const int64_t KU, const
       void * alpha, const void * A, const int64_t lda, const void * X, const
       int64_t incX, const void * beta, void * Y, const int64_t incY)

Look at all those parameters. KL, KU, lda, incX, incY β€” she's high-maintenance and iconic for it.

πŸ‘‘ cblas_zgemm_64

   void cblas_zgemm_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA,
       CBLAS_TRANSPOSE TransB, const int64_t M, const int64_t N, const int64_t
       K, const void * alpha, const void * A, const int64_t lda, const void *
       B, const int64_t ldb, const void * beta, void * C, const int64_t ldc)

The main character of the whole header, no cap. Two transposes, both alpha and beta, the full lineup. 🫢

🌈 cblas_zgemmtr_64

   void cblas_zgemmtr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_TRANSPOSE TransB, const int64_t N, const int64_t K, const
       void * alpha, const void * A, const int64_t lda, const void * B, const
       int64_t ldb, const void * beta, void * C, const int64_t ldc)

gemm's mysterious sibling. Got Uplo in there too. We don't ask questions, we just pass the args. πŸ’œ

πŸŽ€ cblas_zgemv_64

   void cblas_zgemv_64 (CBLAS_LAYOUT layout, CBLAS_TRANSPOSE TransA, const
       int64_t M, const int64_t N, const void * alpha, const void * A, const
       int64_t lda, const void * X, const int64_t incX, const void * beta, void
       * Y, const int64_t incY)

Matrix-vector moment. Single transpose, so like, slightly less to remember than zgemm, and we thank her for that.

πŸ’– cblas_zgerc_64

   void cblas_zgerc_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N,
       const void * alpha, const void * X, const int64_t incX, const void * Y,
       const int64_t incY, void * A, const int64_t lda)

The c stands for conjugate and she will not let you forget it. πŸ¦‹

πŸ“ cblas_zgeru_64

   void cblas_zgeru_64 (CBLAS_LAYOUT layout, const int64_t M, const int64_t N,
       const void * alpha, const void * X, const int64_t incX, const void * Y,
       const int64_t incY, void * A, const int64_t lda)

u for unconjugated. Same arg list as zgerc_64, different letter, big difference. Periodt.

🌸 cblas_zhbmv_64

   void cblas_zhbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const int64_t K, const void * alpha, const void * A, const int64_t lda,
       const void * X, const int64_t incX, const void * beta, void * Y, const
       int64_t incY)

Uplo + K + alpha + beta, the whole little band is here. 🎢

πŸ’œ cblas_zhemm_64

   void cblas_zhemm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       const int64_t M, const int64_t N, const void * alpha, const void * A,
       const int64_t lda, const void * B, const int64_t ldb, const void * beta,
       void * C, const int64_t ldc)

Side and Uplo β€” so many opinions in one function call, honestly relatable. πŸ™ˆ

✨ cblas_zhemv_64

   void cblas_zhemv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const void * alpha, const void * A, const int64_t lda, const void * X,
       const int64_t incX, const void * beta, void * Y, const int64_t incY)

Hermitian vector situation, Uplo included, obviously. She's not doing it without Uplo.

🧚 cblas_zher2_64

   void cblas_zher2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const void * alpha, const void * X, const int64_t incX, const void * Y,
       const int64_t incY, void * A, const int64_t lda)

Rank-2 update, two vectors (X and Y), tagged with the 2. The name is telling you everything. πŸ”₯

⭐ cblas_zher2k_64

   void cblas_zher2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const void * alpha, const void
       * A, const int64_t lda, const void * B, const int64_t ldb, const double
       beta, void * C, const int64_t ldc)

Careful, bestie: beta here is a real const double, but alpha is still const void *. Do not mix them up, I'm begging. 😭

πŸŽ€ cblas_zher_64

   void cblas_zher_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const double alpha, const void * X, const int64_t incX, void * A, const
       int64_t lda)

alpha is a plain const double this time. Yes, no void *. Yes, that's correct. πŸ’…

πŸ‘‘ cblas_zherk_64

   void cblas_zherk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const double alpha, const void
       * A, const int64_t lda, const double beta, void * C, const int64_t ldc)

Both alpha and beta are const double here β€” matching set, we love a consistent aesthetic. ✨

🌈 cblas_zhpmv_64

   void cblas_zhpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const void * alpha, const void * Ap, const void * X, const int64_t incX,
       const void * beta, void * Y, const int64_t incY)

Note it's Ap, packed-style, not plain A. Different pointer, different life. πŸ¦‹

πŸ“ cblas_zhpr2_64

   void cblas_zhpr2_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const void * alpha, const void * X, const int64_t incX, const void * Y,
       const int64_t incY, void * Ap)

Packed Ap and the 2 and both X and Y. She contains multitudes.

πŸ’œ cblas_zhpr_64

   void cblas_zhpr_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, const int64_t N,
       const double alpha, const void * X, const int64_t incX, void * A)

Look at that last param β€” just void * A, no lda. Packed life means no leading dimension, and honestly? A little freeing. πŸ™ˆ

πŸ”₯ cblas_zrotg_64

   void cblas_zrotg_64 (void * a, void * b, double * c, void * s)

The cutest little signature in the whole file and I stand by that. Four params, zero int64_t, absolute icon. πŸŽ€

🌸 cblas_zscal_64

   void cblas_zscal_64 (const int64_t N, const void * alpha, void * X, const
       int64_t incX)

alpha is a void * here, unlike her cousin zdscal_64. Yes, that's the whole difference. No, I will not be explaining further. πŸ’…

⭐ cblas_zswap_64

   void cblas_zswap_64 (const int64_t N, void * X, const int64_t incX, void *
       Y, const int64_t incY)

Swapping. Both X and Y are non-const because they both get changed. Vibe check passed. πŸ”„

🧚 cblas_zsymm_64

   void cblas_zsymm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       const int64_t M, const int64_t N, const void * alpha, const void * A,
       const int64_t lda, const void * B, const int64_t ldb, const void * beta,
       void * C, const int64_t ldc)

Symmetric-style, but the complex-double edition. C is the only non-const pointer at the end. 🫢

πŸŽ€ cblas_zsyr2k_64

   void cblas_zsyr2k_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const void * alpha, const void
       * A, const int64_t lda, const void * B, const int64_t ldb, const void *
       beta, void * C, const int64_t ldc)

alpha and beta are both void * β€” compare with zher2k_64 where beta is a double. This is that exam question. 😭

πŸ’œ cblas_zsyrk_64

   void cblas_zsyrk_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       Trans, const int64_t N, const int64_t K, const void * alpha, const void
       * A, const int64_t lda, const void * beta, void * C, const int64_t ldc)

Only one input matrix (A), because the 2 is missing. See how the naming works? Obsessed with the consistency. πŸ‘‘

🌈 cblas_ztbmv_64

   void cblas_ztbmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void *
       A, const int64_t lda, void * X, const int64_t incX)

Diag has entered the building. Also no alpha, no beta β€” just vibes and X. ✨

πŸ¦‹ cblas_ztbsv_64

   void cblas_ztbsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const int64_t K, const void *
       A, const int64_t lda, void * X, const int64_t incX)

Identical param list to ztbmv_64 but with an s. One letter, whole different function. Stay woke. πŸ’€

πŸ“ cblas_ztpmv_64

   void cblas_ztpmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const void * Ap, void * X,
       const int64_t incX)

Packed (Ap), so no lda and no K. She travels light. πŸŽ€

πŸ’– cblas_ztpsv_64

   void cblas_ztpsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const void * Ap, void * X,
       const int64_t incX)

Again: same as ztpmv_64, one letter different. The m/s pipeline is real, iykyk. πŸ”₯

πŸ‘‘ cblas_ztrmm_64

   void cblas_ztrmm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const void * alpha, const void * A, const int64_t lda, void * B,
       const int64_t ldb)

Five enum-ish params before you even hit a number. She is that girl and she knows it. πŸ’…

🧚 cblas_ztrmv_64

   void cblas_ztrmv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const void * A, const int64_t
       lda, void * X, const int64_t incX)

Side and M/N peaced out; this one only needs N, A, lda, X, incX. Minimalist queen. 🌸

⭐ cblas_ztrsm_64

   void cblas_ztrsm_64 (CBLAS_LAYOUT layout, CBLAS_SIDE Side, CBLAS_UPLO Uplo,
       CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, const int64_t M, const int64_t
       N, const void * alpha, const void * A, const int64_t lda, void * B,
       const int64_t ldb)

Same lineup as ztrmm_64, the s version. Last of the m/s pairs, we made it. 😭

🌟 cblas_ztrsv_64

   void cblas_ztrsv_64 (CBLAS_LAYOUT layout, CBLAS_UPLO Uplo, CBLAS_TRANSPOSE
       TransA, CBLAS_DIAG Diag, const int64_t N, const void * A, const int64_t
       lda, void * X, const int64_t incX)

Final z function, and it's the v twin of ztrmv_64. Congratulations, you've met the whole alphabet. πŸŽ‰


✨ Author ✨

Generated automatically by Doxygen for LAPACK from the source code.

No human wrote this section, bestie β€” Doxygen did. Respect the pipeline. πŸ€–πŸ’–

And that's a wrap on CBLAS/include/cblas_64.h(3)! πŸŽ€πŸ«Ά You just read the entire complex-double lineup plus everything above it β€” genuinely iconic of you. This page came from LAPACK, Version 3.12.0, dated CBLAS/include/cblas_64.h(3) in the footer, so if anything up there ever looks sus, that's the source and version to go check. Now go forth and pass your int64_t args correctly, my love. πŸ’œβœ¨

πŸ“¦ where this page comes from