Automatisation du cycle de vie des opérateurs
La suite oam-tools est un ensemble d'utilitaires conçu pour rationaliser le développement d'opérateurs sur l'architecture Ascend. Elle permet de remplacer la rédaction manuelle de code boilerplate par une approche déclarative, tout en garantissant la conformité aux standards de la communauté CANN et en facilitant l'analyse comparative des performances.
Module 1 : Génération de squelette de code (oam-generate)
Cet utilitaire transforme une spécification déclarative au format YAML en une structure de projet complète. Il génère l'implémentation C++, les en-têtes, les scripts de compilation CMake, ainsi que les squelettes de tests unitaires et de benchmark.
Spécification déclarative
Voici un exemple de fichier de configuration pour une opération de multiplication matricielle :
# kernel_spec.yaml
kernel_definition:
identifier: "MatMulKernel"
input_tensors:
- alias: "left_matrix"
precision: "fp16"
dimensions: ["dim_M", "dim_K"]
- alias: "right_matrix"
precision: "fp16"
dimensions: ["dim_K", "dim_N"]
output_tensors:
- alias: "result_matrix"
precision: "fp16"
dimensions: ["dim_M", "dim_N"]
execution_graph:
operation: "matrix_multiplication"
sources: ["left_matrix", "right_matrix"]
target: "result_matrix"
Exécution et arborescence
La génération s'effectue via la ligne de commande suivante :
oam-generate --spec kernel_spec.yaml --dest ./generated_kernel
Le résultat est une arborescence standardisée :
generated_kernel/
├── MatMulKernel.cpp # Implémentation du noyau
├── MatMulKernel.h # Déclarations des interfaces
├── CMakeLists.txt # Configuration de la compilation
├── test_matmul.cpp # Squelette de test unitaire
└── bench_matmul.cpp # Squelette de test de performance
Implémentation de la logique de calcul
Le dévelopepur doit ensuite remplir la fonction de calcul. Voici une approche optimisée utilisant le tuilage (tiling) :
// Extrait de MatMulKernel.cpp
void MatMulKernel::ExecuteCompute() {
// Récupération des tenseurs locaux
auto lhs_data = this->inputTensors[0].template Get<LocalTensor<AscendC::fp16>>();
auto rhs_data = this->inputTensors[1].template Get<LocalTensor<AscendC::fp16>>();
auto res_data = this->outputTensors[0].template Get<LocalTensor<AscendC::fp16>>();
// Extraction des dimensions globales
uint32_t total_m = lhs_data.GetShape()[0];
uint32_t total_k = lhs_data.GetShape()[1];
uint32_t total_n = rhs_data.GetShape()[1];
// Paramétrage des blocs de tuilage
const uint32_t block_m = 256;
const uint32_t block_n = 256;
const uint32_t block_k = 128;
// Itération par blocs pour optimiser l'utilisation de la mémoire SRAM
for (uint32_t idx_m = 0; idx_m < total_m; idx_m += block_m) {
for (uint32_t idx_n = 0; idx_n < total_n; idx_n += block_n) {
auto lhs_block = lhs_data.Slice(idx_m, block_m, 0, total_k);
auto rhs_block = rhs_data.Slice(0, total_k, idx_n, block_n);
auto res_block = res_data.Slice(idx_m, block_m, idx_n, block_n);
// Appel de l'instruction matérielle
AscendC::MatMul(lhs_block, rhs_block, res_block);
AscendC::SetFlag(); // Synchronisation du pipeline
}
}
}
Module 2 : Analyse statique et conformité (oam-lint)
Le compilateur CANN impose des règles strictes concernant l'alignement mémoire, le nommage et la documentation. L'outil oam-lint valide le code source avant la soumisison.
oam-lint --target ./generated_kernel/MatMulKernel.cpp --strict
Exemple de rapport d'analyse :
[INFO] Analyse de la conformite CANN...
[OK] Alignement memoire (256-octets detecte)
[OK] Convention de nommage (lhs_block, rhs_block)
[ERR] Documentation Doxygen absente pour ExecuteCompute()
[ERR] Depassement de la limite de caracteres (Ligne 42: 120 chars)
Score de conformite: 50% (2 OK, 2 ERR)
Module 3 : Évaluation comparative des performances (oam-bench)
Cet outil automatise l'exécution de l'opérateur sur le matériel NPU et compare les résultats avec les implémentations officielles de la bibliothèque CANN.
Configuration du benchmark
# bench_config.yaml
target_kernel: "MatMulKernel"
test_matrix:
- dims: [512, 512, 512]
- dims: [1024, 1024, 1024]
- dims: [2048, 2048, 2048]
data_type: "fp16"
iterations: 200
baseline: "cann_official"
Exécution et rapport
oam-bench --config bench_config.yaml --output ./perf_report
Le rapport généré au format Markdown présente les écarts de latence :
| Dimensions (MxKxN) | Baseline CANN (ms) | Implemantation Actuelle (ms) | Delta |
|---|---|---|---|
| 512x512x512 | 1.8 | 2.1 | +16% |
| 1024x1024x1024 | 6.5 | 7.2 | +10% |
| 2048x2048x2048 | 28.4 | 29.1 | +2% |
Note : L'exécution de ce module nécessite impérativement un environnement matériel NPU.
Workflow de contribution et extension
L'architecture de oam-tools supporte l'ajout de plugins personnalisés (en Python ou C++). Le processus de soumission de correctifs ou de nouvelles fonctionnalités suit le standard Git :
# Clonage et isolation de la branche de travail
git clone https://atomgit.com/cann/oam-tools.git
cd oam-tools
git checkout -b enhancement/custom-lint-rule
# Execution de la suite de tests locale
pytest tests/unit/
bash tests/hardware/integration.sh
# Validation et poussée des modifications
git add .
git commit -m "feat(lint): add custom memory alignment rule"
git push origin enhancement/custom-lint-rule
Une fois la demande de fusion (Merge Request) créée, le comité technique CANN évalue la conformité du plugin avant son intégration dans la branche principale.