Skip to content

将元素寻址相关元数据和索引迁移到 int64_t #12

Description

@SnifferCaptain

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_textent_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. YTensorBaseYTensor

迁移:

  • 构造函数 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_tsize_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 新旧格式兼容策略明确且有测试。
  • 全部现有测试及新增边界测试通过。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions