Skip to content

Commit aeabde1

Browse files
committed
refactor(tensor-core): remove default fallback to eliminate circular dependency
Delete tensor_core_launcher_impl.cuh and require explicit fallback specification via launch_tensor_core_sgemm_with_fallback(). Benefits: - Compile-time decoupling from specific kernels - Single responsibility: type conversion + Tensor Core launch - Interface expresses intent: caller must decide fallback strategy
1 parent 61ea9ec commit aeabde1

7 files changed

Lines changed: 94 additions & 70 deletions

File tree

CONTEXT.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
**位置**: `src/kernels/tensor_core_launcher.cuh`
3131

3232
统一的 SGEMM 启动接口,提供:
33-
- `launch_tensor_core_sgemm()` - 安全的端到端 FP32 入口点(使用默认 fallback)
34-
- `launch_tensor_core_sgemm_with_fallback()` - 支持自定义 fallback 策略的模板版本
33+
- `launch_tensor_core_sgemm_with_fallback()` - 端到端 FP32 入口点(强制显式指定 fallback)
3534
- `FallbackKernel` - fallback 函数类型定义
3635
- `kTensorCoreVerifyTolerance` - Tensor Core 验证容差
3736

@@ -40,15 +39,17 @@
4039
- FP32 → FP16 类型转换
4140
- 不支持情况下的 fallback 到用户指定的策略
4241

43-
**设计优势**
44-
- 解耦 Tensor Core 模块与特定 fallback 内核
45-
- 用户可注入自定义 fallback(如 naive、tiled、bank-conflict-free)
46-
- 支持运行时选择 fallback 策略
47-
48-
#### Tensor Core Launcher Impl
49-
**位置**: `src/kernels/tensor_core_launcher_impl.cuh`
50-
51-
默认实现,使用 bank-conflict-free 作为 fallback。
42+
**设计原则**
43+
- **不提供默认 fallback**:调用者必须显式指定 fallback 策略
44+
- **编译期解耦**:Tensor Core 模块不依赖任何具体内核
45+
- **深度提升**:模块职责单一(类型转换 + Tensor Core 启动)
46+
47+
**便利函数**
48+
调用点可以使用 `defaultTensorCoreFallback()` 便利函数(定义在各自的调用位置):
49+
```cpp
50+
launch_tensor_core_sgemm_with_fallback(A, B, C, M, K, N,
51+
defaultTensorCoreFallback(), stream);
52+
```
5253
5354
#### Tensor Core Benchmark
5455
**位置**: `src/kernels/tensor_core_benchmark.cuh`

src/benchmark_runner.cuh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@
1313

1414
#include <cstdio>
1515

