Bumblebee lets you run accelerated OpenGL through your Nvidia Optimus secondary GPU on Ubuntu. CUDA can be installed to run on that GPU without OpenGL or Bumblebee. There are guides out there for both of those individual situations.
Many CUDA devs will also use OpenGL apps, and a proportion will also develop for both platforms. Guides to the concurrent installation of both are rare and seem to go stale fast.
What follows is a simple script for the installation of both that worked for me at this moment in time with current packages for all the pieces and an up to date distro. YMMV, especially if some weeks have passed.
Download the CUDA SDK: wget http://developer.download.nvidia.com/compute/cuda/5_0/rel-update-1/installers/cuda_5.0.35_linux_64_ubuntu11.10-1.run Update packages: sudo apt-get update sudo apt-get upgrade Make sure you have developer tools installed to be able to build all of the CUDA examples, including the OpenGL and computer vision ones: sudo apt-get install build-essential libopencv-dev linux-headers-`uname -r` freeglut3-dev libx11-dev libxmu-dev libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev Purge the default display driver. sudo apt-get --purge remove nvidia* Delete/disable the xorg config if any on your system: sudo mv /etc/X11/xorg.conf /etc/X11/xorg.conf.`date "+%Y-%m-%d_%H-%M-%S"`.disabled
Blacklist other drivers by (creating then) editing /etc/modprobe.d/blacklist-nouveau.conf by adding these lines:
blacklist nvidiafb blacklist nouveau blacklist rivafb blacklist rivatv blacklist vga16fb options nouveau modeset=0
Continuing …
Update the kernel image. sudo update-initramfs -u Restart your laptop.
From what I have read, we need to be careful to install Nvidia drivers from the ubuntu-x-swat/x-updates
PPA and not from inside the CUDA installer that we downloaded above.
Lets install bumblebee (enable universe repository first if not yet done):
Add a PPA for the latest Nvidia drivers that will work with optimus: sudo add-apt-repository ppa:ubuntu-x-swat/x-updates Install Bumblebee using this driver: sudo add-apt-repository ppa:bumblebee/stable sudo apt-get update sudo apt-get install bumblebee bumblebee-nvidia linux-headers-generic
At this point, after making it through the bumblebee install, you should have working OpenGL drivers which pipe through your Nvidia Optimus GPU. You can test this by running optirun glxinfo
and spotting the OpenGL vendor string: OpenGL vendor string: NVIDIA Corporation
. On my Dell Inspiron 17R SE with Geforce GT 650M, I was getting an error at this point and had to go in and modify a Bumblebee config file manually:
vim /etc/bumblebee/xorg.conf.nvidia Change the line: Option "ConnectedMonitor" "DFP" to: Option "UseDisplayDevice" "none"
For me that was enough to get working OpenGL via the Optimus GPU using optirun
. The next stage is to install the 700MB CUDA toolkit we started downloading at the beginning of all this:
Make the installer executable and run it: sudo chmod +x cuda_5.0.35_linux_64_ubuntu11.10-1.run ./cuda_5.0.35_linux_64_ubuntu11.10-1.run -override compiler (The flag " -override compiler" is used to suppress an error message about the compiler being unsupported). Accept the EULA and when prompted to install drivers, answer no to the following question: Install NVIDIA Accelerated Graphics Driver for Linux-x86_64 304.54? ((y)es/(n)o/(q)uit): (You already have drivers that work with Bumblebee's Hackoptimus, but these would mess that up) Answer y(es) to this one: Install the CUDA 5.0 Toolkit? ((y)es/(n)o/(q)uit): Hit \for the default location: Enter Toolkit Location [ default is /usr/local/cuda-5.0 ]: Yes to the samples (we should have installed their dependencies earlier): Install the CUDA 5.0 Samples? ((y)es/(n)o/(q)uit): Set the sample location where you want it, confirm, and wait for installation to finish. Make the CUDA samples owned by your normal user rather than root. I installed cuda at /bucket/cuda-5.0, so I started by going there: pushd /bucket/cuda-5.0 sudo chown -R yourusername:yourusername . Put the CUDA compiler and lib paths on your env vars by adding this to your $HOME/.bashrc: export CUDA_HOME=/usr/local/cuda-5.0 export LD_LIBRARY_PATH=${CUDA_HOME}/lib64 export PATH=${PATH}:${CUDA_HOME}/bin
We should be all done. Lets test that by building some samples:
Enter the CUDA paths into your current terminal so you don't need to log back in: export CUDA_HOME=/usr/local/cuda-5.0 export LD_LIBRARY_PATH=${CUDA_HOME}/lib64 export PATH=${PATH}:${CUDA_HOME}/bin Go to a CUDA Toolkit sample, build it and run it: pushd/samples/1_Utilities/deviceQuery make pushd ../../bin/linux/release/ optirun ./deviceQuery
Tadaa! You should see an image like the screenshot in this post.
Ughh, there is more…
This CUDA release does an explicit check of the compiler version and refuses to compile on anything over 4.6. To fix that edit this file:
/usr/local/cuda-5.0/include/host_config.h
Edit line 82 to stop the compiler refusing to run:
// #error — unsupported GNU version! gcc 4.7 and up are not supported!
All of the compilation units for your projects will have to add the following two lines at the top of the file before any CUDA-related
#warning — unsupported GNU version! gcc 4.7 and up are not supported! (was an error --- [AHC])
#include
s.
#undef _GLIBCXX_ATOMIC_BUILTINS #undef _GLIBCXX_USE_INT128
Addendum 1: Changing over to GCC 4.6 from GCC 4.7.2
Ugh, The fixes for GCC 4.7.x compatibility above involve breaking atomics.
What we need to do instead is install GCC/G++ 4.6 and tell CUDA to use them.
- apt-get install g++ 4.6 (pulls in gcc obv.)
- Go where nvcc lives. E.g.: pushd /usr/local/cuda-5.0/bin
- Make links to the 4.6.x versions of gcc and g++ here so nvcc finds them first, ahead of the 4.7.x versions:
- ln -s /usr/bin/g++-4.6 g++
- ln -s /usr/bin/gcc-4.6 gcc
You might need this flag every time you compile if you modify the install slightly from the steps above, but I didn’t need it.
Addendum 2 – Keeping the Nvidia Driver Loaded While the GPU is Powered-Down in ACPI state D3
After running with the above setup for a while, I got an error running my CUDA app that then stuck for any use of the GPU:
Digging around, the advice I found led me to look at [email protected]:/tmp$ optirun glxinfo
[55397.040397] [ERROR]Cannot access secondary GPU - error: [XORG] (EE) NVIDIA(0): Failed to initialize the NVIDIA GPU at PCI:1:0:0. Please
[55397.040507] [ERROR]Aborting because fallback start is disabled.
/var/log/kern.log
(see Appendix 1 below) and add a couple of lines to /etc/rc.local
:
vim /etc/rc.local
Read more about nvidia-smi here.# Keep the Nvidia driver loaded even when the GPU is powered off:
# This is required for Bumblebee in any case, even without CUDA
# sudo nvidia-smi -pm ENABLED
PATH="/usr/lib/nvidia-current/bin/":"$PATH" LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"/usr/lib/nvidia-current/" /usr/lib/nvidia-current/bin/nvidia-smi -pm ENABLED
# Only allow one program on the GPU at a time:
# sudo nvidia-smi -c EXCLUSIVE_PROCESS
PATH="/usr/lib/nvidia-current/bin/":"$PATH" LD_LIBRARY_PATH="$LD_LIBRARY_PATH":"/usr/lib/nvidia-current/" /usr/lib/nvidia-current/bin/nvidia-smi -c EXCLUSIVE_PROCESS
To avoid this issue, possibly flash support needs to be disabled in all web browsers.
- Chrome: Go to “chrome://plugins/”. Scroll down to the flash plugin and click “Disable”.
- Firefox: Go through menus: Tools->Add-ons, Tab Plugins. Scroll to Shockwave Flash and click “Disable”.
I went ahead and disabled it like this without testing if the previous step worked first: no time.
Sources
http://askubuntu.com/a/134961/130331
http://askubuntu.com/a/36936/130331
Bumblebee Installation
http://whoochee.blogspot.co.uk/2012/12/optimus-and-discrete-nvidia-gpu-under.html
CUDA Installation on Ubuntu
https://www.udacity.com/wiki/CS344/ubuntu_dev
https://www.udacity.com/wiki/CS344/troubleshoot_gcc47
Appendix 1: Bumblebee Errors Logged in /var/log/kern.log
After running for I while I was seeing phrases like “GPU at 0000:01:00.0 has fallen off the bus“, “Refused to change power state, currently in D3” (ACPI state for being turned off), and “NVRM: os_pci_init_handle: invalid context” in /var/log/kern.log
, along with CUDA and GL not working:
Feb 17 13:03:45 regent2 kernel: [51212.394006] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 304.64 Tue Oct 30 10:58:20 PDT 2012
Feb 17 13:03:46 regent2 kernel: [51213.810606] bbswitch: disabling discrete graphics
Feb 17 13:03:46 regent2 kernel: [51213.810777] bbswitch: Result of Optimus _DSM call: 01000059
Feb 17 13:03:46 regent2 kernel: [51213.823836] pci 0000:01:00.0: Refused to change power state, currently in D0
Feb 17 13:03:46 regent2 kernel: [51214.023700] pci 0000:01:00.0: power state changed by ACPI to D3
Feb 17 13:04:59 regent2 kernel: [51286.521297] bbswitch: enabling discrete graphics
Feb 17 13:04:59 regent2 kernel: [51286.946780] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.946797] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.946878] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.946885] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.964418] nvidia 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.964422] nvidia 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:04:59 regent2 kernel: [51286.964434] vgaarb: device changed decodes: PCI:0000:01:00.0,olddecodes=none,decodes=none:owns=none
Feb 17 13:04:59 regent2 kernel: [51286.964520] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 304.64 Tue Oct 30 10:58:20 PDT 2012
Feb 17 13:05:01 regent2 kernel: [51288.314416] bbswitch: disabling discrete graphics
Feb 17 13:05:01 regent2 kernel: [51288.314805] bbswitch: Result of Optimus _DSM call: 01000059
Feb 17 13:05:01 regent2 kernel: [51288.328710] pci 0000:01:00.0: Refused to change power state, currently in D0
Feb 17 13:05:01 regent2 kernel: [51288.528614] pci 0000:01:00.0: power state changed by ACPI to D3
Feb 17 13:06:35 regent2 kernel: [51381.921678] bbswitch: enabling discrete graphics
Feb 17 13:06:35 regent2 kernel: [51382.344817] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.344824] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.344867] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.344870] pci 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.358899] nvidia 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.358905] nvidia 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:35 regent2 kernel: [51382.358919] vgaarb: device changed decodes: PCI:0000:01:00.0,olddecodes=none,decodes=none:owns=none
Feb 17 13:06:35 regent2 kernel: [51382.359024] NVRM: loading NVIDIA UNIX x86_64 Kernel Module 304.64 Tue Oct 30 10:58:20 PDT 2012
Feb 17 13:06:39 regent2 kernel: [51386.809566] NVRM: GPU at 0000:01:00.0 has fallen off the bus.
Feb 17 13:06:39 regent2 kernel: [51386.809571] NVRM: os_pci_init_handle: invalid context!
Feb 17 13:06:39 regent2 kernel: [51386.809572] NVRM: os_pci_init_handle: invalid context!
Feb 17 13:06:39 regent2 kernel: [51386.809575] NVRM: GPU at 0000:01:00.0 has fallen off the bus.
Feb 17 13:06:39 regent2 kernel: [51386.809577] NVRM: os_pci_init_handle: invalid context!
Feb 17 13:06:39 regent2 kernel: [51386.809578] NVRM: os_pci_init_handle: invalid context!
Feb 17 13:06:39 regent2 kernel: [51386.859402] NVRM: RmInitAdapter failed! (0x26:0xffffffff:1183)
Feb 17 13:06:39 regent2 kernel: [51386.859410] NVRM: rm_init_adapter(0) failed
Feb 17 13:06:56 regent2 kernel: [51402.950516] bbswitch: enabling discrete graphics
Feb 17 13:06:56 regent2 kernel: [51402.950529] nvidia 0000:01:00.0: power state changed by ACPI to D0
Feb 17 13:06:56 regent2 kernel: [51402.966322] nvidia 0000:01:00.0: Refused to change power state, currently in D3
Feb 17 13:06:56 regent2 kernel: [51402.966336] nvidia 0000:01:00.0: power state changed by ACPI to D0