1#ifndef __MATH_MFMA_KERNEL_H__
2#define __MATH_MFMA_KERNEL_H__
94#include <hip/hip_runtime.h>
121#if defined(__gfx90a__) || defined(__gfx942__)
184template < const
int LX >
186 return (
sizeof(
real) == 8 ||
sizeof(
real) == 4) && (
LX >= 4) && (
LX <= 12);
259#define NEKO_MFMA_NWF_CANDIDATES 5
260#define NEKO_MFMA_TILE_CANDIDATES 2
261#define NEKO_MFMA_CANDIDATES \
262 (NEKO_MFMA_NWF_CANDIDATES * NEKO_MFMA_TILE_CANDIDATES)
263#define NEKO_MFMA_NWF(C) (1 << ((C) % NEKO_MFMA_NWF_CANDIDATES))
264#define NEKO_MFMA_TILE(C) ((C) / NEKO_MFMA_NWF_CANDIDATES)
265#define NEKO_MFMA_NTHRDS(C) dim3(64, NEKO_MFMA_NWF(C), 1)
322#define NEKO_MFMA_PAD_N(LX, SZ) (((LX) % 2 == 0) ? (NEKO_MFMA_PAD) : 0)
324#define NEKO_MFMA_PAD_N(LX, SZ) \
325 ((((LX) % 4 == 0) && !((LX) == 4 && (SZ) == 4)) ? 1 : 0)
328#define NEKO_MFMA_SJ_N(LX, SZ) ((LX) + NEKO_MFMA_PAD_N(LX, SZ))
329#define NEKO_MFMA_SK_N(LX, SZ) (NEKO_MFMA_SJ_N(LX, SZ) * (LX))
330#define NEKO_MFMA_CUBE_N(LX, SZ) (NEKO_MFMA_SK_N(LX, SZ) * (LX))
350#define NEKO_MFMA_SD_N(LX, SZ) NEKO_MFMA_SJ_N(LX, SZ)
351#define NEKO_MFMA_DMAT_N(LX, SZ) (NEKO_MFMA_SD_N(LX, SZ) * (LX))
366#ifdef MFMA_F64_USE_16X16
369 return sizeof(
real) == 8;
375#ifdef MFMA_F64_USE_16X16
382 return (
sizeof(
real) == 8) ?
"4x4x4" :
"16x16";
418#define NEKO_MFMA_NGROUPS(LX) (((LX) * (LX) + 15) / 16)
426#define NEKO_MFMA_LDS_N(EB, LX, SZ) \
427 ((3 * NEKO_MFMA_DMAT_N(LX, SZ) + 4 * (EB) * NEKO_MFMA_CUBE_N(LX, SZ)) * (SZ))
428#define NEKO_MFMA_LDS_FITS(EB, LX, SZ) \
429 (NEKO_MFMA_LDS_N(EB, LX, SZ) <= NEKO_EB_MAX_LDS)
437#define NEKO_MFMA_EB_N(NWF, LX, SZ) \
438 ((NWF) / NEKO_MFMA_NGROUPS(LX) >= 16 && NEKO_MFMA_LDS_FITS(16, LX, SZ) ? 16 :\
439 (NWF) / NEKO_MFMA_NGROUPS(LX) >= 8 && NEKO_MFMA_LDS_FITS(8, LX, SZ) ? 8 : \
440 (NWF) / NEKO_MFMA_NGROUPS(LX) >= 4 && NEKO_MFMA_LDS_FITS(4, LX, SZ) ? 4 : \
441 (NWF) / NEKO_MFMA_NGROUPS(LX) >= 2 && NEKO_MFMA_LDS_FITS(2, LX, SZ) ? 2 : 1)
442#define NEKO_MFMA_EB(LX, C) \
443 NEKO_MFMA_EB_N(NEKO_MFMA_NWF(C), LX, sizeof(real))
445#define NEKO_MFMA_WPE(LX, C) (NEKO_MFMA_NWF(C) / NEKO_MFMA_EB(LX, C))
459#define NEKO_MFMA_SPT_N(WPE, LX, SZ) \
460 ((NEKO_MFMA_CUBE_N(LX, SZ) + (WPE) * 64 - 1) / ((WPE) * 64))
461#define NEKO_MFMA_SPT(LX, C) \
462 NEKO_MFMA_SPT_N(NEKO_MFMA_WPE(LX, C), LX, sizeof(real))
487#ifndef NEKO_MFMA_VECTOR_GREG_VGPRS
488#define NEKO_MFMA_VECTOR_GREG_VGPRS 64
490#define NEKO_MFMA_VECTOR_GREG_N(SPT, SZ) \
491 ((7 * (SPT) * ((SZ) / 4)) <= NEKO_MFMA_VECTOR_GREG_VGPRS)
492#define NEKO_MFMA_VECTOR_GREG(LX, C) \
493 NEKO_MFMA_VECTOR_GREG_N(NEKO_MFMA_SPT(LX, C), sizeof(real))
495#define NEKO_MFMA_NBLCKS(NELV, LX, C) \
496 dim3(((NELV) + NEKO_MFMA_EB(LX, C) - 1) / NEKO_MFMA_EB(LX, C), 1, 1)
513 const char *
v =
getenv(
"NEKO_MFMA_TUNE");
516 return (
atoi(
v) != 0);
535 const char *
v =
getenv(
"NEKO_MFMA_NWF");
536 const char *t =
getenv(
"NEKO_MFMA_TILE");
572 const char *
v =
getenv(
"NEKO_MFMA_NWF");
602#define NEKO_TUNE_LOG_MFMA(LX, T3) \
604 for (int c = 0; c < NEKO_MFMA_CANDIDATES; c++) { \
605 if ((T3)[c] >= NEKO_TUNE_INIT) { continue; } \
606 sprintf(neko_log_buf, "MFMA %s %2dwf %-2de %-5s: %9.2f us/call", \
607 mfma_tile_name(c), NEKO_MFMA_NWF(c), NEKO_MFMA_EB(LX, c), \
608 NEKO_MFMA_PAD_N(LX, sizeof(real)) ? "pad" : "plain", \
609 NEKO_TUNE_US((T3)[c], iters)); \
610 log_message(neko_log_buf); \
623#define NEKO_TUNE_LOG_MFMA_VEC(LX, T3) \
625 for (int c = 0; c < NEKO_MFMA_CANDIDATES; c++) { \
626 if ((T3)[c] >= NEKO_TUNE_INIT) { continue; } \
627 sprintf(neko_log_buf, "MFMA %s %2dwf %-2de %-5s %-4s: %9.2f us/call", \
628 mfma_tile_name(c), NEKO_MFMA_NWF(c), NEKO_MFMA_EB(LX, c), \
629 NEKO_MFMA_PAD_N(LX, sizeof(real)) ? "pad" : "plain", \
630 NEKO_MFMA_VECTOR_GREG(LX, c) ? "reg" : "glob", \
631 NEKO_TUNE_US((T3)[c], iters)); \
632 log_message(neko_log_buf); \
636#if defined(__gfx90a__) || defined(__gfx942__)
647template<
typename T >
682template< const
int LX, const
int PAD >
697template< const
int LX, const
int PAD >
699 return row + mfma_cube<LX, PAD>::SD *
col;
707template< const
int LX, const
int AXIS, const
int PAD = 0 >
710 const int a = n %
LX;
711 const int b = n /
LX;
712 if (
AXIS == 0)
return p + C::SJ *
a + C::SK * b;
713 if (
AXIS == 1)
return a + C::SJ * p + C::SK * b;
714 return a + C::SJ * b + C::SK * p;
735template< const
int LX, const
int PAD >
741 const int k = s / C::SK;
742 const int rem = s -
k * C::SK;
743 const int j =
rem / C::SJ;
744 const int i =
rem -
j * C::SJ;
765template<
typename T,
const int LX,
const int AXIS,
772 const int lane,
const int wf = 0) {
774 const int g =
lane >> 4;
775 const int c =
lane & 15;
781 for (
int p = 0; p <
NPASS; ++p) {
782 const int nt = wf + p *
NWF;
784 const int n = nt * 16 + c;
785 typename mma_t::acc_t
acc = {0, 0, 0, 0};
788 const int l =
ks * 4 + g;
790 if (c <
LX && l <
LX)
794 if (l <
LX && n <
LX *
LX)
800 for (
int r = 0; r < 4; ++r) {
801 const int m = mma_t::out_row(g, r);
802 if (m <
LX && n <
LX *
LX) {
853template<
const int LX,
const int AXIS,
860 const int lane,
const int wf = 0) {
864 const int MT = (
LX + 3) / 4;
894 const int n =
ng * 16 +
gemm * 4 +
lo;
901 const int l =
ks * 4 +
kq;
903 if (l <
LX && n <
LX *
LX)
948template<
typename T,
const int LX,
const int AXIS,
950 const int TILE = 0,
const int PAD = 0 >
964 const int NWF,
const int PAD >
970#ifdef MFMA_F64_USE_16X16
984 const int NWF,
const int PAD >
__global__ void ale_add_kinematics_kernel(const int n, T *__restrict__ wx, T *__restrict__ wy, T *__restrict__ wz, const T *__restrict__ x_ref, const T *__restrict__ y_ref, const T *__restrict__ z_ref, const T *__restrict__ phi, const T *__restrict__ x, const T *__restrict__ y, const T *__restrict__ z, const kinematics_params_t kin_params)
__global__ void T *__restrict__ T *__restrict__ const T *__restrict__ const T *__restrict__ v
static __global__ void hip_mfma_arch_probe(int *flag)
static bool mfma_lx_supported()
static const char * mfma_tile_name(const int c)
#define NEKO_MFMA_NWF_CANDIDATES
#define NEKO_MFMA_CANDIDATES
static int neko_mfma_pin()
static int neko_mfma_candidates()
#define NEKO_MFMA_TILE_CANDIDATES
static bool hip_have_mfma()
static int neko_mfma_nwf_pin()
#define NEKO_MFMA_TILE(C)
static int neko_mfma_sweep()
static bool mfma_tile_offered(const int c)