Tema 3

  • Deadline soft: 23 mai 2024, ora 23:55.
  • Primiți un bonus de 10% din punctajul obținut pentru trimiterea temei înainte de 20 mai 2024, ora 23:55.
  • Deadline hard: 26 mai 2024, ora 23:55.
  • Veți primi o depunctare de 10% din punctajul maxim al temei pentru fiecare zi de întârziere (după 23 mai), până la maxim 3 zile, adică până pe 26 mai 2024, ora 23:55.

  • Dată publicare: 10 mai 2024
  • Dată actualizare enunț: 23 mai 2024

Enunț

Se dă următoarea operație cu matrice:

$$ C = (A^t \times B + B \times A) \times B^t $$

unde:

  • $A$ si $B$ sunt matrice pătratice de dimensiune N x N, cu elemente de tip double
  • $A$ este o matrice superior triunghiulară
  • $A^t$ este transpusa lui $A$ și $B^t$ este transpusa lui $B$
  • $\times$ este operația de înmulțire
  • $+$ este operația de adunare

Se dorește implementarea expresiei de mai sus folosind limbajele C/C++, în 3 moduri:

  • blas - o variantă care folosește una sau mai multe funcții din BLAS Atlas pentru realizarea operațiilor de înmulțire și adunare.
  • neopt - o variantă “de mână” fără îmbunătățiri.
  • opt_m - o variantă îmbunătățită a versiunii neopt. Îmbunătățirea are în vedere exclusiv modificarea codului pentru a obține performanțe mai bune.

Fiecare din cele 3 implementări de mai sus va ține cont de faptul că A este o matrice superior triunghiulară.

Rulare și testare

Pentru testarea temei vă este oferit un schelet de cod pe care trebuie să-l completați cu implementările celor 3 variante menționate mai sus. Scheletul de cod este structurat astfel:

  • main.c - conține funcția main, precum și alte funcții folosite pentru citirea fișierului cu descrierea testelor, scrierea matricei rezultat într-un fișier, generarea datelor de intrare și rularea unui test. Acest fișier va fi suprascris în timpul corectării și nu trebuie modificat.
  • utils.h - fișier header. Acest fișier va fi suprascris în timpul corectării și nu trebuie modificat.
  • solver_blas.c - în acest fișier trebuie să adăugați implementarea variantei blas.
  • solver_neopt.c - în acest fișier trebuie să adăugați implementarea variantei neopt.
  • solver_opt.c - în acest fișier trebuie să adăugați implementarea variantei opt_m.
  • Makefile - Makefile folosit la compilarea cu gcc. Acest fișier va fi suprascris în timpul corectării și nu trebuie modificat.
  • compare.c - utilitar ce poate fi folosit pentru a compara două fisiere rezultat. Acest fișier va fi suprascris în timpul corectării și nu trebuie modificat.

Puteți aduce orice modificare scheletului de cod exceptând cele 3 fișiere menționate mai sus.

În urma rulării comenzii make vor rezulta 3 fișere binare, tema3_blas, tema3_neopt și tema3_opt_m corespunzătoare celor 3 variante care trebuie implementate.

Rularea se va realiza astfel:

./tema3_<mod> input 

unde:

  • mod este unul din modurile blas, neopt, opt_m
  • input este fișierul ce contine descrierea testelor.

Fișierul input este structurat astfel:

  • pe prima linie se află numărul de teste.
  • pe următoarele linii se regăsește descrierea fiecărui test:
    • valoarea lui N.
    • seed-ul folosit la generarea datelor.
    • calea către fișierul de ieșire ce conține matricea rezultat.

Rularea se va face pe partiția haswell folosind sbatch. Compilarea se va face folosind gcc-8.5.0.

Pentru a vedea cat de incarcate sunt nodurile puteti folosi scontrol:

[vlad.spoiala@fep8 sol]$ for node in haswell-wn{29..40}; do echo -n $node; scontrol show node $node | grep CPU; done
haswell-wn29   CPUAlloc=20 CPUTot=32 CPULoad=13.62
haswell-wn30   CPUAlloc=18 CPUTot=32 CPULoad=4.19
haswell-wn31   CPUAlloc=18 CPUTot=32 CPULoad=3.76
haswell-wn32   CPUAlloc=18 CPUTot=32 CPULoad=3.79
haswell-wn33   CPUAlloc=18 CPUTot=32 CPULoad=3.76
haswell-wn34   CPUAlloc=18 CPUTot=32 CPULoad=3.79
haswell-wn35   CPUAlloc=18 CPUTot=32 CPULoad=3.75
haswell-wn36   CPUAlloc=18 CPUTot=32 CPULoad=3.88
haswell-wn37   CPUAlloc=18 CPUTot=32 CPULoad=3.76
haswell-wn38   CPUAlloc=18 CPUTot=32 CPULoad=3.87
haswell-wn39   CPUAlloc=18 CPUTot=32 CPULoad=3.95
haswell-wn40   CPUAlloc=18 CPUTot=32 CPULoad=3.47

