歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Ubuntu 16.04 LTS+NVIDIA@GT620M+CUDA6.5環境搭建總結

Ubuntu 16.04 LTS+NVIDIA@GT620M+CUDA6.5環境搭建總結

日期:2017/2/28 13:48:14   编辑:Linux教程

引言

為了完成tensorflow中CIFAR10關於cuda-convnet最後兩層的實現聯系,我重新搭建了一下CUDA環境。可我萬萬沒想到,這環境竟然倒騰了我兩個星期的業余時間,搞得我心煩意亂,像個鬼影似的,在我腦子裡萦繞又揮之不去。不過最終還是走出了陰霾,我現在做一個經驗總結,把我對cuda的一些理解與我對某些問題的解決思路分享給大家。

我先介紹一下這項環境配置工作的目標,主要是為cuda-convnet搭建運行環境。因此,其實用cuda的哪一個版本都不會有太大關系,不過系統最好時使用Ubuntu,這是因為
Alex Akrizhevsky 是在Linux環境下開發這套程序,相似甚至相同的系統環境更容易復現程序的效果。然後,為什麼我采用的是CUDA6.5,而不是CUDA7.0/7.5/8.0?原因很簡單,因為我之前曾在Ubuntu14.04LTS上搭建caffe成功過,當時采用貌似也就只有CUDA6.5。那為什麼系統又成了Ubuntu16.04LTS了?下面就看看我遇到的問題。

問題

眾所周知,官方驅動對Ubuntu的貌似一向都不大給力,因此apt裡面的驅動才是王道。但這並不是絕對的,畢竟確實也有不少人用官方驅動才安裝成功NVIDIA-Linux-x86_64-xxx.xx.run的。而我其實最初的搭建目標,是打算在Ubuntu14.04安裝CUDA7.5的。當時,我還以為都更新了這麼多次,感覺Nvidia支持力度應該不差,結果出現了循環登錄界面現象,這個現象不大好解,而且貌似在tty1上用
user@machine:~$ apt-get remove --purge nvidia*
都不好使,所以我改回了cuda-6.5。然而,網上流傳著cuda-6.5只支持到nvidia-340的驅動。因此,我直接來一個apt-get install nvidia-340 把它給裝上了。本以為這問題就這麼解決了,可是卻出現了另一個問題——系統黑屏。完了….直接連登陸界面都看不見,其實面對這個情況我還是一如既往的淡定,使用
user@machine:~$ apt-get upgrade
能進系統到system-settings了。接著安裝cuda6.5,這部分還沒多大問題,但裝完後,進入sample編譯完後跑deviceQuery的時候就悲劇了,error(30) 是一個unkown有點無語了。難道是GPU驅動沒裝好?(其實不是,後面我就介紹)最後,又因為我從win系統切換回來,不知得罪哪個系統了,又回到了,黑屏的問題……連重裝系統都不好使,upgrade也廢了….看起來貌似真全廢了。當時,我一直嘗試各種方法,但都沒得到好結果(包括升級到16.04LTS後依然出現unkown的問題,並且因為編譯工具的更新出現各種不適)……然而,我用TRIZ仔細分析了下矛盾後,找到了突破點。

矛盾分析

TRIZ蘇聯的創新發明理論,我這裡不多做介紹,直接用它進行分析。從上面的問題描述上,我們能分析出一種東西,叫做矛盾。當下最主要的矛盾,我想可能在Nvidia的Ubuntu驅動方面。我覺著這個矛盾應該是,在Ubuntu14.04LTS環境下安裝官方驅動會登錄死循環,安裝apt的驅動又會黑屏,不裝又跑不起CUDA,裝了就進不了系統。這是一個技術矛盾,而我們希望得到的理想結果是,裝上驅動而且不會出現故障,但裝上驅動就一定會出現故障,其實可以認為N卡驅動壞了。因此我們需要安裝一個不是驅動的驅動。乍看這話很怪,我後面分析完就不怪了。

