Skip to content

Commit 01eaba2

Browse files
committed
Merge remote-tracking branch 'upstream/main' into merge-ci-files
2 parents e08ff2d + 80665cd commit 01eaba2

File tree

9 files changed

+625
-325
lines changed

9 files changed

+625
-325
lines changed

examples/amd/example_amd_flash_attn_bwd.py

Lines changed: 525 additions & 285 deletions
Large diffs are not rendered by default.

examples/amd/example_amd_flash_attn_fwd.py

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def get_configs():
3434
block_N = [32, 64, 128, 256]
3535
threads = [128, 256, 512]
3636
num_split_q = [64, 128, 256]
37-
num_stages = [0]
37+
num_stages = [0, 1]
3838
enable_rasterization = [True]
3939
k_pack = [2]
4040
panel_size = [7, 8]
@@ -60,18 +60,6 @@ def get_configs():
6060
"qk_coalesced_width": qkw,
6161
"v_coalesced_width": vw,
6262
})
63-
valid_configs.append({
64-
'block_M': 64,
65-
'block_N': 64,
66-
'num_split_q': 64,
67-
'threads': 256,
68-
'num_stages': 1,
69-
'enable_rasterization': True,
70-
'k_pack': 2,
71-
'panel_size': 64,
72-
'qk_coalesced_width': 8,
73-
'v_coalesced_width': 8,
74-
})
7563
return valid_configs
7664

7765

@@ -95,7 +83,7 @@ def fast_flashattn(
9583
qk_coalesced_width: int,
9684
v_coalesced_width: int,
9785
):
98-
scale = (1.0 / dim)**0.5 * 1.44269504
86+
scale = (1.0 / dim)**0.5
9987
head_kv = heads // groups
10088
q_shape = [batch, seq_len, heads, dim]
10189
kv_shape = [batch, seq_len, head_kv, dim]
@@ -185,15 +173,15 @@ def main(
185173
T.reduce_max(acc_s, m_i, dim=1, clear=False)
186174

187175
for i in T.Parallel(block_M):
188-
sf = T.exp2(m_prev[i] * scale - m_i[i] * scale)
176+
sf = T.exp(m_prev[i] * scale - m_i[i] * scale)
189177
l_i[i] *= sf
190178
scale_factor[i] = sf
191179

192180
for i, j in T.Parallel(block_M, dim):
193181
acc_o[i, j] *= scale_factor[i]
194182

195183
for i, j in T.Parallel(block_M, block_N):
196-
acc_s[i, j] = T.exp2(acc_s[i, j] * scale - m_i[i] * scale)
184+
acc_s[i, j] = T.exp(acc_s[i, j] * scale - m_i[i] * scale)
197185

198186
T.reduce_sum(acc_s, row_sum, dim=1)
199187
for i in T.Parallel(block_M):

examples/amd/test.sh

Lines changed: 0 additions & 10 deletions
This file was deleted.

examples/flash_attention/example_mha_bwd.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,10 @@ def flash_fwd(
3838
scores_sum = T.alloc_fragment([block_M], accum_dtype)
3939
logsum = T.alloc_fragment([block_M], accum_dtype)
4040

41-
T.annotate_layout({Q_shared: tilelang.layout.make_swizzled_layout(Q_shared)})
4241
T.copy(Q[bz, bx * block_M:(bx + 1) * block_M, by, :], Q_shared)
4342
T.fill(acc_o, 0)
4443
T.fill(logsum, 0)
4544
T.fill(scores_max, -T.infinity(accum_dtype))
46-
# T.copy(Q_shared, Q_local)
47-
# for i, j in T.Parallel(block_M, dim):
48-
# Q_local[i, j] *= scale
4945
loop_range = (
5046
T.ceildiv(
5147
(bx + 1) * block_M, block_N) if is_causal else T.ceildiv(seq_len, block_N))
@@ -192,9 +188,6 @@ def flash_bwd(
192188

193189
T.annotate_layout({
194190
dQ: make_dq_layout(dQ),
195-
K_shared: tilelang.layout.make_swizzled_layout(K_shared),
196-
dv_shared: tilelang.layout.make_swizzled_layout(dv_shared),
197-
dk_shared: tilelang.layout.make_swizzled_layout(dk_shared),
198191
})
199192
T.copy(K[bz, by * block_M:(by + 1) * block_M, bx, :], K_shared)
200193
T.copy(V[bz, by * block_M:(by + 1) * block_M, bx, :], V_shared)

src/target/codegen_hip.cc

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,18 @@ static std::string GetFP8Type(DataType type) {
4141
stream << "fp8_e4" << vec << "_t";
4242
} else if (type.code() == DataType::kFloat8_e4m3fnuz) {
4343
stream << "fp8_e4" << vec << "_t";
44+
} else if (type.code() == DataType::kFloat8_e4m3) {
45+
stream << "fp8_e4" << vec << "_t";
46+
} else if (type.code() == DataType::kFloat8_e4m3b11fnuz) {
47+
stream << "fp8_e4" << vec << "_t";
4448
} else if (type.code() == DataType::kFloat8_e5m2) {
4549
stream << "fp8_e5" << vec << "_t";
50+
} else if (type.code() == DataType::kFloat8_e5m2fnuz) {
51+
stream << "fp8_e5" << vec << "_t";
52+
} else if (type.code() == DataType::kFloat8_e8m0fnu) {
53+
stream << "fp8_e8" << vec << "_t";
4654
} else {
47-
LOG(FATAL) << "Unsupported FP8 type in HIP codegen";
55+
LOG(FATAL) << "Unsupported FP8 type in HIP codegen: " << type;
4856
}
4957
return stream.str();
5058
}
@@ -926,10 +934,10 @@ void CodeGenTileLangHIP::VisitExpr_(const CallNode *op, std::ostream &os) {
926934
{"float8_e4m3fnuzx8", "long"},
927935
{"float32x16", "float32x16"}};
928936
std::string call_mfma_code = R"({
929-
*((({C_dtype}*){c_ref}) + {c_bias}) = {mfma_buildin}(*((({A_dtype}*){a_ref}) + {a_bias}),
930-
*((({B_dtype}*){b_ref}) + {b_bias}),
931-
*((({C_dtype}*){c_ref}) + {c_bias}), 0, 0, 0);
932-
})";
937+
*((({C_dtype}*){c_ref}) + {c_bias}) = {mfma_buildin}(*((({A_dtype}*){a_ref}) + {a_bias}),
938+
*((({B_dtype}*){b_ref}) + {b_bias}),
939+
*((({C_dtype}*){c_ref}) + {c_bias}), 0, 0, 0);
940+
})";
933941
std::string mfma_buildin = "__builtin_amdgcn_mfma_" + prefix;
934942
Replacer replacer;
935943

