Category: Image processing / Machine vision

Background Story

For a project I’ve been working on, the need came to build the program to run on Windows OS. The project was written in c++ and used OpenCV and Boost libraries. For ease of configuration I employed CMake.

Despite the target being Windows, I was developing and testing everything under GNU/Linux 😛 , fortunately I managed to write the code with minimal amount of native unix API calls. For example, file handling was done via Boost Filesystem and so on.

Therefore the only consideration was running the CMake script in windows, using Visual Studio or GCC (via MinGW). First attempt was done with VS 2013, but compilation failed with a bug of VS c++ compiler related to c++ template classes and getting a later version was taking time. So I gave a try for gcc on windows!

Objectives

First I wanted to see if c++ building on windows with relative ease is possible. Next, I wanted to avoid the dependency of Visual Studio for the matter. This might be specially useful if you code for commercial work, but cannot afford to buy the license or simply dislike Visual Studio 😛

Step 1. Install MinGW

I went for MinGW-w64 (http://mingw-w64.org/doku.php) build since its more accepted and supports 64 bit. (Don’t expect citations justifying this 😀 ).

The workaround may clash with existing “make” executable in the PATH. So take care!!

When configuring Boost, “c1 is not recognized as an internal command”

Cause : Not specifying toolchain when executing bootstrap.bat and b2.exe

Windows shows errors “libboost_system_xx_mingw_xx.dll” is not installed or “libopencv_imgproc310.dll is not installed” or similar errors

Cause : Windows cannot locate the DLL files.

Simplest fix is just copying the necessary DLL files and package them when distributing.

Warning : Always check legal matters (license agreement) before packing libraries that are not owned by you. Even if the libraries are open source, the license type may restrict distribution in binary format like this.

Follow the guide at http://docs.nvidia.com/cuda/cuda-getting-started-guide-for-linux/#axzz43DrWGyFP

They’ll replace ubuntu driver with their version (352.79 instead of 352.68 in my case)

Warning 1 :Do not reboot right now, otherwise you may come to a black screen and will have to boot from a live cd and chroot !! From my experience you have to run gpu-manager manually (explained below)

Warning 2: nvidia-prime will set nvidia chipset as the default** This doesn’t work very well and consume power (caused kde to crash with multiple monitors, strange font sizes, etc).

Use nvidia-settings and set intel as the primary chipset.

Login from the command line (alt + ctrl +f1);

Run the following commands, first will stop the DM (sddm for kubuntu, kde dropped KDM since kde 5) second will run gpu-manager that’ll go through the configuration.

sudo systemctl stop sddm

sudo gpu-manager

Observe the output of gpu-manager. Now you can reboot and see the results.

I prefer to use cmake script for OpenCV projects so I’ll explain that method. Other options are easily found on internet.

If you observe closely, the compatibility matrix shown at nvidia website, maximum supported gcc version at this time is 4.9 with CUDA 7.5 Now the issue is Ubuntu 15.10 have gcc 5+.

So the first fix had to be install gcc 4.9 and point nvcc to gcc 4.9. In cMake scripts, the following declarations worked for me. In addition I had to specify some more info. Some people suggest editing nvcc.profile but I didn’t bother, I was already using cmake for the opencv projects!

The first two lines found via opencv cmake config and the third had to be added after cmake complained “missing CUDA_CUDART_LIBRARY”.

Now everything should work fine;

If you get “invalid device ordinal” when running CUDA apps, the reason is the driver seems not to load properly on resuming from sleep. Dmesg will show this as “gpu falling off the bus”. Currently I couldn’t find a fix for the matter, I guess editing the config of nvidia-primus or bumblebee may help.

Some history without dates 😛

Initially the only solution for graphics switching and keeping the nvidia chipset from overheating or acting strange required some hacking of ACPI calls. Then this project called Bumblebee emerged (http://bumblebee-project.org/). Thanks for the bumblebee daemon, it was possible to have proper power management. Some time later, they released a kernel module called “bbswitch”. This module make life even easier by automatically enabling power management.

Since the beginning I went with bumblebee + nvidia propriatery drivers, so as usual I went that way with ubuntu.

By now, Nvidia has released their version of optimus switching for Linux, the package is known as nvidia-prime. In past, the only alternative was bumblebee. I’m yet to see which works better, but I’m not much concerned as the only use of nvidia in linux is for CUDA based stuff. On windows however, it sees enough action ;).