我們需要從微觀層面分析,到底為什麼N卡驅動是壞的,驅動是跟誰發生沖突,從而尋找物理矛盾?據我的了解加上實驗的驗證,我發現N卡驅動雖然裝上後進不了圖形界面,但實際上能進系統的tty1模式並能夠正常運行,甚至還能夠跑CUDA的程序。也就是說,N卡驅動只是跟上層圖形界面啟動器發生了沖突,而非底層驅動失效。物理矛盾找到了,那怎麼解決呢?大家都明白,換個圖形界面啟動器就好了嘛,Ubuntu14.04的Xserver啟動器,我不是很會換。但前面Ubuntu16.04LTS不是已經把驅動裝上了嗎?行,我先把系統升級,再讓驅動給安上。結果確實沒問題了,原因是Ubuntu16.04LTS已經放棄了過去的Xserver,而換成了wayland的圖形啟動器。這就是我們的那個不是(Ubuntu14.04的)驅動的(Ubuntu16.04的)驅動了。那接下來新的問題出現了,跑CUDA例程出現的unkown怎麼解決,還有編譯工具過新的問題怎麼解決?

因為Ubuntu16.04LTS更新了gnu,而且在string的memcpy方面有比較大的改動,因此老會出現問題

"/usr/include/string.h:652:42: error: 'memcpy' was not declared in this scope"

這個問題還是比較好解決的,一般我是在編譯文件裡面,添加一個叫做-D_FORCE_INLINES 的編譯選項。不過,面對cuda6.5的編譯,由於不支持gnu-4.9及以上的版本,我是直接使用

user@machine:~$ sudo update-alternative --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 0
user@machine:~$ sudo update-alternative --install /usr/bin/gcc gcc /usr/bin/gcc-5.0 1
user@machine:~$ sudo update-alternative --install /usr/bin/g++ g++ /usr/bin/g++-4.8 0
user@machine:~$ sudo update-alternative --install /usr/bin/g++ g++ /usr/bin/g++-5.0 1

這時我們就可以使用下面的兩條指令來選擇切換gnu版本

user@machine:~$ sudo update-alternative --config g++
user@machine:~$ sudo update-alternative --config gcc

解決了gnu版本問題,我們就可以開始安裝cuda工具,這部分網上的材料比較多,因此不做贅述,可以參考 http://www.linuxidc.com/Linux/2015-04/116444.htm 的CUDA安裝部分。

最後,就是編譯了CUDA提供的sample後,在跑deviceQuery時出現的unkown問題,類似如下:

./deviceQuery Starting...

CUDA Device Query (Runtime API) version (CUDART static linking)

cudaGetDeviceCount returned 30
-> unknown error
Result = FAIL

這個問題其實也很獨特,每個人這個問題都可能不一樣,我只能介紹我遇到的情況。我的這個問題主要的原因其實是因為~/.bashrc裡面沒有真正的加上LD_LIBRARY_PATH。(其實我有根據cuda的安裝提示加上,只是LD_LIBRARY_PATH我漏掉了最後的PATH成了LD_LIBRARY,結果引發了這出慘案……)另外,還有一種可能是權限不夠,可以通過執行的時候加上sudo解決這個問題,下面是我的log:

user@machine:~$ sudo ./deviceQuery
[sudo] password for user: 
./deviceQuery Starting...

 CUDA Device Query (Runtime API) version (CUDART static linking)

Detected 1 CUDA Capable device(s)

Device 0: "GeForce GT 620M"
  CUDA Driver Version / Runtime Version          6.5 / 6.5
  CUDA Capability Major/Minor version number:    2.1
  Total amount of global memory:                 1024 MBytes (1073479680 bytes)
  ( 2) Multiprocessors, ( 48) CUDA Cores/MP:     96 CUDA Cores
  GPU Clock rate:                                1250 MHz (1.25 GHz)
  Memory Clock rate:                             900 Mhz
  Memory Bus Width:                              64-bit
  L2 Cache Size:                                 131072 bytes
  Maximum Texture Dimension Size (x,y,z)         1D=(65536), 2D=(65536, 65535), 3D=(2048, 2048, 2048)
  Maximum Layered 1D Texture Size, (num) layers  1D=(16384), 2048 layers
  Maximum Layered 2D Texture Size, (num) layers  2D=(16384, 16384), 2048 layers
  Total amount of constant memory:               65536 bytes
  Total amount of shared memory per block:       49152 bytes
  Total number of registers available per block: 32768
  Warp size:                                     32
  Maximum number of threads per multiprocessor:  1536
  Maximum number of threads per block:           1024
  Max dimension size of a thread block (x,y,z): (1024, 1024, 64)
  Max dimension size of a grid size    (x,y,z): (65535, 65535, 65535)
  Maximum memory pitch:                          2147483647 bytes
  Texture alignment:                             512 bytes
  Concurrent copy and kernel execution:          Yes with 1 copy engine(s)
  Run time limit on kernels:                     Yes
  Integrated GPU sharing Host Memory:            No
  Support host page-locked memory mapping:       Yes
  Alignment requirement for Surfaces:            Yes
  Device has ECC support:                        Disabled
  Device supports Unified Addressing (UVA):      Yes
  Device PCI Bus ID / PCI location ID:           1 / 0
  Compute Mode:
     < Default (multiple host threads can use ::cudaSetDevice() with device simultaneously) >

