Nvidia, oddawaj moje OpenCL

Jednym z uroków użytkowania dystrybucji oznaczonych skrótem LTS (Long Term Support) jest błogie przeświadczenie o nieomylności deweloperów i ekipy testującej wydanie dopuszczone do użytkowania z takim właśnie nobilitującym skrótem. Dlatego wyrwani z tej błogości czujemy się paskudnie, gdy okazuje się, że nasz nieomylny LTS jednak płata jakieś figle. Takim kubłem zimnej wody dla wielu fotografów i użytkowników Ubuntu 14.04 i Minta 17 (oraz pochodnych) okazały się niedomówienia podczas instalacji sterowników Nvidii, które zamiast przenosić nas na wyższy poziom sprawnego wykorzystania sprzętu, pozbawiły system obsługi OpenCL. Jak skutecznie może być to uciążliwe z pewnością przekonali się wszyscy użytkujący oprogramowanie korzystające z mocy obliczeniowych kart graficznych (Darktable, Aftershot Pro, inne).

Zabrzmiało dramatycznie, jednak uściślijmy – problemy z OpenCL występują tylko podczas instalowania sterowników innych, niż te repozytoryjne o numerze 331.xx (czyli domyślne dla LTSa). Niemniej – w sieci różnie o tym piszą i są osoby które miały z tym problemy również na tej wersji. Czym to się objawia? Brakiem obsługi OpenCL w programach które to potrafią. Łatwo to sprawdzić uruchamiając Darktable w terminalu:

darktable -d opencl

Jeżeli wynikiem jest:

[opencl_init] opencl related configuration options:
[opencl_init]
[opencl_init] opencl: 1
[opencl_init] opencl_library: ”
[opencl_init] opencl_memory_requirement: 768
[opencl_init] opencl_memory_headroom: 300
[opencl_init] opencl_device_priority: ‘*/!0,*/*/*’
[opencl_init] opencl_size_roundup: 16
[opencl_init] opencl_async_pixelpipe: 0
[opencl_init] opencl_synch_cache: 0
[opencl_init] opencl_number_event_handles: 25
[opencl_init] opencl_micro_nap: 1000
[opencl_init] opencl_use_pinned_memory: 0
[opencl_init] opencl_use_cpu_devices: 0
[opencl_init] opencl_avoid_atomics: 0
[opencl_init] opencl_omit_whitebalance: 0
[opencl_init]
[opencl_init] trying to load opencl library: ‘
[opencl_init] could not find opencl runtime library ‘libOpenCL’
[opencl_init] no working opencl library found. Continue with opencl disabled
[opencl_init] FINALLY: opencl is NOT AVAILABLE on this system.
[opencl_init] initial status of opencl enabled flag is OFF.

Czyli jak mówią ostatniej linijki – ‘could not find opencl runtime library ‘libOpenCL” – program nie skorzysta z uroczych możliwości przyśpieszenia obróbki dzięki wykorzystaniu naszej karty graficznej.

Ale jest pewien sposób i jeżeli ktoś nie stroni od użytkowania terminala i wpisania/wyedytowania paru komend to jest dla niego nadzieja.

Na początku uściślijmy, jakie pakiety są nam potrzebne, aby zadziało OpenCL oferowane przez Nvidia. W moim przypadku lista paczek to:

ii libcuda1-340 340.24-0ubuntu1~xedgers14.04.1 amd64 NVIDIA CUDA runtime library
ii nvidia-340 340.24-0ubuntu1~xedgers14.04.1 amd64 NVIDIA binary driver – version 340.24
ii nvidia-340-uvm 340.24-0ubuntu1~xedgers14.04.1 amd64 NVIDIA Unified Memory kernel module
ii nvidia-libopencl1-340 340.24-0ubuntu1~xedgers14.04.1 amd64 NVIDIA OpenCL Driver and ICD Loader library
ii nvidia-opencl-icd-340 340.24-0ubuntu1~xedgers14.04.1 amd64 NVIDIA OpenCL ICD
ii nvidia-settings 340.24-0ubuntu1~xedgers14.04.1 amd64 Tool for configuring the NVIDIA graphics driver

Jak widać, korzystam z nowszych sterowników 340.24 oferowanych w repozytorium ppa:xorg-edgers/ppa. Pokrótce rzecz wyjaśniając, problem z OpenCL wynika z faktu, że podczas startu systemu nie jest wczytywany moduł nvidia-uvm, a nawet jeśli się załaduje – to nie tworzy odpowiedniego urządzenia w /dev/nvidia-uvm. Dlatego rozwiązaniem jest przekonanie systemu, aby jednak załadował moduł nvidia-uvm i utworzył odpowiednie urządzenie.

Pierwsza rzecz to błahostka:

sudo bash -c 'echo "nvidia-uvm" >> /etc/modules'

Z drugą jest gorzej, bo jak zgrabnie utworzyć urządzenie? Z pomocą przyjdzie nam udev i odpowiednia regułka. Na początek otwieramy do edycji plik (którego nie ma) /etc/udev/rules.d/70-nvidia-uvm.rules:

sudo gedit /etc/udev/rules.d/70-nvidia-uvm.rules

… i wklejamy doń:

KERNEL=="nvidia_uvm", RUN+="/bin/bash -c '/bin/mknod -m 666 /dev/nvidia-uvm c $(grep nvidia-uvm /proc/devices | cut -d \  -f 1) 0; /bin/chgrp video /dev/nvidia-uvm'"

Zapisujemy – gotowe.

Jak to przetestować? Albo uruchomić ponownie komputer, albo wykonać w terminalu polecenie:

sudo modprobe nvidia-uvm