Rust in Everything
基于 candle 0.11.0

错误与所有权

PyTorch 的一行 h = (x @ w).relu() 出错时抛异常,异常栈指到这一行;a.add_(1) 改的东西所有指向 a 的名字都看得见。candle 的同一行写成 x.matmul(&w)?.relu()?:每一步都返回 Result,错误一路向上传,默认不带位置;张量本身不可变,clone() 只是多一个引用。这一部分讲由此带来的写法变化,Rust 的 Result 和借用本身不展开。

  1. Result 到处都是:漏写 ? 是编译错误;&a + &b + &c 能链着写,&x * 2.0 + 1.0 不行;形状、dtype、设备三类报错和 PyTorch 的原文对照;错误只有一行、没有位置,在调用处加 context;tokenizers 的错误要 map_err 才能 ?。
  2. 引用与不可变:Tensor 的公开方法全部拿 &self,&a + &b 之后两个都能用,和 burn 的按值消费相反;clone() 不复制数据,等于 PyTorch 的 b = a,要独立的一份用 copy();没有 add_ 和 +=,原地写只有 slice_set、Var::set、inplace_op*,写进去的值所有共享 storage 的张量都看得见。
flowchart TB
  op["x.matmul(w)"] --> r{"返回 Result"}
  r -->|Err| q["问号向上传"]
  r -->|Ok| t["新的 Tensor"]
  t --> rc["clone 只加计数"]
  rc --> ro["共享 storage 只读"]
  ro --> w["slice_set 或 Var set"]
  w --> all["所有共享者都变"]

两页都以 CPU 为准,涉及 Metal 的地方单独说明。错误类型和 Tensor 的内部结构见源码卷的错误和 Tensor 的结构。

💬 关联讨论

发起讨论
加载中...