Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/metaltile-codegen/src/cuda/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use crate::{
/// Shared preamble for every emitted CUDA kernel: headers, the `MT_INF`
/// constant (NVRTC has no `INFINITY` macro), and the block-scaled-quant
/// decode helpers ported verbatim from `msl/preamble.rs` (pure arithmetic
/// → identical to `quant::codec`). Unused helpers are pruned by the
/// → identical to `kernels::quant::codec`). Unused helpers are pruned by the
/// compiler, so we always emit them.
const CUDA_PREAMBLE: &str = r#"// Generated by MetalTile (CUDA backend). DO NOT EDIT.
#include <cuda_fp16.h>
Expand Down
65 changes: 0 additions & 65 deletions crates/metaltile-std/src/ffai/mod.rs

This file was deleted.

39 changes: 21 additions & 18 deletions crates/metaltile-std/src/kernels/convolution/consolidated/conv1d.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ pub fn mt_conv1d_quant<T>(
#[allow(clippy::too_many_arguments)]
fn blockscaled_setup(
kernel: metaltile::core::ir::Kernel,
fmt: crate::quant::format::QFormat,
fmt: crate::kernels::quant::format::QFormat,
batch: usize,
in_ch: usize,
in_len: usize,
Expand All @@ -406,8 +406,8 @@ fn blockscaled_setup(
let bias_f: Vec<f32> = (0..out_ch).map(|i| ((i % 5) as f32 / 5.0 - 0.5) * 2.0).collect();
let weight_f: Vec<f32> =
(0..(out_ch * c_dim)).map(|i| ((i % 11) as f32 / 11.0 - 0.5) * 4.0).collect();
let p = crate::quant::format::pack(fmt, &weight_f, out_ch, c_dim);
let wdq = crate::quant::format::dequant(fmt, &p, out_ch, c_dim);
let p = crate::kernels::quant::format::pack(fmt, &weight_f, out_ch, c_dim);
let wdq = crate::kernels::quant::format::dequant(fmt, &p, out_ch, c_dim);
let input = crate::utils::unpack_f32(&crate::utils::pack_f32(&input_f, dt), dt);
let bias = crate::utils::unpack_f32(&crate::utils::pack_f32(&bias_f, dt), dt);
let expected = {
Expand Down Expand Up @@ -438,8 +438,8 @@ fn blockscaled_setup(
};
let weight_dt = if fmt.element_bits() == 8 { DType::U8 } else { DType::U32 };
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let mut s = TestSetup::new(kernel)
Expand Down Expand Up @@ -467,7 +467,7 @@ fn blockscaled_setup(
if dilation > 1 {
s = s.constexpr("dilation", dilation as u32);
}
if matches!(fmt, crate::quant::format::QFormat::Nvfp4) {
if matches!(fmt, crate::kernels::quant::format::QFormat::Nvfp4) {
s = s.constexpr("global", p.global);
}
s.expect(TestBuffer::from_vec("out", crate::utils::pack_f32(&expected, dt), dt))
Expand Down Expand Up @@ -911,13 +911,13 @@ pub mod kernel_tests {
// Named FMT values in this mini-list: mxfp4=0, nvfp4=1, fp8_e5m2=2, int8=3.
// Named DIL values: audio=0, fishspeech=1.
let fmt = if FMT == 0u32 {
crate::quant::format::QFormat::Mxfp4
crate::kernels::quant::format::QFormat::Mxfp4
} else if FMT == 1u32 {
crate::quant::format::QFormat::Nvfp4
crate::kernels::quant::format::QFormat::Nvfp4
} else if FMT == 2u32 {
crate::quant::format::QFormat::Fp8E5m2
crate::kernels::quant::format::QFormat::Fp8E5m2
} else {
crate::quant::format::QFormat::Int8
crate::kernels::quant::format::QFormat::Int8
};
let kernel = if DIL == 0u32 {
if FMT == 0u32 {
Expand Down Expand Up @@ -1021,22 +1021,25 @@ pub mod kernel_benches {
// Named FMT values in this mini-list: mxfp4=0, nvfp4=1, fp8_e5m2=2, int8=3.
// Named DIL values: audio=0, fishspeech=1.
let fmt = if FMT == 0u32 {
crate::quant::format::QFormat::Mxfp4
crate::kernels::quant::format::QFormat::Mxfp4
} else if FMT == 1u32 {
crate::quant::format::QFormat::Nvfp4
crate::kernels::quant::format::QFormat::Nvfp4
} else if FMT == 2u32 {
crate::quant::format::QFormat::Fp8E5m2
crate::kernels::quant::format::QFormat::Fp8E5m2
} else {
crate::quant::format::QFormat::Int8
crate::kernels::quant::format::QFormat::Int8
};
let (codes_dt, codes_len) = if fmt.element_bits() == 8 {
(DType::U8, out_ch * c_dim)
} else {
(DType::U32, crate::quant::format::bitstream_words(out_ch * c_dim, fmt.element_bits()))
(
DType::U32,
crate::kernels::quant::format::bitstream_words(out_ch * c_dim, fmt.element_bits()),
)
};
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let n_blocks = out_ch * (c_dim / fmt.block_size());
Expand Down Expand Up @@ -1091,7 +1094,7 @@ pub mod kernel_benches {
if DIL == 1u32 {
s = s.constexpr("dilation", 1u32);
}
if matches!(fmt, crate::quant::format::QFormat::Nvfp4) {
if matches!(fmt, crate::kernels::quant::format::QFormat::Nvfp4) {
s = s.constexpr("global", 1.0f32);
}
s.grid_1d(n_out, 256)
Expand Down
23 changes: 13 additions & 10 deletions crates/metaltile-std/src/kernels/convolution/conv2d_block_scaled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! taps clamped to contribute zero. `C` is a multiple of `block_size` (4-bit
//! `block_size` a multiple of 8). fp8_e4m3 reuses the nvfp8 kernel. Codegen-only;
//! correctness pinned by the in-source `#[test_kernel]`s vs a
//! `quant::format::dequant` oracle running the dense conv2d math.
//! `kernels::quant::format::dequant` oracle running the dense conv2d math.

use metaltile::kernel;
/// Quantized-weight conv2d, folded over the 28-format axis (§7). Geometry is the
Expand Down Expand Up @@ -176,7 +176,7 @@ pub mod kernel_tests {

use super::*;
use crate::{
quant::format::QFormat,
kernels::quant::format::QFormat,
utils::{pack_f32, unpack_f32},
};

Expand Down Expand Up @@ -277,8 +277,8 @@ pub mod kernel_tests {
let bias_f = ramp(out_ch, 5, 2.0);
// Quantize the [out_ch, C] filter via the shared codec.
let w_f = ramp(out_ch * contraction, 11, 4.0);
let p = crate::quant::format::pack(fmt, &w_f, out_ch, contraction);
let wdq = crate::quant::format::dequant(fmt, &p, out_ch, contraction);
let p = crate::kernels::quant::format::pack(fmt, &w_f, out_ch, contraction);
let wdq = crate::kernels::quant::format::dequant(fmt, &p, out_ch, contraction);
let input = unpack_f32(&pack_f32(&input_f, dt), dt);
let bias = unpack_f32(&pack_f32(&bias_f, dt), dt);
// Oracle: dense conv2d over the dequantized filter row [out_ch, C].
Expand All @@ -292,8 +292,8 @@ pub mod kernel_tests {
// off the format so new integer formats pick up the right buffer types.
let weight_dt = if fmt.element_bits() == 8 { DType::U8 } else { DType::U32 };
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let mut s = TestSetup::new(kernel)
Expand Down Expand Up @@ -382,7 +382,7 @@ pub mod kernel_benches {
use metaltile::{bench, core::ir::Kernel, test::*};

use super::*;
use crate::quant::format::QFormat;
use crate::kernels::quant::format::QFormat;

#[allow(clippy::too_many_arguments)]
fn conv2d_bench(
Expand All @@ -409,11 +409,14 @@ pub mod kernel_benches {
let (codes_len, codes_dt) = if fmt.element_bits() == 8 {
(n_codes, DType::U8)
} else {
(crate::quant::format::bitstream_words(n_codes, fmt.element_bits()), DType::U32)
(
crate::kernels::quant::format::bitstream_words(n_codes, fmt.element_bits()),
DType::U32,
)
};
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let n_blocks = out_ch * (contraction / fmt.block_size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ pub mod kernel_tests {

use super::*;
use crate::{
quant::format::{QFormat, ScaleKind},
kernels::quant::format::{QFormat, ScaleKind},
utils::{pack_f32, unpack_f32},
};

Expand Down Expand Up @@ -440,8 +440,8 @@ pub mod kernel_tests {
let input_f = ramp(batch * in_ch * in_h * in_w, 13, 2.0);
// Quantize the [out_ch, BK] filter via the shared codec.
let filter_f = ramp(out_ch * bk, 11, 2.0);
let p = crate::quant::format::pack(fmt, &filter_f, out_ch, bk);
let wdq = crate::quant::format::dequant(fmt, &p, out_ch, bk);
let p = crate::kernels::quant::format::pack(fmt, &filter_f, out_ch, bk);
let wdq = crate::kernels::quant::format::dequant(fmt, &p, out_ch, bk);
let input = unpack_f32(&pack_f32(&input_f, dt), dt);
let expected = naive_conv2d_mma(&input, &wdq, batch, in_ch, in_h, in_w, out_ch, kh, kw);
// Axis-driven binding (robust across all element widths/scale kinds):
Expand Down Expand Up @@ -872,7 +872,7 @@ pub mod kernel_benches {
use metaltile::{bench, core::ir::Kernel, test::*};

use super::*;
use crate::quant::format::{QFormat, ScaleKind};
use crate::kernels::quant::format::{QFormat, ScaleKind};

#[allow(clippy::too_many_arguments)]
fn mma_bench(
Expand Down Expand Up @@ -900,7 +900,10 @@ pub mod kernel_benches {
let (codes_len, codes_dt) = if fmt.element_bits() == 8 {
(out_ch * bk, DType::U8)
} else {
(crate::quant::format::bitstream_words(out_ch * bk, fmt.element_bits()), DType::U32)
(
crate::kernels::quant::format::bitstream_words(out_ch * bk, fmt.element_bits()),
DType::U32,
)
};
let scales_dt = match fmt.scale_kind() {
ScaleKind::F32 => DType::F32,
Expand Down
20 changes: 10 additions & 10 deletions crates/metaltile-std/src/kernels/convolution/conv3d_block_scaled.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//! taps clamped to contribute zero. `C` is a multiple of `block_size` (4-bit
//! `block_size` a multiple of 8). fp8_e4m3 reuses the nvfp8 kernel.
//! Codegen-only; correctness pinned by the in-source `#[test_kernel]`s vs a
//! `quant::format::dequant` oracle running the dense conv3d math.
//! `kernels::quant::format::dequant` oracle running the dense conv3d math.

use metaltile::kernel;

Expand Down Expand Up @@ -193,7 +193,7 @@ pub mod kernel_tests {

use super::*;
use crate::{
quant::format::QFormat,
kernels::quant::format::QFormat,
utils::{pack_f32, unpack_f32},
};

Expand Down Expand Up @@ -315,8 +315,8 @@ pub mod kernel_tests {
let bias_f = ramp(out_ch, 5, 2.0);
// Quantize the [out_ch, C] filter via the shared codec.
let w_f = ramp(out_ch * contraction, 11, 4.0);
let p = crate::quant::format::pack(fmt, &w_f, out_ch, contraction);
let wdq = crate::quant::format::dequant(fmt, &p, out_ch, contraction);
let p = crate::kernels::quant::format::pack(fmt, &w_f, out_ch, contraction);
let wdq = crate::kernels::quant::format::dequant(fmt, &p, out_ch, contraction);
let input = unpack_f32(&pack_f32(&input_f, dt), dt);
let bias = unpack_f32(&pack_f32(&bias_f, dt), dt);
// Oracle: dense conv3d over the dequantized filter row [out_ch, C].
Expand All @@ -330,8 +330,8 @@ pub mod kernel_tests {
// off the format so new integer formats pick up the right buffer types.
let weight_dt = if fmt.element_bits() == 8 { DType::U8 } else { DType::U32 };
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let mut s = TestSetup::new(kernel)
Expand Down Expand Up @@ -424,7 +424,7 @@ pub mod kernel_benches {
use metaltile::{bench, core::ir::Kernel, test::*};

use super::*;
use crate::quant::format::QFormat;
use crate::kernels::quant::format::QFormat;

#[allow(clippy::too_many_arguments)]
fn conv3d_bench(
Expand Down Expand Up @@ -455,11 +455,11 @@ pub mod kernel_benches {
let (codes_len, codes_dt) = if fmt.element_bits() == 8 {
(total, DType::U8)
} else {
(crate::quant::format::bitstream_words(total, fmt.element_bits()), DType::U32)
(crate::kernels::quant::format::bitstream_words(total, fmt.element_bits()), DType::U32)
};
let scales_dt = match fmt.scale_kind() {
crate::quant::format::ScaleKind::F32 => DType::F32,
crate::quant::format::ScaleKind::F16 => DType::F16,
crate::kernels::quant::format::ScaleKind::F32 => DType::F32,
crate::kernels::quant::format::ScaleKind::F16 => DType::F16,
_ => DType::U8,
};
let n_blocks = out_ch * (contraction / fmt.block_size());
Expand Down
Loading
Loading