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 !