Error LNK2019 when building Tensorflow debug

Viewed 463

I try make a debug build of the CPU version of the C++ API of Tensorflow 2.0 in Windows. The command I use for building is:

bazel build -c dbg --copt=/w34716 tensorflow:tensorflow.dll

But when I build this I get this error:

depth_space_ops.lo.lib(depthtospace_op.obj) : error LNK2019: unresolved external symbol "public: void __cdecl tensorflow::functor::DepthToSpaceOpFunctor<struct Eigen::GpuDevice,struct Eigen::half,1>::operator()(struct Eigen::GpuDevice const &,class Eigen::TensorMap<class Eigen::Tensor<struct Eigen::half const ,4,1,__int64>,16,struct Eigen::MakePointer>,int,class Eigen::TensorMap<class Eigen::Tensor<struct Eigen::half,4,1,__int64>,16,struct Eigen::MakePointer>)" (??R?$DepthToSpaceOpFunctor@UGpuDevice@Eigen@@Uhalf@2@$00@functor@tensorflow@@QEAAXAEBUGpuDevice@Eigen@@V?$TensorMap@V?$Tensor@$$CBUhalf@Eigen@@$03$00_J@Eigen@@$0BA@UMakePointer@2@@4@HV?$TensorMap@V?$Tensor@Uhalf@Eigen@@$03$00_J@Eigen@@$0BA@UMakePointer@2@@4@@Z) referenced in function "public: virtual void __cdecl tensorflow::DepthToSpaceOp<struct Eigen::ThreadPoolDevice,struct Eigen::half>::Compute(class tensorflow::OpKernelContext *)" (?Compute@?$DepthToSpaceOp@UThreadPoolDevice@Eigen@@Uhalf@2@@tensorflow@@UEAAXPEAVOpKernelContext@2@@Z)

The only thing I found regarding this issue was this GitHub issue, which wasn't solved.

Does anyone know how to solve this issue?

1 Answers

Facing the same necessity, I dug around in the code and actually found the source of the problem: It is contained in the following two if blocks: https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/core/kernels/spacetodepth_op.cc#L129 and https://github.com/tensorflow/tensorflow/blob/v2.3.0/tensorflow/core/kernels/depthtospace_op.cc#L115.

If you are building a non-GPU version of the library in debug, it is sort of clear why the error happens: the if (std::is_same<Device, GPUDevice>::value) for the DepthToSpaceOp class, for example, parametrized with CPUDevice, would evaluate to if (false) during compile time. With any optimizations enabled, the code in the if-clause (which explicitly triggers DepthToSpaceOpFunctor with a template parameter GPUDevice - exactly the missing symbols you are getting) would not be compiled at all, and therefore not need to be linked.

In the debug build, it is still likely compiled, even though it is clear that it will never be executed. Then the linker tries to find the operator() for the DepthToSpaceOpFunctor template-parametrized with GPUDevice, and fails to do so.

A quick-and-dirty way to fix this is to comment out the entire if-clauses (if you are building a CPU-only dll) in both files mentioned above.

A more elegant solution is to avoid these linker errors via template specialization by changing the explicit references to GPUDevice to Device, since those will be in the code that is executed only when Device is GPUDevice. I will soon add a pull request to a similar issue I raised on github, hopefully, after a bit more testing.

Update: The pull request is submitted, you can find the code changes to fix this particular set of linker errors here: https://github.com/tensorflow/tensorflow/pull/42307/files#

For a GPU debug dll - I am not sure why these errors would still be there, but there are yet other linking errors in this case anyway ;)

Related