Skip to content

Commit 73bb550

Browse files
committed
add comments
1 parent 3ec271b commit 73bb550

File tree

1 file changed

+36
-22
lines changed

1 file changed

+36
-22
lines changed

test/ops/CUDABlasTest.cpp

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#include <ATen/ATen.h>
22
#include <ATen/cuda/CUDAContextLight.h>
33

4-
// at::cuda::blas::gemm<T> is compiled with hidden symbol visibility inside
5-
// libtorch and cannot be resolved from external code. It IS exported by the
6-
// Paddle compat library, so we only include CUDABlas.h and instantiate the
7-
// gemm tests when linking against Paddle (USE_PADDLE_API=1).
4+
// 【差异点1】at::cuda::blas::gemm<T> 符号可见性差异
5+
// PyTorch(libtorch)将 at::cuda::blas::gemm<T> 编译为 hidden visibility
6+
// (动态符号表中 nm -D 结果为小写 't'),外部代码无法链接该符号。
7+
// Paddle compat 库中该符号为公开导出(大写 'T'),可正常从外部调用。
8+
// 因此仅在 Paddle 构建(USE_PADDLE_API=1)时包含头文件并实例化 gemm 测试;
9+
// Torch 构建输出 "not_exported" 占位,保持两端输出行对齐。
810
#if USE_PADDLE_API
911
#include <ATen/cuda/CUDABlas.h>
1012
#endif
@@ -50,10 +52,13 @@ static void write_gemm_result_to_file(FileManerger* file,
5052
// at::cuda::getCurrentCUDABlasHandle tests
5153
// ============================================================
5254

53-
// Verify that getCurrentCUDABlasHandle returns a non-null handle.
54-
// Uses `auto` to stay type-agnostic between PyTorch (cublasHandle_t) and
55-
// Paddle compat (at::cuda::CUDAContextBlasHandle which aliases the same type
56-
// in CUDA builds but differs in HIP/ROCm builds).
55+
// 验证 getCurrentCUDABlasHandle 返回非空 handle。
56+
// 使用 `auto` 接收返回值以屏蔽类型差异:
57+
// 【差异点2】返回类型差异
58+
// PyTorch:直接返回 cublasHandle_t
59+
// Paddle compat:返回 at::cuda::CUDAContextBlasHandle,
60+
// 在 CUDA 构建中该类型 typedef 为 cublasHandle_t,
61+
// 在 HIP/ROCm 构建中则为 phi::blasHandle_t(不同类型)。
5762
TEST_F(CUDABlasTest, HandleNonNull) {
5863
auto file_name = g_custom_param.get();
5964
FileManerger file(file_name);
@@ -66,21 +71,22 @@ TEST_F(CUDABlasTest, HandleNonNull) {
6671
return;
6772
}
6873
#if USE_PADDLE_API
69-
// Paddle's getCurrentCUDABlasHandle() internally calls
70-
// phi::DeviceContextPool::Instance().Get(GPUPlace()), which requires
71-
// prior framework initialization via paddle::framework::InitDevices().
72-
// In a standalone C++ test binary this pool is not initialized, so
73-
// Paddle throws a PreconditionNotMet exception. Record the difference.
74+
// 【差异点3】Paddle 的 getCurrentCUDABlasHandle() 实现依赖框架全局状态
75+
// Paddle 内部调用 phi::DeviceContextPool::Instance().Get(GPUPlace()),
76+
// 该调用要求事先通过 paddle::framework::InitDevices() 初始化
77+
// DeviceContextPool。 在独立 C++ 测试二进制中框架未初始化,Paddle 抛出
78+
// PreconditionNotMet 异常。 PyTorch 无此约束,只需 CUDA
79+
// 分配器初始化即可正常返回 handle。 输出 "exception_needs_pool_init"
80+
// 记录该行为差异。
7481
try {
7582
auto handle = at::cuda::getCurrentCUDABlasHandle();
7683
file << std::to_string(handle != nullptr ? 1 : 0) << " ";
7784
} catch (const std::exception&) {
7885
file << "exception_needs_pool_init ";
7986
}
8087
#else
81-
// PyTorch requires the CUDA caching allocator to be initialized before
82-
// the first cuBLAS handle creation. A dummy tensor allocation on the
83-
// GPU is the canonical way to trigger that initialisation.
88+
// PyTorch 在首次创建 cuBLAS handle 前要求 CUDA 缓存分配器已初始化。
89+
// 分配一个 dummy GPU tensor 是触发该初始化的标准方式。
8490
{
8591
auto _init = at::zeros({1}, at::kFloat).cuda();
8692
(void)_init;
@@ -110,7 +116,8 @@ TEST_F(CUDABlasTest, HandleConsistency) {
110116
return;
111117
}
112118
#if USE_PADDLE_API
113-
// Same pool-init constraint as HandleNonNull.
119+
// 与 HandleNonNull 相同的 pool-init 限制(见差异点3),
120+
// Paddle 在 DeviceContextPool 未初始化时抛出异常。
114121
try {
115122
auto handle1 = at::cuda::getCurrentCUDABlasHandle();
116123
auto handle2 = at::cuda::getCurrentCUDABlasHandle();
@@ -137,9 +144,14 @@ TEST_F(CUDABlasTest, HandleConsistency) {
137144

138145
#if USE_PADDLE_API
139146

140-
// Helper: create a 1-D float32 tensor from an initializer list on CPU and
141-
// move it to the current CUDA device. at::tensor(initializer_list<float>)
142-
// without explicit TensorOptions is not in Paddle's ATen/Utils.h overload set.
147+
// 【差异点4】at::tensor(initializer_list<T>) 无 TensorOptions 重载缺失
148+
// PyTorch 的 ATen/Utils.h 提供 at::tensor(std::initializer_list<float>)
149+
// 直接推断类型的重载; Paddle compat 的 ATen/Utils.h 仅提供
150+
// at::tensor(ArrayRef<T>, TensorOptions) 形式, 不支持不带 TensorOptions 的
151+
// initializer_list 重载。 因此此处使用 cpu_fill_f32 辅助函数代替
152+
// at::tensor({...}) 构造张量。
153+
154+
// 辅助函数:在 CPU 上从 initializer_list 填充 float32 一维张量后移至 GPU。
143155
static at::Tensor cpu_fill_f32(std::initializer_list<float> vals) {
144156
auto t = at::zeros({(int64_t)vals.size()}, at::kFloat);
145157
float* p = t.data_ptr<float>();
@@ -535,8 +547,10 @@ TEST_F(CUDABlasTest, GemmLargeMatrix) {
535547

536548
#else // !USE_PADDLE_API
537549

538-
// at::cuda::blas::gemm<T> is not exported from libtorch (hidden symbol
539-
// visibility). Emit "not_exported" so both output files stay line-aligned.
550+
// 【差异点1 对应桩代码】
551+
// at::cuda::blas::gemm<T> 在 libtorch 中为 hidden visibility,外部无法链接。
552+
// 输出 "not_exported" 占位,保持 torch/paddle 两端输出文件行数对齐,
553+
// 以便比对脚本(result_cmp.sh)能逐行对比其余可比较的测试结果。
540554
#define CUDABLAS_GEMM_STUB(name) \
541555
TEST_F(CUDABlasTest, name) { \
542556
auto file_name = g_custom_param.get(); \

0 commit comments

Comments
 (0)