19 / 20 · Travaux pratiques
Projet final : modèle de vérification N×N à tuiles
Combinez N et K arbitraires avec remplissage et pauses et comparez à une référence indépendante.
Les leçons sont gratuites. Inscrivez-vous pour enregistrer vos progrès.
Assembler le modèle complet
Le projet accepte A de dimensions M×K et B de dimensions K×P sur une grille N×N. Chaque tuile spatiale démarre vide, les opérandes de remplissage sont des zéros valides et les écritures sont masquées par coordonnées. Un seul traitement occupe une tuile et les pauses globales figent le temps logique. La quantification de sortie reste un test distinct après la somme large.
Enregistrez ceci sous capstone-lab.mjs et exécutez node capstone-lab.mjs. Aucun paquet n’est nécessaire. Les entrées sont de petits jeux entiers dans la plage exacte de JavaScript Number ; des plages plus grandes nécessitent BigInt et des vérifications explicites de largeur. Ceci vérifie un modèle arithmétique/d’ordonnancement Node indépendamment d’une exécution RTL ou DDS.
import assert from 'node:assert/strict';
function golden(A,B){return A.map(r=>B[0].map((_,j)=>
r.reduce((s,a,k)=>s+a*B[k][j],0)));}
function solve(A,B,N,pauses=new Set()){
const M=A.length,K=A[0].length,P=B[0].length;
assert.ok(N>=1&&Number.isInteger(N)&&K>=1);assert.equal(B.length,K);
assert.ok(A.every(r=>r.length===K)&&B.every(r=>r.length===P));
const C=Array.from({length:M},()=>Array(P).fill(null));
let advances=0,physical=0;
for(let r0=0;r0<M;r0+=N)for(let c0=0;c0<P;c0+=N){
const job=r0*P+c0;
let g=Array.from({length:N},()=>Array.from({length:N},()=>
({a:null,b:null,acc:0,count:0})));
const token=(value,k)=>({value,k,job});let t=0,p=0;
while(t<K+2*N-2){
if(pauses.has(p)){p++;continue;}
const next=g.map(r=>r.map(pe=>({...pe})));
for(let i=0;i<N;i++)for(let j=0;j<N;j++){
const ka=t-i,kb=t-j;
const a=j?g[i][j-1].a:(ka>=0&&ka<K?
token(r0+i<M?A[r0+i][ka]:0,ka):null);
const b=i?g[i-1][j].b:(kb>=0&&kb<K?
token(c0+j<P?B[kb][c0+j]:0,kb):null);
const pe=next[i][j];pe.a=a;pe.b=b;
if(a&&b){assert.equal(a.job,b.job);assert.equal(a.k,b.k);
assert.equal(a.k,pe.count);pe.acc+=a.value*b.value;pe.count++;}}
g=next;t++;p++;
}
for(let i=0;i<N;i++)for(let j=0;j<N;j++){
assert.equal(g[i][j].count,K);
if(r0+i<M&&c0+j<P){assert.equal(C[r0+i][c0+j],null);
C[r0+i][c0+j]=g[i][j].acc;}}
advances+=t;physical+=p;
}
return {C,advances,physical};
}
const A=[[1,2,3],[4,5,6],[7,8,9]],B=[[1,0,2],[0,1,0],[2,0,1]];
for(const N of [1,2,3])assert.deepEqual(
solve(A,B,N,new Set([1,2])).C,golden(A,B));
const run=solve(A,B,2,new Set([1,2]));
assert.deepEqual(run.C,[[7,2,5],[16,5,14],[25,8,23]]);
assert.equal(run.advances,20);assert.equal(run.physical,28);
assert.deepEqual(solve([[2,-1],[0,3]],[[4,5],[-2,1]],2).C,
[[10,9],[-6,3]]);
assert.deepEqual(solve([[-128]],[[-128]],1).C,[[16384]]);
console.log('Capstone lab passed');La fonction de référence ne connaît que l’arithmétique matricielle. Le solveur déplace indépendamment des jetons étiquetés, vérifie les termes ordonnés et masque les écritures. Pour N=2, quatre tuiles prennent vingt fronts advance. Suspendre les fronts physiques un et deux de chaque tuile ajoute huit pauses, totalisant vingt-huit fronts physiques. Initialisation, chargement mémoire et transfert sérialisé de sortie sont exclus.
Remettez le journal, la trace k consommée d’une tuile, l’analyse de largeur signée et une conception d’enveloppe de résultats valid/ready. Conservez le contrat aux fronts lors du passage en RTL. Commencez par N=1, K=1 et 2×2 avant d’agrandir. Ajoutez quantification, conservation des sommes partielles ou double tampon une à la fois avec de nouvelles vérifications explicites.
Les trois tailles de grille testent des répartitions différentes : N=1 répète des produits scalaires sans décalage, N=2 teste quatre tuiles avec remplissage et N=3 utilise une tuile complète. Toutes doivent produire la même matrice mathématique. Initialiser C à null distingue un zéro valide d’une sortie non livrée et détecte les écritures dupliquées. Le numéro job dérivé de la tuile est ici unique ; le RTL réel doit définir la largeur de son étiquette et sa politique de réutilisation. En extension, essayez M=2, K=3, P=1 avec des valeurs attendues calculées à la main. La grille interne reste carrée tandis que la matrice de sortie est rectangulaire. Vérifiez que chaque tuile consomme tout K et supprime les écritures hors plage.
Essayez vous-même
Pour l’exemple 3×3 avec N=3 et des pauses aux fronts physiques un et deux, trouvez les nombres de fronts advance et physiques. Et si la mesure inclut un front clear précédent ?
Lire l’explication
Il y a sept fronts advance et neuf fronts physiques d’intervalle de calcul avec les deux pauses. Inclure un front clear précédent donne dix ; chargement et transfert de sortie restent exclus.