有没有适用于Ruby的好的OpenCL封装?

14

我了解到:

https://github.com/lsegal/barracuda

从2011年之后就没有更新过。

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

从2010年之后就没有更新过。

这些项目已经死了吗?还是它们一直没有变化,因为它们的功能和OpenCL/Ruby自那时以来也没有变化。是否有人在使用这些项目?有运气吗?

如果没有,你能推荐另一个适用于Ruby的opencl gem吗?或者通常如何进行此类调用?只需从Ruby中调用原始C代码吗?


这看起来更加陈旧,但另一个选项是:https://github.com/QaDeS/ffi-opencl - Nevir
所以我收集到的簡短回答是“不”。 - Abraham P
这里没有更多内容,但链接可能仍然有用。请点击此处查看:http://www.khronos.org/opencl/resources - user1220978
自己做好之后再发回来... :) - rogerdpack
还有一个 ruby ffi opencl gem,它是通过 swig 自动生成的。https://github.com/sempervictus/ffi-opencl - Bjoern Rennhak
3个回答

4
你可以尝试使用opencl_ruby_ffi,它是由我的一位同事积极开发的,并且已经与OpenCL 1.2版本良好地配合。OpenCL 2.0也应该很快会推出。
sudo gem install opencl_ruby_ffi

在Khronos论坛上,您可以找到一个快速示例,展示了它的工作原理:

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!"

能否再详细解释一下这里正在发生什么?我在哪里可以读取到实际添加的值等信息? - Automatico
我已经对源代码进行了注释,加法的结果是通过操作queue.enqueue_read_buffer从GPU内存中检索出来的。网络上有很多(C)OpenCL教程可用,一旦你掌握了API的要点,将其翻译成Ruby应该相当容易。 - Kevin

2
您可以将您希望的C语言功能打包成一个gem。这很简单,这样您就可以将所有C语言逻辑封装在特定的命名空间中,以便在其他项目中重复使用。 http://guides.rubygems.org/c-extensions/

我会直接给你赏金。我可不想让积分浪费了…… - Abraham P
2
是的!!- 我永远不会忘记你亚伯拉罕P. - jmontross

0
如果你想要使用GPU进行高速计算,Cumo / NArray是一个不错的选择。Cumo与NArray具有相同的接口。尽管它是基于cuda而不是opencl。

https://github.com/sonots/cumo


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接