CUDA环境详解
CUDA環(huán)境詳解
本文主要介紹 CUDA 環(huán)境,這一堆東西網(wǎng)上有很多博客介紹過了,我再來一篇:),參考前輩們的文章,看能不能寫的更清楚一點。讀后仍有問題,歡迎留言交流。
CUDA APIs
CUDA是由NVIDIA推出的通用并行計算架構(gòu),通過一些CUDA庫提供了一系列API供應(yīng)用程序調(diào)用。開發(fā)者可調(diào)用這些API充分利用GPU來處理圖像,視頻解碼等。
CUDA 的 API 其實是可以分層次來理解的,這也造成了有時會出現(xiàn) nvcc -V 顯示的 CUDA 版本和 nvidia-smi 顯示的 CUDA 版本不一致的情況,其實這就是由于它們根本就是不同層次的 API,因此并不一定是一起安裝的,也就不一定是同一個版本的。
CUDA API體系包括:CUDA函數(shù)庫(CUDA Libraries),CUDA運行時API(CUDA Runtime API),CUDA驅(qū)動API(CUDA Driver API),結(jié)構(gòu)圖如下:
圖1:CUDA API體系結(jié)構(gòu),圖源:[1]CUDA Driver API
GPU設(shè)備的抽象層,通過提供一系列接口來操作GPU設(shè)備,性能最好,但編程難度高,一般不會使用該方式開發(fā)應(yīng)用程序。
用于支持driver API的必要文件(如libcuda.so)是由GPU driver installer安裝的。 我么你常用的 nvidia-smi就屬于這一類API。
CUDA Runtime API
對CUDA Driver API進(jìn)行了一定的封裝,調(diào)用該類API可簡化編程過程,降低開發(fā)難度。
用于支持runtime API的必要文件(如libcudart.so以及nvcc)是由CUDA Toolkit installer安裝的。
CUDA Toolkit Installer:有時可能會集成了GPU driver Installer。nvcc是與CUDA Toolkit一起安裝的CUDA compiler-driver tool,即 CUDA 的編譯器,它只知道它自身構(gòu)建時的 CUDA runtime版本。它不知道安裝了什么版本的GPU driver,甚至不知道是否安裝了GPU driver。
CUDA Libraries
是對CUDA Runtime API更高一層的封裝,通常是一些成熟的高效函數(shù)庫,開發(fā)者也可以自己封裝一些函數(shù)庫便于使用。
比如常見的 cuFFT、cuBLAS 庫。
關(guān)系
應(yīng)用程序可調(diào)用CUDA Libraries或者CUDA Runtime API來實現(xiàn)功能,當(dāng)調(diào)用CUDA Libraries時,CUDA Libraries會調(diào)用相應(yīng)的CUDA Runtime API,CUDA Runtime API再調(diào)用CUDA Driver API,CUDA Driver API再操作GPU設(shè)備。
cudatoolkit
幾個概念辨析
- CUDA:為“GPU通用計算”構(gòu)建的運算平臺。
- cuDNN:為深度學(xué)習(xí)計算設(shè)計的軟件庫。
- CUDA Toolkit (Nvidia): CUDA完整的工具安裝包,其中提供了 Nvidia 驅(qū)動程序、開發(fā) CUDA 程序相關(guān)的開發(fā)工具包等可供安裝的選項。包括 CUDA 程序的編譯器、IDE、調(diào)試器等,CUDA 程序所對應(yīng)的各式庫文件以及它們的頭文件。
- CUDA Toolkit (Pytorch): CUDA不完整的工具安裝包,其主要包含在使用 CUDA 相關(guān)的功能時所依賴的動態(tài)鏈接庫。不會安裝驅(qū)動程序。
- NVCC 是CUDA的編譯器,只是 CUDA Toolkit 中的一部分
注:CUDA Toolkit 完整和不完整的區(qū)別:在安裝了CUDA Toolkit (Pytorch)后,只要系統(tǒng)上存在與當(dāng)前的 cudatoolkit 所兼容的 Nvidia 驅(qū)動,則已經(jīng)編譯好的 CUDA 相關(guān)的程序就可以直接運行,不需要重新進(jìn)行編譯過程。如需要為 Pytorch 框架添加 CUDA 相關(guān)的拓展時(Custom C++ and CUDA Extensions),需要對編寫的 CUDA 相關(guān)的程序進(jìn)行編譯等操作,則需安裝完整的 Nvidia 官方提供的 CUDA Toolkit。
完整版cudatoolkit內(nèi)容
一般的結(jié)構(gòu)中,include 包含頭文件,bin 包含可執(zhí)行文件,lib 包含程序?qū)崿F(xiàn)文件編譯生成的library,src包含源代碼,doc或help包含文檔,samples包含例子。
- Compiler:NVCC
- Tools:分析器profiler、調(diào)試器debuggers等
- Libraries:科學(xué)庫和實用程序庫
- CUDA Samples:CUDA和library API的代碼示例
- CUDA Driver:驅(qū)動,需要與“有CUDA功能的GPU”和“CUDA”都兼容。CUDA工具包都對應(yīng)一個最低版本的CUDA Driver,CUDA Driver向后兼容。
conda下的cudatoolkit
通過 conda 安裝 cudatoolkit 包含的庫文件在 ~/anaconda3/lib 中,或者在 ~/anaconda3/pkgs/cudatoolkit-xxx/lib 中查看,grep 一下 libcu、libnpp、libnv 這幾個名字查看即可,當(dāng)然這樣 grep 出來的也不一定確實 cudatoolkit 的文件,可能有 libcurl 之類的,只是初步過濾。
ls ~/anaconda3/lib/ | egrep 'libcu|libnpp|libnv' ls ~/anaconda3/pkgs/cudatoolkit-11.0.221-h6bb024c_0/lib/ | egrep 'libcu|libnpp|libnv' # 這里的11.0.221-h6bb024c_0z是筆者的版本。大家的可能不同,請自行查看確認(rèn)conda 的 cudatoolkit只包含pytorch或其他框架( tensorflow、xgboost、Cupy)會使用到的so庫文件。
本機(jī)CUDA多版本管理
修改軟連接
我們安裝的不同版本的 CUDA Runtime API 一般都會在 /usr/local 目錄下。
我們可以通過:
ls -l /usr/local | grep cuda來查看自己的機(jī)器上有多少個cuda版本,通常不帶版本號的 cuda 會是其他帶版本號的cuda-x.x的軟鏈接。即像下面這樣:
lrwxrwxrwx 1 root root 21 12月 10 2020 cuda -> /usr/local/cuda-11.1/而我們只要把我們使用cuda時都指向這個軟鏈接 /usr/local/cuda,并在需要切換版本時切換這個軟鏈接的指向即可。
sudo rm -rf cuda sudo ln -s /usr/local/cuda-9.0 /usr/local/cuda修改環(huán)境變量
注意此時如果nvcc -V的輸出還是更改之前的CUDA版本的話, 可能是環(huán)境變量中直接指定了 CUDA 版本路徑,比如在 ~/.bashrc 中有類似以下的語句:
export PATH=/usr/local/cuda-11.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-11.1/lib64:$LD_LIBRARY_PATH此時我們要修改環(huán)境變量為(在命令行中執(zhí)行僅當(dāng)前終端生效,修改 ~/.bashrc 永久生效):
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH就可以愉快地用指向 /usr/local/cuda 的軟鏈接來控制本機(jī)的 CUDA 版本了。
附:幾個環(huán)境變量的含義
PATH
PATH是可執(zhí)行文件路徑,是三個中我們最常接觸到的,因為我們命令行中的每句能運行的命令,如ls、top、ps等,都是系統(tǒng)通過PATH找到了這個命令執(zhí)行文件的所在位置,再run這個命令(可執(zhí)行文件)。 比如說,在用戶的目錄~/mycode/下有一個bin文件夾,里面放了有可執(zhí)行的二進(jìn)制文件、shell腳本等。如果想要在任意目錄下都能運行上述bin文件夾的可執(zhí)行文件,那么只需要把這個bin的路徑添加到PATH即可,方法如下:
# vim ~/.bashrc PATH=~/mycode/bin:$PATHLIBRARY_PATH和LD_LIBRARY_PATH
這兩個路徑可以放在一起討論,
- LIBRARY_PATH是程序編譯期間查找動態(tài)鏈接庫時指定查找共享庫的路徑
- LD_LIBRARY_PATH是程序加載運行期間查找動態(tài)鏈接庫時指定除了系統(tǒng)默認(rèn)路徑之外的其他路徑
兩者的共同點是庫,庫是這兩個路徑和PATH路徑的區(qū)別,PATH是可執(zhí)行文件。
兩者的差異點是使用時間不一樣。一個是編譯期,對應(yīng)的是開發(fā)階段,如gcc編譯;一個是加載運行期,對應(yīng)的是程序已交付的使用階段。
配置方法也是類似:
export LD_LIBRARY_PATH=XXXX:$LD_LIBRARY_PATHPytorch CUDA版本相關(guān)的幾個常用的變量
我們通常考察 Pytorch 中的以下幾個變量來確定當(dāng)前 Pytorch 的 CUDA 信息:
- torch.cuda.is_available(),CUDA 是否可用。
- torch.version.cuda,CUDA 版本。
- torch.utils.cpp_extension.CUDA_HOME, CUDA 路徑 CUDA_HOME。
可以通過下面這一句來在命令行中查看上述三個變量信息:
python -c "import torch; from torch.utils.cpp_extension import CUDA_HOME; print(torch.cuda.is_available(), torch.version.cuda, CUDA_HOME)"Pytorch用的到底是哪個版本的CUDA?
其實就是看 CUDA_HOME 環(huán)境變量到底被指定為什么。
Pytorch 搜索 CUDA_HOME 的順序如下:
顯式指定的環(huán)境變量 CUDA_HOME
即如:
export CUDA_HOME=/usr/local/cuda11.5即直接指定 /usr/local/cuda11.5 路徑下的 CUDA 為使用的 CUDA。
默認(rèn)搜索的路徑 /usr/local/cuda
我們之前也提到過本機(jī) CUDA 多版本管理通常是通過改變上述路徑的軟鏈接來實現(xiàn),這也是 Pytorch 一個默認(rèn)會搜索的路徑。
nvcc 的所在目錄
即 which nvcc 的上級目錄,之前提到過,nvcc 是 CUDA 的編譯器,但是,他對于 Pytorch 并不是必須的,即可能 nvcc 并不存在,但是 Pytorch 還是可以正常通過 cudatoolkit 來調(diào)用 GPU,即下一條。
cudatoolkit
如果上述都不存在,則 torch.utils.cpp_extension.CUDA_HOME 會被設(shè)置為 None。然后 Pytorch 會使用 conda 安裝的 cudatoolkit,其路徑為cudart 庫文件目錄的上級目錄(此時可能是通過 conda 安裝的 cudatoolkit,一般直接用 conda install cudatoolkit,就是在這里搜索到 cuda 庫的)。
Ref:
[1]:NVIDIA Docker CUDA容器化原理分析
[2]:怎么在docker中使用nvidia顯卡
[3]:[docker gpu報錯Error response from daemon: could not select device driver ““ with capabilities: [[gpu]]](https://blog.csdn.net/weixin_44966641/article/details/123760614)
總結(jié)
- 上一篇: 工行跨行转账多久可以到
- 下一篇: 恒易贷现在还款中但是没到账