数组
这一部分走张量主线:建数组、计算、读回主机。jax.Array 和 tenferro 的 Tensor / TracedTensor 都是「形状加 dtype 加一块数据」,大多数运算能一一对上。不同的地方在三件 JAX 替你决定、tenferro 另有规矩的事上:数据怎么排(C 序还是列主序),dtype 从哪来(x64 开关还是 Rust 类型),整数怎么算(取整方向、除以 0、越界下标)。每页都是同一个任务的两份程序,数字从实测输出里贴。tenferro 张量内部的布局、所有权和 dtype 表,见 tenferro 卷的张量。
- 布局与 reshape:同一段平铺数据,JAX 按 C 序读、tenferro 按列主序读;reshape 也按列主序,等于
jnp.reshape(order="F");TRG 里先 transpose 再 reshape 的代码两边一字不改就能得到同一个 lnZ;进出主机的边界上要写order="F";批维放在右边。 - dtype:JAX 不开 x64 时默认 float32 并静默降精度,tenferro 的 dtype 由 Rust 字面量决定(
1.0是 F64、1是 I32);整数加 float32 在 tenferro 里提升成 F64(JAX、PyTorch 是 float32);没有弱类型,对应物是scale_real;astype拆成只许变宽的convert和有损的cast,越界的浮点转整数报错而不是饱和。 - 整数运算:
/向零截断,对应lax.div,不是//;除以 0 返回错误,JAX 静默给出 −1、−2 或 0;溢出两边都回绕;scale_real(0.5)作用在整数上什么也不做;越界下标两边都不报错,但 tenferro 不换算负下标、scatter是累加且会把越界的更新写到边上。
flowchart TB host["主机 Vec 或 npy"] -->|"order F"| t["Tensor 列主序"] host -.->|"C 序直接传"| bad["静默错位"] lit["Rust 字面量"] -->|决定| dt["dtype"] dt --> t t --> op["运算"] op -->|"混合 dtype"| promo["traced eager 提升"] op -->|"整数 / 0"| err["Err"] op -->|"越界下标"| clamp["夹到边上"] op --> back["as_slice 列主序"] back -->|"reshape order F"| np["NumPy 数组"]
💬 关联讨论
发起讨论加载中...