Issue:将元素寻址相关元数据和索引迁移到 int64_t
背景
当前张量的 shape、stride、storage offset、元素坐标及大量算子循环使用 32 位 int。当张量元素数量或物理跨度超过 INT_MAX 时,可能出现:
- stride 溢出
- view offset 溢出
- 构造或算子因
checkedIntSize() 被拒绝
- broadcast、copy、reduce 等算子将
size_t 截断为 int
- 大张量无法正确切片、遍历或序列化
需要将所有与“元素数量、元素位置、物理寻址”相关的类型迁移到 std::int64_t,使 64 位平台能够支持超过 INT_MAX 个元素或跨度的大张量。
类型规则
直接使用标准类型,不引入 index_t、extent_t 等类型别名。
使用 std::int64_t:
- shape extent
- stride
- storage offset
- 元素坐标
- 逻辑/物理线性索引
- slice 的
start/end/step
- repeat、split、unfold 等涉及元素数量的参数
- element-wise 算子的循环索引和迭代空间
- batch/view 等计算出的元素偏移
继续使用 int:
- axis
- ndim/rank
- axes 列表
- permutation/order
- 线程数
- SIMD/GEMM tile 内部的小范围计数
继续使用 std::size_t:
size()
nbytes()
elementSize()
- 内存分配大小
- 容器长度
memcpy 等字节数量参数
示例接口:
std::vector<std::int64_t> shape() const;
std::int64_t shape(int axis) const;
std::vector<std::int64_t> stride() const;
std::int64_t stride(int axis) const;
std::int64_t offset(const std::vector<std::int64_t>& coordinate) const;
YTensorBase slice(
int axis,
std::int64_t start,
std::int64_t end,
std::int64_t step = 1,
bool autoFix = true
) const;
实现范围
1. Layout 元数据
修改 strided layout:
struct YMeta<YLayoutType::Strided> {
std::int64_t offset = 0;
std::vector<std::int64_t> shape;
std::vector<std::int64_t> stride;
};
Nested layout 中涉及 shape、offset、stride 的字段同步迁移。
2. YTensorBase 和 YTensor
迁移:
- 构造函数 shape 参数
shape()、stride()、offset()
toIndex()、toIndex_()、toCoord()
atData()、atData_()
autoShape()
slice()
view()、reshape()
repeat()
split()
unfold()
- 工厂函数中的 shape 参数
- 内部
stridedShape/Stride/Offset 接口
axis、ndim 和 permutation 保持 int。
3. Strided 算子
检查并迁移以下模块中的元素索引传播链:
- view
- broadcast
- copy/concat/split
- reduction
- matmul
- contiguous/clone/cast
- function 层的迭代坐标
不能只修改成员字段;所有中间表达式也必须以 64 位执行。例如避免:
int coordinate;
int stride;
std::int64_t offset = coordinate * stride; // 乘法已经在int中溢出
4. 并行循环
当前 parallelFor(int, int, ...) 和 checkedIntSize() 会限制大张量。
需要:
- 让通用 element-wise 迭代空间支持
std::int64_t
- 或使用 64 位外层分块,再调用现有较小范围循环
- 移除算子中仅为了调用
parallelFor 而执行的 checkedIntSize(tensor.size())
不能通过无检查的 size_t -> int64_t 或 size_t -> int 转换绕过限制。
5. Matmul/AVX2
不要求机械地把所有微内核参数改成 64 位。
推荐:
- batch 数量和矩阵物理 offset 使用
int64_t
- 外层迭代空间支持 64 位
- tile 大小和微内核局部计数继续使用
int
- 现有 GEMM 接口无法处理的超大单维度,应显式检查或分块
- 禁止静默缩窄
m/n/k/lda/ldb/ldc
6. 溢出检查
保留并补全 checked arithmetic:
- shape 乘积
- contiguous stride 计算
coordinate * stride
- base offset 与相对 offset 相加
- element count 与 element size 相乘
- 转换为
size_t
- 转换为
ptrdiff_t
- 转换到仍使用
int 的微内核参数
有符号 int64_t 溢出属于未定义行为,必须在乘法或加法前检查,而不是计算后判断。
负 stride 和反向 view 必须继续正确工作。
7. .yt 文件格式
当前 shape 按 32 位整数写入,需要升级格式:
- 新格式使用明确的
int64_t shape 编码
- 提升文件格式版本
- 旧版本文件继续按
int32_t shape 读取并无损提升
- 新格式不得依赖平台原生
int 宽度
- 校验 shape extent 非负
- 校验 shape 乘积和 payload 字节数
- 更新 Python 转换脚本及文件格式文档
非目标
本任务不要求:
- 将 axis、ndim、rank 改成
int64_t
- 将所有
std::vector<int> 全局替换
- 给 dtype、线程数或 tile 大小改类型
- 引入大量整数类型别名或 strong type
- 支持 32 位进程中的超大张量
- 在测试中实际分配数 GB 内存
测试要求
增加不依赖巨大内存分配的边界测试:
- 包含大于
INT_MAX extent 的零元素 shape
- stride 大于
INT_MAX 的小 storage view
- offset 大于
INT_MAX 的元数据计算
- 负 stride/reversed view
- shape、stride 和 offset 的 64 位公开 API
INT64_MAX 附近的 checked-add/checked-multiply
- element count 乘 element size 的溢出
- 64 位并行/分块循环边界
- 新文件格式的 64 位 shape round-trip
- 旧 32 位 shape 文件兼容读取
- 非法或溢出的文件 shape 被拒绝
- 现有普通张量、空张量、广播、切片、reduction、concat 和 matmul 测试不回归
验收标准
- shape、stride、offset 和元素坐标不再受 32 位
int 限制。
- 通用 element-wise、copy、broadcast 和 reduction 路径不再因元素总数超过
INT_MAX 而直接失败。
- axis、ndim、axes 和 permutation 保持
int。
size/nbytes 等内存容量接口保持 size_t。
- 不存在未经检查的 64 位到 32 位缩窄。
- 不存在先以 32 位运算、再转换为 64 位的溢出表达式。
.yt 新旧格式兼容策略明确且有测试。
- 全部现有测试及新增边界测试通过。
Issue:将元素寻址相关元数据和索引迁移到
int64_t背景
当前张量的 shape、stride、storage offset、元素坐标及大量算子循环使用 32 位
int。当张量元素数量或物理跨度超过INT_MAX时,可能出现:checkedIntSize()被拒绝size_t截断为int需要将所有与“元素数量、元素位置、物理寻址”相关的类型迁移到
std::int64_t,使 64 位平台能够支持超过INT_MAX个元素或跨度的大张量。类型规则
直接使用标准类型,不引入
index_t、extent_t等类型别名。使用
std::int64_t:start/end/step继续使用
int:继续使用
std::size_t:size()nbytes()elementSize()memcpy等字节数量参数示例接口:
实现范围
1. Layout 元数据
修改 strided layout:
Nested layout 中涉及 shape、offset、stride 的字段同步迁移。
2.
YTensorBase和YTensor迁移:
shape()、stride()、offset()toIndex()、toIndex_()、toCoord()atData()、atData_()autoShape()slice()view()、reshape()repeat()split()unfold()stridedShape/Stride/Offset接口axis、ndim 和 permutation 保持
int。3. Strided 算子
检查并迁移以下模块中的元素索引传播链:
不能只修改成员字段;所有中间表达式也必须以 64 位执行。例如避免:
4. 并行循环
当前
parallelFor(int, int, ...)和checkedIntSize()会限制大张量。需要:
std::int64_tparallelFor而执行的checkedIntSize(tensor.size())不能通过无检查的
size_t -> int64_t或size_t -> int转换绕过限制。5. Matmul/AVX2
不要求机械地把所有微内核参数改成 64 位。
推荐:
int64_tintm/n/k/lda/ldb/ldc6. 溢出检查
保留并补全 checked arithmetic:
coordinate * stridesize_tptrdiff_tint的微内核参数有符号
int64_t溢出属于未定义行为,必须在乘法或加法前检查,而不是计算后判断。负 stride 和反向 view 必须继续正确工作。
7.
.yt文件格式当前 shape 按 32 位整数写入,需要升级格式:
int64_tshape 编码int32_tshape 读取并无损提升int宽度非目标
本任务不要求:
int64_tstd::vector<int>全局替换测试要求
增加不依赖巨大内存分配的边界测试:
INT_MAXextent 的零元素 shapeINT_MAX的小 storage viewINT_MAX的元数据计算INT64_MAX附近的 checked-add/checked-multiply验收标准
int限制。INT_MAX而直接失败。int。size/nbytes等内存容量接口保持size_t。.yt新旧格式兼容策略明确且有测试。