8 нояб. 2012 г.

Ubuntu - Optimus < 0

Если бы не сегодняшнее горе, то я бы не написал этот блог пост. Проблема возникла в том, что после установки очередной порции обновлений, и, кажется, пакета linux-image-3.5.0.18 что-то там, я сломал свой линукс до неузнаваемости. Оказалось, что пропали драйвера от пакета nvidia-current, и в общем всё нахрен сломалось. Побаловавшись с тем, что вроде бы работало, я сломал свои иксы напрочь и даже чудом лишился файла xorg.conf.

Потерев все ppa, удалив все где упоминались слова типа nvidia и bumblebee, я вернул систему в божеский вид и запустил драйвера nouveau. Отлично, полёт нормальный, но мне захотелось вернуть свою CUDA назад. Что я для этого сделал? С ходу не отвечу, потому что подбирал много параметров, но я решился на установку сырых пакетов из ppa:xorg-edgers/ppa. Кстати, советую поставить заголовки нового ядра: обычные и generic. Думаю, пригодятся :)

Когда bumblebee установился, я понял, что моя Intel карта перестала работать, выдавая вот такую ошибку:

$ glxinfo
name of display: :0
Xlib: extension "NV-GLX" missing on display ":0".
X Error of failed request: BadAlloc (insufficient resources for operation)
  Major opcode of failed request: 153 (GLX)
  Minor opcode of failed request: 3 (X_GLXCreateContext)
  Serial number of failed request: 17
  Current serial number in output stream: 18

Единственная внятная статья по этому поводу мне не помогла. Но я решил на неё забить, потому что я хотел вернуть Optimus назад.

Проект bumblebee не заработал, потому что при запуске любого приложения выдавалась ошибка с "якобы" вот таким решением. Оказалось, что вроде бы драйвер nvidia не может быть найден. Если помните, то nvidia-current решило мне похожую проблему ранее. Но опять таки я не загружал нужный мне модуль, потому что горе-погроммисты переименовали его. И теперь, правильнее было бы подправить /etc/bumblebee/bumblebee.conf вот так:

...
Driver=nvidia
...
[driver-nvidia]
# Module name to load, defaults to Driver if empty or unset
KernelDriver=nvidia_current
Module=nvidia
...

Руки бы им за подчёркивание оторвать. На всякий случай, я также добавил nvidia модуль в /etc/modules:

...
nouveau # не знаю, но в блеклист я этот модуль не стал добавлять
nvidia_current

Ну и немного для истории, вот моя видео карта:

$ optirun ./deviceQuery 
./deviceQuery Starting...

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

Detected 1 CUDA Capable device(s)

Device 0: "GeForce GT 540M"
  CUDA Driver Version / Runtime Version          5.0 / 5.0
  CUDA Capability Major/Minor version number:    2.1
  Total amount of global memory:                 2048 MBytes (2147155968 bytes)
  ( 2) Multiprocessors x ( 48) CUDA Cores/MP:    96 CUDA Cores
  GPU Clock rate:                                1344 MHz (1.34 GHz)
  Memory Clock rate:                             900 Mhz
  Memory Bus Width:                              128-bit
  L2 Cache Size:                                 131072 bytes
  Max Texture Dimension Size (x,y,z)             1D=(65536), 2D=(65536,65535), 3D=(2048,2048,2048)
  Max Layered Texture Size (dim) x layers        1D=(16384) x 2048, 2D=(16384,16384) x 2048
  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
  Maximum sizes of each dimension of a block:    1024 x 1024 x 64
  Maximum sizes of each dimension of a grid:     65535 x 65535 x 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 = 5.0, CUDA Runtime Version = 5.0, NumDevs = 1, Device0 = GeForce GT 540M


$ optirun ./bandwidthTest 
[CUDA Bandwidth Test] - Starting...
Running on...

 Device 0: GeForce GT 540M
 Quick Mode

 Host to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(MB/s)
   33554432   6269.0

 Device to Host Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(MB/s)
   33554432   6277.8

 Device to Device Bandwidth, 1 Device(s)
 PINNED Memory Transfers
   Transfer Size (Bytes) Bandwidth(MB/s)
   33554432   23688.5

