Differences

This shows you the differences between two versions of the page.

Link to this comparison view

asc:teme:tema2 [2020/04/16 21:52]
vlad.spoiala [Resurse]
asc:teme:tema2 [2024/04/22 09:02] (current)
tudor.calafeteanu
Line 1: Line 1:
-====== Tema 2 ====== +====== Tema 2 - Implementarea CUDA a algoritmului de consens Proof of Work din cadrul Bitcoin ​====== 
-    * **Deadline soft:** 22 aprilie 2020, ora 23:55. Primiți un bonus de 10% din punctajul obtinut pentru trimiterea temei înainte de 22 aprilie ​2020, ora 23:55. + 
-    * **Deadline hard:** 29 aprilie 2020, ora 23:55. Veți primi o depunctare de 10% din punctajul maxim al temei pentru fiecare zi de întârziere, ​până la maxim 7 zile, adică până pe 29 aprilie 2020, ora 23:55.+<note important>​  
 +  ​* **Soft deadline:** **8 Mai 2024**. Primiți un bonus de 10% din punctajul obtinut pentru trimiterea temei înainte de **30 aprilie ​2024, ora 23:55**
 +  * **Hard deadline:** **12 Mai 2024**. Veți primi o depunctare de 10% din punctajul maxim al temei pentru fiecare zi de întârziere
 +  * **Responsabili:​** [[tudor.calafeteanu@stud.acs.upb.ro |Tudor Calafeteanu]][[costin.carabas@gmail.com|Costin Carabaș ]] 
 +</​note>​ 
 + 
 +<note tip> 
 +  * Dată publicare: 22 Aprilie 2024 
 +  * Dată actualizare22 Aprilie 2024 
 +</​note>​ 
 ===== Enunț ===== ===== Enunț =====
  
-Se dă următoarea operație cu matrice:+Implementarea unui algoritm de consens distribuit Proof of Work pe blockchain folosind programare pe GPU în CUDA.
  
