Jun 15 2009

Ruby and CUDA and Thrust, Oh My!

Thought I would have a bit of fun to see if I could get CUDA and Thrust working with Ruby. Since no CUDA bindings exist, and I didn’t want to give up the power of Thrust, I decided to emply RubyInline to create wrappers. Got it a nice little demo working in under 30 minutes.

vectors.cu

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
 
#include <iostream>
 
#include "vector_test.h"
 
extern "C" int vector_test() {
   thrust::host_vector H(4);
   H[0] = 14;
   H[1] = 20;
   H[2] = 38;
   H[3] = 46;
 
   std::cout << "H has size "<< H.size() << std::endl;
 
   for(int i = 0; i < H.size(); i++)
      std::cout << "H[" << i << "] = " << H[i] << std::endl;
 
   H.resize(2);
 
   std::cout << "H now has size " << H.size() << std::endl;
 
   thrust::device_vector D = H;
 
   D[0] = 99;
   D[1] = 88;
 
   for(int i = 0; i < D.size(); i++)
      std::cout << "D[" << i << "] = " << D[i] << std::endl;
 
   return 0;
}

vector_test.h

extern "C" int vector_test();

Compile a shared library: nvcc –shared -o libvectors.so vectors.cu -I/usr/local/cuda/include -L/usr/local/cuda/lib -lcudart

cuda_inline.rb

require 'rubygems'
require 'inline'
 
class MyWrapper
   inline(:C) do |builder|
      builder.include '"vector_test.h"'
      builder.add_compile_flags '-x c++', '-lstdc++', '-L/usr/local/cuda/lib', '-L.', '-lvectors', '-I.'
      builder.c '
         void wrapper() {
            vector_test();
         }'
   end
end
t = MyWrapper.new()
t.wrapper

Note here that I have to specify for RubyInline to look in the current directory for headers and libraries!

So, as long as libvectors.so and vector_test.h is in the directory you are running cuda_inline.rb from, everything is gravy! Maybe not the most efficient tool-chain, but it works!

$ ruby cuda_inline.rb
ld warning: in ./libvectors.so, file is not of required architecture
H has size 4
H[0] = 14
H[1] = 20
H[2] = 38
H[3] = 46
H now has size 2
D[0] = 99
D[1] = 88

  • Share/Bookmark