TensorFlow OpKernel 中的静态成员如何表现?

How does a static member in a TensorFlow OpKernel behave?

具体来说,如果我有一个从 OpKernel 继承的 Op,并且在其中我声明了一些私有成员 static。我可以安全地假设这个内核的所有实例化都将访问同一个静态成员吗​​?所有内核是否都放在同一个地址space/进程中的同一个machine/worker(可能是不同的CPU)?显然,这不适用于映射到分布式设置中单独机器的内核。例如

class MyOpKernel : public OpKernel {
  public:
    explicit MyOpKernel(OpKernelConstruction* ctx) : OpKernel(ctx) {
      if (!BigRODataObject)
        BigRODataObject = some_init_func();
    }

    void Compute( ... ) { // uses BigRODataObject }

  private:
    static BRODOType* BigRODataObject = null; 
};

最后,在实现一个OpKernel时,有没有比static更好的方法来在相同类型的OpKernel之间共享内存中的一大块只读数据?数据太大,无法在内存中容纳多个副本。

tensorflow::OpKernelstatic 成员在同一进程中该内核的所有实例之间共享。如果您是 运行 单个 TensorFlow 进程,则所有实例(包括分配给 CPU 或 GPU 的实例,以及来自不同会话的实例)将共享相同的 static 成员。

使用 static 成员不会在会话关闭时处理销毁,并且不允许不同的对象在不同的​​会话中,所以我不推荐这种风格;然而,替代方案有点复杂。对于共享状态,我们通常使用 ResourceMgr (via OpKernelContext::resource_manager()) 来存储对象。典型的实现使用 "constructor" op 在第一次使用时实例化对象,拥有它,并输出一个(字符串)句柄。共享状态的用户对句柄进行数据依赖,并在 ResourceMgr 中查找它以访问该对象。当 "constructor" op 被删除时,该对象将被删除。这是用于 tf.Variabletf.FIFOQueue 等有状态操作的方法