如何使用 FFI 将二维向量从 Rust 传递到 Fortran?
How to pass 2D Vector from Rust to Fortran with FFI?
我正在尝试将 2D f64 向量 (Vec) 从 Rust 传递到 Fortran 函数。我一直在使用 .as_mut_ptr().
将一维向量与其他 Fortran 函数一起使用
我不完全确定如何 post 像这样的最小工作示例,但我们开始吧:
extern "C" {
fn fortran1_(
vector: *mut f64,
length1: *const uint32_t
);
fn fortran2_(
vector: *mut f64,
length1: *const uint32_t,
length2: *const uint32_t
);
}
pub fn fortran1(
length1: u32
) -> Vec<f64>{
let mut vector = vec![0_f64; length1];
unsafe{
fortran1_(
vector.as_mut_ptr(),
&length1)
}
return vector;
}
pub fn fortran2(
length1: u32,
length2: u32
)-> Vec<Vec<f64>>{
let mut vector = vec![vec![0_f64; length1]; length2];
unsafe{
fortran2_(vector.as_mut_ptr(),
&length1,
&length2)
}
return vector;
}
谢谢
您的 Rust Vec<Vec<_>>
表示与 Fortran 的标准数据模型之间存在大量不匹配。
Fortran 期望二维数组布置在 f64
的连续切片中,但 Vec<Vec<_>>
将其每一行放在单独的堆分配中。
Fortran 索引从 1 开始,但 Vec
从 0 开始。
您最好实施 struct Fortran2d<T> { vec: Vec<T>, rows: usize, cols:usize, }
并在该模拟 Fortran 索引上实施方法。我认为那是最不痛苦的。
impl Fortran2d<T> {
/// maps fortran style 2d index to internal vec index
fn index(&self, c: usize, r: usize) -> usize {
assert!(c > 0 && c <= self.cols);
assert!(r > 0 && r <= self.rows);
(c - 1) + (r - 1) * self.cols
}
}
我正在尝试将 2D f64 向量 (Vec
我不完全确定如何 post 像这样的最小工作示例,但我们开始吧:
extern "C" {
fn fortran1_(
vector: *mut f64,
length1: *const uint32_t
);
fn fortran2_(
vector: *mut f64,
length1: *const uint32_t,
length2: *const uint32_t
);
}
pub fn fortran1(
length1: u32
) -> Vec<f64>{
let mut vector = vec![0_f64; length1];
unsafe{
fortran1_(
vector.as_mut_ptr(),
&length1)
}
return vector;
}
pub fn fortran2(
length1: u32,
length2: u32
)-> Vec<Vec<f64>>{
let mut vector = vec![vec![0_f64; length1]; length2];
unsafe{
fortran2_(vector.as_mut_ptr(),
&length1,
&length2)
}
return vector;
}
谢谢
您的 Rust Vec<Vec<_>>
表示与 Fortran 的标准数据模型之间存在大量不匹配。
Fortran 期望二维数组布置在 f64
的连续切片中,但 Vec<Vec<_>>
将其每一行放在单独的堆分配中。
Fortran 索引从 1 开始,但 Vec
从 0 开始。
您最好实施 struct Fortran2d<T> { vec: Vec<T>, rows: usize, cols:usize, }
并在该模拟 Fortran 索引上实施方法。我认为那是最不痛苦的。
impl Fortran2d<T> {
/// maps fortran style 2d index to internal vec index
fn index(&self, c: usize, r: usize) -> usize {
assert!(c > 0 && c <= self.cols);
assert!(r > 0 && r <= self.rows);
(c - 1) + (r - 1) * self.cols
}
}