Thursday 7 January 2016

Deep Learning: MatConvNet on a 32-bit system

Note: This post is going to be very different from the other ones on my blog, because I want there to be a reference out there in case someone else runs into the same issue I did. So, no detailed background, diving right in.


For whatever reason, you have a 32-bit system with a decent enough graphics card that can handle a deep learning library. In today's day and age, you are a rarity. Most systems are implicitly 64-bit and existing libraries (rightly) do not support 32-bit systems. Welcome to hell.


I have spent considerable time going down dead-ends (problematic installations, unsupported versions, etc.) and backtracking to get GPU-based deep learning work on my system. Unfortunately, I didn't document my steps in a detailed manner, so I am relying on some rudimentary notes, diff and my memory to write the following; there might be oversights or errors.


MatConvNet is a fairly simple deep learning framework, and it is easy to get started doing things right away. Personally, I prefer Caffe, but I inherited some code based around MatConvNet, so went ahead with using it. I used MatConvNet beta v1.17 with Matlab R2014a on a 32-bit Windows 7 system with an NVIDIA NVS4200M graphics card and driver version 354.56 with CUDA v6.5. Compilation was done using the Windows SDK 7.1 (which installs MSVC++ 2010) and NVCC compilers.

The first step is to go ahead and edit the vl_compilenn.m file and add in support for a 32-bit architecture. MatConvNet does not natively support 32-bit systems so this needs to be done by hand. A simple rule-of-thumb is to search for occurrences of win64 and add in clauses for win32 usually just replicating the parameter values from the former.

As an example, opts.imageLibrary selection should look like this:

if isempty(opts.imageLibrary)
    switch arch
        ...
        case 'win64', opts.imageLibrary = 'gdiplus' ;
        case 'win32', opts.imageLibrary = 'gdiplus' ;
    end
end

Similarly, go ahead and add in library path info for your CUDA installation (CUDAROOT/lib/Win32 in my case). I also found that adding the include path of the Windows SDK (SDKROOT\Include in my case) to flags.nvcc and disabling check_clpath() (instead adding --cl-version 2010 -ccbin "MSVCROOT\VC\bin" to nvcc_opts in nvcc_compile()) helps. Finish duplicating parameter values from win64 for win32 architectures wherever necessary.

If you try to compile at this point, you might be lucky and not encounter any issues except a linking error at the tail end. This is because the linker is looking for a static gpu.lib file from Matlab's installation, but cannot find it. For some reason, only the dynamic version gpu.dll seems to be present in MATLABROOT\bin\win32. Use dumpbin and lib from the Windows SDK 7.1 command prompt (in Program Files\Windows SDK 7.1)  and follow the instructions here to generate the static library.

Cross your fingers, and hopefully everything should go off smoothly. Test that everything is working fine using vl_testnn('gpu', 1).

Hope this helps! If you run into issues, please leave a comment below and I'll try to help out if I can.