Exemple ndarray
Pour donner un aperçu de l’API ndarray, voici un produit de matrice basique :
use ndarray::prelude::*;
let x = array![[1.2, 3.4],
[5.6, 7.8],
[9.1, 2.3]];
let y = array![[0.0, 0.1, 0.2],
[1.0, 1.1, 1.2]];
let mut out = Array2::<f64>::zeros((3, 3));
// ndarray fournit sa propre API d'itération optimisée...
azip!((mut out_row in out.rows_mut(), x_row in x.rows()) {
// ...mais on peut aussi itérer de façon standard
for (out_elem, y_col) in out_row.iter_mut().zip(y.columns()) {
*out_elem = x_row.dot(&y_col);
}
});
Bien sûr, ceci n’est qu’une démo d’API, n’implémentez jamais matmul
comme
ça :
- Accès inefficace aux colonnes de y (éléments espacés)
- SIMD inexistant (conséquence du point précédent)
- Cache CPU mal utilisé sur les grandes matrices (pas de blocking)
- Exécution séquentielle sur un seul coeur CPU
- …alors qu’il suffit d’un
x.dot(&y)
pour confier tout ce travail à un BLAS !