假设一个执行流程为op1->op2->op3->op4,且整个过程在op1,op2,op4在GPU上跑,op3由于没有GPU的实现,在CPU上跑。假设op2的输出为a,op3的输入和输出也均为a(比如scale op)。在framework/operator.cc的OperatorWithKernel::RunImpl函数,先调用PrepareData将a从gpu上转化为cpu上的数据,且换到runtime_ctx的input中,且由于op3的输入输出均为a,transferd_inplace_vars中包含了a的变量。在op3的执行过程中,从Input中获取了转化后的a的变量,从output中获取输出的a的变量(与输入不是同一个变量),output中的a会重新分配内存,op3的计算结果放到了output的3中。
op3执行结束后,调用TransferInplaceVarsBack想把op3中output拷贝回原来的scope中,但是在拷贝回去的时候,获得的是op3中input的a,导致op3的结果丢失。
碰到的错误如下图所示,图表示的是sum op后面接着一个momentum,momentum利用sum的结果更新权重。第一个红色框中3个数表示sum op需要的输入a, b和结果c。第2个红框表示momentum使用的sum的结果。
这边还有一个问题是:PrepareData和TransferInplaceVarsBack这套机制是使用在什么场景中?什么样情况下能工作正确?
16条答案
按热度按时间js5cn81o16#
@zhangting2020 resnet50打印出来的program, sum op中就有输入输出是一样的名字。