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
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ func.def inline @ggml_mul_mat_f32_f32_wmma_tiled(%weight_format: index, %token_c
%result_stage_bytes = index.constant 2048 : offset
%c0_f32x4 = vector.constant 0.0 : vector<4xf32>
%c0_f16x4 = vector.constant 0.0 : vector<4xf16>
// engine #1962 (the dense form of #1539): the activations go through f16 for the matrix multiply and f16 ends at
// 65504, so an unnormalised activation above that became inf and the product NaN. Narrow at 2^-6 and scale the f32
// accumulator back by 2^6 on publish: exact while the scaled value is a normal f16, window [3.9e-3, 4.19e6].
%activation_prescale = vector.constant 0.015625 : vector<4xf32>
%result_unscale = vector.constant 64.0 : vector<4xf32>
%zero_accumulator = vector.constant 0.0 : vector<4xf32>
%m = index.constant 16 : index
%n = index.constant 16 : index
Expand Down Expand Up @@ -136,7 +141,8 @@ func.def inline @ggml_mul_mat_f32_f32_wmma_tiled(%weight_format: index, %token_c
%bounded_token, %input_token_count = index.assume %token, %bounded_token_count [lt(%token, %bounded_token_count)] : index, index
%mask = vector.mask.range [%input_k to %bounded_input_size step %c1] : index -> vector<4xi1>
%loaded = vector.load.mask %input_view[%bounded_token, %input_k], %mask, %c0_f32x4 : view<[%bounded_token_count]x[%bounded_input_size]xf32>, vector<4xi1>, vector<4xf32>
%converted = vector.fptrunc %loaded : vector<4xf32> to vector<4xf16>
%prescaled = vector.mulf %loaded, %activation_prescale : vector<4xf32>
%converted = vector.fptrunc %prescaled : vector<4xf32> to vector<4xf16>
scf.yield %converted : vector<4xf16>
} else {
scf.yield %c0_f16x4 : vector<4xf16>
Expand Down Expand Up @@ -184,28 +190,32 @@ func.def inline @ggml_mul_mat_f32_f32_wmma_tiled(%weight_format: index, %token_c
vector.fragment.store<result> %result00, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes00 {
%values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_f32_f32_wmma.publish_vector4>(%writes00, %token0, %channel0, %bounded_token_count, %bounded_output_size, %output_accumulation, %output_unary_op, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result01, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes01 {
%values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_f32_f32_wmma.publish_vector4>(%writes01, %token1, %channel0, %bounded_token_count, %bounded_output_size, %output_accumulation, %output_unary_op, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result10, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes10 {
%values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_f32_f32_wmma.publish_vector4>(%writes10, %token0, %channel1, %bounded_token_count, %bounded_output_size, %output_accumulation, %output_unary_op, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result11, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes11 {
%values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_token, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_f32_f32_wmma.publish_vector4>(%writes11, %token1, %channel1, %bounded_token_count, %bounded_output_size, %output_accumulation, %output_unary_op, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
template.apply<@ggml.mul_mat_f32_f32_wmma.finish_tile>(%bounded_token_count, %bounded_output_size, %output_tile_count, %token_tile_count, %output_accumulation, %output_unary_op, %epsilon, %channel_tile, %token_tile, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (index, index, index, index, index, index, f32, index, index, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,16 @@ template.def<@ggml.mul_mat_id_f32_f32_wmma.core> device @ggml_mul_mat_id_f32_f32
%c0_i32 = scalar.constant 0 : i32
%cn1_i32 = scalar.constant -1 : i32
%c0_f16x4 = vector.constant 0.0 : vector<4xf16>
// engine #1539: the activations go through f16 for the matrix multiply, and f16 ends at 65504. An expert's
// down-projection reads the SwiGLU output, which is not normalised: flint's layer 46 reaches +-9.1e4 on an ordinary
// prompt, the narrowing made that inf, the route sum inf - inf = NaN, and the NaN was stored as that token's keys and
// values. So the activations are narrowed at 2^-6 of their value and the f32 accumulator is scaled back by 2^6 when a
// tile is published. Both factors are powers of two, so nothing is rounded differently while the scaled value is a
// normal f16: the representable window moves from [6.1e-5, 6.55e4] to [3.9e-3, 4.19e6]. Below 3.9e-3 an element is
// rounded to a multiple of 3.8e-6 instead of keeping 11 bits, which is far under the rounding already applied to the
// order-1 elements it is summed with (4.9e-4 at 1.0).
%activation_prescale = vector.constant 0.015625 : vector<4xf32>
%result_unscale = vector.constant 64.0 : vector<4xf32>
%zero_accumulator = vector.constant 0.0 : vector<4xf32>
%m = index.constant 16 : index
%n = index.constant 16 : index
Expand Down Expand Up @@ -209,7 +219,8 @@ template.def<@ggml.mul_mat_id_f32_f32_wmma.core> device @ggml_mul_mat_id_f32_f32
%input_k = index.add %k_origin, %load_k : index
%mask = vector.mask.range [%input_k to %input_size step %c1] : index -> vector<4xi1>
%loaded = vector.load.mask %input_view[%token, %input_route, %input_k], %mask, %c0_f32x4 : view<[%bounded_token_count]x[%bounded_input_route_count]x[%input_size]xf32>, vector<4xi1>, vector<4xf32>
%converted = vector.fptrunc %loaded : vector<4xf32> to vector<4xf16>
%prescaled = vector.mulf %loaded, %activation_prescale : vector<4xf32>
%converted = vector.fptrunc %prescaled : vector<4xf32> to vector<4xf16>
scf.yield %converted : vector<4xf16>
} else {
scf.yield %c0_f16x4 : vector<4xf16>
Expand Down Expand Up @@ -277,28 +288,32 @@ template.def<@ggml.mul_mat_id_f32_f32_wmma.core> device @ggml_mul_mat_id_f32_f32
vector.fragment.store<result> %result00, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes00 {
%values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_id_f32_f32_wmma.publish_vector4>(%writes00, %bounded_assignment0, %assignment_token0, %assignment_route0, %channel0, %bounded_token_count, %bounded_route_count, %bounded_output_size, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result01, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes01 {
%values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_id_f32_f32_wmma.publish_vector4>(%writes01, %bounded_assignment1, %assignment_token1, %assignment_route1, %channel0, %bounded_token_count, %bounded_route_count, %bounded_output_size, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result10, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes10 {
%values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_id_f32_f32_wmma.publish_vector4>(%writes10, %bounded_assignment0, %assignment_token0, %assignment_route0, %channel1, %bounded_token_count, %bounded_route_count, %bounded_output_size, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
vector.fragment.store<result> %result11, %result_fragment_view[%c0, %c0] shape [%m, %n] : vector<4xf32>, view<16x16xf32, %result_fragment_layout>
kernel.barrier<workgroup> scope(subgroup) ordering(acq_rel)
scf.if %writes11 {
%values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%scaled_values = vector.load %result_physical_view[%publish_route, %publish_channel_add] : view<16x16xf32> -> vector<4xf32>
%values = vector.mulf %scaled_values, %result_unscale : vector<4xf32>
template.apply<@ggml.mul_mat_id_f32_f32_wmma.publish_vector4>(%writes11, %bounded_assignment1, %assignment_token1, %assignment_route1, %channel1, %bounded_token_count, %bounded_route_count, %bounded_output_size, %values, %bias, %output, %residual_input, %residual_output, %norm_weight, %normalized_output, %completion_counters) : (i1, index, index, index, index, index, index, index, vector<4xf32>, buffer, buffer, buffer, buffer, buffer, buffer, buffer)
}
kernel.barrier<workgroup> scope(workgroup) ordering(acq_rel)
Expand Down
Loading