やりたいこと
rust ndarray
を用いて線形代数や一般的な行列演算を高速に行いたいと思っています。高速に行いたいため、効率よくCPUのコアを使って欲しいと思っています。
やったこと
ndarray
とndarray_linalg
を用いて、行列演算を試験的逆行列を求めるコードかき、top
コマンドでCPUの使用率をモニターしました。
使用したコードは以下です。
rust
1 2use ndarray::{Array2, Array}; 3use ndarray_linalg::InverseInto; 4use ndarray_rand::RandomExt; 5use ndarray_rand::rand_distr::Normal; 6 7fn main() { 8 let a = Array::random((100000,100000), Normal::new(1.,1.).unwrap()); 9 let inv_a = a.inv_into().unwrap(); 10}
結果
CPUの使用率をモニターしたところ100%に張り付いており1コアのみで演算を行っているようにおもいました。
調べたこと
ndarray_linalg
のソースを読んで調べてみたのですが、逆行列を求めている該当の部分に関しては、ndarray-linalg/src/solve.rsの部分だと考えています。
impl<A, S> InverseInto for ArrayBase<S, Ix2> where A: Scalar + Lapack, S: DataMut<Elem = A> + RawDataClone, { type Output = Self; fn inv_into(self) -> Result<Self::Output> { let f = self.factorize_into()?; f.inv_into() } }
とあり、Scalar
かLapack
にinv_into
が実装されていると考えました。そこで、Scalar
はcauchyで実装されているもので、inv_into
が実装されていなさそうだとおもいました。
そのため、Lapack
で逆行列を求めるinv_into
が実装されていると考えました。
Lapack
は/ndarray-linalg/lax/src/lib.rsに実装されておりました。そのため、inv_into
はOperatorNorm_
,
QR_
,SVD_
,SVDDC_
,Solve_
,Solveh_
,Cholesky_
,Eig_
,Eigh_
,Triangular_
,Tridiagonal_
,Rcond_
,LeastSquaresSvdDivideConquer_
のうちのどれかに実装されていそうだと考えました。結局、Solve_
で実装されていると考えました。inv
の実装しか見つからなかったのでinv_into
の中身がどこにあるのかは結局よくわかりませんでした。
また、inv
の中身に関しても、Rust初心者なので理解できませんでした。
結局、なぜマルチスレッドで計算できないのかがよくわかりませんでした。
お答えいただきたいこと
intel_mklを用いて計算しているのであればマルチスレッドで計算されると考えておりました。
なぜマルチスレッドにならないか、どのようにすれば解決するのかを教えていただきたいです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/13 09:46