6 нояб. 2012 г.

CUDA куда-куда? А! В Ubuntu 12.10 - CUDA Part

Круто - но стрёмно! Вот пришла пора описать как я ставил саму CUDA, и какие сложности попались мне на пути. Версия, которую мне захотелось поставить - CUDA 5.0. Четвертая версия сама по себе уже старовата, да и меня прельщала возможность использования Nsight for Linux, нежели чем какие-нибудь собственные make файлы.

Проще говоря, скачать и поставить не проблема, всяких док полно в интернете. Главное есть некоторые нюансы, которые я бы упомянул:

  • Не ставьте драйвера NVIDIA, входящие в комплект SDK;
  • Не ставьте поддержку Optimus - я не знаю, в чем её смысл, но думаю ничего хорошего она вам не принесёт. Во всяком случае интернет молчит по этому поводу;
  • Скорей всего инсталлятор попросит у вас GCC 4.6 - качайте отдельный метапакет для этого. У CUDA заголовков внутри прописана версия компилятора. Поэтому, если попытаетесь всё поднять на 4.7, то у вас отвалится. Любые попытки исправить (особенно, если вы новичок как я) оставьте на потом;

Когда всё поставите (соглашайтесь с дефолтными путями), то первым делом надо собрать каталог ~/NVIDIA_CUDA-5.0_Samples. При сборка каталога командой make вы получите около пяти ошибок, которые легко решаются. И так, понеслось...

g++ -m64 -o vectorAddDrv vectorAddDrv.o -L/usr/local/cuda-5.0/lib64 -lcuda
/usr/bin/ld: error: cannot find -lcuda
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuInit'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuDeviceGetCount'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuDeviceComputeCapability'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuDeviceGetName'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuDeviceGet'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuCtxCreate_v2'
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuModuleLoadDataEx'
...
vectorAddDrv.o:vectorAddDrv.cpp:function main: error: undefined reference to 'cuMemcpyDtoH_v2'
vectorAddDrv.o:vectorAddDrv.cpp:function CleanupNoFailure(): error: undefined reference to 'cuMemFree_v2'
vectorAddDrv.o:vectorAddDrv.cpp:function CleanupNoFailure(): error: undefined reference to 'cuMemFree_v2'
vectorAddDrv.o:vectorAddDrv.cpp:function CleanupNoFailure(): error: undefined reference to 'cuMemFree_v2'
vectorAddDrv.o:vectorAddDrv.cpp:function CleanupNoFailure(): error: undefined reference to 'cuCtxDetach'
collect2: error: ld returned 1 exit status
make[1]: *** [vectorAddDrv] Error 1

Лечится такая ошибка вот этим. Почему именно в .bashrc, а не в .bash_profile? Потому что из под иксов, при запуске gnome-terminal, вызывается именно первый файл, а не второй. Второй будет использоваться только в голой консоли. На всякий случай, вот мой файл:

export PATH=$PATH:/usr/local/cuda-5.0/bin
export LPATH=/usr/lib/nvidia-current:$LPATH
export LIBRARY_PATH=/usr/lib/nvidia-current:$LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-5.0/lib:/usr/local/cuda-5.0/lib64:/usr/lib/nvidia-current

Когда возникнет ошибка вида MPI not found (simpleMPI), то советую посмотреть сюда для наглядности и поставить ещё один пакет:

sudo apt-get install libopenmpi-dev

Потом у вас должна возникнуть ошибка с libcublas, которая лечится добавлением опции -ldl к компилятору:

cdpLUDecomposition: dlaswp.o dgetf2.o dgetrf.o cdp_lu.o cdp_lu_main.o
    $(NVCC) $(CCFLAGS) $(GENCODE_FLAGS) -o $@ $+ $(LDFLAGS) $(EXTRA_LDFLAGS) -ldl

Собственно это всё, после этого все демки должны будут скомпилиться и работать. Кстати, к сожалению позднее появление этой статьи в моём браузере является причиной написания этого блог-поста. Прочтите и не пожалеете.

