Ruby(2.0)c扩展从c函数返回数组的数组
我正在编写一个Ruby c扩展来使用Ruby(2.0)c扩展从c函数返回数组的数组,c,ruby,ruby-c-extension,C,Ruby,Ruby C Extension,我正在编写一个Ruby c扩展来使用Acceleratemacos框架执行线性代数计算。为了使用所有可用的内核,我还使用了rb\u thread\u call\u without\u gvl来解锁全局VM锁 我不是c专家,所以请容忍我 其想法是创建一个对两个输入矩阵进行操作的ruby方法 VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB) 在这个方法中,我创建了一个struct,然后将其传递给实际函数 void* matmat_
Accelerate
macos
框架执行线性代数计算。为了使用所有可用的内核,我还使用了rb\u thread\u call\u without\u gvl
来解锁全局VM锁
我不是c专家,所以请容忍我
其想法是创建一个对两个输入矩阵进行操作的ruby方法
VALUE matmat_mul(VALUE self, VALUE matrixA, VALUE matrixB)
在这个方法中,我创建了一个struct
,然后将其传递给实际函数
void* matmat_mul_nogvl(void* inputMatricesPtr)
您可以从输出中看到,在c代码中,一切都按照预期工作,但我很难理解如何从c代码返回最终矩阵(数组数组)。最后一个矩阵是nil
。我想我错过了将matC
转换回Ruby对象的部分
这是到目前为止我的代码(有很多调试printf
来验证计算是否正确)
并使用以下ruby代码对其进行测试
require './blasnogvl'
puts "#{Time.now} - Started"
rows = 4
cols = 3
mat = Array.new(rows){Array.new(cols){rand}}
puts "#{Time.now} - Matrix generated"
mat[0] = [0.0, 1.0, 2.0]
mat[1] = [3.0, 4.0, 5.0]
mat[2] = [6.0, 7.0, 8.0]
mat[3] = [6.0, 7.0, 8.0]
puts mat.to_s
matA = mat
matB = mat.transpose
operation = RG::LinearAlgebra::Operation.new
matC = operation.matmat_mul(matA, matB)
puts "After calculation matA is"
puts matA.to_s
puts "After calculation matB is"
puts matB.to_s
puts "matC in ruby is"
puts matC.to_s
puts "#{Time.now} - Matrix calculated"
您的
matmat_mul
函数调用的最终值return Qnil
,这基本上是ruby中的return nil
因此,您需要为矩阵创建ruby数组,创建一个数组来保存每行数据,填充这些行并将它们推入结果数组
首先可以通过
rb_ary_new
实现,但是由于尺寸已经知道,我们可以给ruby一个提示,它将使用rb_ary_new_capa
,大小是多少,然后用rb_ary_push
填充值,这是matmatmat_mul
函数调用的return Qnil
的Array最终值的实现,这在ruby中基本上是return nil
因此,您需要为矩阵创建ruby数组,创建一个数组来保存每行数据,填充这些行并将它们推入结果数组
首先可以通过rb\u ary\u new
来实现,但是由于维度已经知道,我们可以给ruby一个提示,它将使用rb\u ary\u new\u capa
,然后用rb\u ary\u push
填充值,这是数组的一个实现#
require 'mkmf'
extension_name = 'blasnogvl'
have_framework('Accelerate')
create_makefile(extension_name)
require './blasnogvl'
puts "#{Time.now} - Started"
rows = 4
cols = 3
mat = Array.new(rows){Array.new(cols){rand}}
puts "#{Time.now} - Matrix generated"
mat[0] = [0.0, 1.0, 2.0]
mat[1] = [3.0, 4.0, 5.0]
mat[2] = [6.0, 7.0, 8.0]
mat[3] = [6.0, 7.0, 8.0]
puts mat.to_s
matA = mat
matB = mat.transpose
operation = RG::LinearAlgebra::Operation.new
matC = operation.matmat_mul(matA, matB)
puts "After calculation matA is"
puts matA.to_s
puts "After calculation matB is"
puts matB.to_s
puts "matC in ruby is"
puts matC.to_s
puts "#{Time.now} - Matrix calculated"
// Multiplication code above ...
VALUE matrixC = rb_ary_new_capa(rowsC);
for (i = 0; i < rowsC; i++) {
VALUE rowC = rb_ary_new_capa(colsC);
for (j = 0; j < colsC; j++)
rb_ary_push(rowC, DBL2NUM(matC[i * colsC + j]);
rb_ary_push(matrixC, rowC);
}
return matrixC;