@@ -955,6 +963,13 @@ void CodeGenTileLangHIP::VisitExpr_(const CallNode *op, std::ostream &os) {
955963
op->args, true, os);
956964
} else if (op->op.same_as(tl::tl_gemm_sp())) {
957965
LOG(FATAL) << "tl_gemm_sp is not supported on HIP";
966+
} else if (op->op.same_as(tl::loop_break())) {
967+
this->PrintIndent();
968+
this->stream << "break;\n";
969+
} else if (op->op.same_as(tl::no_set_max_nreg())) {
970+
// HIP doesn't need explicit register management like CUDA
971+
// This is a no-op for HIP
972+
return;
958973
} else {
959974
CodeGenC::VisitExpr_(op, os);
960975
}
@@ -1160,7 +1175,8 @@ inline void PrintConst(const FloatImmNode *op, std::ostream &os,
11601175
os << "bfloat16_t";
11611176
os << '(' << std::scientific << op->value << 'f' << ')';
11621177
return;
1163-
} else if (op->dtype.is_float8_e4m3fnuz()) {
1178+
} else if (op->dtype.is_float8_e4m3fnuz() || op->dtype.is_float8_e4m3() ||
1179+
op->dtype.is_float8_e4m3fn()) {
11641180
os << "fp8_e4_t";
11651181
os << '(' << std::scientific << op->value << 'f' << ')';
11661182
return;

src/tl_templates/hip/common.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,13 @@ template <typename T1, typename T2>
109109
TL_DEVICE void AtomicAdd(T1 *address, T2 val) {
110110
atomicAdd(reinterpret_cast<T1 *>(address), static_cast<T1>(val));
111111
}
112+
113+
// Overload for when the first argument is a value instead of a pointer
114+
template <typename T1, typename T2>
115+
TL_DEVICE void AtomicAdd(T1 address, T2 val) {
116+
atomicAdd(reinterpret_cast<T1 *>(&address), static_cast<T1>(val));
117+
}
118+
119+
template <typename T1, typename T2> TL_DEVICE T1 AtomicAddRet(T1 &ref, T2 val) {
120+
return atomicAdd(&ref, static_cast<T1>(val));
121+
}

src/tl_templates/hip/gemm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ template <int M, int N, int K, int num_warp_m, int num_warp_n, bool TransposeA,
7070
typename B_type, typename C_type, typename AccDataType = float>
7171
class GemmTensorOp {
7272
public:
73-
static_assert(!clear_accum, "clear_accum=true is not supported yet");
73+
// Note: clear_accum=true is not fully supported in HIP implementation
74+
// but we'll handle it by manually clearing the accumulator
75+
// static_assert(!clear_accum, "clear_accum=true is not supported yet");
7476

7577
static constexpr int micro_size_x = 16;
7678
static constexpr int micro_size_y = 16;

src/tl_templates/hip/hip_fp8.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
using fp8_e4_t = __hip_fp8_e4m3_fnuz;
66
using fp8_e4_2_t = __hip_fp8x2_e4m3_fnuz;
77

8+
// Additional FP8 types for compatibility
9+
using fp8_e5_t = __hip_fp8_e5m2_fnuz;
10+
using fp8_e5_2_t = __hip_fp8x2_e5m2_fnuz;
11+
// Note: E8M0 types are not supported in current HIP version
12+
// using fp8_e8_t = __hip_fp8_e8m0_fnuz;
13+
// using fp8_e8_2_t = __hip_fp8x2_e8m0_fnuz;
14+
815
// Simple wrapper that provides member access for generated code
916
struct fp8_e4_4_t {
1017
union {
@@ -43,6 +50,54 @@ struct __align__(16) fp8_e4_16_t {
4350
fp8_e4_8_t y;
4451
};
4552

53+
// FP8 E5M2 vector types
54+
struct fp8_e5_4_t {
55+
union {
56+
__hip_fp8x4_e5m2_fnuz data;
57+
struct {
58+
fp8_e5_t x, y, z, w;
59+
};
60+
};
61+
__device__ fp8_e5_4_t() = default;
62+
__device__ fp8_e5_4_t(const __hip_fp8x4_e5m2_fnuz &val) : data(val) {}
63+
__device__ operator __hip_fp8x4_e5m2_fnuz() const { return data; }
64+
};
65+
66+
struct __align__(8) fp8_e5_8_t {
67+
fp8_e5_4_t x;
68+
fp8_e5_4_t y;
69+
};
70+
71+
struct __align__(16) fp8_e5_16_t {
72+
fp8_e5_8_t x;
73+
fp8_e5_8_t y;
74+
};
75+
76+
// FP8 E8M0 vector types - not supported in current HIP version
77+
/*
78+
struct fp8_e8_4_t {
79+
union {
80+
__hip_fp8x4_e8m0_fnuz data;
81+
struct {
82+
fp8_e8_t x, y, z, w;
83+
};
84+
};
85+
__device__ fp8_e8_4_t() = default;
86+
__device__ fp8_e8_4_t(const __hip_fp8x4_e8m0_fnuz &val) : data(val) {}
87+
__device__ operator __hip_fp8x4_e8m0_fnuz() const { return data; }
88+
};
89+
90+
struct __align__(8) fp8_e8_8_t {
91+
fp8_e8_4_t x;
92+
fp8_e8_4_t y;
93+
};
94+
95+
struct __align__(16) fp8_e8_16_t {
96+
fp8_e8_8_t x;
97+
fp8_e8_8_t y;
98+
};
99+
*/
100+
46101
__device__ fp8_e4_4_t make_fp8_e4_4_t(fp8_e4_t x, fp8_e4_t y, fp8_e4_t z,
47102
fp8_e4_t w) {
48103
// reinterpret the 4 fp8_e4_t values to signed char value and shift

testing/python/amd/test_tilelang_gemm_mfma_intrinsic.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ def test_assert_tl_matmul():
238238
128, 256, 256, "int8", "int32", b_transposed=False, accum_dtype="int32")
239239
assert_tl_matmul_correctness(
240240
128, 256, 256, "int8", "int32", b_transposed=False, accum_dtype="int32", k_pack=2)
241+
assert_tl_matmul_correctness(128, 128, 128, "float8_e4m3fnuz", "float16")
242+
assert_tl_matmul_correctness(128, 256, 256, "float8_e4m3fnuz", "float32")
243+
assert_tl_matmul_correctness(128, 256, 256, "float8_e4m3fnuz", "float32", k_pack=2)
244+
assert_tl_matmul_correctness(128, 256, 256, "float8_e4m3fnuz", "float32", b_transposed=False)
245+
assert_tl_matmul_correctness(
246+
128, 256, 256, "float8_e4m3fnuz", "float32", b_transposed=False, k_pack=2)
241247

242248

243249
if __name__ == "__main__":

0 commit comments

Comments
 (0)