2013-01-17 8 views
14

Ich bin mir dessen bewusst:Gibt es einen guten OpenCL-Wrapper für Ruby?

https://github.com/lsegal/barracuda

die seit 01/11

Und

nicht aktualisiert

http://rubyforge.org/projects/ruby-opencl/

die seit 03/10 nicht aktualisiert .

Sind diese Projekte tot? Oder haben sie sich einfach nicht geändert, weil ihre Funktionsweise und OpenCL/Ruby sich seitdem nicht geändert haben. Benutzt jemand diese Projekte? Etwas Glück?

Wenn nicht, können Sie ein anderes Opencl Juwel für Ruby empfehlen? Oder wie wird diese Art von Anruf normalerweise gemacht? Rufe einfach rohes C von Ruby auf?

+0

Das sieht noch abgestanden, aber noch eine weitere Option: https://github.com/QaDeS/ffi-opencl – Nevir

+0

Also ich sammle die kurze Antwort ist "Nein" ... –

+0

Nichts mehr [hier] (http://www.khronos.org/opencl/resources), aber der Link kann trotzdem nützlich sein –

Antwort

2

Sie können die C-Funktionalität, die Sie möchten, als Schmuckstück verpacken. Dies ist ziemlich einfach und auf diese Weise können Sie Ihre gesamte c-Logik in einen bestimmten Namespace einfügen, den Sie in anderen Projekten wiederverwenden können.

http://guides.rubygems.org/c-extensions/

+0

Gehen Sie voran und geben Sie das Kopfgeld. Ich will nicht, dass Punkte verschwendet werden, ich ... –

+2

Ja !! - Ich werde dich nie vergessen Abraham P. – jmontross

4

Sie opencl_ruby_ffi versuchen können, ist es aktiv (von einem Kollegen von mir) entwickelt und auch mit OpenCL Version 1.2 arbeiten. OpenCL 2.0 sollte in Kürze verfügbar sein.

sudo gem install opencl_ruby_ffi 

In Khronos forum können Sie ein kurzes Beispiel finden, das zeigt, wie es funktioniert:

require 'opencl_ruby_ffi' 

# select the first platform/device available 
# improve it if you have multiple GPU on your machine 
platform = OpenCL::platforms.first 
device = platform.devices.first 

# prepare the source of GPU kernel 
# this is not Ruby but OpenCL C 
source = <<EOF 
__kernel void addition( float2 alpha, __global const float *x, __global float *y) {\n\ 
    size_t ig = get_global_id(0);\n\ 
    y[ig] = (alpha.s0 + alpha.s1 + x[ig])*0.3333333333333333333f;\n\ 
} 
EOF 

# configure OpenCL environment, refer to OCL API if necessary 
context = OpenCL::create_context(device) 
queue = context.create_command_queue(device, :properties => OpenCL::CommandQueue::PROFILING_ENABLE) 

# create and compile the OpenCL C source code 
prog = context.create_program_with_source(source) 
prog.build 

# allocate CPU (=RAM) buffers and 
# fill the input one with random values 
a_in = NArray.sfloat(65536).random(1.0) 
a_out = NArray.sfloat(65536) 

# allocate GPU buffers matching the CPU ones 
b_in = context.create_buffer(a_in.size * a_in.element_size, :flags => OpenCL::Mem::COPY_HOST_PTR, :host_ptr => a_in) 
b_out = context.create_buffer(a_out.size * a_out.element_size) 

# create a constant pair of float 
f = OpenCL::Float2::new(3.0,2.0) 

# trigger the execution of kernel 'addition' on 128 cores 
event = prog.addition(queue, [65536], f, b_in, b_out, 
         :local_work_size => [128]) 
# #Or if you want to be more OpenCL like: 
# k = prog.create_kernel("addition") 
# k.set_arg(0, f) 
# k.set_arg(1, b_in) 
# k.set_arg(2, b_out) 
# event = queue.enqueue_NDrange_kernel(k, [65536],:local_work_size => [128]) 

# tell OCL to transfer the content GPU buffer b_out 
# to the CPU memory (a_out), but only after `event` (= kernel execution) 
# has completed 
queue.enqueue_read_buffer(b_out, a_out, :event_wait_list => [event]) 

# wait for everything in the command queue to finish 
queue.finish 
# now a_out contains the result of the addition performed on the GPU 

# add some cleanup here ... 

# verify that the computation went well 
diff = (a_in - a_out*3.0) 
65536.times { |i| 
    raise "Computation error #{i} : #{diff[i]+f.s0+f.s1}" if (diff[i]+f.s0+f.s1).abs > 0.00001 
} 
puts "Success!" 
+0

Ist es möglich, ein bisschen mehr darüber zu erzählen, was hier passiert? Wo kann ich die tatsächlich hinzugefügten Werte auslesen? – Automatico

+0

Ich habe den Quellcode kommentiert, das Ergebnis der Addition wird aus dem GPU-Speicher mit der Operation 'queue.enqueue_read_buffer' abgerufen. Es gibt viele (C) OpenCL-Tutorials, die im Internet verfügbar sind. Es sollte ziemlich einfach sein, in Ruby zu übersetzen, sobald Sie den Kern der API gefunden haben. – Kevin

+0

Vielen Dank! :) – Automatico

Verwandte Themen