【问题标题】:Adding a TensorFlow Op that uses malloc() and has state添加一个使用 malloc() 并具有状态的 TensorFlow Op
【发布时间】:2017-03-02 19:45:09
【问题描述】:

我编写了一个 TensorFlow Op,它封装了一个用 C 编写的库,该库在内部调用 malloc() 来分配缓冲区并保持状态。我在构造函数中初始化库,这是发生malloc() 调用的地方,然后在Compute() 中我将它与互斥锁一起使用。析构函数对free() 进行适当的调用。

在我的模型中,每个线程都会创建一个 Op 的副本,都在同一个图中,并在共享会话中运行它。代码经常因指针相关问题而崩溃,例如“已释放对象的校验和不正确 - 对象可能在被释放后被修改”。我为 Op 编写的单线程单元测试工作正常。

我怀疑图形优化器可能正在重用 Op 的单个实例,或者类似的东西。有没有办法告诉它 Op 是有状态的并且应该保持原样?崩溃还有其他可能的原因吗?

我在 OSX 10.10 下运行 TensorFlow 1.0.0 并使用 clang 7.0 编译 Op。我先把C文件编译成共享对象,再把C++文件和共享对象一起编译。

【问题讨论】:

  • 如果最简单的解决方案是修复库本身,我应该使用什么来代替 malloc/free?
  • 您是否考虑过在您的代码上运行AddressSanitizerThreadSanitizer 和/或UndefinedBehaviorSanitizer?如果不;你应该。运行Clang Tidy 和/或cppcheck 可能也不会受到伤害......在编译器中启用所有警告也永远不会受到伤害......
  • 没有人说你不应该在 C 库中使用 malloc/free。诀窍是正确使用它们;-)。然而,在 C++ 库中,您有更好的选择,例如析构函数和智能指针。
  • 是的,公共子表达式消除器会导致问题。使用 .SetIsStateful 。我在我的记忆中做这件事,比如this
  • @YaroslavBulatov 这太好了,谢谢!我知道它必须存在,因为 py_func() 可以成为有状态的,但我不知道如何。

标签: c++ tensorflow


【解决方案1】:

根据documentation“添加新操作”:

重要提示:您的 OpKernel 实例可以同时访问。您的 Compute 方法必须是线程安全的。使用互斥锁保护对类成员的任何访问。或者更好的是,不要通过班级成员分享状态!考虑使用ResourceMgr 来跟踪操作状态。

不幸的是,在撰写此答案时,ResourceMgr 的使用非常粗略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 2020-08-14
    相关资源
    最近更新 更多