C++ 是一种较低级的语言,它在此领域提供了更多选择。 这增加了复杂性,并严重影响了 C++ 前端的设计和人体工程学。 特别是,对于 C++ 前端中的模块,我们可以选择使用*值语义*或*引用语义*。 第一种情况是最简单的,并且在到目前为止的示例中已进行了展示:模块对象在堆栈上分配,并在传递给函数时可以被复制,移动(使用`std::move`)或通过引用或指针获取:
C++ 是一种较低级的语言,它在此领域提供了更多选择。 这增加了复杂性,并严重影响了 C++ 前端的设计和人体工程学。 特别是,对于 C++ 前端中的模块,我们可以选择使用*值语义*或*引用语义*。 第一种情况是最简单的,并且在到目前为止的示例中已进行了展示:模块对象在栈上分配,并在传递给函数时可以被复制,移动(使用`std::move`)或通过引用或指针获取:
@@ -77,7 +77,7 @@ TORCH_LIBRARY_IMPL(myops, CUDA, m) {
## 添加 Autograd 支持
至此,我们有了一个同时具有 CPU 和 CUDA 实现的运算符。 我们如何为它添加 Autograd 支持? 您可能会猜到,我们将注册一个 Autograd 内核(类似于[自定义 Autograd 函数](cpp_autograd)教程中描述的内容)! 但是,有一个变数:与 CPU 和 CUDA 内核不同,Autograd 内核需要*重新分发*:它需要回调分派器才能到达最终的 CPU 和 CUDA 实现。
至此,我们有了一个同时具有 CPU 和 CUDA 实现的运算符。 我们如何为它添加 Autograd 支持? 您可能会猜到,我们将注册一个 Autograd 内核(类似于[自定义 Autograd 函数](cpp_autograd)教程中描述的内容)! 但是,有一个变数:与 CPU 和 CUDA 内核不同,Autograd 内核需要*重新分发*:它需要回调调度器才能到达最终的 CPU 和 CUDA 实现。
因此,在编写 Autograd 内核之前,让我们编写一个*调度函数*,该函数调用调度器以为您的运算符找到合适的内核。 该函数构成了供您的运算符使用的公共 C++ API,实际上,PyTorch C++ API 中的所有张量函数都在后台完全以相同的方式调用了调度器。 调度函数如下所示: