快捷方式

Torch 库 API

PyTorch C++ API 提供了扩展 PyTorch 核心运算符库的功能,可以使用户自定义运算符和数据类型。使用 Torch 库 API 实现的扩展可以在 PyTorch eager API 和 TorchScript 中使用。

有关库 API 的教程式介绍,请查看使用自定义 C++ 运算符扩展 TorchScript 教程。

TORCH_LIBRARY(ns, m)

用于定义一个函数宏,该函数将在静态初始化时运行,以在命名空间 ns 中定义运算符库(必须是有效的 C++ 标识符,无引号)。

当您想要定义 PyTorch 中尚不存在的一组新的自定义运算符时,请使用此宏。

用法示例

TORCH_LIBRARY(myops, m) {
  // m is a torch::Library; methods on it will define
  // operators in the myops namespace
  m.def("add", add_impl);
}

m 参数绑定到一个 torch::Library,用于注册运算符。对于任何给定的命名空间,只能有一个 TORCH_LIBRARY()

TORCH_LIBRARY_IMPL(ns, k, m)

用于定义一个函数宏,该函数将在静态初始化时运行,以在命名空间 ns 中为分发键 k (必须是 c10::DispatchKey 的非限定枚举成员) 定义运算符重载(必须是有效的 C++ 标识符,无引号)。

当您想要在新分发键上实现一组预先存在的自定义运算符时,请使用此宏(例如,您想要为已存在的运算符提供 CUDA 实现)。一种常见的用法模式是使用 TORCH_LIBRARY() 为您想要定义的所有新运算符定义模式,然后使用多个 TORCH_LIBRARY_IMPL() 块来为 CPU、CUDA 和 Autograd 提供运算符的实现。

在某些情况下,您需要定义一些适用于所有命名空间的东西,而不仅仅是一个命名空间(通常是回退)。在这种情况下,请使用保留命名空间 _,例如:

TORCH_LIBRARY_IMPL(_, XLA, m) {
   m.fallback(xla_fallback);
}

用法示例

TORCH_LIBRARY_IMPL(myops, CPU, m) {
  // m is a torch::Library; methods on it will define
  // CPU implementations of operators in the myops namespace.
  // It is NOT valid to call torch::Library::def()
  // in this context.
  m.impl("add", add_cpu_impl);
}

如果 add_cpu_impl 是一个重载函数,请使用 static_cast 来指定您想要的重载(通过提供完整类型)。

class Library

此对象提供了用于定义运算符并在分发键处提供实现的 API。

通常,torch::Library 不是直接分配的;而是由 TORCH_LIBRARY()TORCH_LIBRARY_IMPL() 宏创建。

torch::Library 上的大多数方法都返回对自身的引用,支持方法链式调用。

// Examples:

TORCH_LIBRARY(torchvision, m) {
   // m is a torch::Library
   m.def("roi_align", ...);
   ...
}

TORCH_LIBRARY_IMPL(aten, XLA, m) {
   // m is a torch::Library
   m.impl("add", ...);
   ...
}

公共函数

template<typename Schema>
inline Library &def(Schema &&raw_schema, const std::vector<at::Tag> &tags = {}, _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) &

声明一个带有模式的运算符,但不为其提供任何实现。

您需要使用 impl() 方法来提供实现。所有模板参数都会被推断出来。

// Example:
TORCH_LIBRARY(myops, m) {
  m.def("add(Tensor self, Tensor other) -> Tensor");
}

参数

raw_schema – 要定义的运算符的模式。通常,这是一个 const char* 字符串字面量,但此处接受 torch::schema() 接受的任何类型。

inline Library &set_python_module(const char *pymodule, const char *context = "")

声明对于所有后续定义的运算符,它们的伪实现可以在给定的 Python 模块 (pymodule) 中找到。

这会注册一些帮助文本,如果找不到伪实现,则会使用这些文本。