deviceQuery, CUDA Driver = CUDART, CUDA Driver Version = 6.5, CUDA Runtime Version = 6.5, NumDevs = 1, Device0 = GeForce GT 620M
Result = PASS

出現這個log就意味著,cuda環境成功配置了。

解答總結

下面是整個CUDA環境的配置流程:
1.安裝Ubuntu16.04LTS系統,也可以從較低版本中升級上來。
2.從System Settings中安裝Nvidia驅動。
3.用 apt-get install g++-4.8 gcc-4.8安裝老版本gnu。
4.用update-alternative指令配置gnu環境,使其能夠升降級。
5.編譯CUDA工具。
6.編譯CUDA的sample,並調用deviceQuery測試安裝是否成功。

一些注意事項:
1.Ubuntu16.04LTS使用wayland圖形界面啟動器,比原來的Xserver更容易避免N卡驅動與系統應用層的沖突。
2.安裝好N卡驅動並進入圖形界面後,可以利用Nvidia X server Settings來切換顯卡。
3.注意用編譯選項-D_FORCE_INLINES解決“‘memcpy’ was not declared in this scope”的問題。
4.想要知道N卡驅動是否安裝成功,我們可以查看System Settings的detail信息,看是否又有我們的獨顯型號來判斷。
5.編譯sample的過程中可能遇到/usr/bin/ld -nvcudev:can’t find the directories 類似的現象,這是有可能是因為我們使用了nvidia-340以上的顯卡驅動,從而找不著路徑,在默認編譯環境裡面找不到相應的庫,這時我們只要在.barshrc文件裡面最後加上下面一行就解決問題了:
export LIBRARY_PATH=/usr/lib/nvidia-xxx(版本號):LIBRARY_PATH

總的來講,CUDA其實只是一套編譯工具,它是在原有的GNU工具的基礎上加入了兼容NVIDIA的GPU架構的指令集,提供了一套能調用GPU資源的API。因此CUDA本身的安裝並不存在多大問題,大部分都只是N卡驅動以及編譯鏈接的問題。所以,我建議如果在CUDA環境搭建的時候,遇到問題有優先從編譯鏈接上找原因,尤其是驅動已經明確安裝成功的時候,基本可以明確是編譯鏈接的問題。N卡驅動一般只會跟上層圖形界面應用服務產生矛盾,所以基本可以分離N卡驅動與CUDA代碼執行的問題。不過,有一個很重要的例外,就是執行一些不符合自身顯卡計算能力的代碼時,同樣也會出現code=30的unknown錯誤,如下:

CUDA error at src/nvmatrix.cu:1548 code=30(cudaErrorUnknown) "cudaCreateTextureObject(&_texObj, &resDesc, &texDesc, NULL)"

這個錯誤是因為我的GT620M的計算能力只有2.1,編譯的時候使用sm_20架構的編譯選項,而這個TextureObject的代碼只能在sm_30以上的架構使用,所以會出現這種錯誤。實際上,我很鄙視Nvidia CUDA的nvcc編譯工具。因為在編譯階段這個使用架構不兼容代碼的問題是可以提示錯誤的,從而減少開發者遇到問題的處理效率,而且我覺著這只是一個宏定義處理的問題而已,看來Nvidia在這方面的支持力度還有待提高!

Ubuntu 14.04 安裝配置CUDA http://www.linuxidc.com/Linux/2014-10/107501.htm

Ubuntu 12.04配置NVIDIA CUDA5.5實錄 http://www.linuxidc.com/Linux/2014-10/107502.htm

Ubuntu安裝Theano+CUDA http://www.linuxidc.com/Linux/2014-10/107503.htm

關於Ubuntu 12.04 下 CUDA5.5 的安裝請參看如下鏈接 Ubuntu 12.04 安裝 CUDA-5.5

更多Ubuntu相關信息見Ubuntu 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=2

Copyright © Linux教程網 All Rights Reserved