Я не буду, наверное, описывать как программировать под CUDA, потому что сам не умею, но точно прошу вас запомнить следующие команды. Они вам помогут:

optirun nsight    # запускает Eclipse, чтобы программы работали с CUDA
optirun cuda-gdb yourCudaProgram    # запускает отладчик через CUDA

Погуглив в интернете более интенсивно, я понял, что nvcc почему-то не генерит отладочные символы (Debug Symbols) для устройства. В общем, если знаете ответ на этот вопрос, будьте добры, напишите мне где-нибудь...

4 нояб. 2012 г.

CUDA куда-куда? А! В Ubuntu 12.10 - Optimus Part

Линуксу - нет! Так получилось, что во время написания этого поста, я являюсь счастливым обладателем ноутбука фирмы ASUS, модель X7BS. Если захочется погуглить, то в нем Intel Core i7 - 2630QM, 2.0GHz, что даёт мне 8 гипертрединговых ядер, ну и два жёстких по 500 Gb. Однако не это в нём примечательное, а то, что он является обладателем технологии NVIDIA Optimus. Другими словами, его видеокарта GeForce GT 540M (2 Gb) умеет распоряжаться интегрированной Intel'овской картой.

Ну раз моя видеокарта может пользоваться CUDA технологией, то я решил поковырять параллельное программирование на ней на досуге. Проблема в том, что официально NVIDIA поддерживает MS Visual Studio 2008/2010 своим плагином Nsight для разработки приложений под CUDA. Начиная с 5.0 версии, они разродились самостоятельной средой разработки на основе Eclipse. Но минус в том, что эта IDE доступна для Linux'a и Мака (кажется).

Попробовав поставить старые .deb пакеты под обновившуюся недавно Убунту, я наткнулся на несколько, для меня, новостей: Optimus под линуксом идёт плохо, CUDA поддерживает старый компилятор GCC-4.6. Всё это меня расстроило в конец, потому что с OpenSuse дела тоже идут не гладко со старыми компиляторами, поэтому я решил написать статью о том как запустить CUDU с моей видеокартой под линукс.

Для начала нам надо запустить Оптимус. Под ОпенЗюзе есть хорошая статья (на немецком и русском языках), которая дала мне понять, что с Оптимусом под линуксом жить можно. Хочу сразу же обратить внимание на небольшую и простую переписку в форуме, которая мне помогла установить поддержку Оптимуса. Кстати да, я там отличился. У вас, скорей всего, как и у меня x-swat репозитории для 12.10 окажутся пустыми. Но это и не важно, ибо он не нужен вроде как :) В лучшем случае, если не полетит, то в файле /etc/bumblebee/bumblebee.conf должно быть так:

...
Driver=
...
[driver-nvidia]
# Module name to load, defaults to Driver if empty or unset
KernelDriver=nvidia-current
Module=nvidia
...

Про всяких пользователей я умолчу, так как все должно было бы встать нормально. Если что, проверьте своего пользователя, чтобы он был в группе bumblebee:

$ groups
user adm cdrom sudo dip plugdev lpadmin sambashare bumblebee

Если у вас всё взлетит, то вы увидите следующие или похожие результаты:


$glxgears
Running synchronized to the vertical refresh. The framerate should be approximately the same as the monitor refresh rate.
304 frames in 5.0 seconds = 60.613 FPS
... Intel
$ optirun glxgears
4439 frames in 5.0 seconds = 887.763 FPS
... NVIDIA
$ glxspheres
Polygons in scene: 62464
Visual ID of window: 0xa3
Context is Direct
OpenGL Renderer: Mesa DRI Intel(R) Sandybridge Mobile
60.271004 frames/sec - 67.262440 Mpixels/sec
... Intel
$ optirun glxspheres
Polygons in scene: 62464
Visual ID of window: 0x21
Context is Direct
OpenGL Renderer: GeForce GT 540M/PCIe/SSE2
110.310679 frames/sec - 123.106717 Mpixels/sec
... NVIDIA

Вот собственно и всё для этой части. Что-то поздно и я подумываю над тем, чтобы пойти спать. К сожалению, я не закончил статью, а посему про CUDA напишу позже... Ку!