参数

  • pymodule: python 模块

  • context: 我们可以将其包含在错误消息中。

inline Library &impl_abstract_pystub(const char *pymodule, const char *context = "")

已弃用;请改用 set_python_module。

template<typename NameOrSchema, typename Func>
inline Library &def(NameOrSchema &&raw_name_or_schema, Func &&raw_f, const std::vector<at::Tag> &tags = {}) &

为一个模式定义一个运算符,然后为其注册一个实现。

如果您不打算使用调度器来构建运算符实现,这通常是您会使用的。它大致相当于调用 def() 然后调用 impl(),但如果您省略运算符的模式,我们将从您的 C++ 函数的类型中推断出来。所有模板参数都会被推断出来。

// Example:
TORCH_LIBRARY(myops, m) {
  m.def("add", add_fn);
}

参数
  • raw_name_or_schema – 要定义的运算符的模式,或者如果模式要从 raw_f 推断,则仅为运算符的名称。通常是 const char* 字面量。

  • raw_f – 实现此运算符的 C++ 函数。torch::CppFunction 的任何有效构造函数在此处都被接受;通常您提供函数指针或 lambda。

template<typename Name, typename Func>
inline Library &impl(Name name, Func &&raw_f, _RegisterOrVerify rv = _RegisterOrVerify::REGISTER) &

为一个运算符注册一个实现。

您可以为单个运算符在不同的分发键处注册多个实现(请参阅 torch::dispatch())。实现必须具有相应的声明(来自 def()),否则它们将无效。如果您计划注册多个实现,请在 def() 运算符时不要提供函数实现。

// Example:
TORCH_LIBRARY_IMPL(myops, CUDA, m) {
  m.impl("add", add_cuda);
}

参数
  • name – 要实现的运算符的名称。此处请勿提供模式。

  • raw_f – 实现此运算符的 C++ 函数。torch::CppFunction 的任何有效构造函数在此处都被接受;通常您提供函数指针或 lambda。

template<typename Func>
inline Library &fallback(Func &&raw_f) &

为所有运算符注册一个回退实现,如果运算符没有可用的特定实现,则将使用该回退实现。

必须有与回退关联的 DispatchKey;例如,仅从命名空间为 _TORCH_LIBRARY_IMPL() 中调用此方法。

// Example:

TORCH_LIBRARY_IMPL(_, AutogradXLA, m) {
  // If there is not a kernel explicitly registered
  // for AutogradXLA, fallthrough to the next
  // available kernel
  m.fallback(torch::CppFunction::makeFallthrough());
}

// See aten/src/ATen/core/dispatch/backend_fallback_test.cpp
// for a full example of boxed fallback

参数

raw_f – 实现回退的函数。未装箱的函数通常不适用于作为回退函数,因为回退函数必须适用于每个运算符(即使它们具有不同的类型签名)。典型的参数是 CppFunction::makeFallthrough()CppFunction::makeFromBoxedFunction()

class CppFunction

表示实现运算符的 C++ 函数。

大多数用户不会直接与此类交互,除非通过错误消息:此函数的构造函数定义了可以通过接口绑定的允许的“函数”类事物集。

此类擦除了传入函数的类型,但通过函数的推断模式持久地记录了该类型。

公共函数

template<typename Func>
inline explicit CppFunction(Func *f, std::enable_if_t<c10::guts::is_function_type<Func>::value, std::nullptr_t> = nullptr)

此重载接受函数指针,例如 CppFunction(&add_impl)

template<typename FuncPtr>
inline explicit CppFunction(FuncPtr f, std::enable_if_t<c10::is_compile_time_function_pointer<FuncPtr>::value, std::nullptr_t> = nullptr)

此重载接受编译时函数指针,例如 CppFunction(TORCH_FN(add_impl))

template<typename Lambda>
inline explicit CppFunction(Lambda &&f, std::enable_if_t<c10::guts::is_functor<std::decay_t<Lambda>>::value, std::nullptr_t> = nullptr)

