Multiple updates and refactorings (#280)
This commit is contained in:
@@ -37,11 +37,12 @@ static std::string to_string(const cute::UMMA::Major& major) {
|
||||
|
||||
static std::string to_string(const GemmType& type) {
|
||||
switch (type) {
|
||||
case GemmType::Normal: return "GemmType::Normal";
|
||||
case GemmType::MGroupedContiguous: return "GemmType::MGroupedContiguous";
|
||||
case GemmType::MGroupedMasked: return "GemmType::MGroupedMasked";
|
||||
case GemmType::KGroupedContiguous: return "GemmType::KGroupedContiguous";
|
||||
case GemmType::Batched: return "GemmType::Batched";
|
||||
case GemmType::Normal: return "GemmType::Normal";
|
||||
case GemmType::MGroupedContiguous: return "GemmType::MGroupedContiguous";
|
||||
case GemmType::MGroupedMasked: return "GemmType::MGroupedMasked";
|
||||
case GemmType::MGroupedContiguousWithPsumLayout: return "GemmType::MGroupedContiguousWithPsumLayout";
|
||||
case GemmType::KGroupedContiguous: return "GemmType::KGroupedContiguous";
|
||||
case GemmType::Batched: return "GemmType::Batched";
|
||||
}
|
||||
DG_HOST_UNREACHABLE("Unknown GEMM type");
|
||||
}
|
||||
@@ -51,6 +52,8 @@ static std::string to_string(const at::ScalarType& dtype) {
|
||||
case torch::kInt: return "int";
|
||||
case torch::kFloat: return "float";
|
||||
case torch::kBFloat16: return "cutlass::bfloat16_t";
|
||||
case torch::kFloat8_e4m3fn: return "cutlass::float_e4m3_t";
|
||||
case kPackedFP4: return "cutlass::detail::float_e2m1_unpacksmem_t";
|
||||
default: DG_HOST_UNREACHABLE("Unsupported dtype");
|
||||
}
|
||||
}
|
||||
@@ -65,6 +68,7 @@ static CUtensorMapDataType aten_dtype_to_tensor_map_dtype(const at::ScalarType&
|
||||
case torch::kFloat: return CU_TENSOR_MAP_DATA_TYPE_FLOAT32;
|
||||
case torch::kBFloat16: return CU_TENSOR_MAP_DATA_TYPE_BFLOAT16;
|
||||
case torch::kFloat8_e4m3fn: return CU_TENSOR_MAP_DATA_TYPE_UINT8;
|
||||
case kPackedFP4: return CU_TENSOR_MAP_DATA_TYPE_16U4_ALIGN16B;
|
||||
default: DG_HOST_UNREACHABLE("Unsupported dtype");
|
||||
}
|
||||
}
|
||||
@@ -98,6 +102,10 @@ static CUtensorMap make_tma_2d_desc(const torch::Tensor& t,
|
||||
if (swizzle_mode != 0)
|
||||
smem_inner_dim = swizzle_mode / elem_size;
|
||||
|
||||
// Inner dim must be a multiple of 64B for .b4x16_p64
|
||||
if (t.scalar_type() == kPackedFP4)
|
||||
DG_HOST_ASSERT(gmem_inner_dim % 128 == 0);
|
||||
|
||||
CUtensorMap tensor_map;
|
||||
const cuuint64_t gmem_dims[2] = {static_cast<cuuint64_t>(gmem_inner_dim), static_cast<cuuint64_t>(gmem_outer_dim)};
|
||||
const cuuint32_t smem_dims[2] = {static_cast<cuuint32_t>(smem_inner_dim), static_cast<cuuint32_t>(smem_outer_dim)};
|
||||
@@ -126,6 +134,10 @@ static CUtensorMap make_tma_3d_desc(const torch::Tensor& t,
|
||||
if (swizzle_mode != 0)
|
||||
smem_dim_0 = swizzle_mode / elem_size;
|
||||
|
||||
// Inner dim must be a multiple of 64B for .b4x16_p64
|
||||
if (t.scalar_type() == kPackedFP4)
|
||||
DG_HOST_ASSERT(gmem_dim_0 % 128 == 0);
|
||||
|
||||
CUtensorMap tensor_map;
|
||||
const cuuint64_t gmem_dims[3] = {static_cast<cuuint64_t>(gmem_dim_0), static_cast<cuuint64_t>(gmem_dim_1), static_cast<cuuint64_t>(gmem_dim_2),};
|
||||
const cuuint32_t smem_dims[3] = {static_cast<cuuint32_t>(smem_dim_0), static_cast<cuuint32_t>(smem_dim_1), static_cast<cuuint32_t>(smem_dim_2)};
|
||||
@@ -204,7 +216,7 @@ static CUtensorMap make_tma_cd_desc(const torch::Tensor& t,
|
||||
static CUtensorMap make_tma_sf_desc(const cute::UMMA::Major& major,
|
||||
const torch::Tensor& t,
|
||||
int shape_mn, int shape_k,
|
||||
const int& block_mn, const int& block_k,
|
||||
const int& block_mn, const int& gran_k,
|
||||
const int& num_groups,
|
||||
const int& swizzle_mode, const int& swizzle_base = 0,
|
||||
const bool& allow_tf32 = false) {
|
||||
@@ -215,7 +227,7 @@ static CUtensorMap make_tma_sf_desc(const cute::UMMA::Major& major,
|
||||
|
||||
shape_mn = get_tma_aligned_size(shape_mn, static_cast<int>(t.element_size()));
|
||||
return make_tma_2d_desc(t,
|
||||
shape_mn, ceil_div(shape_k, block_k * (t.scalar_type() == torch::kFloat ? 1 : 4)) * num_groups,
|
||||
shape_mn, ceil_div(shape_k, gran_k * (t.scalar_type() == torch::kFloat ? 1 : 4)) * num_groups,
|
||||
block_mn, 1,
|
||||
shape_mn,
|
||||
swizzle_mode, swizzle_base,
|
||||
|
||||
@@ -79,11 +79,11 @@ static void sm100_bf16_gemm(const torch::Tensor& a,
|
||||
const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 64);
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::Normal, KernelType::KernelNoSF,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const auto& tensor_map_a = make_tma_a_desc(major_a, a, m, k,
|
||||
@@ -104,7 +104,7 @@ static void sm100_bf16_gemm(const torch::Tensor& a,
|
||||
|
||||
// Launch
|
||||
const SM100BF16GemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = 1,
|
||||
.compiled_dims = compiled_dims,
|
||||
.gemm_config = config,
|
||||
@@ -124,16 +124,25 @@ static void sm100_bf16_gemm(const torch::Tensor& a,
|
||||
static void sm100_m_grouped_bf16_gemm_contiguous(const torch::Tensor& a,
|
||||
const torch::Tensor& b,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& m_indices,
|
||||
const torch::Tensor& grouped_layout,
|
||||
const int& num_groups, const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 64);
|
||||
const std::string& compiled_dims,
|
||||
const bool& use_psum_layout,
|
||||
const std::optional<int>& expected_m_for_psum_layout) {
|
||||
const auto& gemm_type = use_psum_layout ? GemmType::MGroupedContiguousWithPsumLayout : GemmType::MGroupedContiguous;
|
||||
|
||||
// NOTES: If actual M is dynamic, estimate config via `num_groups` and `expected_m`.
|
||||
// Otherwise, treat the contiguous layout as a whole.
|
||||
const auto& m_for_config = expected_m_for_psum_layout.has_value() ? expected_m_for_psum_layout.value() : m;
|
||||
const auto& num_groups_for_config = expected_m_for_psum_layout.has_value() ? num_groups : 1;
|
||||
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::MGroupedContiguous, KernelType::KernelNoSF,
|
||||
gemm_type, KernelType::KernelNoSF,
|
||||
// NOTES: `num_groups` is 1, since the contiguous layout is seen as a whole
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), false,
|
||||
m_for_config, n, k, num_groups_for_config, major_a, major_b,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const auto& tensor_map_a = make_tma_a_desc(major_a, a, m, k,
|
||||
@@ -154,14 +163,14 @@ static void sm100_m_grouped_bf16_gemm_contiguous(const torch::Tensor& a,
|
||||
|
||||
// Launch
|
||||
const SM100BF16GemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.compiled_dims = compiled_dims,
|
||||
.gemm_config = config,
|
||||
.launch_args = LaunchArgs(config.num_sms, config.thread_config.num_threads,
|
||||
config.smem_config.smem_size,
|
||||
config.multicast_config.num_multicast),
|
||||
.grouped_layout = m_indices.data_ptr(),
|
||||
.grouped_layout = grouped_layout.data_ptr(),
|
||||
.tensor_map_a = tensor_map_a,
|
||||
.tensor_map_b = tensor_map_b,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
@@ -179,11 +188,11 @@ static void sm100_m_grouped_bf16_gemm_masked(const torch::Tensor& a,
|
||||
const int& expected_m,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 64);
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::MGroupedMasked, KernelType::KernelNoSF,
|
||||
expected_m, n, k, num_groups, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const auto& tensor_map_a = make_tma_a_desc(major_a, a, m, k,
|
||||
@@ -204,7 +213,7 @@ static void sm100_m_grouped_bf16_gemm_masked(const torch::Tensor& a,
|
||||
|
||||
// Launch
|
||||
const SM100BF16GemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.compiled_dims = compiled_dims,
|
||||
.gemm_config = config,
|
||||
@@ -243,7 +252,8 @@ static void sm100_bf16_k_grouped_gemm(const torch::Tensor& a,
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::KGroupedContiguous, KernelType::KernelNoSF,
|
||||
m, n, max_k, num_groups, cute::UMMA::Major::MN, cute::UMMA::Major::MN,
|
||||
torch::kBFloat16, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Create tensor descriptors
|
||||
@@ -290,7 +300,8 @@ static void sm100_bf16_bhr_hdr_bhd(const torch::Tensor& tensor_a,
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::Batched, KernelType::KernelNoSF,
|
||||
b, d, r, h, cute::UMMA::Major::K, cute::UMMA::Major::K,
|
||||
torch::kBFloat16, tensor_d.scalar_type(), false,
|
||||
tensor_a.scalar_type(), tensor_b.scalar_type(),
|
||||
tensor_d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const int& load_block_m = SM100ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
@@ -337,7 +348,8 @@ static void sm100_bf16_bhd_hdr_bhr(const torch::Tensor& tensor_a,
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::Batched, KernelType::KernelNoSF,
|
||||
b, r, d, h, cute::UMMA::Major::K, cute::UMMA::Major::MN,
|
||||
torch::kBFloat16, tensor_d.scalar_type(), false,
|
||||
tensor_a.scalar_type(), tensor_b.scalar_type(),
|
||||
tensor_d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const int& load_block_m = SM100ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
|
||||
@@ -15,10 +15,11 @@
|
||||
|
||||
namespace deep_gemm {
|
||||
|
||||
class SM100FP8Gemm1D1DRuntime final: public LaunchRuntime<SM100FP8Gemm1D1DRuntime> {
|
||||
class SM100FP8FP4Gemm1D1DRuntime final: public LaunchRuntime<SM100FP8FP4Gemm1D1DRuntime> {
|
||||
public:
|
||||
struct Args {
|
||||
int m, n, k, num_groups;
|
||||
int gran_k_a, gran_k_b;
|
||||
const std::string& compiled_dims;
|
||||
const std::optional<std::string>& epilogue_type;
|
||||
|
||||
@@ -41,6 +42,7 @@ using namespace deep_gemm;
|
||||
|
||||
static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sm100_fp8_gemm_1d1d_impl<
|
||||
{}, {},
|
||||
{}, {},
|
||||
{}, {}, {},
|
||||
{}, {}, {},
|
||||
@@ -50,12 +52,14 @@ static void __instantiate_kernel() {{
|
||||
{}, {},
|
||||
{}, {},
|
||||
{},
|
||||
{}, {},
|
||||
{}, {}, {},
|
||||
{}
|
||||
>);
|
||||
}};
|
||||
)",
|
||||
to_string(args.gemm_config.major_a), to_string(args.gemm_config.major_b),
|
||||
args.gran_k_a, args.gran_k_b,
|
||||
get_compiled_dim(args.m, 'm', args.compiled_dims), get_compiled_dim(args.n, 'n', args.compiled_dims), get_compiled_dim(args.k, 'k', args.compiled_dims),
|
||||
args.gemm_config.block_m, args.gemm_config.block_n, args.gemm_config.block_k,
|
||||
args.num_groups,
|
||||
@@ -64,7 +68,8 @@ static void __instantiate_kernel() {{
|
||||
args.gemm_config.thread_config.num_non_epilogue_threads, args.gemm_config.thread_config.num_epilogue_threads,
|
||||
args.gemm_config.multicast_config.num_multicast, args.gemm_config.multicast_config.is_multicast_on_a,
|
||||
args.gemm_config.num_sms,
|
||||
to_string(args.gemm_config.gemm_type), args.gemm_config.with_accumulation, to_string(args.gemm_config.cd_dtype),
|
||||
to_string(args.gemm_config.gemm_type), args.gemm_config.with_accumulation,
|
||||
to_string(args.gemm_config.a_dtype), to_string(args.gemm_config.b_dtype), to_string(args.gemm_config.cd_dtype),
|
||||
get_default_epilogue_type(args.epilogue_type));
|
||||
}
|
||||
|
||||
@@ -78,19 +83,20 @@ static void __instantiate_kernel() {{
|
||||
}
|
||||
};
|
||||
|
||||
static void sm100_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims,
|
||||
const std::optional<std::string>& epilogue_type = std::nullopt) {
|
||||
const auto& aligned_k = align(k, 128);
|
||||
static void sm100_fp8_fp4_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
const int& m, const int& n, const int& k,
|
||||
const int& gran_k_a, const int& gran_k_b,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims,
|
||||
const std::optional<std::string>& epilogue_type = std::nullopt) {
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::Normal, KernelType::Kernel1D1D,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const auto& cd = c.value_or(d);
|
||||
@@ -110,14 +116,16 @@ static void sm100_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa
|
||||
static_cast<int>(d.stride(-2)), 1,
|
||||
config.smem_config.swizzle_cd_mode);
|
||||
const auto& tensor_map_sfa = make_tma_sf_desc(cute::UMMA::Major::MN, sfa, m, k,
|
||||
config.block_m, config.block_k, 1, 0);
|
||||
config.block_m, gran_k_a, 1, 0);
|
||||
const auto& tensor_map_sfb = make_tma_sf_desc(cute::UMMA::Major::MN, sfb, n, k,
|
||||
config.block_n, config.block_k, 1, 0);
|
||||
config.block_n, gran_k_b, 1, 0);
|
||||
|
||||
// Launch
|
||||
const SM100FP8Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
const SM100FP8FP4Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = 1,
|
||||
.gran_k_a = gran_k_a,
|
||||
.gran_k_b = gran_k_b,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = epilogue_type,
|
||||
.gemm_config = config,
|
||||
@@ -131,24 +139,33 @@ static void sm100_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa
|
||||
.tensor_map_sfb = tensor_map_sfb,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
};
|
||||
const auto& code = SM100FP8Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_fp8_gemm_1d1d", code);
|
||||
SM100FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
const auto& code = SM100FP8FP4Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_fp8_fp4_gemm_1d1d", code);
|
||||
SM100FP8FP4Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void sm100_m_grouped_fp8_gemm_contiguous_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& m_indices,
|
||||
const int& num_groups, const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 128);
|
||||
static void sm100_m_grouped_fp8_fp4_gemm_contiguous_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& grouped_layout,
|
||||
const int& num_groups, const int& m, const int& n, const int& k,
|
||||
const int& gran_k_a, const int& gran_k_b,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims,
|
||||
const bool& use_psum_layout,
|
||||
const std::optional<int>& expected_m_for_psum_layout) {
|
||||
const auto& gemm_type = use_psum_layout ? GemmType::MGroupedContiguousWithPsumLayout : GemmType::MGroupedContiguous;
|
||||
|
||||
// NOTES: If actual M is dynamic, estimate config via `num_groups` and `expected_m`.
|
||||
// Otherwise, treat the contiguous layout as a whole.
|
||||
const auto& m_for_config = expected_m_for_psum_layout.has_value() ? expected_m_for_psum_layout.value() : m;
|
||||
const auto& num_groups_for_config = expected_m_for_psum_layout.has_value() ? num_groups : 1;
|
||||
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::MGroupedContiguous, KernelType::Kernel1D1D,
|
||||
// NOTES: `num_groups` is 1, since the contiguous layout is seen as a whole
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), false,
|
||||
gemm_type, KernelType::Kernel1D1D,
|
||||
m_for_config, n, k, num_groups_for_config, major_a, major_b,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Create tensor descriptors
|
||||
@@ -168,45 +185,48 @@ static void sm100_m_grouped_fp8_gemm_contiguous_1d1d(const torch::Tensor& a, con
|
||||
static_cast<int>(d.stride(-2)), 1,
|
||||
config.smem_config.swizzle_cd_mode);
|
||||
const auto& tensor_map_sfa = make_tma_sf_desc(cute::UMMA::Major::MN, sfa, m, k,
|
||||
config.block_m, config.block_k, 1, 0);
|
||||
config.block_m, gran_k_a, 1, 0);
|
||||
const auto& tensor_map_sfb = make_tma_sf_desc(cute::UMMA::Major::MN, sfb, n, k,
|
||||
config.block_n, config.block_k, num_groups, 0);
|
||||
config.block_n, gran_k_b, num_groups, 0);
|
||||
|
||||
// Launch kernel
|
||||
const SM100FP8Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
const SM100FP8FP4Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.gran_k_a = gran_k_a,
|
||||
.gran_k_b = gran_k_b,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
.gemm_config = config,
|
||||
.launch_args = LaunchArgs(config.num_sms, config.thread_config.num_threads,
|
||||
config.smem_config.smem_size,
|
||||
config.multicast_config.num_multicast),
|
||||
.grouped_layout = m_indices.data_ptr(),
|
||||
.grouped_layout = grouped_layout.data_ptr(),
|
||||
.tensor_map_a = tensor_map_a,
|
||||
.tensor_map_b = tensor_map_b,
|
||||
.tensor_map_sfa = tensor_map_sfa,
|
||||
.tensor_map_sfb = tensor_map_sfb,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
};
|
||||
const auto& code = SM100FP8Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_m_grouped_fp8_gemm_contiguous_1d1d", code);
|
||||
SM100FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
const auto& code = SM100FP8FP4Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_m_grouped_fp8_fp4_gemm_contiguous_1d1d", code);
|
||||
SM100FP8FP4Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void sm100_m_grouped_fp8_gemm_masked_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& masked_m,
|
||||
const int& num_groups, const int& m, const int& n, const int& k,
|
||||
const int& expected_m,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 128);
|
||||
static void sm100_m_grouped_fp8_fp4_gemm_masked_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& masked_m,
|
||||
const int& num_groups, const int& m, const int& n, const int& k,
|
||||
const int& expected_m,
|
||||
const int& gran_k_a, const int& gran_k_b,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::MGroupedMasked, KernelType::Kernel1D1D,
|
||||
expected_m, n, k, num_groups, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Create tensor descriptors
|
||||
@@ -226,14 +246,16 @@ static void sm100_m_grouped_fp8_gemm_masked_1d1d(const torch::Tensor& a, const t
|
||||
static_cast<int>(d.stride(-2)), num_groups,
|
||||
config.smem_config.swizzle_cd_mode);
|
||||
const auto& tensor_map_sfa = make_tma_sf_desc(cute::UMMA::Major::MN, sfa, m, k,
|
||||
config.block_m, config.block_k, num_groups, 0);
|
||||
config.block_m, gran_k_a, num_groups, 0);
|
||||
const auto& tensor_map_sfb = make_tma_sf_desc(cute::UMMA::Major::MN, sfb, n, k,
|
||||
config.block_n, config.block_k, num_groups, 0);
|
||||
config.block_n, gran_k_b, num_groups, 0);
|
||||
|
||||
// Launch kernel
|
||||
const SM100FP8Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
const SM100FP8FP4Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.gran_k_a = gran_k_a,
|
||||
.gran_k_b = gran_k_b,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
.gemm_config = config,
|
||||
@@ -247,19 +269,19 @@ static void sm100_m_grouped_fp8_gemm_masked_1d1d(const torch::Tensor& a, const t
|
||||
.tensor_map_sfb = tensor_map_sfb,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
};
|
||||
const auto& code = SM100FP8Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_fp8_m_grouped_gemm_masked_1d1d", code);
|
||||
SM100FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
const auto& code = SM100FP8FP4Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_m_grouped_fp8_fp4_gemm_masked_1d1d", code);
|
||||
SM100FP8FP4Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
const int& m, const int& n,
|
||||
const std::vector<int>& ks, const torch::Tensor& ks_tensor,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
static void sm100_k_grouped_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
const int& m, const int& n,
|
||||
const std::vector<int>& ks, const torch::Tensor& ks_tensor,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
DG_HOST_ASSERT(major_a == cute::UMMA::Major::MN and major_b == cute::UMMA::Major::MN);
|
||||
|
||||
int sum_k = 0, sum_sf_k = 0;
|
||||
@@ -274,7 +296,8 @@ static void fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Tensor&
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::KGroupedContiguous, KernelType::Kernel1D1D,
|
||||
m, n, max_k, num_groups, cute::UMMA::Major::MN, cute::UMMA::Major::MN,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Create tensor descriptors
|
||||
@@ -299,9 +322,11 @@ static void fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Tensor&
|
||||
config.block_n, config.block_k, 1, 0);
|
||||
|
||||
// Launch kernel
|
||||
const SM100FP8Gemm1D1DRuntime::Args& args = {
|
||||
const SM100FP8FP4Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = sum_k,
|
||||
.num_groups = num_groups,
|
||||
.gran_k_a = 128,
|
||||
.gran_k_b = 128,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
.gemm_config = config,
|
||||
@@ -315,9 +340,9 @@ static void fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Tensor&
|
||||
.tensor_map_sfb = tensor_map_sfb,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
};
|
||||
const auto& code = SM100FP8Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_fp8_k_grouped_gemm_1d1d", code);
|
||||
SM100FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
const auto& code = SM100FP8FP4Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_k_grouped_fp8_gemm_1d1d", code);
|
||||
SM100FP8FP4Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void sm100_fp8_bmm(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
@@ -330,7 +355,8 @@ static void sm100_fp8_bmm(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const auto& config = get_best_config<SM100ArchSpec>(
|
||||
GemmType::Batched, KernelType::Kernel1D1D,
|
||||
m, n, k, batch_size, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const int& load_block_m = SM100ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
@@ -364,9 +390,11 @@ static void sm100_fp8_bmm(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
config.block_n, config.block_k, batch_size, 0);
|
||||
|
||||
// Launch
|
||||
const SM100FP8Gemm1D1DRuntime::Args& args = {
|
||||
const SM100FP8FP4Gemm1D1DRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = batch_size,
|
||||
.gran_k_a = 128,
|
||||
.gran_k_b = 128,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
.gemm_config = config,
|
||||
@@ -380,9 +408,9 @@ static void sm100_fp8_bmm(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
.tensor_map_sfb = tensor_map_sfb,
|
||||
.tensor_map_cd = tensor_map_cd
|
||||
};
|
||||
const auto& code = SM100FP8Gemm1D1DRuntime::generate(args);
|
||||
const auto& code = SM100FP8FP4Gemm1D1DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_fp8_gemm_1d1d", code);
|
||||
SM100FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
SM100FP8FP4Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
} // namespace deep_gemm
|
||||
|
||||
149
csrc/jit_kernels/impls/sm100_tf32_hc_prenorm_gemm.hpp
Normal file
149
csrc/jit_kernels/impls/sm100_tf32_hc_prenorm_gemm.hpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#pragma once
|
||||
|
||||
#include <torch/python.h>
|
||||
|
||||
#include "../../jit/compiler.hpp"
|
||||
#include "../../jit/device_runtime.hpp"
|
||||
#include "../../jit/kernel_runtime.hpp"
|
||||
#include "../../utils/exception.hpp"
|
||||
#include "../../utils/format.hpp"
|
||||
#include "../../utils/math.hpp"
|
||||
#include "../heuristics/sm100.hpp"
|
||||
#include "runtime_utils.hpp"
|
||||
|
||||
namespace deep_gemm {
|
||||
|
||||
class SM100BF16HCPrenormGemmRuntime final: public LaunchRuntime<SM100BF16HCPrenormGemmRuntime> {
|
||||
public:
|
||||
struct Args {
|
||||
int m, n, k;
|
||||
int block_m, block_n, block_k;
|
||||
int num_splits;
|
||||
int swizzle_cd_mode;
|
||||
int num_stages;
|
||||
int num_mma_threads, num_cast_and_reduce_threads;
|
||||
|
||||
LaunchArgs launch_args;
|
||||
|
||||
CUtensorMap tensor_map_a;
|
||||
CUtensorMap tensor_map_b;
|
||||
CUtensorMap tensor_map_d;
|
||||
float* sqr_sum;
|
||||
};
|
||||
|
||||
static std::string generate_impl(const Args& args) {
|
||||
return fmt::format(R"(
|
||||
#include <deep_gemm/impls/sm100_tf32_hc_prenorm_gemm.cuh>
|
||||
|
||||
using namespace deep_gemm;
|
||||
|
||||
static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sm100_tf32_hc_prenorm_gemm_impl<
|
||||
{}, {},
|
||||
{}, {}, {},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}, {}
|
||||
>);
|
||||
}};
|
||||
)",
|
||||
args.n, args.k,
|
||||
args.block_m, args.block_n, args.block_k,
|
||||
args.num_splits,
|
||||
args.swizzle_cd_mode,
|
||||
args.num_stages,
|
||||
args.num_mma_threads, args.num_cast_and_reduce_threads);
|
||||
}
|
||||
|
||||
static void launch_impl(const KernelHandle& kernel, const LaunchConfigHandle& config, Args args) {
|
||||
// TODO: optimize `args` copy
|
||||
DG_CUDA_UNIFIED_CHECK(launch_kernel(kernel, config,
|
||||
args.m, args.tensor_map_a, args.tensor_map_b, args.tensor_map_d, args.sqr_sum));
|
||||
}
|
||||
};
|
||||
|
||||
static void sm100_tf32_hc_prenorm_gemm(const torch::Tensor& a,
|
||||
const torch::Tensor& b,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& sqr_sum,
|
||||
const int& m, const int& n, const int& k,
|
||||
const int& num_splits) {
|
||||
constexpr int block_m = 64;
|
||||
constexpr int block_k = 64;
|
||||
constexpr int num_mma_threads = 128;
|
||||
constexpr int num_cast_and_reduce_threads = 128;
|
||||
|
||||
const int block_n = align(n, 16);
|
||||
DG_HOST_ASSERT(n <= block_n);
|
||||
DG_HOST_ASSERT(n <= 128 and n % 8 == 0);
|
||||
DG_HOST_ASSERT(k % block_k == 0);
|
||||
|
||||
const auto& swizzle_cd_mode = get_swizzle_mode(block_n, sizeof(float));
|
||||
const auto& tensor_map_a = make_tma_a_desc(cute::UMMA::Major::K, a, m, k,
|
||||
block_m, block_k,
|
||||
static_cast<int>(a.stride(get_non_contiguous_dim(cute::UMMA::Major::K))), 1,
|
||||
get_swizzle_mode(block_k, a.element_size()), 0,
|
||||
true);
|
||||
const auto& tensor_map_b = make_tma_b_desc(cute::UMMA::Major::K, b, n, k,
|
||||
block_n, block_k,
|
||||
static_cast<int>(b.stride(get_non_contiguous_dim(cute::UMMA::Major::K))), 1,
|
||||
get_swizzle_mode(block_k, b.element_size()), 0,
|
||||
true);
|
||||
const auto& tensor_map_d = num_splits == 1 ? make_tma_cd_desc(d, m, n,
|
||||
block_m, block_n,
|
||||
static_cast<int>(d.stride(-2)), 1,
|
||||
swizzle_cd_mode)
|
||||
: make_tma_3d_desc(d, n, m, num_splits,
|
||||
block_n, block_m, 1,
|
||||
static_cast<int>(d.stride(-2)),
|
||||
static_cast<int>(d.stride(-3)),
|
||||
swizzle_cd_mode);
|
||||
|
||||
// Calculate stages
|
||||
int num_stages = 12, smem_size = 0;
|
||||
while (num_stages > 0) {
|
||||
const int smem_a_per_stage = block_m * block_k * static_cast<int>(sizeof(nv_bfloat16));
|
||||
const int smem_b_per_stage = block_n * block_k * static_cast<int>(sizeof(float));
|
||||
const int smem_cd = block_m * swizzle_cd_mode;
|
||||
const int smem_barriers = (num_stages * 4 + 1) * 8;
|
||||
const int smem_tmem_ptr = 4;
|
||||
smem_size = (smem_a_per_stage + smem_b_per_stage) * num_stages +
|
||||
smem_cd + smem_barriers + smem_tmem_ptr;
|
||||
|
||||
if (smem_size <= SM100ArchSpec::smem_capacity)
|
||||
break;
|
||||
-- num_stages;
|
||||
}
|
||||
DG_HOST_ASSERT(num_stages > 0);
|
||||
|
||||
// Print configs
|
||||
if (get_env("DG_JIT_DEBUG", 0)) {
|
||||
printf("M: %d, N: %d, K: %d -> "
|
||||
"block M: %d, block N: %d, block K: %d, split K: %d"
|
||||
"stages: %d, shared memory: %d, swizzle CD: %d\n",
|
||||
m, n, k, block_m, block_n, block_k, num_splits,
|
||||
num_stages, smem_size, swizzle_cd_mode);
|
||||
}
|
||||
|
||||
// Launch
|
||||
const SM100BF16HCPrenormGemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.block_m = block_m, .block_n = block_n, .block_k = block_k,
|
||||
.num_splits = num_splits,
|
||||
.swizzle_cd_mode = swizzle_cd_mode,
|
||||
.num_stages = num_stages,
|
||||
.num_mma_threads = num_mma_threads,
|
||||
.num_cast_and_reduce_threads = num_cast_and_reduce_threads,
|
||||
.launch_args = LaunchArgs(num_splits * ceil_div(m, block_m), num_mma_threads + num_cast_and_reduce_threads, smem_size, 1),
|
||||
.tensor_map_a = tensor_map_a,
|
||||
.tensor_map_b = tensor_map_b,
|
||||
.tensor_map_d = tensor_map_d,
|
||||
.sqr_sum = sqr_sum.data_ptr<float>()
|
||||
};
|
||||
const auto& code = SM100BF16HCPrenormGemmRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm100_tf32_hc_prenorm_gemm", code);
|
||||
SM100BF16HCPrenormGemmRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
} // namespace deep_gemm
|
||||
@@ -79,13 +79,11 @@ static void sm90_bf16_gemm(const torch::Tensor& a,
|
||||
const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b,
|
||||
const std::string& compiled_dims) {
|
||||
DG_HOST_ASSERT(not c.has_value());
|
||||
|
||||
const auto& aligned_k = align(k, 64);
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Normal, KernelType::KernelNoSF,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -107,7 +105,7 @@ static void sm90_bf16_gemm(const torch::Tensor& a,
|
||||
|
||||
// Launch
|
||||
const SM90BF16GemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = 1,
|
||||
.compiled_dims = compiled_dims,
|
||||
.gemm_config = config,
|
||||
@@ -138,7 +136,8 @@ static void sm90_m_grouped_bf16_gemm_contiguous(const torch::Tensor& a,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::MGroupedContiguous, KernelType::KernelNoSF,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -192,7 +191,8 @@ static void sm90_bf16_m_grouped_gemm_masked(const torch::Tensor& a,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::MGroupedMasked, KernelType::KernelNoSF,
|
||||
expected_m, n, k, num_groups, major_a, major_b,
|
||||
torch::kBFloat16, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -253,7 +253,8 @@ static void sm90_bf16_k_grouped_gemm(const torch::Tensor& a,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::KGroupedContiguous, KernelType::KernelNoSF,
|
||||
m, n, max_k, num_groups, cute::UMMA::Major::MN, cute::UMMA::Major::MN,
|
||||
torch::kBFloat16, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Create tensor descriptors
|
||||
@@ -300,7 +301,8 @@ static void sm90_bf16_bhr_hdr_bhd(const torch::Tensor& tensor_a,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Batched, KernelType::KernelNoSF,
|
||||
b, d, r, h, cute::UMMA::Major::K, cute::UMMA::Major::K,
|
||||
torch::kBFloat16, tensor_d.scalar_type(), false,
|
||||
tensor_a.scalar_type(), tensor_b.scalar_type(),
|
||||
tensor_d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const int& load_block_m = SM90ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
@@ -346,7 +348,8 @@ static void sm90_bf16_bhd_hdr_bhr(const torch::Tensor& tensor_a,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Batched, KernelType::KernelNoSF,
|
||||
b, r, d, h, cute::UMMA::Major::K, cute::UMMA::Major::MN,
|
||||
torch::kBFloat16, tensor_d.scalar_type(), false,
|
||||
tensor_a.scalar_type(), tensor_b.scalar_type(),
|
||||
tensor_d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
const int& load_block_m = SM90ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
|
||||
@@ -88,7 +88,8 @@ static void sm90_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Normal, KernelType::Kernel1D1D,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -138,7 +139,7 @@ static void sm90_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
SM90FP8Gemm1D1DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void sm90_fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
static void sm90_k_grouped_fp8_gemm_1d1d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
@@ -156,7 +157,8 @@ static void sm90_fp8_k_grouped_gemm_1d1d(const torch::Tensor& a, const torch::Te
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::KGroupedContiguous, KernelType::Kernel1D1D,
|
||||
m, n, max_k, num_groups, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
|
||||
@@ -87,11 +87,11 @@ static void sm90_fp8_gemm_1d2d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
DG_HOST_ASSERT(not c.has_value() and d.scalar_type() == torch::kBFloat16);
|
||||
DG_HOST_ASSERT(major_a == cute::UMMA::Major::K and major_b == cute::UMMA::Major::K);
|
||||
|
||||
const auto& aligned_k = align(k, 128);
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Normal, KernelType::Kernel1D2D,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), c.has_value(),
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -118,7 +118,7 @@ static void sm90_fp8_gemm_1d2d(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
// Launch
|
||||
const SM90FP8Gemm1D2DRuntime::Args& args = {
|
||||
.major_sfb = major_sfb,
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = 1,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = epilogue_type,
|
||||
@@ -148,11 +148,11 @@ static void sm90_m_grouped_fp8_gemm_contiguous_1d2d(const torch::Tensor& a, cons
|
||||
DG_HOST_ASSERT(d.scalar_type() == torch::kBFloat16);
|
||||
DG_HOST_ASSERT(major_a == cute::UMMA::Major::K and major_b == cute::UMMA::Major::K);
|
||||
|
||||
const auto& aligned_k = align(k, 128);
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::MGroupedContiguous, KernelType::Kernel1D2D,
|
||||
m, n, k, 1, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -179,7 +179,7 @@ static void sm90_m_grouped_fp8_gemm_contiguous_1d2d(const torch::Tensor& a, cons
|
||||
// Launch
|
||||
const SM90FP8Gemm1D2DRuntime::Args& args = {
|
||||
.major_sfb = major_sfb,
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
@@ -207,14 +207,14 @@ static void sm90_m_grouped_fp8_gemm_masked_1d2d(const torch::Tensor& a, const to
|
||||
const int& expected_m,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b, const cute::UMMA::Major& major_sfb,
|
||||
const std::string& compiled_dims) {
|
||||
const auto& aligned_k = align(k, 128);
|
||||
DG_HOST_ASSERT(d.scalar_type() == torch::kBFloat16);
|
||||
DG_HOST_ASSERT(major_a == cute::UMMA::Major::K and major_b == cute::UMMA::Major::K);
|
||||
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::MGroupedMasked, KernelType::Kernel1D2D,
|
||||
expected_m, n, k, num_groups, major_a, major_b,
|
||||
torch::kFloat8_e4m3fn, d.scalar_type(), false,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), false,
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
@@ -241,7 +241,7 @@ static void sm90_m_grouped_fp8_gemm_masked_1d2d(const torch::Tensor& a, const to
|
||||
// Launch
|
||||
const SM90FP8Gemm1D2DRuntime::Args& args = {
|
||||
.major_sfb = major_sfb,
|
||||
.m = m, .n = n, .k = aligned_k,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = num_groups,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
@@ -261,4 +261,71 @@ static void sm90_m_grouped_fp8_gemm_masked_1d2d(const torch::Tensor& a, const to
|
||||
SM90FP8Gemm1D2DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
static void sm90_fp8_bmm(const torch::Tensor& a, const torch::Tensor& sfa,
|
||||
const torch::Tensor& b, const torch::Tensor& sfb,
|
||||
const std::optional<torch::Tensor>& c,
|
||||
const torch::Tensor& d,
|
||||
const int& batch_size, const int& m, const int& n, const int& k,
|
||||
const cute::UMMA::Major& major_a, const cute::UMMA::Major& major_b, const cute::UMMA::Major& major_sfb,
|
||||
const std::string& compiled_dims) {
|
||||
DG_HOST_ASSERT(d.scalar_type() == torch::kBFloat16);
|
||||
DG_HOST_ASSERT(major_a == cute::UMMA::Major::K and major_b == cute::UMMA::Major::K);
|
||||
|
||||
const auto& config = get_best_config<SM90ArchSpec>(
|
||||
GemmType::Batched, KernelType::Kernel1D2D,
|
||||
m, n, k, batch_size, major_a, major_b,
|
||||
a.scalar_type(), b.scalar_type(),
|
||||
d.scalar_type(), c.has_value(),
|
||||
device_runtime->get_num_sms());
|
||||
|
||||
// Requires no TMA splits
|
||||
DG_HOST_ASSERT(config.smem_config.swizzle_a_mode == config.block_k);
|
||||
DG_HOST_ASSERT(config.smem_config.swizzle_b_mode == config.block_k);
|
||||
const int& load_block_m = SM90ArchSpec::get_ab_load_block_m(config.multicast_config, config.block_m);
|
||||
const auto& tensor_map_a = make_tma_3d_desc(a, k, m, batch_size,
|
||||
config.block_k, load_block_m, 1,
|
||||
a.stride(1),
|
||||
a.stride(0),
|
||||
config.smem_config.swizzle_a_mode);
|
||||
|
||||
const int& load_block_n = SM90ArchSpec::get_ab_load_block_n(config.multicast_config, config.block_n);
|
||||
const auto& tensor_map_b = make_tma_3d_desc(b, k, n, batch_size,
|
||||
config.block_k, load_block_n, 1,
|
||||
b.stride(1),
|
||||
b.stride(0),
|
||||
config.smem_config.swizzle_b_mode);
|
||||
|
||||
const int& store_block_m = SM90ArchSpec::get_cd_store_block_m(config.block_m);
|
||||
const int& store_block_n = SM90ArchSpec::get_cd_store_block_n(config.block_n);
|
||||
const auto& tensor_map_d = make_tma_3d_desc(d, n, m, batch_size,
|
||||
store_block_n, store_block_m, 1,
|
||||
d.stride(1), d.stride(0),
|
||||
config.smem_config.swizzle_cd_mode);
|
||||
|
||||
const auto& tensor_map_sfa = make_tma_sf_desc(cute::UMMA::Major::MN, sfa, m, k,
|
||||
config.block_m, config.block_k, batch_size, 0);
|
||||
|
||||
// Launch
|
||||
const SM90FP8Gemm1D2DRuntime::Args& args = {
|
||||
.major_sfb = major_sfb,
|
||||
.m = m, .n = n, .k = k,
|
||||
.num_groups = batch_size,
|
||||
.compiled_dims = compiled_dims,
|
||||
.epilogue_type = std::nullopt,
|
||||
.gemm_config = config,
|
||||
.launch_args = LaunchArgs(config.num_sms, config.thread_config.num_threads,
|
||||
config.smem_config.smem_size,
|
||||
config.multicast_config.num_multicast),
|
||||
.sfb = sfb.data_ptr(),
|
||||
.grouped_layout = nullptr,
|
||||
.tensor_map_a = tensor_map_a,
|
||||
.tensor_map_b = tensor_map_b,
|
||||
.tensor_map_d = tensor_map_d,
|
||||
.tensor_map_sfa = tensor_map_sfa,
|
||||
};
|
||||
const auto& code = SM90FP8Gemm1D2DRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm90_fp8_gemm_1d2d", code);
|
||||
SM90FP8Gemm1D2DRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
} // namespace deep_gemm
|
||||
|
||||
152
csrc/jit_kernels/impls/sm90_tf32_hc_prenorm_gemm.hpp
Normal file
152
csrc/jit_kernels/impls/sm90_tf32_hc_prenorm_gemm.hpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#pragma once
|
||||
|
||||
#include <torch/python.h>
|
||||
|
||||
#include "../../jit/compiler.hpp"
|
||||
#include "../../jit/device_runtime.hpp"
|
||||
#include "../../jit/kernel_runtime.hpp"
|
||||
#include "../../utils/exception.hpp"
|
||||
#include "../../utils/format.hpp"
|
||||
#include "../../utils/math.hpp"
|
||||
#include "../heuristics/sm90.hpp"
|
||||
#include "runtime_utils.hpp"
|
||||
|
||||
namespace deep_gemm {
|
||||
|
||||
class SM90BF16HCPrenormGemmRuntime final: public LaunchRuntime<SM90BF16HCPrenormGemmRuntime> {
|
||||
public:
|
||||
struct Args {
|
||||
int m, n, k;
|
||||
int block_m, block_n, block_k;
|
||||
int num_splits;
|
||||
int swizzle_cd_mode;
|
||||
int num_stages;
|
||||
int num_math_threads, num_tma_threads;
|
||||
|
||||
LaunchArgs launch_args;
|
||||
|
||||
CUtensorMap tensor_map_a;
|
||||
CUtensorMap tensor_map_b;
|
||||
CUtensorMap tensor_map_d;
|
||||
float* sqr_sum;
|
||||
};
|
||||
|
||||
static std::string generate_impl(const Args& args) {
|
||||
return fmt::format(R"(
|
||||
#include <deep_gemm/impls/sm90_tf32_hc_prenorm_gemm.cuh>
|
||||
|
||||
using namespace deep_gemm;
|
||||
|
||||
static void __instantiate_kernel() {{
|
||||
auto ptr = reinterpret_cast<void*>(&sm90_tf32_hc_prenorm_gemm_impl<
|
||||
{}, {},
|
||||
{}, {}, {},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}, {}
|
||||
>);
|
||||
}};
|
||||
)",
|
||||
args.n, args.k,
|
||||
args.block_m, args.block_n, args.block_k,
|
||||
args.num_splits,
|
||||
args.swizzle_cd_mode,
|
||||
args.num_stages,
|
||||
args.num_math_threads, args.num_tma_threads);
|
||||
}
|
||||
|
||||
static void launch_impl(const KernelHandle& kernel, const LaunchConfigHandle& config, Args args) {
|
||||
// TODO: optimize `args` copy
|
||||
DG_CUDA_UNIFIED_CHECK(launch_kernel(kernel, config,
|
||||
args.m, args.tensor_map_a, args.tensor_map_b, args.tensor_map_d, args.sqr_sum));
|
||||
}
|
||||
};
|
||||
|
||||
static void sm90_tf32_hc_prenorm_gemm(const torch::Tensor& a,
|
||||
const torch::Tensor& b,
|
||||
const torch::Tensor& d,
|
||||
const torch::Tensor& sqr_sum,
|
||||
const int& m, const int& n, const int& k,
|
||||
const int& num_splits) {
|
||||
constexpr int block_m = 64;
|
||||
constexpr int block_k = 64;
|
||||
constexpr int num_math_threads = 128;
|
||||
constexpr int num_tma_threads = 128;
|
||||
constexpr int num_threads = num_math_threads + num_tma_threads;
|
||||
|
||||
const int block_n = align(n, 16);
|
||||
DG_HOST_ASSERT(n <= block_n);
|
||||
// Only support small N for now
|
||||
DG_HOST_ASSERT(n <= 32 and n % 8 == 0);
|
||||
DG_HOST_ASSERT(k % block_k == 0);
|
||||
|
||||
const auto& swizzle_cd_mode = get_swizzle_mode(block_n, sizeof(float));
|
||||
const auto& tensor_map_a = make_tma_a_desc(cute::UMMA::Major::K, a, m, k,
|
||||
block_m, block_k,
|
||||
static_cast<int>(a.stride(get_non_contiguous_dim(cute::UMMA::Major::K))), 1,
|
||||
get_swizzle_mode(block_k, a.element_size()), 0,
|
||||
true);
|
||||
const auto& tensor_map_b = make_tma_b_desc(cute::UMMA::Major::K, b, n, k,
|
||||
block_n, block_k,
|
||||
static_cast<int>(b.stride(get_non_contiguous_dim(cute::UMMA::Major::K))), 1,
|
||||
get_swizzle_mode(block_k, b.element_size()), 0,
|
||||
true);
|
||||
const auto& tensor_map_d = num_splits == 1 ? make_tma_cd_desc(d, m, n,
|
||||
block_m, block_n,
|
||||
static_cast<int>(d.stride(-2)), 1,
|
||||
swizzle_cd_mode)
|
||||
: make_tma_3d_desc(d, n, m, num_splits,
|
||||
block_n, block_m, 1,
|
||||
static_cast<int>(d.stride(-2)),
|
||||
static_cast<int>(d.stride(-3)),
|
||||
swizzle_cd_mode);
|
||||
|
||||
// Calculate stages
|
||||
int num_stages = 12, smem_size = 0;
|
||||
while (num_stages > 0) {
|
||||
const int smem_a_per_stage = block_m * block_k * static_cast<int>(sizeof(nv_bfloat16));
|
||||
const int smem_b_per_stage = block_n * block_k * static_cast<int>(sizeof(float));
|
||||
const int smem_cd = block_m * swizzle_cd_mode;
|
||||
const int smem_barriers = num_stages * 2 * 8;
|
||||
smem_size = (smem_a_per_stage + smem_b_per_stage) * num_stages +
|
||||
smem_cd + smem_barriers;
|
||||
|
||||
if (smem_size <= SM90ArchSpec::smem_capacity)
|
||||
break;
|
||||
-- num_stages;
|
||||
}
|
||||
DG_HOST_ASSERT(num_stages > 0);
|
||||
|
||||
// Print configs
|
||||
if (get_env("DG_JIT_DEBUG", 0)) {
|
||||
printf("M: %d, N: %d, K: %d -> "
|
||||
"block M: %d, block N: %d, block K: %d, split K: %d"
|
||||
"stages: %d, shared memory: %d, swizzle CD: %d\n",
|
||||
m, n, k, block_m, block_n, block_k, num_splits,
|
||||
num_stages, smem_size, swizzle_cd_mode);
|
||||
}
|
||||
|
||||
smem_size = SM90ArchSpec::smem_capacity;
|
||||
|
||||
// Launch
|
||||
const SM90BF16HCPrenormGemmRuntime::Args& args = {
|
||||
.m = m, .n = n, .k = k,
|
||||
.block_m = block_m, .block_n = block_n, .block_k = block_k,
|
||||
.num_splits = num_splits,
|
||||
.swizzle_cd_mode = swizzle_cd_mode,
|
||||
.num_stages = num_stages,
|
||||
.num_math_threads = num_math_threads,
|
||||
.num_tma_threads = num_tma_threads,
|
||||
.launch_args = LaunchArgs(num_splits * ceil_div(m, block_m), num_threads, smem_size, 1),
|
||||
.tensor_map_a = tensor_map_a,
|
||||
.tensor_map_b = tensor_map_b,
|
||||
.tensor_map_d = tensor_map_d,
|
||||
.sqr_sum = sqr_sum.data_ptr<float>()
|
||||
};
|
||||
const auto& code = SM90BF16HCPrenormGemmRuntime::generate(args);
|
||||
const auto& runtime = compiler->build("sm90_tf32_hc_prenorm_gemm", code);
|
||||
SM90BF16HCPrenormGemmRuntime::launch(runtime, args);
|
||||
}
|
||||
|
||||
} // namespace deep_gemm
|
||||
@@ -37,7 +37,6 @@ static void call_cublaslt_api(const cublasOperation_t& trans_a,
|
||||
const bool& accumulate) {
|
||||
cublasComputeType_t compute_type = CUBLAS_COMPUTE_32F_FAST_TF32;
|
||||
cudaDataType_t scale_type = CUDA_R_32F;
|
||||
const int& math_sms = device_runtime->get_num_sms();
|
||||
|
||||
// Operation description
|
||||
cublasLtMatmulDesc_t desc;
|
||||
@@ -45,9 +44,13 @@ static void call_cublaslt_api(const cublasOperation_t& trans_a,
|
||||
DG_CUBLASLT_CHECK(cublasLtMatmulDescSetAttribute(desc, CUBLASLT_MATMUL_DESC_TRANSA, &trans_a, sizeof(trans_a)));
|
||||
DG_CUBLASLT_CHECK(cublasLtMatmulDescSetAttribute(desc, CUBLASLT_MATMUL_DESC_TRANSB, &trans_b, sizeof(trans_b)));
|
||||
DG_CUBLASLT_CHECK(cublasLtMatmulDescSetAttribute(desc, CUBLASLT_MATMUL_DESC_SCALE_TYPE, &scale_type, sizeof(scale_type)));
|
||||
|
||||
#if DG_CUBLASLT_ADVANCED_FEATURES_COMPATIBLE
|
||||
const int& math_sms = device_runtime->get_num_sms();
|
||||
DG_CUBLASLT_CHECK(cublasLtMatmulDescSetAttribute(desc, CUBLASLT_MATMUL_DESC_SM_COUNT_TARGET, &math_sms, sizeof(math_sms)));
|
||||
|
||||
#if DG_FP8_COMPATIBLE
|
||||
#endif
|
||||
|
||||
#if DG_FP8_COMPATIBLE and DG_CUBLASLT_ADVANCED_FEATURES_COMPATIBLE
|
||||
bool fp8_fast_accumulate = false;
|
||||
if (a.scalar_type() == torch::kFloat8_e4m3fn)
|
||||
DG_CUBLASLT_CHECK(cublasLtMatmulDescSetAttribute(desc, CUBLASLT_MATMUL_DESC_FAST_ACCUM, &fp8_fast_accumulate, sizeof(fp8_fast_accumulate)));
|
||||
|
||||
@@ -174,13 +174,13 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
const int& logits_stride,
|
||||
const int& block_table_stride,
|
||||
const int& num_sms,
|
||||
const int& num_math_warp_groups) {
|
||||
const int& split_kv) {
|
||||
const int num_specialized_threads = 128;
|
||||
const int mma_m = (device_runtime->get_arch_major() == 10 ? 128 : 64);
|
||||
const int num_math_warp_groups = split_kv / mma_m;
|
||||
const int num_math_threads = num_math_warp_groups * 128;
|
||||
const int num_extra_threads = device_runtime->get_arch_major() == 10 ? 128 : 0;
|
||||
const int num_q_stages = 3, num_kv_stages = 3;
|
||||
const int split_kv = num_math_warp_groups * block_kv;
|
||||
DG_HOST_ASSERT(logits_stride % (num_math_warp_groups * block_kv) == 0);
|
||||
const int num_q_stages = 3, num_kv_stages = (device_runtime->get_arch_major() == 10 ? 4 : 3);
|
||||
DG_HOST_ASSERT(split_kv % mma_m == 0 and logits_stride % split_kv == 0);
|
||||
|
||||
// Construct TMAs
|
||||
DG_HOST_ASSERT(head_dim == 32 or head_dim == 64 or head_dim == 128);
|
||||
@@ -196,23 +196,39 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
next_n * num_heads, 1, next_n * num_heads, 0);
|
||||
|
||||
// Calculate shared memory size
|
||||
const int swizzle_alignment = head_dim * 8;
|
||||
int smem_size = 0;
|
||||
if (device_runtime->get_arch_major() == 9) {
|
||||
const int swizzle_alignment = head_dim * 8;
|
||||
|
||||
const int smem_q_size_per_stage = next_n * num_heads * head_dim * static_cast<int>(q.element_size());
|
||||
const int aligned_smem_weight_size_per_stage = align(next_n * num_heads * static_cast<int>(weights.element_size()), swizzle_alignment);
|
||||
const int smem_q_pipe_size = num_q_stages * (smem_q_size_per_stage + aligned_smem_weight_size_per_stage) + align(num_q_stages * 8 * 2, swizzle_alignment);
|
||||
const int smem_q_size_per_stage = next_n * num_heads * head_dim * static_cast<int>(q.element_size());
|
||||
const int aligned_smem_weight_size_per_stage = align(next_n * num_heads * static_cast<int>(weights.element_size()), swizzle_alignment);
|
||||
const int smem_q_pipe_size = num_q_stages * (smem_q_size_per_stage + aligned_smem_weight_size_per_stage) + align(num_q_stages * 8 * 2, swizzle_alignment);
|
||||
|
||||
const int smem_kv_size_per_stage = block_kv * head_dim * static_cast<int>(kv_cache.element_size());
|
||||
const int aligned_smem_kv_scale_size_per_stage = align(block_kv * static_cast<int>(kv_cache_scales.element_size()), swizzle_alignment);
|
||||
const int smem_kv_pipe_size = num_kv_stages * (smem_kv_size_per_stage + aligned_smem_kv_scale_size_per_stage) + align(num_kv_stages * 8 * 2, swizzle_alignment);
|
||||
const int smem_kv_size_per_stage = block_kv * head_dim * static_cast<int>(kv_cache.element_size());
|
||||
const int aligned_smem_kv_scale_size_per_stage = align(block_kv * static_cast<int>(kv_cache_scales.element_size()), swizzle_alignment);
|
||||
const int smem_kv_pipe_size = num_kv_stages * (smem_kv_size_per_stage + aligned_smem_kv_scale_size_per_stage) + align(num_kv_stages * 8 * 2, swizzle_alignment);
|
||||
|
||||
// Allocate some shared memory for UMMA barriers and tensor memory pointer, although it is not used in SM90
|
||||
const int smem_umma_barriers = num_math_warp_groups * 2 * 8;
|
||||
const int smem_tmem_ptr = 4;
|
||||
// Allocate some shared memory for UMMA barriers and tensor memory pointer, although it is not used in SM90
|
||||
const int smem_umma_barriers = num_math_warp_groups * 2 * 8;
|
||||
const int smem_tmem_ptr = 4;
|
||||
|
||||
const int smem_size = smem_q_pipe_size + num_math_warp_groups * smem_kv_pipe_size + smem_umma_barriers + smem_tmem_ptr;
|
||||
DG_HOST_ASSERT(smem_size <= SM90ArchSpec::smem_capacity);
|
||||
DG_HOST_ASSERT(smem_size <= SM100ArchSpec::smem_capacity);
|
||||
smem_size = smem_q_pipe_size + num_math_warp_groups * smem_kv_pipe_size + smem_umma_barriers + smem_tmem_ptr;
|
||||
DG_HOST_ASSERT(smem_size <= SM90ArchSpec::smem_capacity);
|
||||
} else {
|
||||
const int smem_q_size_per_stage = next_n * num_heads * head_dim * static_cast<int>(q.element_size());
|
||||
const int smem_kv_size_per_stage = split_kv * head_dim * static_cast<int>(kv_cache.element_size());
|
||||
const int smem_kv_scale_size_per_stage = split_kv * static_cast<int>(kv_cache_scales.element_size());
|
||||
const int smem_weight_size_per_stage = next_n * num_heads * static_cast<int>(weights.element_size());
|
||||
|
||||
const int smem_barriers = (num_q_stages + num_kv_stages) * 2 * 8;
|
||||
const int smem_umma_barriers = num_math_warp_groups * 2 * 8;
|
||||
const int smem_tmem_ptr = 4;
|
||||
|
||||
smem_size = num_q_stages * (smem_q_size_per_stage + smem_weight_size_per_stage) +
|
||||
num_kv_stages * (smem_kv_size_per_stage + smem_kv_scale_size_per_stage) +
|
||||
smem_barriers + smem_umma_barriers + smem_tmem_ptr;
|
||||
DG_HOST_ASSERT(smem_size <= SM100ArchSpec::smem_capacity);
|
||||
}
|
||||
|
||||
// Launch
|
||||
const SMXXFP8PagedMQALogitsRuntime::Args& args = {
|
||||
@@ -238,7 +254,7 @@ static void smxx_fp8_paged_mqa_logits(const torch::Tensor& q,
|
||||
.num_specialized_threads = num_specialized_threads,
|
||||
.num_math_threads = num_math_threads,
|
||||
.launch_args = LaunchArgs(num_sms,
|
||||
num_specialized_threads + num_math_threads + num_extra_threads,
|
||||
num_specialized_threads + num_math_threads,
|
||||
smem_size)
|
||||
};
|
||||
const auto& code = SMXXFP8PagedMQALogitsRuntime::generate(args);
|
||||
|
||||
Reference in New Issue
Block a user