neural_renderer是一个非常好的三维结构渲染器,[github链接](https://github.com/daniilidis-group/neural_renderer)。
我down下来使用以下命令安装时报了一个错误。
```python
python setup.py install
```
```shell
D:/Anaconda/envs/python37/lib/site-packages/torch/include\ATen/Context.h(119): warning: field of class type without a DLL interface used in a class with a DLL interface
D:/Anaconda/envs/python37/lib/site-packages/torch/include\ATen/Context.h(120): warning: field of class type without a DLL interface used in a class with a DLL interface
D:/Anaconda/envs/python37/lib/site-packages/torch/include\ATen/TensorGeometry.h(56): warning: field of class type without a DLL interface used in a class with a DLL interface
D:/Anaconda/envs/python37/lib/site-packages/torch/include\ATen/TensorGeometry.h(57): warning: field of class type without a DLL interface used in a class with a DLL interface
neural_renderer/cuda/rasterize_cuda_kernel.cu(9): error: function "atomicAdd(double *, double)" has already been defined
1 error detected in the compilation of "C:/Users/luxuff/AppData/Local/Temp/tmpxft_000007ec_00000000-8_rasterize_cuda_kernel.cpp4.ii".
error: command 'C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0\\bin\\nvcc.exe' failed with exit code 2
```
问题的关键其实就是上述描述的倒数第四行,"atomicAdd(double *, double)" has already been defined。
打开该文件查看,似乎没什么问题:
```c++
#include <iostream>
#include <ATen/ATen.h>
#include <cuda.h>
#include <cuda_runtime.h>
// for the older gpus atomicAdd with double arguments does not exist
#if __CUDA_ARCH__ < 600 and defined(__CUDA_ARCH__)
static __inline__ __device__ double atomicAdd(double* address, double val) {
unsigned long long int* address_as_ull = (unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed,
__double_as_longlong(val + __longlong_as_double(assumed)));
// Note: uses integer comparison to avoid hang in case of NaN (since NaN != NaN) } while (assumed != old);
} while (assumed != old);
return __longlong_as_double(old);
}
#endif
```
后来在CSDN [这篇文章](https://blog.csdn.net/AUTO1993/article/details/78753576)中找到了解决方案:
```c++
#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600
#else
static __inline__ __device__ double atomicAdd(double *address, double val) {
unsigned long long int* address_as_ull = (unsigned long long int*)address;
unsigned long long int old = *address_as_ull, assumed;
if (val==0.0)
return __longlong_as_double(old);
do {
assumed = old;
old = atomicCAS(address_as_ull, assumed, __double_as_longlong(val +__longlong_as_double(assumed)));
} while (assumed != old);
return __longlong_as_double(old);
}
#endif
```
解决措施是:将原来代码的宏定义由
```c++
#if __CUDA_ARCH__ < 600 and defined(__CUDA_ARCH__)
//代码内容
#endif
```
改为
```c++
#if !defined(__CUDA_ARCH__) || __CUDA_ARCH__ >= 600
#else
//代码内容
#endif
```
改完之后确实能正常安装neural_renderer了,但我懵逼了,这俩结构翻译过来不是一个意思吗???
我坚信我应该遗漏了什么关键要素,最后试出了另外两种方式。
我将原宏定义改成了如下内容
```c++
#if defined(__CUDA_ARCH__) and __CUDA_ARCH__ < 600
//代码内容
#endif
或者
#if __CUDA_ARCH__ < 600 && defined(__CUDA_ARCH__)
//代码内容
#endif
```
结果都可以正常执行安装了,原因未知,待后期查证。

neural_renderer的atomicAdd报错