Linux下的CUDA多版本管理
Linux下的CUDA多版本管理
關(guān)于CUDA、cuDNN等的簡介和安裝可參考:顯卡、顯卡驅(qū)動、CUDA、CUDA Toolkit、cuDNN 梳理。
CUDA多版本
有時(shí)我們會在一臺機(jī)器上同時(shí)看到多個(gè)版本的CUDA,比如nvcc -V和nvidia-smi的輸出就可能會不同:
在我們實(shí)驗(yàn)室的服務(wù)器上nvcc --version顯示的結(jié)果如下:
nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2018 NVIDIA Corporation Built on Tue_Jun_12_23:07:04_CDT_2018 Cuda compilation tools, release 9.2, V9.2.148而nvidia-smi顯示結(jié)果如下:
+-----------------------------------------------------------------------------+ | NVIDIA-SMI 410.104 Driver Version: 410.104 CUDA Version: 10.0 | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |===============================+======================+======================| | 0 Tesla V100-PCIE... On | 00000000:01:00.0 Off | Off | | N/A 28C P0 26W / 250W | 0MiB / 16130MiB | 0% Default | +-------------------------------+----------------------+----------------------+ | 1 Tesla P100-PCIE... On | 00000000:02:00.0 Off | Off | | N/A 24C P0 30W / 250W | 0MiB / 16280MiB | 0% Default | +-------------------------------+----------------------+----------------------++-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+可以看到nvcc的CUDA 版本是9.2,而nvidia-smi的CUDA版本是10.0。如果nvidia-smi命令列出的CUDA版本與nvcc -V列出的版本號不一致,可能是由以下原因之一引起的:
1)安裝多版本cuda后,還沒有刷新環(huán)境變量,刷新即可;
2)CUDA有兩種API,分別是運(yùn)行時(shí)API和驅(qū)動API,即所謂的Runtime API與Driver API,nvidia-smi的結(jié)果除了有GPU驅(qū)動版本型號,還有CUDA Driver API的版本號,這里是10.0,而nvcc的結(jié)果是對應(yīng)CUDA Runtime API。
對于原因二的一個(gè)具體解釋如下:
CUDA有兩個(gè)主要的API:runtime(運(yùn)行時(shí)) API和driver(驅(qū)動) API。這兩個(gè)API都有對應(yīng)的CUDA版本(如9.2和10.0等)。
- 用于支持driver API的必要文件(如libcuda.so)是由GPU driver installer安裝的。nvidia-smi就屬于這一類API。
- 用于支持runtime API的必要文件(如libcudart.so以及nvcc)是由CUDA Toolkit installer安裝的。(CUDA Toolkit Installer有時(shí)可能會集成了GPU driver Installer)。nvcc是與CUDA Toolkit一起安裝的CUDA compiler-driver tool,它只知道它自身構(gòu)建時(shí)的CUDA runtime版本。它不知道安裝了什么版本的GPU driver,甚至不知道是否安裝了GPU driver。
綜上,如果driver API和runtime API的CUDA版本不一致可能是因?yàn)槟闶褂玫氖菃为?dú)的GPU driver installer,而不是CUDA Toolkit installer里的GPU driver installer。
補(bǔ)充說明:在安裝CUDA 時(shí)候會安裝3大組件,分別是 NVIDIA 驅(qū)動、toolkit和samples。NVIDIA驅(qū)動是用來控制GPU硬件,toolkit里面包括nvcc編譯器等,samples或者說SDK 里面包括很多樣例程序包括查詢設(shè)備、帶寬測試等等。上面說的CUDA Driver API是依賴于NVIDIA驅(qū)動安裝的,而CUDA Runtime API 是通過CUDA toolkit安裝的。
runtime API 與 driver API 的區(qū)別
下圖很清楚的展示前面提到的各種概念之間的關(guān)系,其中runtime API和driver API在很多情況非常相似,也就是說用起來的效果是等價(jià)的,但是你不能混合使用這兩個(gè)API,因?yàn)槎呤腔コ獾摹R簿褪钦f在開發(fā)過程中,你只能選擇其中一種API。簡單理解二者的區(qū)別就是:runtime是更高級的封裝,開發(fā)人員用起來更方便,而driver API更接近底層,速度可能會更快。
兩種API詳細(xì)的區(qū)別如下:
-
復(fù)雜性
- runtime API通過提供隱式初始化、上下文管理和模塊管理來簡化設(shè)備代碼管理。這使得代碼更簡單,但也缺乏驅(qū)動程序API所具有的控制級別。
- 相比之下,driver API提供了更細(xì)粒度的控制,特別是在上下文和模塊加載方面。實(shí)現(xiàn)內(nèi)核啟動要復(fù)雜得多,因?yàn)閳?zhí)行配置和內(nèi)核參數(shù)必須用顯式函數(shù)調(diào)用指定。
-
控制
- 對于runtime API,其在運(yùn)行時(shí),所有內(nèi)核都在初始化期間自動加載,并在程序運(yùn)行期間保持加載狀態(tài)。
- 而使用driver API,可以只加載當(dāng)前需要的模塊,甚至動態(tài)地重新加載模塊。driver API也是語言獨(dú)立的,因?yàn)樗惶幚韈ubin對象。
-
上下文管理
上下文管理可以通過driver API完成,但是在runtime API中不公開。相反,runtime API自己決定為線程使用哪個(gè)上下文:
- 如果一個(gè)上下文通過driver API成為調(diào)用線程的當(dāng)前上下文,runtime將使用它,
- 如果沒有這樣的上下文,它將使用“主上下文(primary context)”。
主上下文會根據(jù)需要創(chuàng)建,每個(gè)設(shè)備每個(gè)進(jìn)程一個(gè)上下文,并進(jìn)行引用計(jì)數(shù),然后在沒有更多的引用時(shí)銷毀它們。在一個(gè)進(jìn)程中,所有runtime API的用戶都將共享主上下文,除非上下文已成為每個(gè)線程的當(dāng)前上下文。runtime使用的上下文,即當(dāng)前上下文或主上下文,可以用cudaDeviceSynchronize()同步,也可以用cudaDeviceReset()銷毀。
但是,將runtime API與主上下文一起使用會有tradeoff。例如,對于那些需要給較大的軟件包寫插件的開發(fā)者來說者會帶來不少麻煩,因?yàn)槿绻械牟寮荚谕粋€(gè)進(jìn)程中運(yùn)行,它們將共享一個(gè)上下文,但可能無法相互通信。也就是說,如果其中一個(gè)在完成所有CUDA工作后調(diào)用cudaDeviceReset(),其他插件將失敗,因?yàn)樗鼈兪褂玫纳舷挛脑谒鼈儾恢榈那闆r下被破壞。為了避免這個(gè)問題,CUDA clients可以使用driver API來創(chuàng)建和設(shè)置當(dāng)前上下文,然后使用runtime API來處理它。但是,上下文可能會消耗大量的資源,比如設(shè)備內(nèi)存、額外的主機(jī)線程和設(shè)備上上下文切換的性能成本。當(dāng)將driver API與基于runtime API(如cuBLAS或cuFFT)構(gòu)建的庫一起使用時(shí),這種runtime-driver上下文共享非常重要。
CUDA多版本管理
我們可以通過:
ls -l /usr/local | grep cuda來查看自己的機(jī)器上有多少個(gè)cuda版本,通常不帶版本號的 cuda 會是其他帶版本號的cuda-x.x的軟鏈接。即像下面這樣:
lrwxrwxrwx 1 root root 21 12月 10 2020 cuda -> /usr/local/cuda-11.1/而我們只要把我們使用cuda時(shí)都指向這個(gè)軟鏈接/usr/local/cuda,并在需要切換版本時(shí)切換這個(gè)軟鏈接的指向即可。
sudo rm -rf cuda sudo ln -s /usr/local/cuda-9.0/ /usr/local/cuda注意此時(shí)如果nvcc -V的輸出還是更改之前的CUDA版本的話,要修改環(huán)境變量:
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH并且要去 ~/.bashrc 中查看以下是不是會顯式地指定CUDA版本如:
export PATH=/usr/local/cuda-11.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-11.1/lib64:$LD_LIBRARY_PATH如果有這兩句的話,直接換成上面兩句指向軟鏈接 /usr/local/cuda 的兩句即可。
Ref
https://bbs.huaweicloud.com/blogs/detail/140384
https://blog.csdn.net/weixin_38705903/article/details/101850116
總結(jié)
以上是生活随笔為你收集整理的Linux下的CUDA多版本管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一千卡等于多少米
- 下一篇: 双流车管所24小时咨询电话?