#include #include #include #include #include #ifdef __SM90__ #include "sm90_fp8_gemm_1d2d_bias.hpp" #endif #include "sm89_fp8_gemm_1d2d.hpp" namespace blockwise{ template static auto get_shape(const torch::Tensor& t) { return [&t] (std::index_sequence) { return std::make_tuple(static_cast(t.sizes()[Is])...); }(std::make_index_sequence()); } #ifdef __SM90__ static void fp8_gemm_nt_sm90(const std::pair& a, const std::pair& b, const torch::Tensor& d, const std::optional& bias, const std::optional& c, const int num_sms) { // Type and shape checks const auto& [m , k ] = get_shape<2>(a.first); const auto& [n , k_] = get_shape<2>(b.first); const auto& [m_, n_] = get_shape<2>(d); // The SM90 kernel always adds bias; synthesize a zero bias when the layer is // bias-less (e.g. the no-bias video FFN of v3 checkpoints), mirroring SM89 below. torch::Tensor bias_tensor = bias.has_value() ? bias.value() : torch::zeros({n}, d.options().dtype(torch::kFloat32)); sm90_fp8_gemm_1d2d_bias(a.first, a.second, b.first, b.second, bias_tensor, c, d, m, n, k, num_sms); } #endif static void fp8_gemm_nt_sm89(const std::pair& a, const std::pair& b, const torch::Tensor& d, const std::optional& bias, const bool use_fast_accum = true) { const auto& [m, k] = get_shape<2>(a.first); const auto& [n, k_] = get_shape<2>(b.first); const auto& [m_, n_] = get_shape<2>(d); // The SM89 kernel always adds bias; synthesize a zero bias when the layer is // bias-less so we add 0 rather than uninitialized memory (mirrors SM90 above). torch::Tensor bias_tensor = bias.has_value() ? bias.value() : torch::zeros({n}, d.options().dtype(torch::kFloat32)); blockwise::sm89_fp8_gemm_1d2d_bias( a.first, a.second, // a data, sfa scales b.first, b.second, // b data, sfb scales bias_tensor, // bias (or empty tensor) d, // output m, n, k, use_fast_accum); // pass through accumulation mode } PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) { // m.def("package_name", &function_name, "function_docstring"") #ifdef __SM90__ m.def("fp8_gemm_nt_sm90", &fp8_gemm_nt_sm90, py::arg("a"), py::arg("b"), py::arg("d"), py::arg("bias") = std::nullopt, py::arg("c") = std::nullopt, py::arg("num_sms") = 132 ); #endif m.def("fp8_gemm_nt_sm89", &fp8_gemm_nt_sm89, py::arg("a"), py::arg("b"), py::arg("d"), py::arg("bias") = std::nullopt, py::arg("use_fast_accum") = true ); } };