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