Pentru a evita rularea pe nodurile incarcate puteti folosi optiunea –exclude din sbatch. De exemplu, pentru a nu rula pe nodurile 29 si 30 putem folosi sbatch in felul urmator:

[vlad.spoiala@fep8 sol]$ sbatch -p haswell --time 00:03:00 --exclude=haswell-wn[29-30] test_all_opt.sh
Submitted batch job 471560

Jobul ruleaza pe haswell-wn31:

[vlad.spoiala@fep8 sol]$ squeue -u vlad.spoiala
             JOBID PARTITION     NAME     USER ST       TIME  NODES NODELIST(REASON)
            471560   haswell test_all vlad.spo  R       0:06      1 haswell-wn31

Testele voastre de performanță trebuie realizate pe partiția haswell deoarece evaluarea temelor se va face pe această partiție.

Fisierul input contine 3 teste:

3
400 123 out1
800 456 out2
1200 789 out3

În cazul fișierului input avem 3 teste pentru urmatoarele valori ale lui N: 400, 800, respectiv 1200. Seed-urile folosite la generarea datelor de intrare sunt 123, 456, respectiv 789. Fișierele de output sunt out1, out2, respectiv out3.

Pentru a fi luată în considerare la punctaj, implementarea trebuie să producă rezultate corecte pe toate cele 3 teste din fișierul input.

Fișierul input_valgrind ce va fi folosit pentru rulările de valgrind contine un singur test:

1
400 123 out1

Punctaj

Punctajul este impărțit astfel:

  • 15p pentru implementarea variantei blas dintre care:
    • 12p dacă implementarea obține rezultate corecte
    • 3p pentru descrierea implementării în README
  • 15p pentru implementarea variantei neopt dintre care:
    • 12p dacă implementarea obține rezultate corecte
    • 3p pentru descrierea implementării în README
  • 20p pentru implementarea variantei opt_m dintre care:
    • 15p dacă implementarea obține rezultate corecte și timpul de calcul pe partiția haswell este mai mic de 10s pentru testul cu N = 1200
    • 5p pentru descrierea implementării în README
  • 9p dacă cele 3 implementări nu prezintă probleme de acces la memorie
    • Pentru a rezolva acest subpunct va trebui să folosiți valgrind cu opțiunile –tool=memcheck –leak-check=full
    • Veți include 3 fișiere, neopt.memory, blas.memory si opt_m.memory, cu output-urile rulării valgrind pentru fiecare din cele 3 variante având ca input fișierul input_valgrind
  • 17p pentru analiza celor 3 implementări folosind cachegrind
    • 6p pentru includerea în arhivă a 3 fisiere, neopt.cache, blas.cache si opt_m.cache reprezentând output-urile rulării valgrind cu optiunile –tool=cachegrind –branch-sim=yes –cache-sim=yes pe partiția haswell având ca input fișierul input_valgrind
    • 6p pentru explicații oferite despre valorile obținute (I refs, D refs, Branches etc.)
    • 5p pentru explicații oferite despre efectul optmizărilor făcute de mână în varianta opt_m asupra valorilor obținute
  • 24p pentru o analiză comparativă a performanței pentru cele 3 variante:
    • 15p pentru realizarea unor grafice relevante bazate pe rularea a cel puțin 5 teste (5 valori diferite ale lui N: adică încă cel puțin două valori diferite de 400, 800 și 1200 pentru N)
    • 9p pentru explicații oferite în README
  • (Bonus)
    • Veți primi un bonus de maxim 10p dacă timpul de calcul pentru varianta opt_m este mai mic de 7s pentru testul cu N = 1200
    • Consultați main.c pentru mai multe detalii
    • Bonusul se calculează doar pe partiția haswell