-$$ C =  B \times A^t  + A^2 \times B $$+<note important>​**Disclaimer**:​ Această temă a pornit de la algoritmul Bitcoin descris în [[https://​bitcoin.org/​bitcoin.pdf|whitepaper]] , însă nu replică în totalitate algoritmul și structurile de date.</​note>​
  
-unde: +===== Introducere =====
-  * $A$ si $B$ sunt matrice patratice de double de dimensiune N x N +
-  * $A$ este o matrice superior triunghiulara +
-  * $A^t$ este transpusa lui $A$ +
-  * $\times$ este operația de înmulțire +
-  * $+$ este operatia de adunare +
-  * $A^2$ este $A$ ridicat la patrat+
  
-Se dorește implementarea operației de mai sus in C/C++ în 5 moduri: +Blockchain-ul este tehnologie ​care a devenit cunoscută odată cu apariția criptomonedelor,​ precum Bitcoin-ul, Ethereum, etcEste formă de înregistrare descentralizată și distribuită a tranzacțiilor și datelor, care funcționează pe baza unui lanț de blocuriFiecare bloc înregistrează ​serie de tranzacții și este legat de blocurile anterioare printr-un proces ​de criptare și verificarecunoscut sub numele ​de "​hashing"​
-  * **blas** ​- o variantă ​care folosește una sau mai multe functii din [[http://​www.netlib.org/​blas/​ | BLAS Atlas]] pentru realizarea operatiilor de inmultire de matrice. Adunarea matricelor poate fi facuta "de mana". Aceasta implementare va tine cont de faptul ca A este o matrice superior triunghiulara. +
-  * **neopt** - o variantă "de mână"​ fără îmbunătățiriAceasta implementare va tine cont de faptul ca A este o matrice superior triunghiulara. +
-  * **opt_m** - variantă îmbunătățită a versiunii **neopt**. Îmbunătățirea are în vedere exclusiv modificarea codului pentru a obține performanțe mai bune. +
-  * **opt_f** - variantă îmbunătățită obținută prin compilarea codului ​de la varianta **neopt** cu flag-ul -O3 +
-  * **opt_f_extra** - o variantă îmbunătățită obținută prin compilarea codului ​de la varianta **neopt** cu flag-ul -O3 si alte [[https://​gcc.gnu.org/​onlinedocs/​gcc-5.4.0/​gcc/​Optimize-Options.html|flag-uri de optimizare specifice]]. Se vor avea in vedere flag-uri care actioneaza asupra unei singure optimizarinu flag-uri care actioneaza asupra unui grup de optimizari.+
  
-===== Rulare și testare =====+{{:​asc:​teme:​blockchain.jpg?​700|}}
  
-Pentru testarea temei vă este oferit un schelet de cod pe care trebuie să-l completați cu +**Descentralizare**: Datele sunt stocate ​și gestionate ​de o rețea descentralizată de nodurieliminând astfel nevoia de o autoritate centrală.
-implementarile pentru cele 4 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ă adaugați implementarea variantei **blas**. +
-  * **solver_neopt.c** - în acest fișier trebuie să adaugați implementarea variantei **neopt**. +
-  * **solver_opt.c** - în acest fișier trebuie să adaugați implementarea variantei **opt_m**. +
-  * **Makefile** - Makefile folosit la compilarea cu gcc. +
-  * **input** - fișierul ​de input care contine 3 teste pentru urmatoarele valori ale lui N: 400800, 1200  +
-  * **compare.c** - utilitar ce poate fi folosit pentru a compara doua fisiere rezultat. __Acest fișier va fi suprascris în timpul corectării și nu trebuie modificat__.+
  
-<note important>​Putețaduce orice modificare scheletului de cod exceptând cele 3 fișiere menționate mai sus.</​note>​+**Imutabilitate**:​ Datele înregistrate în blocurile blockchain-ului sunt imutabile șnu pot fi modificate sau șterse ulterior.
  
-În urma rulării comenzii ​**make** cu oricare din cele 2 Makefile-uri vor rezulta 5 fișere binare**tema2_blas**,​ **tema2_neopt**,​ **tema2_opt_m**,​ **tema2_opt_f** si **tema2_opt_f_extra** corespunzătoare celor 5 variante care trebuie implementate.+**Transparență**: Tranzacțiile ​și înregistrările sunt publice și transparenteiar oricine poate să le verifice.
  
-<note tip>​Rularea se va realiza astfel: +**Securitate**Criptografia și algoritmii de consens asigură securitatea și integritatea datelor stocate în blockchain.
-<​code>​./​tema2_<​mod>​ input </​code>​+
  
-unde: + 
-  * mod este unul din modurile ​**blas**, **neopt**, **opt_m**, **opt_f** sau **opt_f_extra**. + 
-  * input este fișierul ce contine descrierea testelor+===== Obiectivele temei ===== 
-  ​+În cadrul acestei teme veți participa ca nod într-un blockchain, ​unde execuția tranzacțiilor se va face pe GPU. 
 +Obiectivele temei
 +  * Înțelegerea conceptelor de bază ale blockchain-ului;​ 
 +  * Înțelegerea algoritmului de consens distribuit;​ 
 +  * Participarea la algoritmul de consens din perspectiva unui nod; 
 +  * Programarea pe GPU și folosirea limbajului CUDA; 
 + 
 +===== Algoritmul de consens ===== 
 +Calculatoarele participante la consens se numesc noduri (sau mineri în cazul PoW). Aceste noduri nu se cunosc și nu au încredere unele în altele.  
 +Scopul unui mecanism de consens ​este de a aduce toate nodurile în acord, adică de a avea încredere ​unul în celălalt, într-un mediu în care nodurile nu au încredere unul în celălalt. 
 + 
 +  * Minerii (aceștia veți fi voi) efectuează lucrări de calcul în rezolvarea unei probleme matematice complexe. Demonstrarea rezolvării problemei aduce de la sine și încredere. 
 +  * Problema matematică poate deveni mai complexă, în funcție de numărul de participanți la consens. 
 + 
 +Minerul care a rezolvat primul problema, va propaga răspunsul în rețea, iar acest va fi validat de către ceilalți participanți la rețea. Astfel, problema are 2 proprietăți:​ 
 +  * Este greu de calculat răspunsul;​ 
 +  * Este ușor de verificat răspunsul. 
 + 
 +Minerul care a rezolvat primul problema va fi recompensat. În cazul vostru, veți primi punctaj 😁 
 + 
 +==== Structura unui bloc ==== 
 + 
 +Un bloc este format ​din
 +  ​Hash-ul blocului anterior - o valoare predefinită;​ 
 +  ​Root hash-ul tranzacțiilor - o valoare calculată de host, tranzactiile avand valori predefinite;​ 
 +  * Nonce (Number used only once) - un număr întreg random, pozitiv, pe 32 biți, pe care minerii încearcă să îl găsească, astfel încât hash-ul block-ului rezultat să fie mai mic decât o dificultate threshold (un alt hash, ales în funcție de numărul de 0-uri consecutive din prefix). Acest număr trebuie să îl găsiți, prin metoda trial-and-error. 
 + 
 + 
 + 
 +{{:​asc:​teme:​merkle.png?​300|}} 
 + 
 + 
 + 
 +Hash-ul rezultat al blocului se va folosi în continuare pentru crearea unui alt bloc. De aici vine denumirea de blockchain: se creează un lanț de blocuri, iar fiecare bloc depinde de cel anterior. 
 + 
 + 
 +{{:​asc:​teme:​block.png?​400|}} 
 + 
 + 
 +==== Rezolvarea problemei ==== 
 + 
 +Problema de rezolvat este găsirea unei nonce care, atunci când se aplică o funcție hash, cum ar fi SHA-256, hash-ul începe cu un număr de zero biți. Munca medie necesară este exponențială în funcție de numărul de biți zero necesari și poate fi verificată prin executarea unui singur hash. 
 + 
 +De exemplu, pornim de la “Hello world” și trebuie să găsim un nonce astfel încât hash-ul să înceapă cu un 0. 
 +Pentru nonce = 4, aplicând sha256(“Hello world4”) obținem un hash ce începe cu un 0: 
 + 
 +"//​Hello world4//"​ -> **0**9b044fe014a500edc4358d55e4b59d595b7a2c9d01143ae37c577d1f68378e4 
 + 
 +Considerăm această problemă ca având **dificultatea = 1**. 
 +Pentru o problemă cu **dificultatea = 3**, hash-ul rezultat va începe cu trei de 0: “**000**”. 
 + 
 + 
 +===== Cerințe ale temei ===== 
 + 
 + 
 +==== Înțelegerea algoritmului de consens pe CPU ==== 
 + 
 +  * Veți porni de la directorul **cpu_miner**, ce conține implementarea deja făcută pe CPU. Acesta ​**nu** face parte din rezolvarea temei. Scopul codului este de a înțelege funcționalitatea pe CPUca apoi să optimizați căutarea nonce-ului pe GPU, folosind CUDA. 
 +  ​Acesta conține 5 teste: 
 +    ​4 pentru a vă familiariza cu funcțiile folosite. 
 +    ​al 5-lea este efectiv implementarea miner-ului pe CPU 
 +  ​Căutarea nonce-ului din testul 5 ar trebui să dureze ~2s pe xl, pentru o dificultate de 5 leading 0s. 
 +  ​Aceasta este o abordare simplistă a calculării unui block hash, cu complexitate redusă. Nu reflectă implementarea reală a algoritmilor de consens POW, având scop pur educativ. 
 +  ​Pași pentru rulare: 
 +    ​To compile: ​ make 
 +    ​To run:      make run 
 +    * To clean: ​   make clean 
 + 
 +==== Implementarea algoritmului de consens pe GPU ==== 
 +  * Veți porni de la directorul **gpu_miner**,​ în care veți realiza implementarea în CUDA a logicii din //​cpu_miner//​
 +  * Veți implementa funcția device //​findNonce//,​ care va paraleliza căutarea nonce-ului, folosind CUDA Threads. Aceasta trebuie implementată astfel încât să caute prin toate numerele de la 1 la MAX_NONCE. 
 +  * Pentru a va ajută, aveți deja implementate funcții ajutătoare în //​utils.cu//​. Vă recomandăm să va folosiți de ele în implementarea voastră. 
 +  * Nonce-ul găsit, hash-ul block-ului, precum și timpul rulării kernel-ului,​ vor fi scrise într-un fișier //​results.csv//,​ în urmă apelarii funcției //​printResult//​ din //​utils.cu//​. 
 +  * Pași pentru rulare: 
 +    * To compile: ​ make 
 +    * To run:      make run 
 +    * To clean: ​   make clean 
 + 
 +==== Evaluarea performanței ==== 
 + 
 +  * Punctajul se va acorda în funcție de durata rulării kernel-ului //​findNonce//​. Pentru a testa eficiența implementării,​ în cazul valorilor predefinte în //utils// (previous block hash și cele 4 tranzacții,​ pentru o dificultate de 5 zero-uri), timpii rezultați sunt considerați:​ 
 +    * 100% pct implementare:​ //t// < 1s. 
 +    * 75% pct implementare: ​ //t// < 1.5s. 
 +    * 50% pct implementare: ​ //t// < 2s (durata rulării pe CPU). 
 +    * 0% pct implementare: ​  //t// >= 2s SAU Nonce/Block hash incorect. 
 +Unde //t// este timpul //minim// înregistrat în urma a 5 rulări succesive. Motivul pentru care rulăm de mai multe ori este că timpul poate fi diferit cu câteva zecimi de la o rulare la alta. 
 +<note important>​Această abordare o vom folosi ​și în testarea noastră, folosind teste **private**,​ pentru a vă oferi punctajul. Pentru a testa tema cu testele private, folositi submisia pe [[https://​curs.upb.ro/​2023/​mod/​assign/​view.php?​id=166059|Moodle]].</​note>​ 
 + 
 +===== Observații ===== 
 +  * Compilarea si rularea temei se vor face **EXCLUSIV** pe coada //xl//. Nu este nevoie să modificăți nimic în //​Makefile//,​ regulile sunt deja făcute. Tot ce trebuie să faceți este să apelați //make//, //make run// și //make clean//, ca la laborator
 +  ​* Veți modifica **DOAR** fișierul //​gpu_miner.cu//​. Celelate fișiere din directorul //​gpu_miner//​ se vor suprascrie la testarea automată. 
 +  * Deși nonce-ul este un număr întreg, pozitiv, pe 32 biți, MAX_NONCE pe GPU este setat cu valoarea 1e8, în loc de UINT32_MAX (~4.29 * 1e9). Motivul este de a reduce timpul și de a nu întâmpină bottleneck-uri când sunt trimise multe job-uri, în același timp, de la mai mulți studenți, pe coada xl. 
 + 
 +<note warning>​ 
 +Temele vor fi testate împotriva plagiatului. Orice tentativă de copiere va fi depunctată conform [[asc:​regulament|regulamentului]]. 
 +Rezultatele notării automate este orientativă și poate fi afectată de corectarea manuală.
 </​note>​ </​note>​
  
-Fișierul **input** este structurat astfel: +===== Notare ===== 
-  * pe prima linie numărul de teste. +Toate modificările vor fi aduse fișierului ​**gpu_miner.cu**. Acest fișier îl veți submite pentru a fi evaluat ​și notat.
-  ​pe următoarele linii descrierea fiecarui 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 coada **ibm-nehalem.q**. Compilarea se va face folosind **gcc-5.4.0** din modulul **compilers/​gnu-5.4.0**. Pentru a incarca modulul pentru GCC trebuie sa dati pe una din masinile din coada ibm-nehalem.q urmatoarea comanda<​code>​ module load compilers/​gnu-5.4.0 </​code>​+Punctajul maxim este de 100 pct distribuite astfel:
  
-Pentru variantele **blas**, **neopt** si **opt_m** nu vor fi utilizate flag-uri ​de optimizare pentru compilare (va fi utilizat -O0).  +20 pct EXPLICAȚII 
-Pentru linkarea cu BLAS Atlas se va folosi versiunea single-threaded ​**libsatlas.so.3.10** de pe masinile din coada ibm-nehalem.q +  ​Implementare descrisă în READMEalături ​de rezultate și o discuție asupra lor
-disponibile in directorul <​code>/​usr/​lib64/​atlas</​code> ​  +  Programul compilează,​ codul nu are disfuncționalități majore. 
-Fișierele output referință le găsiți aici: +80 pct IMPLEMENTARE 
-<​code>​ /​export/​asc/​tema2/</​code>​+  * Punctaj dat de vmchecker.
  
-===== Punctaj =====+Arhiva temei va fi încărcată pe [[https://​curs.upb.ro/​2023/​mod/​assign/​view.php?​id=166059|Moodle]]. Aceasta va cuprinde obligatoriu:​ 
 +  * gpu_miner.cu 
 +  * README
  
-Punctajul este impărțit astfel: +===== Bonus ===== 
-  * **15p** pentru implementarea variantei **blas** dintre care: +Pentru a primi un punctaj bonus de maxim 10 pct, va trebui să schimbați realizarea Merkle Tree-ului din metoda secvențială,​ pe CPU, într-una paralelă, pe GPU. 
-    * 12p daca implementarea obtine rezultate corecte +Cerințe
-    * 3p pentru descrierea implementarii in README +  * Puteți observa că Merkle Tree-ul se poate realiza într-un mod paralel, față de cel secvențial implementat deja. 
-  * **15p** pentru implementarea variantei **neopt** dintre care: +  * Va trebui să vă creați un fișier de intrare //​inputs.txt//,​ din care să citiți //n// tranzacții,​ //n// >1000. Este la latitudinea voastră dacă folosiți același previous block hash folosit deja în cod, sau citiți unul nou. 
-    * 12p daca implementarea obtine rezultate corecte +  * Veți defini o altă funcție kernel //​merkleTree//, ​care va realiza în mod paralel crearea top hash-ului, folosind CUDA Threads. 
-    * 3p pentru descrierea implementarii in README  ​ +  * Punctajul se va da pe abordare corectă și eficient paralelă ​generării top hash-ului, în care să arătați speedup-ul obținut de la trecerea secvențială ​pe CPUla cea paralelă pe GPU. Timpul nu va fi luat în considerare,​ însă nu  trebuie să dureze rularea job-ului mai mult decât valoarea predefinită în RUN_TIME.
-  * **20p** pentru implementarea variantei **opt_m** dintre ​care+
-    * 15p daca implementarea obtine rezultate corecte si timpul de calcul este cu cel putin 30% mai mic decat cel al variantei **neopt** pentru testul cu N 1200 +
-    * 5p pentru descrierea implementarii in README +
-  * **20p** pentru implementarea variantei **opt_f_extra** dintre ​care+
-    * 10p daca implementarea obtine rezultate corecte si timpul de calcul este cu cel putin 5% mai mic decat cel al variantei **opt_f** pentru testul cu N = 1200 +
-    * 10p pentru explicatii legate de alegerea flag-urilor si impactul flag-urilor asupra performantei +
-  * **30p** pentru ​analiza comparativa ​performantei pentru cele 5 variante: +
-    * 15p pentru realizarea unor grafice relevante bazate ​pe rularea a cel putin 5 teste (5 valori diferite ale lui N: adica inca cel putin doua valori diferite de 400800 si 1200 pentru N) +
-    * 15p pentru explicatii oferite in README  +
-  * **(Bonus)** ​  +
-    * 20p daca timpul de calcul al variantei **opt_m** pentru testul cu N = 1200 este cel mult 4 secunde sau +
-    * 10p daca timpul de calcul al variantei **opt_m** pentru testul cu N = 1200 este intre 4 si 8 secunde +
-    * Bonusurile se calculeaza doar pe coada ibm-nehalem.q+
  
-<note important>​Pentru a fi luată în considerare la punctaj, implementarea trebuie să producă rezultate corecte pe cele 3 teste din fisierul **input**.</​note>​+===== Resurse necesare realizării temei =====
  
-===== Precizări ​și recomandări =====+Pentru a clona [[https://​gitlab.cs.pub.ro/​asc/​asc-public | repo-ul]] ​și a accesa resursele temei 2:
  
-<note warning>Timpul maxim pentru rularea celor 3 teste folosind oricare din cele 5 variante este de 2 minuteAceastă limită de timp se referă la rularea întregului program, nu doar la partea intensiv computațională.</note>+<code bash> 
 +student@asc:​~$ git clone https://​gitlab.cs.pub.ro/​asc/​asc-public.git 
 +student@asc:​~$ cd asc-public/​assignments/​2-cuda_proof_of_work 
 +</code>
  
-  * Pentru a simplifica implementarea puteți presupune că N este multiplu de 40 și că este mai mic sau egal cu 1600. +===== Suport, întrebări și clarificări =====
-  * Î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 vedea ce optimizari sunt prezente in fiecare nivel de optimizare puteti ​folosi ​comanda: +Pentru ​întrebări sau nelămuriri legate ​de temă folosiți [[https://​curs.upb.ro/​2023/​mod/​forum/​view.php?​id=166058|forumul temei]]. ​
-<​code>​ gcc -Q -Olevel --help=optimizers </code>+
  
-<​note ​tip>Pentru ​evita aglomerarea cozii se recomanda rularea ​de teste pentru valori ale lui N mai mici sau egale cu 1600.</​note>​+<​note ​important> 
 +Orice intrebare e recomandat să conțină o descriere cât mai clară ​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.
  
-<​note>​ Se recomandă ștergerea fișierelor coredump în cazul rulărilor care se termină cu eroare pentru a evita problemele cu spațiul de stocare.</​note>​+**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ă.
  
-<​note>​ În cazul în care job-urile vă rămân "​agățate",​ va recomandam să utilizați de pe fep.grid.pub.ro,​ comanda <​code>​ qstat </​code>​ pentru a vedea câte job-uri aveți pornite, și apoi să utilizați comanda <​code>​qdel -f <​id-sesiune>​ </​code>​ unde <​id-sesiune>​ sunt primele cifre din stânga, rezultate după comanda **qstat**. 
 </​note>​ </​note>​
  
-<note warning> Sesiunile interactive deschise prin qlogin nu sunt permise pe coada ibm-nehalem.q. Va trebui sa utilizati qsub pentru a folosi aceasta coada. </​note>​ +
-===== Resurse ===== +
-  * {{:​asc:​resurse:​cluster-cheat-sheet.pdf| Cluster cheat sheet}} +
-  * {{:​asc:​tema2:​skel1.1.zip| Schelet de cod}}+
asc/teme/tema2.txt · Last modified: 2024/04/22 09:02 by tudor.calafeteanu
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