mirror of
https://github.com/Niko1221/Strata.git
synced 2026-11-07 18:35:04 -10:00
Dense Q8_0 GEMV: one row per block where measured faster (gfx1201: n_in <= 4096 with n_out >= 4096; sm_86: n_out >= 2048), the same bits as two rows
This commit is contained in:
1 parent
5ef9f4c812
commit
945fee2365
1 file changed
+46
-1
@@ -27,6 +27,7 @@
|
||||
#include "strata/kernels/dp4a.hpp"
|
||||
#include "strata/kernels/q8_1_finite.hpp"
|
||||
#include "strata/kernels/iq_kernels.hpp"
|
||||
#include "strata/kernels/gfx_arch.hpp"
|
||||
#include "s26_tsum.cuh"
|
||||
#if !defined(__HIPCC__)
|
||||
#include "q8_1_il.cuh"
|
||||
@@ -42,6 +43,7 @@
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <cstdio>
|
||||
@@ -1258,6 +1260,49 @@ __global__ void native_mmvq_multi_kernel(const typename F::Block* __restrict__ w
|
||||
}
|
||||
}
|
||||
|
||||
// MODEL-UPDATE: the dense Q8_0 projections of Unsloth's files (all of attention, SSM and the shared expert are Q8_0
|
||||
// there) take one row per block where that was measured faster - the same per-row sums and reduction as two rows per
|
||||
// block (each row its own partials), so every output is the same bits. q8_gemv_bench, 2-4 columns:
|
||||
// gfx1201 (R9700): n_in <= 4096 with n_out >= 4096 (qkv 2560->10240 73-79% -> 83-84% of the 644 GB/s, gate 2560->6144
|
||||
// 51-68% -> 76-78%, q 2560->12288 74-80% -> 85-86%); 6144->2560 is slower there (79% -> 55-59%) and keeps two rows.
|
||||
// sm_86 (RTX A4000): every n_out >= 2048 (+1-4% at 2-4 columns, 6144->2560 at 6 columns 70% -> 76%).
|
||||
// Other cards keep two rows until measured (STRATA_NO_MMVQ_ROWS2=1 forces one row everywhere; =0 keeps two everywhere).
|
||||
int dev_class() { // 1 = gfx12, 2 = sm_86, 0 = the rest; per device
|
||||
static int cls[16]; // 0 unknown, else class + 1
|
||||
int dev = 0;
|
||||
if (cudaGetDevice(&dev) != cudaSuccess || dev < 0 || dev >= 16) return 0;
|
||||
if (cls[dev] == 0) {
|
||||
int c = 0;
|
||||
#if defined(__HIPCC__)
|
||||
cudaDeviceProp p;
|
||||
if (cudaGetDeviceProperties(&p, dev) == cudaSuccess && strata::kernels::gfx_arch_is_gfx12(p.gcnArchName)) c = 1;
|
||||
#else
|
||||
int major = 0, minor = 0;
|
||||
if (cudaDeviceGetAttribute(&major, cudaDevAttrComputeCapabilityMajor, dev) == cudaSuccess &&
|
||||
cudaDeviceGetAttribute(&minor, cudaDevAttrComputeCapabilityMinor, dev) == cudaSuccess && major == 8 && minor == 6)
|
||||
c = 2;
|
||||
#endif
|
||||
(void) cudaGetLastError();
|
||||
cls[dev] = c + 1;
|
||||
}
|
||||
return cls[dev] - 1;
|
||||
}
|
||||
template<typename F>
|
||||
bool q8_0_rows1(int n_in, int n_out) {
|
||||
if constexpr (!std::is_same_v<F, SmallTraits<Q80Block, 8>>) {
|
||||
(void) n_in; (void) n_out;
|
||||
return false;
|
||||
} else {
|
||||
static const int env = [] {
|
||||
const char* v = std::getenv("STRATA_NO_MMVQ_ROWS2");
|
||||
return v == nullptr || v[0] == '\0' ? -1 : v[0] != '0';
|
||||
}();
|
||||
if (env == 0) return false;
|
||||
const int c = dev_class();
|
||||
return (c == 1 && n_in <= 4096 && n_out >= 4096) || (c == 2 && n_out >= 2048);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename F, int NCOLS>
|
||||
void launch_multi_n(const void* weights, const void* x_q8_1, float* y, int n_in, int n_out, cudaStream_t s) {
|
||||
const auto* w = static_cast<const typename F::Block*>(weights);
|
||||
@@ -1279,7 +1324,7 @@ void launch_multi_n(const void* weights, const void* x_q8_1, float* y, int n_in,
|
||||
const char* v = std::getenv("STRATA_NO_MMVQ_ROWS2");
|
||||
return v != nullptr && v[0] != '\0' && v[0] != '0';
|
||||
}();
|
||||
if (rows1 && n_in / F::DIV >= F::BPI) {
|
||||
if ((rows1 || q8_0_rows1<F>(n_in, n_out)) && n_in / F::DIV >= F::BPI) {
|
||||
if (s26_tsum_on()) launch_pdl(native_mmvq_multi_kernel<F, NCOLS, WARPS, 1, true, false>, dim3(unsigned(n_out)), threads, 0, s, w, x, y, n_in, n_out, no_w2, no_y2);
|
||||
else launch_pdl(native_mmvq_multi_kernel<F, NCOLS, WARPS, 1, false, false>, dim3(unsigned(n_out)), threads, 0, s, w, x, y, n_in, n_out, no_w2, no_y2);
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user