Depunctări posibile:

  • neopt
    • nu se ține cont de faptul că A este matrice superior triunghiulară (între -3p si -6p)
  • blas:
    • nu se ține cont de faptul că A este matrice superior triunghiulară (intre -3p si -6p)
    • unul sau mai multe calcule sunt realizate de mână, fără a folosi funcții din BLAS (intre -3p si -15p)
    • a fost inclus codul BLAS (fisiere .so, .h., .c și altele) în arhiva temei (-15p)
  • opt_m
    • nu se ține cont de faptul că A este matrice superior triunghiulară (intre -3p si -6p)
    • înmulțirea matricelor se realizează cu o complexitate diferită decât în cazul variantei neopt (ex. Strassen vs înmulțire normală de matrice) (-15p)
    • timpul de calcul este mai mare decât timpul maxim permis - -15p
  • analiza comparativă
    • graficele nu au legendă / unități de măsură (intre -2p si -5p)
    • lipsesc parțial sau complet timpii de rulare (intre -1p si -5p)
    • graficele nu conțin toate datele cerute în enunț (intre -2p si -5p)
  • generale:
    • print-uri de debug în cod (intre -1p si -10p)
    • blocuri de cod comentate sau nefolosite (-1p)
    • warning-uri la compilare (intre -1p si -3p)
    • cod înghesuit/ilizibil (intre -1p si -3p)
    • implementare excesivă de funcții în headere (-1p)
    • folosirea de constante hardcodate (-1p)
    • publicarea temei pe GitHub (-100p)

Precizări încărcare / Moodle

Arhiva temei va fi încărcată pe Moodle.

Structura arhivei va fi următoarea:

src
  solver_blas.c       
  solver_neopt.c      
  solver_opt.c        
  ...           
cache
  blas.cache        
  neopt.cache       
  opt_m.cache       
memory
  opt_m.memory     
  neopt.memory     
  blas.memory   
README
grafice
  ...

La încărcarea pe Moodle vor fi verificate următoarele:

  • corectitudinea rezultatelor pentru cele 3 implementări
  • lipsa problemelor de acces la memorie pentru cele 3 implementări
  • prezența unor fișiere .memory valide
  • prezența unor fișiere .cache valide
  • timpii limita pentru opt_m si bonus

Celelalte aspecte ale temei (README, grafice) vor fi verificate ulterior.

Precizări și recomandări

  • Pentru a simplifica implementarea puteți presupune că N este multiplu de 40 și că este mai mic sau egal cu 1600.
  • În compararea rezultatelor se va permite o eroare absolută de maxim $10^{-3}$.
  • În cazul variantei opt_m complexitatea trebuie să fie aceeași cu cea din varianta neopt.
  • Formatul arhivei trebuie să fie zip.

Pentru a evita aglomerarea cozii se recomandă rularea de teste pentru valori ale lui N mai mici sau egale cu 1600.

Se recomandă ștergerea fișierelor coredump în cazul rulărilor care se termină cu eroare pentru a evita problemele cu spațiul de stocare.

În cazul în care job-urile vă rămân “agățate”, va recomandam să utilizați de pe fep.grid.pub.ro, comanda

 squeue 

pentru a vedea câte job-uri aveți pornite, și apoi să utilizați comanda

scancel <job_id> 

pentru a opri un job.

Pentru întrebări sau nelămuriri legate de temă folosiți forumul temei.

Orice întrebare e recomandat să conțină o descriere cât mai clară a eventualei probleme. Întrebări de forma: “Nu merge X. De ce?” fără o descriere mai amănunțită vor primi un răspuns mai greu.

ATENȚIE să nu postați imagini cu părți din soluția voastră pe forumul pus la dispoziție sau orice alt canal public de comunicație. Dacă veți face acest lucru, vă asumați răspunderea dacă veți primi copiat pe temă.

Temele vor fi testate împotriva plagiatului. Orice tentativă de copiere va fi depunctată conform regulamentului. Rezultatele notării automate este orientativă și poate fi afectată de corectarea manuală.

Resurse necesare realizării temei

Pentru a clona repo-ul și a accesa resursele temei 3:

student@asc:~$ git clone https://gitlab.cs.pub.ro/asc/asc-public.git
student@asc:~$ cd asc-public/assignments/3-optimizari

Pentru a valida corectitudinea rezultatelor puteti folosi fisierele output referinta din directorul references.

asc/teme/tema3.txt · Last modified: 2024/05/23 11:23 by vlad.spoiala
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0