注意

RAFT 中的向量搜索和聚类算法正在迁移到一个专门用于向量搜索的新库 cuVS。在迁移过程中,我们将继续支持 RAFT 中的向量搜索算法,但在 RAPIDS 24.06(六月)版本发布后将不再更新它们。我们计划在 RAPIDS 24.10(十月)版本前完成迁移,并在 24.12(十二月)版本中将其完全从 RAFT 中移除。

可中断#

#include <raft/core/interruptible.hpp>

namespace raft::core

struct interrupted_exception : public raft::exception#
#include <interruptible.hpp>

当检测到请求取消此 CPU 线程中执行的工作时,在 interruptible::synchronize 调用期间抛出的异常。

class interruptible#
#include <interruptible.hpp>

合作式可中断执行。

此类提供了从线程外部中断 C++ 线程在代码中指定点执行的功能。特别是,它提供了一个可中断版本的阻塞 CUDA 同步函数,允许中止长时间运行的 GPU 工作。

重要提示: 虽然 CUDA 同步调用可作为取消点,但可中断机制与 CUDA 流或事件无关。换句话说,当你调用 cancel 时,被中断的是 CPU 等待函数,而不是 GPU 流工作。这意味着,当 interrupted_exception 抛出时,任何未完成的 GPU 流工作将继续运行。开发者有责任确保未完成的流工作不会以不良方式影响程序。

synchronize 被取消时,CUDA 流会发生什么?如果你立即捕获 interrupted_exception,你可以安全地再次等待流。否则,某些已分配的资源可能会在活动内核完成使用它们之前被释放,这将导致写入已释放或重新分配的内存,并通常导致未定义行为。死锁的内核可能永远不会完成(或者如果幸运的话可能会崩溃)。实际上,对于紧急程序中断(例如 CTRL+C)的使用场景,结果通常是可以接受的,但使用方需要付出额外的努力才能安全地中断和恢复 GPU 流工作。

公共函数

inline void cancel() noexcept#

取消此 interruptible 令牌对应的 CPU 线程上执行的任何当前或下一次 interruptible::synchronize 调用。

注意,此函数不涉及线程同步/锁,也不抛出任何异常,因此可以安全地从信号处理程序中调用。

公共静态函数

static inline void synchronize(rmm::cuda_stream_view stream)#

同步 CUDA 流,可被在此 CPU 线程上调用 interruptible::cancel 中断。

参数:

stream[in] CUDA 流。

抛出异常:
static inline void synchronize(cudaEvent_t event)#

同步 CUDA 事件,可被在此 CPU 线程上调用 interruptible::cancel 中断。

参数:

event[in] CUDA 事件。

抛出异常:
static inline void yield()#

检查线程状态,判断线程是否可以继续执行或是否被 interruptible::cancel 中断。

这是可中断线程的取消点。它在 interruptible::synchronize 的内部循环中调用。如果两次同步调用间隔很远,建议在其间调用 interruptible::yield(),以确保线程不会长时间无响应。

yieldyield_no_throw 都会在执行后将状态重置为未取消。

抛出异常:

raft::interrupted_exception – 如果在当前 CPU 线程上调用了 interruptible::cancel()

static inline bool yield_no_throw()#

检查线程状态,判断线程是否可以继续执行或是否被 interruptible::cancel 中断。

interruptible::yield 相同,但如果线程被取消,则不抛出异常。

yieldyield_no_throw 都会在执行后将状态重置为未取消。

返回值:

线程是否可以继续,即 true 表示继续,false 表示已取消。

static inline std::shared_ptr<interruptible> get_token()#

获取此 CPU 线程的取消令牌。

返回值:

一个可用于取消在此 CPU 线程上等待的 GPU 工作的对象。

static inline std::shared_ptr<interruptible> get_token(std::thread::id thread_id)#

获取给定 ID 的 CPU 线程的取消令牌。

返回的令牌可能比关联的线程生命周期更长。在这种情况下,使用其 cancel 方法没有效果。

参数:

thread_id[in] C++ CPU 线程的 ID。

返回值:

一个可用于取消在给定 CPU 线程上等待的 GPU 工作的对象。

static inline void cancel(std::thread::id thread_id)#

取消由 thread_id 给定的 CPU 线程上执行的任何当前或下一次 interruptible::synchronize 调用

注意,此函数使用互斥锁安全地获取可能在多个线程之间共享的取消令牌。如果您打算从信号处理程序中使用它,请考虑使用非静态的 cancel()

参数:

thread_id[in] 一个 CPU 线程,应在此线程中中断工作。