此重载接受 lambda 表达式,例如 CppFunction([](const Tensor& self) { ...

})

公共静态函数

static inline CppFunction makeFallthrough()

这会创建一个直通函数。

直通函数会立即重新分派到下一个可用的分派键,但其实现方式比以相同方式手动编写的函数更有效。

template<c10::BoxedKernel::BoxedKernelFunction *func>
static inline CppFunction makeFromBoxedFunction()

从带有签名 void(const OperatorHandle&, Stack*) 的 boxed kernel 函数创建一个函数;即,它们接收 boxed 调用约定中的参数堆栈,而不是在本机 C++ 调用约定中接收参数。

Boxed 函数通常仅用于通过 torch::Library::fallback() 注册后端回退。

template<class KernelFunctor>
static inline CppFunction makeFromBoxedFunctor(std::unique_ptr<KernelFunctor> kernelFunctor)

从 boxed kernel functor 创建一个函数,该 functor 定义了 operator()(const OperatorHandle&, DispatchKeySet, Stack*) (从 boxed 调用约定接收参数)并继承自 c10::OperatorKernel

与 makeFromBoxedFunction 不同,以这种方式注册的函数还可以携带由 functor 管理的附加状态;如果您正在编写一些其他实现的适配器(例如,Python 可调用对象),并且该适配器与注册的 kernel 动态关联,这将非常有用。

template<typename FuncPtr, std::enable_if_t<c10::guts::is_function_type<FuncPtr>::value, std::nullptr_t> = nullptr>
static inline CppFunction makeFromUnboxedFunction(FuncPtr *f)

从 unboxed kernel 函数创建一个函数。

这通常用于注册常用运算符。

template<typename FuncPtr, std::enable_if_t<c10::is_compile_time_function_pointer<FuncPtr>::value, std::nullptr_t> = nullptr>
static inline CppFunction makeFromUnboxedFunction(FuncPtr f)

从编译时 unboxed kernel 函数指针创建一个函数。

这通常用于注册常用运算符。编译时函数指针可用于允许编译器优化(例如,内联)对其的调用。

函数

template<typename Func>
inline CppFunction dispatch(c10::DispatchKey k, Func &&raw_f)

创建一个 torch::CppFunction,它与特定的分派键关联。

除非调度器确定这个特定的 c10::DispatchKey 是应该分派到的键,否则不会调用标记有 c10::DispatchKey 的 torch::CppFunctions。

此函数通常不直接使用,而是首选使用 TORCH_LIBRARY_IMPL(),它将为所有注册调用在其主体内隐式设置 c10::DispatchKey。

template<typename Func>
inline CppFunction dispatch(c10::DeviceType type, Func &&raw_f)

接受 c10::DeviceTypedispatch() 的便捷重载。

inline c10::FunctionSchema schema(const char *str, c10::AliasAnalysisKind k, bool allow_typevars = false)

从字符串构造 c10::FunctionSchema,并显式指定 c10::AliasAnalysisKind。

通常,schema 只是作为字符串传入,但是如果您需要指定自定义别名分析,则可以使用对此函数的调用来替换字符串。

// Default alias analysis (FROM_SCHEMA)
m.def("def3(Tensor self) -> Tensor");
// Pure function alias analysis
m.def(torch::schema("def3(Tensor self) -> Tensor",
c10::AliasAnalysisKind::PURE_FUNCTION));

inline c10::FunctionSchema schema(const char *s, bool allow_typevars = false)

函数 schema 可以直接从字符串字面量构造。


© Copyright PyTorch 贡献者。

使用 Sphinx 构建,主题由 theme 提供,并由 Read the Docs 提供支持。

文档

访问 PyTorch 的综合开发者文档

查看文档

教程

获取面向初学者和高级开发人员的深度教程

查看教程

资源

查找开发资源并获得您的问题解答

查看资源