16+
// ============================================================================
17+
// Tensor Core 便利函数
18+
// ============================================================================
19+
20+
/**
21+
* 默认 Tensor Core fallback 策略
22+
*
23+
* 使用 bank-conflict-free 内核作为 fallback。
24+
* 这是一个便利函数,减少调用点的重复代码。
25+
*/
26+
inline auto defaultTensorCoreFallback() {
27+
return [](const float* A, const float* B, float* C, int M, int K, int N,
28+
cudaStream_t stream) {
29+
launch_bank_conflict_free_sgemm<32>(A, B, C, M, K, N, stream);
30+
};
31+
}
32+
1633
// ============================================================================
1734
// Benchmark 编排器
1835
// ============================================================================
@@ -158,7 +175,8 @@ class BenchmarkRunner {
158175
benchmark.run(
159176
"Tensor Core (WMMA end-to-end)",
160177
[](const float* A, const float* B, float* C, int M, int K, int N) {
161-
launch_tensor_core_sgemm(A, B, C, M, K, N);
178+
launch_tensor_core_sgemm_with_fallback(A, B, C, M, K, N,
179+
defaultTensorCoreFallback());
162180
},
163181
M, K, N, config_.warmup_runs, config_.benchmark_runs, kTensorCoreVerifyTolerance);
164182

src/kernels/tensor_core_launcher.cuh

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,15 @@ inline void launch_tensor_core_sgemm_with_fallback(const float* A, const float*
101101
}
102102

103103
// ============================================================================
104-
// 默认接口声明
104+
// 注意:不提供默认 fallback 版本
105105
// ============================================================================
106-
107-
/**
108-
* 使用 bank-conflict-free 作为默认 fallback
109-
*
110-
* 注意:此函数实现在 tensor_core_launcher_impl.cuh 中,
111-
* 以避免与 bank_conflict_free_sgemm.cuh 的循环依赖。
112-
*
113-
* 使用方法:
114-
* 1. 包含 tensor_core_launcher.cuh 和 bank_conflict_free_sgemm.cuh
115-
* 2. 直接调用 launch_tensor_core_sgemm()
116-
*/
117-
inline void launch_tensor_core_sgemm(const float* A, const float* B, float* C, int M, int K, int N,
118-
cudaStream_t stream = 0);
106+
//
107+
// 此模块不提供 launch_tensor_core_sgemm() 默认入口。
108+
// 调用者必须显式指定 fallback 策略:
109+
//
110+
// launch_tensor_core_sgemm_with_fallback(A, B, C, M, K, N, myFallback, stream);
111+
//
112+
// 这种设计:
113+
// - 消除与具体内核的循环依赖
114+
// - 强制调用者思考"不支持时怎么办"
115+
// - 保持模块职责单一(类型转换 + Tensor Core 启动)

src/kernels/tensor_core_launcher_impl.cuh

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

src/kernels/tensor_core_sgemm.cuh

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
// Tensor Core SGEMM - 公共接口
55
// ============================================================================
66
//
7-
// 此文件作为 Tensor Core 功能的公共入口点,保持向后兼容
8-
// 内部实现已拆分为多个深度模块
7+
// 此文件作为 Tensor Core 功能的公共入口点。
8+
// 内部实现拆分为多个深度模块
99
//
1010
// 1. tensor_core_capabilities.cuh - 能力查询接口
1111
// - tensorCoresAvailable()
@@ -17,25 +17,21 @@
1717
// - launch_tensor_core_sgemm_fp16()
1818
// - launch_tensor_core_sgemm_fp16_fast_path()
1919
//
20-
// 3. tensor_core_launcher.cuh - 统一启动接口(支持自定义 fallback)
20+
// 3. tensor_core_launcher.cuh - 统一启动接口(强制显式 fallback)
2121
// - launch_tensor_core_sgemm_with_fallback()
2222
// - FallbackKernel 类型定义
2323
// - Tensor Core 容差常量
2424
//
25-
// 4. tensor_core_launcher_impl.cuh - 默认实现
26-
// - launch_tensor_core_sgemm() 使用 bank-conflict-free 作为默认 fallback
27-
//
28-
// 5. tensor_core_benchmark.cuh - Tensor Core 专用 benchmark
25+
// 4. tensor_core_benchmark.cuh - Tensor Core 专用 benchmark
2926
// - runTensorCoreComputeOnlyBenchmark()
3027
//
31-
// 这种拆分提高了:
32-
// - 局部性 (Locality):每个关注点有独立的测试面
33-
// - 杠杆 (Leverage):能力检测可被多个模块使用
34-
// - 可测试性:可以独立测试能力检测、纯计算路径、fallback 路径
35-
// - 灵活性:用户可以注入自定义 fallback 策略
28+
// 设计原则:
29+
// - 不提供默认 fallback,强制调用者显式指定
30+
// - 消除与具体内核的循环依赖
31+
// - 每个模块有独立的测试面
3632
// ============================================================================
3733

3834
#include "tensor_core_capabilities.cuh"
3935
#include "tensor_core_compute.cuh"
4036
#include "tensor_core_launcher.cuh"
41-
#include "tensor_core_launcher_impl.cuh"
37+
#include "tensor_core_benchmark.cuh"

tests/test_performance.cu

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,23 @@
2323
#include "utils/benchmark_metrics.cuh"
2424
#include "utils/cuda_utils.cuh"
2525

26+
// ============================================================================
27+
// Tensor Core 便利函数
28+
// ============================================================================
29+
30+
/**
31+
* 默认 Tensor Core fallback 策略
32+
*
33+
* 使用 bank-conflict-free 内核作为 fallback。
34+
* 这是一个便利函数,减少调用点的重复代码。
35+
*/
36+
inline auto defaultTensorCoreFallback() {
37+
return [](const float* A, const float* B, float* C, int M, int K, int N,
38+
cudaStream_t stream) {
39+
launch_bank_conflict_free_sgemm<32>(A, B, C, M, K, N, stream);
40+
};
41+
}
42+
2643
// ============================================================================
2744
// 性能基线结构
2845
// ============================================================================
@@ -255,7 +272,11 @@ TEST_F(PerformanceRegressionTest, TensorCoreKernelPerformance) {
255272
};
256273

257274
for (const auto& [M, K, N] : tc_dimensions) {
258-
runPerformanceTest("TensorCore", launch_tensor_core_sgemm, M, K, N, kTensorCoreVerifyTolerance);
275+
runPerformanceTest("TensorCore",
276+
[](const float* A, const float* B, float* C, int M, int K, int N, cudaStream_t s) {
277+
launch_tensor_core_sgemm_with_fallback(A, B, C, M, K, N,
278+
defaultTensorCoreFallback(), s);
279+
}, M, K, N, kTensorCoreVerifyTolerance);
259280
}
260281
}
261282

