|
|
|
@@ -208,6 +208,91 @@ struct SM100_MMA_F16BF16_TS
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <int M, int N, UMMA::Major a_major, UMMA::Major b_major,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
|
UMMA::Saturate c_sat = UMMA::Saturate::False>
|
|
|
|
|
struct SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 64 || M == 128, "SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN M-mode size should be 64 or 128 for 1 CTA cluster MMA.");
|
|
|
|
|
static_assert((M == 64 && (N % 8 == 0) && (8 <= N) && (N <= 256)) ||
|
|
|
|
|
(M == 128 && (N % 16 == 0) && (16 <= N) && (N <= 256)),
|
|
|
|
|
"SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN N-mode size should be a multiple of 8 between 8 and 256 for M=64,\
|
|
|
|
|
or a multiple of 16 between 16 and 256 for M=128.");
|
|
|
|
|
static_assert(a_major == UMMA::Major::K, "SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN A from TMEM can't be transposed");
|
|
|
|
|
static_assert(b_major == UMMA::Major::K, "SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN B from SMEM requires non-transpose");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint32_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint32_t const& tmem_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& scaleC,
|
|
|
|
|
uint64_t const& idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_TF32_MMA_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
uint32_t mask[4] = {0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::1.kind::tf32 [%0], [%1], %2, %3, {%5, %6, %7, %8}, p; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "r"(tmem_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(scaleC),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN without CUTE_ARCH_TCGEN05_TF32_MMA_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One>
|
|
|
|
|
struct SM100_MMA_TF32_SS_SCALED
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 64 || M == 128, "SM100_MMA_TF32_SS_SCALED M-mode size should be 64 or 128 for 1 CTA cluster MMA.");
|
|
|
|
|
static_assert((N % 8 == 0) && (8 <= N) && (N <= 256),
|
|
|
|
|
"SM100_MMA_TF32_SS_SCALED N-mode size should be a multiple of 8 between 8 and 256.");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint64_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint64_t const& desc_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& accumulate,
|
|
|
|
|
uint64_t const& idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
// ScaleC input should be a literal or compile time constant
|
|
|
|
|
uint32_t mask[4] = {0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::1.kind::tf32 [%0], %1, %2, %3, {%5, %6, %7, %8}, p, %9; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "l"(desc_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(accumulate),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]), "n"(ScaleC));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_SS_SCALED without CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One>
|
|
|
|
@@ -249,6 +334,51 @@ struct SM100_MMA_F16BF16_SS_SCALED
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
|
UMMA::Saturate c_sat = UMMA::Saturate::False>
|
|
|
|
|
struct SM100_MMA_TF32_TS_SCALED
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 64 || M == 128, "SM100_MMA_TF32_TS_SCALED M-mode size should be 64 or 128 for 1 CTA cluster MMA.");
|
|
|
|
|
static_assert((M == 64 && (N % 8 == 0) && (8 <= N) && (N <= 256)) ||
|
|
|
|
|
(M == 128 && (N % 16 == 0) && (16 <= N) && (N <= 256)),
|
|
|
|
|
"SM100_MMA_TF32_TS_SCALED N-mode size should be a multiple of 8 between 8 and 256 for M=64,\
|
|
|
|
|
or a multiple of 16 between 16 and 256 for M=128.");
|
|
|
|
|
static_assert(a_major == UMMA::Major::K, "SM100_MMA_TF32_TS_SCALED A from TMEM can't be transposed");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint32_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint32_t const& tmem_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& accumulate,
|
|
|
|
|
uint64_t const& idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
// ScaleC input should be a literal or compile time constant
|
|
|
|
|
uint32_t mask[4] = {0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::1.kind::tf32 [%0], [%1], %2, %3, {%5, %6, %7, %8}, p, %9; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "r"(tmem_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(accumulate),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]), "n"(ScaleC));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_TS_SCALED without CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
@@ -540,6 +670,89 @@ struct SM100_MMA_F16BF16_2x1SM_TS
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <int M, int N, UMMA::Major a_major, UMMA::Major b_major,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
|
UMMA::Saturate c_sat = UMMA::Saturate::False>
|
|
|
|
|
struct SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 128 || M == 256, "SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN M-mode size should be 128 or 256 for 2 CTA cluster MMA.");
|
|
|
|
|
static_assert((N % 32 == 0) && (32 <= N) && (N <= 256), "SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN N-mode size should be a multiple of 32 between 32 and 256.");
|
|
|
|
|
static_assert(a_major == UMMA::Major::K, "SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN A from TMEM can't be transposed");
|
|
|
|
|
static_assert(b_major == UMMA::Major::K, "SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN B from SMEM requires non-transpose");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint32_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint32_t const& tmem_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& scaleC,
|
|
|
|
|
uint64_t const& idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_TF32_MMA_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
uint32_t mask[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::2.kind::tf32 [%0], [%1], %2, %3, {%5, %6, %7, %8, %9, %10, %11, %12}, p; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "r"(tmem_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(scaleC),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]),
|
|
|
|
|
"r"(mask[4]), "r"(mask[5]), "r"(mask[6]), "r"(mask[7]));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_2x1SM_TS_INTERLEAVED_CF32CTF32CTF32CF32_TN without CUTE_ARCH_TCGEN05_TF32_MMA_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One>
|
|
|
|
|
struct SM100_MMA_TF32_2x1SM_SS_SCALED
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 128 || M == 256, "SM100_MMA_TF32_2x1SM_SS_SCALED M-mode size should be 128 or 256 for 2 CTA cluster MMA.");
|
|
|
|
|
static_assert((N % 16 == 0) && (16 <= N) && (N <= 256), "SM100_MMA_TF32_2x1SM_SS_SCALED N-mode size should be a multiple of 16 between 16 and 256.");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint64_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint64_t const& desc_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& accumulate,
|
|
|
|
|
uint64_t const& idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
// ScaleC input should be a literal or compile time constant
|
|
|
|
|
uint32_t mask[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::2.kind::tf32 [%0], %1, %2, %3, {%5, %6, %7, %8, %9, %10, %11, %12}, p, %13; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "l"(desc_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(accumulate),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]),
|
|
|
|
|
"r"(mask[4]), "r"(mask[5]), "r"(mask[6]), "r"(mask[7]), "n"(ScaleC));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_2x1SM_SS_SCALED without CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One>
|
|
|
|
@@ -581,6 +794,49 @@ struct SM100_MMA_F16BF16_2x1SM_SS_SCALED
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
|
UMMA::Saturate c_sat = UMMA::Saturate::False>
|
|
|
|
|
struct SM100_MMA_TF32_2x1SM_TS_SCALED
|
|
|
|
|
{
|
|
|
|
|
static_assert(M == 128 || M == 256, "SM100_MMA_TF32_2x1SM_TS_SCALED M-mode size should be 128 or 256 for 2 CTA cluster MMA.");
|
|
|
|
|
static_assert((N % 32 == 0) && (32 <= N) && (N <= 256), "SM100_MMA_TF32_2x1SM_TS_SCALED N-mode size should be a multiple of 32 between 32 and 256.");
|
|
|
|
|
static_assert(a_major == UMMA::Major::K, "SM100_MMA_TF32_2x1SM_TS_SCALED A from TMEM can't be transposed");
|
|
|
|
|
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint32_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|
using CRegisters = uint32_t[1];
|
|
|
|
|
|
|
|
|
|
CUTE_HOST_DEVICE static void
|
|
|
|
|
fma(uint32_t const& tmem_a,
|
|
|
|
|
uint64_t const& desc_b,
|
|
|
|
|
uint32_t const& tmem_c,
|
|
|
|
|
uint32_t const& accumulate,
|
|
|
|
|
uint64_t idescE)
|
|
|
|
|
{
|
|
|
|
|
#if defined(CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED)
|
|
|
|
|
if (cute::elect_one_sync()) {
|
|
|
|
|
// ScaleC input should be a literal or compile time constant
|
|
|
|
|
uint32_t mask[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
asm volatile(
|
|
|
|
|
"{\n\t"
|
|
|
|
|
".reg .pred p;\n\t"
|
|
|
|
|
"setp.ne.b32 p, %4, 0;\n\t"
|
|
|
|
|
"tcgen05.mma.cta_group::2.kind::tf32 [%0], [%1], %2, %3, {%5, %6, %7, %8, %9, %10, %11, %12}, p, %13; \n\t"
|
|
|
|
|
"}\n"
|
|
|
|
|
:
|
|
|
|
|
: "r"(tmem_c), "r"(tmem_a), "l"(desc_b), "r"(uint32_t(idescE>>32)), "r"(accumulate),
|
|
|
|
|
"r"(mask[0]), "r"(mask[1]), "r"(mask[2]), "r"(mask[3]),
|
|
|
|
|
"r"(mask[4]), "r"(mask[5]), "r"(mask[6]), "r"(mask[7]), "n"(ScaleC));
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
CUTE_INVALID_CONTROL_PATH("Attempting to use SM100_MMA_TF32_2x1SM_TS_SCALED without CUTE_ARCH_TCGEN05_UTFMMA_SCALED_ENABLED");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <class a_type, class b_type, class c_type,
|
|
|
|
|
int M, int N, UMMA::Major a_major, UMMA::Major b_major, uint32_t ScaleC,
|
|
|
|
|
UMMA::ScaleIn a_neg = UMMA::ScaleIn::One, UMMA::ScaleIn b_neg = UMMA::ScaleIn::One,
|
|
|
|
@@ -1197,7 +1453,7 @@ struct SM100_MMA_MXF8F6F4_SS_SPARSE
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct SM100_MMA_F8F6F4_2x1SM_SS
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
using DRegisters = void;
|
|
|
|
|
using ARegisters = uint64_t[1];
|
|
|
|
|
using BRegisters = uint64_t[1];
|
|
|
|
|