问题描述
使用 Linx BlockISA 编译器(clang 15.0.4, target linx64v5-linux-musl)编译包含 TCOPYIN/TCOPYOUT 操作的 kernel 代码时,当数据类型为 __blkc_bf16(bf16 结构体类型),编译器报错:
error: no viable overloaded '='
blkv_get_tile_ptr(dst)[index_tile] = src[index_gm]; // TCopyIn.hpp:109
dst[index_gm] = blkv_get_tile_ptr(src)[index_tile]; // TCopyOut.hpp:81
具体错误信息:
candidate function (the implicit copy assignment operator) not viable: 'this' object is in address space '6', but method expects object in generic address space
candidate function (the implicit move assignment operator) not viable: 'this' object is in address space '6', but method expects object in generic address space
根本原因分析
-
__blkc_bf16 是一个 struct(定义于 linx_blkc.h),继承自 __bf16_base,包含 short data 成员字段。其赋值操作依赖隐式的拷贝/移动赋值运算符(成员函数)。
-
blkv_get_tile_ptr() 返回 __vbuf__(即 __attribute__((address_space(6)))指针,这意味着 tile 中的元素位于 地址空间 6(向量缓冲区专用地址空间)。
-
TCOPYIN/TCOPYOUT 内部的全局内存指针 src/dst 位于 通用地址空间(address space 0)。
-
赋值语句 blkv_get_tile_ptr(dst)[index_tile] = src[index_gm] 需要调用 __blkc_bf16 的拷贝赋值运算符,但该运算符的 this 参数(左侧,地址空间 6)与运算符期望的通用地址空间(address space 0)不匹配,导致编译失败。
-
对于 float、int 等标量类型,赋值是简单的值拷贝,不涉及成员函数调用,不受地址空间约束。而 __blkc_bf16 是 struct,赋值会调用隐式成员函数,受地址空间限制。
复现步骤
编译命令
cd test/kernel/element_wise/gelu
make TESTCASE=gelu DTYPE=__bf16 tMs=2048 gMs=24*8*1024 SHAPE_NAME=24_8_1024 Approximate=false diss
完整编译命令展开
clang++ -c -target linx64v5-linux-musl -mlxbc -fenable-matrix -O2 \
--sysroot=<toolchain_path>/sysroot \
-isystem <toolchain_path>/sysroot/usr/include/c++/v1 \
-D_LIBCPP_HAS_NO_THREADS -std=c++20 \
-I<project>/include -I<project>/test/common -I<project>/kernels \
-DDTYPE=__bf16 -DtMs=2048 -DgMs=24*8*1024 -DApproximate=false -D__linx \
gelu.cpp -o gelu.o
对比:float 类型可以正常编译
make TESTCASE=gelu DTYPE=float tMs=2048 gMs=24*8*1024 SHAPE_NAME=24_8_1024 Approximate=false diss
# 编译成功(但 gelu.hpp 中的 .data 成员访问会报另一个错误,说明 float 和 __blkc_bf16 的处理方式不同)
完整编译错误输出
In file included from gelu.cpp:1:
In file included from <toolchain>/include/tileop-api/common/pto_tileop.hpp:5:
In file included from <toolchain>/include/tileop-api/common/tileop_api.hpp:4:
In file included from <toolchain>/include/tileop-api/common/tileop_api_impl.hpp:16:
<toolchain>/include/tileop-api/jcore/TCopyIn.hpp:109:38: error: no viable overloaded '='
blkv_get_tile_ptr(dst)[index_tile] = src[index_gm];
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~
...
<toolchain>/include/linx_blkc.h:117:8: note: candidate function (the implicit copy assignment operator) not viable: 'this' object is in address space '6', but method expects object in generic address space
<toolchain>/include/linx_blkc.h:117:8: note: candidate function (the implicit move assignment operator) not viable: 'this' object is in address space '6', but method expects object in generic address space
<toolchain>/include/tileop-api/jcore/TCopyOut.hpp:81:17: error: no viable overloaded '='
dst[index_gm] = blkv_get_tile_ptr(src)[index_tile];
~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
<toolchain>/include/linx_blkc.h:117:8: note: candidate function (the implicit copy assignment operator) not viable: cannot bind reference in address space '6' to object in generic address space in 1st argument
<toolchain>/include/linx_blkc.h:117:8: note: candidate function (the implicit move assignment operator) not viable: cannot bind reference in address space '6' to object in generic address space in 1st argument
影响范围
此问题影响所有使用 __blkc_bf16(以及其他类似的 blkc struct 类型,如 __fp8_e4m3、__fp8_e5m2、__tf32、__hf32 等)作为数据类型进行 TCOPYIN/TCOPYOUT 操作的 kernel。这些 struct 类型都无法在 TCOPYIN/TCOPYOUT 中跨地址空间赋值。
修复建议
此问题需要在编译器/工具链侧修复,有两种思路:
方案 A:在 __blkc_bf16 等 struct 类型中添加跨地址空间的赋值运算符
在 linx_blkc.h 中为 __blkc_bf16(及其他类似 struct)添加支持地址空间 6 的赋值运算符重载,例如:
struct __blkc_bf16 : public __bf16_base {
__blkc_bf16() = default;
// 添加跨地址空间赋值运算符
__blkc_bf16& __vbuf__ operator=(const __blkc_bf16& other) {
data = other.data;
return *this;
}
// 可能还需要 __vbuf__ 版本的拷贝构造等
};
方案 B:在 TCopyIn.hpp/TCopyOut.hpp 中对 struct 类型只拷贝其底层 .data 成员
对 blkc struct 类型,在赋值时只拷贝 .data 字段(标量类型,不受地址空间限制),而非整个结构体赋值:
// TCopyIn 中:
blkv_get_tile_ptr(dst)[index_tile].data = src[index_gm].data;
// TCopyOut 中:
dst[index_gm].data = blkv_get_tile_ptr(src)[index_tile].data;
关键文件说明
为方便复现和定位,以下文件已作为 issue 附件上传:
| 文件 |
说明 |
linx_blkc.h |
编译器内置类型定义,__blkc_bf16 struct 定义所在(第117行),__vbuf__ 宏定义(第8行) |
TCopyIn.hpp |
编译器 tileop-api 库,TCopyIn_Vec_RowMajor 报错位置(第109行) |
TCopyOut.hpp |
编译器 tileop-api 库,TCopyOut_Vec_RowMajor 报错位置(第81行) |
gelu.hpp |
用户 kernel 代码,第115行调用 TCOPYIN,第119行调用 TCOPYOUT |
gelu.cpp |
用户测试代码入口,第71行调用 gelu 函数 |
Makefile |
编译配置 |
Makefile.common |
公共编译配置,定义编译器路径和编译选项 |
工具链版本信息
- 编译器路径:
compiler/toolchain/2026-06-22/linx_blockisa_llvm_musl/bin/clang++
- clang 版本:15.0.4
- target:
linx64v5-linux-musl
- 编译选项:
-mlxbc -fenable-matrix -O2
问题描述
使用 Linx BlockISA 编译器(clang 15.0.4, target
linx64v5-linux-musl)编译包含TCOPYIN/TCOPYOUT操作的 kernel 代码时,当数据类型为__blkc_bf16(bf16 结构体类型),编译器报错:具体错误信息:
根本原因分析
__blkc_bf16是一个 struct(定义于linx_blkc.h),继承自__bf16_base,包含short data成员字段。其赋值操作依赖隐式的拷贝/移动赋值运算符(成员函数)。blkv_get_tile_ptr()返回__vbuf__(即__attribute__((address_space(6)))指针,这意味着 tile 中的元素位于 地址空间 6(向量缓冲区专用地址空间)。TCOPYIN/TCOPYOUT内部的全局内存指针src/dst位于 通用地址空间(address space 0)。赋值语句
blkv_get_tile_ptr(dst)[index_tile] = src[index_gm]需要调用__blkc_bf16的拷贝赋值运算符,但该运算符的this参数(左侧,地址空间 6)与运算符期望的通用地址空间(address space 0)不匹配,导致编译失败。对于
float、int等标量类型,赋值是简单的值拷贝,不涉及成员函数调用,不受地址空间约束。而__blkc_bf16是 struct,赋值会调用隐式成员函数,受地址空间限制。复现步骤
编译命令
完整编译命令展开
对比:float 类型可以正常编译
完整编译错误输出
影响范围
此问题影响所有使用
__blkc_bf16(以及其他类似的 blkc struct 类型,如__fp8_e4m3、__fp8_e5m2、__tf32、__hf32等)作为数据类型进行TCOPYIN/TCOPYOUT操作的 kernel。这些 struct 类型都无法在 TCOPYIN/TCOPYOUT 中跨地址空间赋值。修复建议
此问题需要在编译器/工具链侧修复,有两种思路:
方案 A:在
__blkc_bf16等 struct 类型中添加跨地址空间的赋值运算符在
linx_blkc.h中为__blkc_bf16(及其他类似 struct)添加支持地址空间 6 的赋值运算符重载,例如:方案 B:在
TCopyIn.hpp/TCopyOut.hpp中对 struct 类型只拷贝其底层.data成员对 blkc struct 类型,在赋值时只拷贝
.data字段(标量类型,不受地址空间限制),而非整个结构体赋值:关键文件说明
为方便复现和定位,以下文件已作为 issue 附件上传:
linx_blkc.h__blkc_bf16struct 定义所在(第117行),__vbuf__宏定义(第8行)TCopyIn.hppTCopyOut.hppgelu.hppgelu.cppMakefileMakefile.common工具链版本信息
compiler/toolchain/2026-06-22/linx_blockisa_llvm_musl/bin/clang++linx64v5-linux-musl-mlxbc -fenable-matrix -O2