tests/test_sgemm.cu

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
namespace {
2525
constexpr int PBT_ITERATIONS = 100;
2626

27+
// Tensor Core 默认 fallback(使用 bank-conflict-free)
28+
auto defaultTensorCoreFallback() {
29+
return [](const float* A, const float* B, float* C, int M, int K, int N,
30+
cudaStream_t stream) {
31+
launch_bank_conflict_free_sgemm<32>(A, B, C, M, K, N, stream);
32+
};
33+
}
34+
} // namespace
35+
2736
std::vector<std::tuple<int, int, int>> getStandardDimensions() {
2837
return {
2938
{1, 1, 1}, {2, 2, 2}, {4, 4, 4}, {16, 16, 16},
@@ -246,7 +255,10 @@ TEST_P(TensorCoreSGEMMTest, FastPathCorrectnessProperty) {
246255
ASSERT_TRUE(tensorCoreDimensionsSupported(M_, K_, N_));
247256

248257
VerifyResult result = runKernelAndCompare(
249-
[&] { launch_tensor_core_sgemm(d_A_->get(), d_B_->get(), d_C_->get(), M_, K_, N_); },
258+
[&] {
259+
launch_tensor_core_sgemm_with_fallback(d_A_->get(), d_B_->get(), d_C_->get(),
260+
M_, K_, N_, defaultTensorCoreFallback());
261+
},
250262
kTensorCoreVerifyTolerance);
251263

252264
EXPECT_TRUE(result.passed) << "TensorCore SGEMM fast path failed for dimensions " << M_ << "x"
@@ -261,7 +273,10 @@ class TensorCoreFallbackTest : public SGEMMKernelTest {};
261273

262274
TEST_P(TensorCoreFallbackTest, NonAlignedInputsFallbackSafely) {
263275
VerifyResult result = runKernelAndCompare(
264-
[&] { launch_tensor_core_sgemm(d_A_->get(), d_B_->get(), d_C_->get(), M_, K_, N_); },
276+
[&] {
277+
launch_tensor_core_sgemm_with_fallback(d_A_->get(), d_B_->get(), d_C_->get(),
278+
M_, K_, N_, defaultTensorCoreFallback());
279+
},
265280
kStandardVerifyTolerance);
266281

267282
EXPECT_TRUE(result.passed) << "TensorCore fallback failed for dimensions " << M_ << "x" << K_
@@ -272,9 +287,10 @@ INSTANTIATE_TEST_SUITE_P(TensorCoreFallbackDimensions, TensorCoreFallbackTest,
272287
::testing::ValuesIn(getTensorCoreFallbackDimensions()));
273288

274289
TEST(TensorCoreWrapperTest, ZeroSizeInputsReturnSafely) {
275-
EXPECT_NO_THROW(launch_tensor_core_sgemm(nullptr, nullptr, nullptr, 0, 16, 16));
276-
EXPECT_NO_THROW(launch_tensor_core_sgemm(nullptr, nullptr, nullptr, 16, 0, 16));
277-
EXPECT_NO_THROW(launch_tensor_core_sgemm(nullptr, nullptr, nullptr, 16, 16, 0));
290+
auto fallback = [](const float*, const float*, float*, int, int, int, cudaStream_t) {};
291+
EXPECT_NO_THROW(launch_tensor_core_sgemm_with_fallback(nullptr, nullptr, nullptr, 0, 16, 16, fallback));
292+
EXPECT_NO_THROW(launch_tensor_core_sgemm_with_fallback(nullptr, nullptr, nullptr, 16, 0, 16, fallback));
293+
EXPECT_NO_THROW(launch_tensor_core_sgemm_with_fallback(nullptr, nullptr, nullptr, 16, 16, 0, fallback));
278294
}
279295

280296
class DimensionInvarianceTest : public ::testing::Test {

0 commit comments

Comments
 (0)