Speeding up R with multicore and gputools

multicore and gputools are two R packages that allow for some limited "quick & dirty" parallel processing from within R.  Using both packages I was able to exploit my Macbook's dual core processor and built in GPU to reduce run times for certain computationally intensive tasks.   This is a brief wiki on how go about setting them up.

Multi-core processing in R.

There are various packages out there, most notably snow and it's wrapper snowfall, that enable feature-rich parallel computing in R.  In contrast we will only focus on the relatively simple multicore package which essentially makes use of multiple cores through a single function mclapply.  This function is a parallelized version of lapply.  Getting started with multicore is quite simple, just install the package as usual.  However, there is no Windows binary version, so if you want to use the package in Windows you have to build from source on a PC, something I cannot help you with.

Calling mclapply is easy.  Consider the following example of calculating the distance matrix of 2^10 vectors each of length 2^10.
 
> set.seed(5446)
> p <- 20
> X <- matrix(rnorm(2^p),ncol = 2^(p/2))
>
> lfun <- function(i){
+   d <- dist(X) 
+ }
>
> system.time(res <- lapply(1:4,lfun))
   user  system elapsed
 80.062   0.199  81.204
> system.time(mcres <- mclapply(1:4,lfun))
   user  system elapsed
 57.896   0.294  61.507

As you can see, computing time is reduced by roughly 25% for this particular task.  It goes without saying there are a few more options in mclapply, but in general this is how it works with multicore.  Consult the package documentation for further details.

GPU computing with R - Mac

Computing on a GPU (rather than CPU) can dramatically reduce computation time.  For more info on general purpose GPU computing and its advantages see gpgpu.org

CUDA™, CUBLAS™ and gputools

The NVIDIAŽ CUDA (compute unified device architecture) driver allows access to the computational resources of NVIDIA GPUs.  CUBLAS (CU basic linear algebra subprograms) are libraries of linear algebra routines optimized for use with CUDA. 

The R package gputools provides several functions for fast computation on GPUs, most of them are wrappers for CUBLAS.   One can drastically improve R computation times using the GPU optimized functions in gputools.  Alternitavely, one can work directly in C++ utilizing the CUBLAS libraries and NVIDIA's CUDA toolkit.  Go here for lots of information on CUDA and NVIDIA's tools for GPU computing. 

Setup Information

The steps here were performed on a mid 2010 13" Macbook pro running OS 10.6.8.  This particular Macbook shipped with an integrated NIVIDA GeForce 320M GPU (48 cores).  Setting up your GPU on Unix/Linux is done in a very similar fashion. I'm not sure about Windows, you may want to review the documentation on getting started with CUDA for a possible solution.  The gputools package is currently not available for Windows.

Essentially what you need

Installation of the CUDA software

Follow the detailed instructions in CUDA_Getting_Started_Mac.pdf.  The process did not take me long and the instructions are well written.  Below are some notes about my install:

  1. Installed  gcc C compiler and toolchain via Xcode.  Installing Xcode installs gcc and toolchain automatically. If you are running Lion (OS 10.7.x), Xcode 4 is available as a free download from the Apple's app store.  Since I have Leopard (OS 10.6.8) I had to first register on Apple's developer site, then was able to access a free download of Xcode 3.  Xcode is large (>14 Gb) but once downloaded and installed, I was able to verify the installation of gcc using the command  /usr/bin/gcc --help in the terminal.

  2. Download and install CUDA software.  This was very straightfoward.  Just download free software from NVIDIA website and install per instructions.  After installation I was able to verify my GPU was CUDA enabeled
GPU deviceQuery

Installing gputools package

Binaries for gputools are currently not available.  It is necessary to build the package from source.  Download the source file gputools_x.xx.tar.gz from CRAN. From the terminal cd to the corresponding directory and run

 R CMD INSTALL gputools_x.xx.tar.gz --build

which builds and installs the package.  This was all I needed to do.

A simple example

It appears GPU processing vastly improves computation time.  The syntax for most functions in the gputools package mimic those in the base installation of R and they are called by prefixing "gpu" to the function.  For instance the gputools version of dist is gpuDist.  In the following R example, I calculate the distance matrix based on 2^10 vectors each of length 2^10. 


library(gputools)

set.seed(5446)
p <- 20
X <- matrix(rnorm(2^p),ncol = 2^(p/2))

system.time(d <- dist(X))
system.time(d <- gpuDist(X))


Here is the R output

> system.time(d <- dist(X))
   user  system elapsed
 23.432   0.032  23.529
> system.time(gpud <- gpuDist(X))
   user  system elapsed
  1.255   0.040   2.737


As you can see there is quite an improvement in computation time.  There is one glaring flaw in the gpu implementation in that the precision is poor

> max(abs(c(d) - c(gpud)))
[1] 9.710027e-06

I do not know if the discrepancy is hardware related or an artifact of either the gputools implementation or CUBLAS.