include폴더의 파일들이 이상하게 되어있다. include/torch/csrc/api
가 루트 디렉토리인 include/
와 중복이다. 그냥 빌드하면 중복헤더 오류가 난다.
include/torch/csrc/api
에 있는 파일을 원래의 include에 옮겨준 후, 해당 위치를 참조하는 모든 파일의 include를 변경해주면 빌드가 된다.
libtorch를 VS에서 사용하려면 구성 속성
→ C/C++
→ 언어
→ 준수 모드
를 꺼야 한다.
또는 모든 에러는 std가 모호해서 그런건데 ::std로 바꾸어 주면 된다.
아래의 코드로 위 모든 문제를 해결할 수 있다.
import fileinput
import os
path = 'include'
def GetFileList(dirName):
listOfFile = os.listdir(dirName)
allFiles = list()
for entry in listOfFile:
fullPath = os.path.join(dirName, entry)
if os.path.isdir(fullPath):
allFiles = allFiles + GetFileList(fullPath)
else:
allFiles.append(fullPath)
return allFiles
files=GetFileList(path)
for file in files:
file=file.replace('\\','/')
print(file)
with open(file,encoding='ansi',errors='ignore') as f:
newText=f.read()
newText=newText.replace('::std::', 'std::')
newText=newText.replace('std::', '::std::')
newText=newText.replace('torch/csrc/api/include/', '')
with open(file, "w",encoding='ansi') as f:
f.write(newText)
프로젝트에만 라이브러릴 적용한다면 Debug와 Release를 나눌 필요가 없으나, 해당 라이브러리를 Debug와 Release 모두 전역으로 설치하고자 하면 문제가 생긴다.
Debug용 lib,dll 과 Release용이 이름이 겹친다. (DEBUG_PREFIX를 모르나?)
따라서 Debug용 lib,dll 이름을 바꿔야 전역 설치가 가능해진다.
이걸.. 그냥 이름을 바꾸면 안되고 바이너리 내부의 참조되는 lib,dll 이름을 바꾸어 줘야 한다.
(인터넷에서 찾아볼 수 있는 rename-dll로는 바꿀 수 없다.)
먼저, 바이너리 편집기인 HXD를 설치한다.
HXD link
dll의 크기가 1GB에 가깝기 때문에 notepad++같은 편집기로는 제대로 열지도 못한다.
dll사이의 의존 관계는 Dependencies Walker로 확인 할 수 있다. 확인하는 이유는 어떤 string을 바꿔야 하는지 알아야 하기 때문.
예를들어, torch.dll
의 의존관계를 열어보면 아래와 같다.
이렇게 전체 종속 관계는 아래와 같다.
caffe2_module_test_dynamic.dll
├ torch_cpu.dll
├ c10.dll
caffe2_detectron_ops_gpu.dll
├ torch_cuda.dll
├ c10.dll
torch_cpu.dll
├ c10.dll
torch_cuda.dll
├ torch_cpu.dll
├ c10.dll
├ c10_cuda.dll
c10_cuda.dll
├ c10.dll
이제, 해당 dll을 HXD로 열어 참조 dll의 문자열을 바꿔주면 된다.
그런데, 문자열의 길이가 달라지면 모든 함수 주소의 오프셋이 바뀌기 때문에 반드시 문자열 길이를 똑같이 해야 한다.
예를들어 c10.dll 을 c10d.dll로 바꾸면 안된다. c1d.dll 과 같이 길이가 똑같이 수정한다.
그리고 같은 이름으로 실제 dll도 변경한다.
필자는 아래와 같이 바꾸었다.
Debug
torch_cuda.dll -> torchdcuda.dll
torch_cpu.dll -> torchdcpu.dll
c10.dll -> ctd.dll
c10_cuda.dll -> ctd_cuda.dll
---
caffe2_detectron_ops_gpu.dll -> caffed2detectron_ops_gpu.dll
caffe2_module_test_dynamic.dll -> caffed2module_test_dynamic.dll
caffe2_nvrtc.dll -> caffed2nvrtc.dll
torch.dll -> torcd.dll
torch_global_deps.dll -> torchdglobal_deps.dll
Release
torch_cuda.dll -> torchrcuda.dll
torch_cpu.dll -> torchrcpu.dll
c10.dll -> ctr.dll
c10_cuda.dll -> ctr_cuda.dll
---
caffe2_detectron_ops_gpu.dll -> caffer2detectron_ops_gpu.dll
caffe2_module_test_dynamic.dll -> caffer2module_test_dynamic.dll
caffe2_nvrtc.dll -> caffer2nvrtc.dll
torch.dll -> torcr.dll
torch_global_deps.dll -> torchrglobal_deps.dll
lib의 경우는 내부에서 dll을 찾는 그!! 문자열을 찾아야 한다.
해당 문자열은 HXD로 열었을 떄 Microsoft (R) LINK
하고 좀 뒤에 있는 dll 이름이 되겠다. 해당 dll이름을 아까 바꾼 dll로 다 찾아서 교체해준다.
Microsoft (R) LINK
가 여러개일 수 있는데 맨 처음나오는 부분만 수정하면 된다.
마찬가지로 lib도 dll과 같이 파일이름을 바꿔준다.
아래의 코드 추가
#pragma comment(linker,"-INCLUDE:?warp_size@cuda@at@@YAHXZ")
https://github.com/pytorch/pytorch/issues/18645
https://discuss.pytorch.org/t/compiler-report-std-ambiguous-symbol-error-under-visual-c-2017/39459/5