我正在尝试使用小提琴在Ruby中定义Tinn C lib,但是它给了我一个结构错误
Tinn.h
import numpy as np
np.matmul(matrix_2, vector_2)
Out[ ]:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-752f945775e1> in <module>()
----> 1 np.matmul(matrix_2, vector_2)
ValueError: shapes (3,2) and (3,) not aligned: 2 (dim 1) != 3 (dim 0)
Ruby小提琴
typedef struct
{
// All the weights.
float* w;
// Hidden to output layer weights.
float* x;
// Biases.
float* b;
// Hidden layer.
float* h;
// Output layer.
float* o;
// Number of biases - always two - Tinn only supports a single hidden layer.
int nb;
// Number of weights.
int nw;
// Number of inputs.
int nips;
// Number of hidden neurons.
int nhid;
// Number of outputs.
int nops;
}
Tinn;
float* xtpredict(Tinn, const float* in);
float xttrain(Tinn, const float* in, const float* tg, float rate);
Tinn xtbuild(int nips, int nhid, int nops);
我正在犯这样的错误
module Tinn
extend Fiddle::Importer
dlload './tinn.so'
Tinn = struct [
# All the weights.
'float* w',
# Hidden to output layer weights.
'float* x',
# Biases.
'float* b',
# Hidden layer.
'float* h',
# Output layer.
'float* o',
# Number of biases - always two - Tinn only supports a single hidden layer.
'int nb',
# Number of weights.
'int nw',
# Number of inputs.
'int nips',
# Number of hidden neurons.
'int nhid',
# Number of outputs.
'int nops'
]
extern 'float* xtpredict(Tinn, const float* in)'
extern 'float xttrain(Tinn, const float* in, const float* tg, float rate)'
extern 'Tinn xtbuild(int nips, int nhid, int nops)'
end
第31行指向我们传递struct作为参数的第一个函数
/home/arjun/.rbenv/versions/2.3.3/lib/ruby/2.3.0/fiddle/cparser.rb:177:in `parse_ctype': unknown type: Tinn (Fiddle::DLError)
from /home/arjun/.rbenv/versions/2.3.3/lib/ruby/2.3.0/fiddle/cparser.rb:90:in `block in parse_signature'
from /home/arjun/.rbenv/versions/2.3.3/lib/ruby/2.3.0/fiddle/cparser.rb:90:in `collect'
from /home/arjun/.rbenv/versions/2.3.3/lib/ruby/2.3.0/fiddle/cparser.rb:90:in `parse_signature'
from /home/arjun/.rbenv/versions/2.3.3/lib/ruby/2.3.0/fiddle/import.rb:163:in `extern'
from rb_tinn.rb:31:in `<module:Tinn>'
from rb_tinn.rb:4:in `<main>'
我已经将Tinn定义为结构,但它仍然是错误。
答案 0 :(得分:3)
在Ruby中使用Fiddle的结构作为其C对应物的直接类似物,会产生误导。在Ruby表示中缺少使结构简单和用户友好的许多功能。
要记住的主要原则是Fiddle::CStruct
实际上只是美化的Fiddle::Pointer
,实际上是它的子类。主要限制是您只能在其中声明基本类型。与C语言中定义结构不同,您可以将其用作其他结构中的类型,返回值等。
尽管有关该问题的文档还很少,但这仍然可以在Ruby中完成。如前所述,请记住,Ruby结构是从Fiddle::Pointer
派生的,您只需在签名声明中使用void*
(或Fiddle::TYPE_VOIDP
取决于您是否在使用CParser) 。
在上面的示例中,一旦声明了结构,就可以这样定义方法签名:
float* xtpredict(void* tinn, const float* in)
用void*
代替结构类型,而不是类型名称,然后可以将结构直接传递给它,并获得所需的预期行为。
从方法返回结构的方法相同。再次在签名中使用void*
,然后Ruby将其返回一个Fiddle::Pointer
对象。该指针包含该结构在内存中的地址。由于结构体会在其initialize方法中获取地址,因此请使用返回的指针来初始化您的结构体,它将在内存中的该位置创建。
ptr = getMyStruct
MyStruct.new(ptr.to_i)
相反,如果记忆正确,我相信您也可以像这样使用它:
ptr = getMyStruct
MyStruct.new(ptr.ptr)