没有针对此问题的直接公开指南。我通常只是让 TensorFlow 通过
分配这些信息
template<typename Device, typename Dtype>
class MyOp: public OpKernel {
{
public:
explicit MyOp(OpKernelConstruction *context) :
OpKernel(context)
{
// ...
}
void Compute(OpKernelContext *context) override
{
Tensor* tmp_var = nullptr;
Tensor* output = nullptr;
TensorShape some_shape, some_shape2;
// temparily use this space
OP_REQUIRES_OK(ctx, ctx->allocate_temp(DT_FLOAT, some_shape, &tmp_var));
// allocate memory for output tensor
OP_REQUIRES_OK(ctx, ctx->allocate_output(0, some_shape2, &output));
- 任何需要内存的东西都应该由 TensorFlow 上下文分配,而不是通过自定义
cudaMalloc 或 new type[num] 调用。
- 上下文应该为分配器提供信息
- 见下文
考虑一下,为了简单起见,只需添加两个矩阵 (full example)。
TensorFlow-Operations 通常包含以下结构:
Op description有REGISTER_OP,负责检查形状,设置输出形状(example)
OpKernel 负责分配内存、获取指向输入的指针和设置内容(见上文或this)
Functor 用于实现本身,例如
Tensor* output = nullptr;
Tensor* tmp_var = nullptr;
OP_REQUIRES_OK(ctx, ctx->allocate_output(0, output_shape, &output));
OP_REQUIRES_OK(ctx, ctx->allocate_temp(0, some_shape, &tmp_var));
// the function does not need to care about the memory allocation as everything is already setup at this point
::tensorflow::functor::MyFunctor<Device, Dtype>()(ctx, inputA, inputB, tmp_var, output);
你只剩下实现了
// gpu version
template <typename Dtype>
struct MyFunctor<GPUDevice, Dtype> {
void operator ()(::tensorflow::OpKernelContext* ctx,...)
// cpu version
template <typename Dtype>
struct MyFunctor<CPUDevice, Dtype> {
void operator ()(::tensorflow::OpKernelContext* ctx,...)
编辑
- allocate_persistent:如果您在 Op 调用之间需要数据,例如一次性索引结构,请使用它。[example]
- allocate_temp 只是在
Compute 方法生命周期结束时不会保留的tmp 内存。 [example]
但我强烈建议阅读source-code here 中的评论,然后根据您的用例决定。