我在分布式TensorFlow的contrib实现中遇到了问题。为了不使用非相关细节,该解决方案应用特定的消息协议,以便直接从/向源/目标张量使用RDMA写入,以便在CPU上保存内存副本。
假设我有两个方面,A
和B
,A
想要从B
接收张量。
协议如下:
A
向REQUEST
发送B
条消息。B
在本地查找张量(BaseRendezvousMgr::RecvLocalAsync
)并向META-DATA
发送A
响应。A
使用元数据分配目标张量,并向ACK
发送包含目标地址的B
。B
收到ACK
,并执行远程DMA写入目标地址。在REQUEST
和ACK
之间,B
通过将局部张量保存在本地地图({{1}中来保持局部张量(和Ref()> 0)将张量复制到本地地图,REQUEST
从地图中弹出它。)
为验证我的解决方案,我在每一步都添加了校验和计算。偶尔,我发现校验和在ACK
和REQUEST
之间发生了变化。当我与两名工人一起运行PS时会发生这种情况:
ACK
。REQUEST
。ACK
。REQUEST
。每行的最后一个值是校验和。错误发生在大约50%的时间。我总是在第4行看到它。
我还看到有问题的张量有一个共享缓冲区用于所有step-id (这是给定的。我无法控制它)。所以很可能其他一些线程改变了第3行和第4行之间的张量内容,这是我想要防止的。
所以问题是如何?什么阻止了内容在第1行和第2行,第2行和第3行之间发生变化?要强调的是,第3行和第4行之间经过的时间小于 0.04秒,而经过2到3之间的时间几乎 2.5秒。
感谢您的帮助。如果需要,将发布代码。
答案 0 :(得分:1)
您是否将tf.Variable用于共享缓冲区?如果是这样,使用tfe.Variable(以启用合理的读写语义)或tf.get_variable(...,use_resource = True)来构造它将使任何同步问题消失。
否则,如果不了解有关生成图的更多信息,这很难理解。