This shows you the differences between two versions of the page.
|
asc:teme:tema1 [2023/04/21 23:05] daniel.dosaru [Precizări încărcare] |
asc:teme:tema1 [2026/02/23 18:53] (current) giorgiana.vlasceanu |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Tema 1 - Marketplace ====== | + | ====== Tema 1 ====== |
| - | + | <note important> | |
| - | <note important> | + | * **Deadline soft:** **<del>18</del> 20 Mai 2025, ora 23:55**. Primiți un bonus de 10% din punctajul obținut pentru trimiterea temei înainte de **<del>16</del> 18 Mai 2025, 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 **<del>25</del> 27 Mai 2025, ora 23:55**. |
| - | * **Deadline:** 23 aprilie 2023, ora 23:55. Primiți un bonus de 10% pentru trimiterea temei cu 2 zile înaintea acestui termen, adică înainte de 21 aprilie 2023, ora 23:55. | + | * **Deadline hard:** **<del>25</del> 27 Mai 2025, ora 23:55**. |
| - | * **Deadline hard:** 30 aprilie 2023, 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 30 aprilie 2023, ora 23:55. | + | * **Responsabili:** [[vladspoiala@gmail.com |Vlad Spoiala]], [[emil.slusanschi@cs.pub.ro|Emil Slusanschi]], [[serban.ionescu0609@stud.acs.upb.ro | Serban Ionescu]], [[adumitrescu2708@stud.acs.upb.ro | Alexandra Dumitrescu]]. |
| - | * **Responsabili:** [[ andreicatalin.ouatu@gmail.com | Andrei Ouatu ]], [[daniel.dosaru@upb.ro|Daniel Dosaru]], [[eduard.staniloiu@cs.pub.ro | Eduard Stăniloiu]], [[giorgiana.vlasceanu@gmail.com | Giorgiana Vlăsceanu]] | + | |
| - | * **Autori:** [[LucaIstrate@gmail.com|Luca Istrate]], [[adriana.draghici@cs.pub.ro|Adriana Draghici]], [[soareloredana97@gmail.com|Loredana Soare]], [[eduard.staniloiu@cs.pub.ro | Eduard Stăniloiu]] | + | |
| </note> | </note> | ||
| <note tip> | <note tip> | ||
| - | * Dată publicare: 31 martie | + | * Dată publicare: 7 mai 2025 |
| - | * Dată actualizare enunț: 31 martie | + | * Dată actualizare enunț: 15 mai 2025 |
| </note> | </note> | ||
| - | |||
| - | |||
| - | ===== Scopul temei ===== | ||
| - | |||
| - | * Utilizarea eficientă a elementelor de sincronizare studiate la laborator | ||
| - | * Implementarea unei aplicații concurente utilizând o problemă clasică (Multi Producer, Multi Consumer) | ||
| - | * Aprofundarea anumitor elemente din Python (clase, elemente de sintaxă, thread-uri, sincronizare, precum și folosirea modulelor Python pentru lucrul cu thread-uri) | ||
| ===== Enunț ===== | ===== Enunț ===== | ||
| - | În cadrul acestei teme veți avea de implementat un Marketplace prin intermediul căruia mai mulți **producători** își vor oferi produsele spre vânzare, iar mai mulți **cumpărători** vor achiziționa produsele puse la dispoziție. | + | Se dă următorul calcul cu matrice: |
| + | <code> | ||
| + | C = B * At | ||
| + | D = Ct * A | ||
| + | i = 0 | ||
| + | while (i < N) { | ||
| + | y = Ct * x | ||
| + | x = C * y | ||
| + | i += 1 | ||
| + | } | ||
| + | y = D * x | ||
| + | </code> | ||
| + | unde: | ||
| + | * $A$ si $B$ sunt matrice pătratice de dimensiune N x N cu elemente de tip double | ||
| + | * x si y sunt 2 vectori de dimensiune N x 1 cu elemente de tip double | ||
| + | * $A^t$ este transpusa lui $A$, $C^t$ este transpusa lui $C$ | ||
| + | * $*$ este operația de înmulțire | ||
| - | === Marketplace === | + | 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 [[https://www.netlib.org/lapack/explore-html/de/d6a/group__blas__top.html | 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. | ||
| - | Marketplace-ul este unul destul de simplu, cu **două tipuri de produse (ceai și cafea)** ce vor fi comercializate de către producători. Acesta va fi intermediarul dintre producători și consumatori, prin el realizându-se achiziția de produse: | + | ===== Rulare și testare ===== |
| - | producătorul (producer) va produce o anumită cantitate de produse de un anumit tip / mai multe tipuri | + | |
| - | cumpărătorul (consumer) va cumpăra o anumită cantitate de produse de un tip / de mai multe tipuri. De asemenea, Marketplace-ul va pune la dispoziția fiecărui cumpărător câte un **coș de produse (cart)** (acesta va fi folosit pentru rezervarea produselor care se doresc a fi cumpărate). | + | |
| - | === Producător === | + | 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__. | ||
| - | Vor exista mai mulți producători ce vor produce obiectele de tip cafea / ceai. Fiecare produs va fi furnizat într-o anumită cantitate. Un producător poate produce atât obiecte de tip cafea, cât și de tip ceai. | + | <note important>Puteți aduce orice modificare scheletului de cod exceptând fișierele menționate mai sus.</note> |
| - | === Consumator === | + | Î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. |
| - | În momentul în care un client își dorește să cumpere anumite produse dintr-un magazin, acesta va avea nevoie de un coș de cumpărături pe care să îl folosească în scopul rezervării acestora. Astfel, de fiecare dată când un client își începe cumpărăturile, acesta va primi din partea Marketplace-ului un coș de cumpărături, căruia îi va fi asociat un //id//. Clientul poate: | + | <note tip>Rularea se va realiza astfel: |
| - | * adăuga produse în coș => produsele respective devin indisponibile pentru ceilalți clienți | + | <code>./tema3_<mod> input </code> |
| - | * șterge produse din coș => produsele respective devin disponibile pentru ceilalți clienți | + | |
| - | * plasa o comandă | + | |
| - | ===== Descrierea implementării ===== | + | unde: |
| - | + | * mod este unul din modurile **blas**, **neopt**, **opt_m** | |
| - | + | * input este fișierul ce contine descrierea testelor. | |
| - | Marketplace-ul ce va trebui implementat va simula problema **Multi Producer Multi Consumer (MPMC)**. | + | |
| - | Pentru rezolvarea acestei teme va trebui să completați clasele ''Marketplace, Producer'', și ''Consumer'' cu o implementare corectă a metodelor deja definite. | + | |
| - | + | ||
| - | Rezolvarea temei va fi concentrată preponderent pe metodele clasei //Marketplace//, metode ce vor fi apelate atât de producător, cât și de cumpărător în clasele aferente ale acestora. | + | |
| - | + | ||
| - | Operația efectuată de către producător este cea de //publicare a produselor sale//. Implementarea metodei ''publish'' va fi făcută în clasa //Marketplace//. | + | |
| - | + | ||
| - | Vor exista doua tipuri de operații pe care clientul le poate efectua asupra coșului de cumpărături: | + | |
| - | * ''add_to_cart'' => adaugă un produs în coș | + | |
| - | * ''remove_from_cart'' => șterge un produs din coș | + | |
| - | Ambele metode (''add_to_cart'' și ''remove_from_cart'') vor trebui implementate în clasa //Marketplace//. | + | |
| - | + | ||
| - | În momentul în care un consumator adaugă un produs în coșul pentru cumpărături, produsul respectiv va deveni indisponibil pentru ceilalți clienți ai Marketplace-ului. Clientul își va putea plasa comanda prin apelarea metodei ''place_order'' (din clasa Marketplace). | + | |
| - | În cazul în care un produs este eliminat din coșul pentru cumpărături, acesta devine disponibil pentru ceilalți clienți ai Marketplace-ului. | + | |
| - | + | ||
| - | Funcționalitatea clasei ''Producer'' este să: | + | |
| - | * furnizeze produselor pe care producătorul le pune la dispoziție | + | |
| - | + | ||
| - | + | ||
| - | <note important>''Producer'' produce secvențial numărul de produse și tipul din cadrul fișierului de intrare și așteaptă după realizarea fiecărui produs un număr de secunde specificat. Informațiile se preiau din fișierul de intrare și are următorul format pentru produse''["id", cantitate, timp-așteptare]''.</note> | + | |
| - | + | ||
| - | + | ||
| - | Funcționalitatea clasei ''Consumer'' este să: | + | |
| - | * primească id-ului coșului de cumpărături | + | |
| - | * adauge / elimine din coșul de cumpărături anumite cantități de produse | + | |
| - | * plaseze comenzi | + | |
| - | + | ||
| - | Modulul **Product** conține reprezentările claselor **Coffee** și **Tea**. | + | |
| - | + | ||
| - | Marketplace-ul limitează numărul de produse ce pot fi publicate de către un producător. În momentul în care s-a atins limita, producătorul nu mai poate publica altele până nu sunt cumpărate. El va reîncerca să publice după un timp definit în fișierul de test. | + | |
| - | + | ||
| - | Dacă un cumpărător nu găsește un produs în marketplace, el va încerca mai târziu, după un timp definit în fișierul de test. | + | |
| - | + | ||
| - | <note important>Se consideră timp de așteptare după: | + | |
| - | * adăugarea unui produs | + | |
| - | * semnalizarea că nu se găsește un produs | + | |
| - | * semnalizarea faptul că este plină coada asociată producătorului | + | |
| </note> | </note> | ||
| - | ===== Testare ===== | + | 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. | ||
| - | Testarea se va realiza folosind atât ''unittest''e, cât și teste funcționale. | + | Rularea se va face pe partiția **haswell** folosind **sbatch**. Compilarea se va face folosind **gcc-8.5.0**. |
| - | ==== Unittesting ==== | + | Pentru a vedea cat de incarcate sunt nodurile puteti folosi **scontrol**: |
| + | <code> | ||
| + | [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 | ||
| + | </code> | ||
| - | Pentru testarea funcțiilor din ''Marketplace'' veți folosi modulul de [[https://docs.python.org/3/library/unittest.html | unittesting]] al limbajului Python. | + | 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: |
| - | + | <code> | |
| - | <spoiler Click pentru sumar despre unittesting> | + | [vlad.spoiala@fep8 sol]$ sbatch -p haswell --time 00:03:00 --exclude=haswell-wn[29-30] test_all_opt.sh |
| - | Pentru a defini un set de unitteste trebuie să vă definiți o clasă care moștenește clasa ''unittest.TestCase'' | + | Submitted batch job 471560 |
| - | <code python demo_unittest.py> | + | |
| - | import unittest | + | |
| - | + | ||
| - | class TestStringMethods(unittest.TestCase): | + | |
| - | + | ||
| - | def test_upper(self): | + | |
| - | self.assertEqual('foo'.upper(), 'FOO') | + | |
| </code> | </code> | ||
| - | Pentru a defini un test, numele metodei trebuie să înceapă cu prefixul ''test_'', așa cum puteți observa în exemplul de mai sus: ''test_upper''. | + | Jobul ruleaza pe haswell-wn31: |
| - | Verificările din corpul metodei se fac folosind metodele ''assert*'', în exemplul de mai sus a fost folosită metoda ''assertEqual''. O listă completă a metodelor de verificare disponibile este prezentată în [[https://docs.python.org/3/library/unittest.html#assert-methods | documentație]]. | + | <code> |
| - | + | [vlad.spoiala@fep8 sol]$ squeue -u vlad.spoiala | |
| - | Pentru a rula testele, folosim subcomanda unittest: | + | JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON) |
| - | <code bash> | + | 471560 haswell test_all vlad.spo R 0:06 1 haswell-wn31 |
| - | $ python3 -m unittest demo_unittest.py | + | |
| - | $ # puteti folosi optiunea -v pentru mai multe detalii | + | |
| - | $ python3 -m unittest -v demo_unittest.py | + | |
| </code> | </code> | ||
| - | </spoiler> | ||
| - | Pentru a testa comportamentul clasei ''Marketplace'' definiți în fișierul ''marketplace.py'' o clasă de testare numită ''TestMarketplace''. | + | /* <note warning> Sesiunile interactive deschise prin **srun** nu sunt permise pe partitia xl. Va trebui să utilizați **sbatch** pentru a folosi aceasta partitie. </note> |
| - | Clasa ''TestMarketplace'' va testa funcționalitatea tuturor metodelor definite de ''Marketplace'': ''register_producer'', ''publish'', ''new_cart'', ''add_to_cart'', ''remove_from_cart'', ''place_order''. | + | |
| - | Dacă definiți alte metode, va trebui să adăugați teste și pentru acestea. | + | |
| - | Vă recomandăm să folosiți metoda [[https://docs.python.org/3/library/unittest.html#unittest.TestCase.setUp | setUp]] pentru a inițializa o instanță a clasei testate (''Marketplace'') și orice altceva ce vă ajută în testarea codului. | ||
| - | Un exemplu de utilizare a metodei ''setUp'' este disponibil în [[https://docs.python.org/3/library/unittest.html#organizing-test-code | documentație]]. | ||
| - | + | Pentru variantele **blas**, **neopt** și **opt_m** nu vor fi utilizate flag-uri de optimizare pentru compilare (va fi utilizat -O0). | |
| - | ==== Testarea Funcțională și Formatul Testelor ==== | + | <note warning>//__**TODO**__// |
| - | + | Pentru linkarea cu BLAS Atlas se va folosi versiunea single-threaded **libsatlas.so.3.10** disponibilă în directorul <code>/usr/lib64/atlas</code> de pe mașinile din partiția nehalem. </note> | |
| - | Testarea se va face cu ajutorul a două tipuri de fișiere, cele de input și cele de output ({id}.in și {id}.out), primul fiind în format JSON. Fișierul **{id}.in** va reprezenta fișierul de intrare și va conține configurările necesare pentru fiecare clasă în parte, iar fișierul **{id}.out** va reprezenta fișierul de ieșire prin intermediul căruia se va verifica corectitudinea implementării temei. | + | |
| - | + | ||
| - | Fișierele de input vor fi fișiere JSON ce vor conține următoarele chei: | + | |
| - | * marketplace | + | |
| - | * products | + | |
| - | * producers | + | |
| - | * consumers | + | |
| - | + | ||
| - | Exemplu conținut fișier de intrare și fișierul corespunzător de ieșire: | + | |
| - | <spoiler Click pentru exemplu> | + | |
| - | <code json> | + | |
| - | { | + | |
| - | "products": { | + | |
| - | "id1": { | + | |
| - | "product_type": "Coffee", | + | |
| - | "name": "Arabica", | + | |
| - | "price": 10, | + | |
| - | "acidity": 5.1, | + | |
| - | "roast_level": "medium" | + | |
| - | }, | + | |
| - | "id2": { | + | |
| - | "product_type": "Tea", | + | |
| - | "name": "Earl Grey", | + | |
| - | "price": 10, | + | |
| - | "type": "Green" | + | |
| - | } | + | |
| - | }, | + | |
| - | "consumers": [ | + | |
| - | { | + | |
| - | "name": "cons1", | + | |
| - | "retry_wait_time": 0.1, | + | |
| - | "carts": [ | + | |
| - | [ | + | |
| - | { "type": "add", "prod": "id1", "qty": 2 }, | + | |
| - | { "type": "remove", "prod": "id1", "qty": 1 } | + | |
| - | ], | + | |
| - | [ | + | |
| - | { "type": "add", "prod": "id2", "qty": 3 } | + | |
| - | ] | + | |
| - | ] | + | |
| - | } | + | |
| - | ], | + | |
| - | "producers": [ | + | |
| - | { | + | |
| - | "name": "prod1", | + | |
| - | "products": [ | + | |
| - | [ "id1", 1, 0.1 ], | + | |
| - | [ "id2", 1, 0.1 ] | + | |
| - | ], | + | |
| - | "republish_wait_time": 0.2 | + | |
| - | }, | + | |
| - | { | + | |
| - | "name": "prod2", | + | |
| - | "products": [ | + | |
| - | [ "id2", 1, 0.2 ] | + | |
| - | ], | + | |
| - | "republish_wait_time": 0.2 | + | |
| - | } | + | |
| - | ], | + | |
| - | "marketplace": { | + | |
| - | "queue_size": 8 | + | |
| - | } | + | |
| - | } | + | |
| - | </code> | + | |
| - | Conținut fișier de ieșire: | + | */ |
| + | <note warning> Testele voastre de performanță trebuie realizate pe partiția **haswell** deoarece evaluarea temelor se va face pe această partiție. </note> | ||
| + | Fisierul **input** contine 3 teste: | ||
| <code> | <code> | ||
| - | cons1 bought Coffee(name='Arabica', price=10, acidity=5.1, roast_level='medium') | + | 3 |
| - | cons1 bought Tea(name='Earl Grey', price=10, type='Black') | + | 200 123 out1 |
| - | cons1 bought Tea(name='Earl Grey', price=10, type='Black') | + | 600 456 out2 |
| - | cons1 bought Tea(name='Earl Grey', price=10, type='Black') | + | 1000 789 out3 |
| </code> | </code> | ||
| - | </spoiler> | + | În cazul fișierului **input** avem 3 teste pentru urmatoarele valori ale lui N: 200, 600, respectiv 1000. Seed-urile folosite la generarea datelor de intrare sunt 123, 456, respectiv 789. Fișierele de output sunt out1, out2, respectiv out3. |
| - | <note warning>Atât conținutul fișierului de intrare, cât și conținutul fișierului de ieșire sunt descrise în [[https://gitlab.cs.pub.ro/asc/asc-public/-/blob/master/assignments/1-marketplace/skel/test-gen/README_TESTS.md| README]] </note> | + | <note important> Pentru a fi luată în considerare la punctaj, implementarea trebuie să producă rezultate corecte pe toate cele 3 teste din fișierul **input**. </note> |
| - | Pentru a putea compara fișierele de ieșire obținute de voi cu cele de referința, scriptul de testare va ordona output-ul rezultat, întrucât avem de-a face cu multithreading. | + | Fișierul **input_valgrind** ce va fi folosit pentru rulările de valgrind contine un singur test: |
| + | <code> | ||
| + | 1 | ||
| + | 400 123 out1 | ||
| + | </code> | ||
| - | ===== Logging ===== | ||
| - | Vrem să utilizăm fișiere de logging în aplicațiile pe care le dezvoltăm pentru a putea urmări flowul acestora a.î. să ne ajute în procesul de debug. | + | ===== Punctaj ===== |
| - | Folosind modulul de [[https://docs.python.org/3/library/logging.html | logging]], trebuie să implementați un fișier de log, numit "marketplace.log", în care veți urmări comportamentul clasei ''Marketplace''. | + | Punctajul este impărțit astfel: |
| + | * **10p** pentru implementarea corecta a variantei **blas** | ||
| + | * **10p** pentru implementarea corecta a variantei **neopt** | ||
| + | * **15p** pentru implementarea variantei **opt_m** dintre care: | ||
| + | * 10p dacă implementarea obține rezultate corecte și timpul de calcul pe partiția **haswell ** este mai mic de 12s pentru testul cu N = 1000 | ||
| + | * 5p daca timpul de calcul pe partitia **haswell ** pentru testul cu N = 1000 este mai mic de 5s. Veti obtine un punctaj partial daca timpul de calcul este intre 5s si 9s. | ||
| + | * **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** | ||
| + | * **16p** 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** | ||
| + | * 5p 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 performantelor obținute | ||
| + | * **40p** pentru o analiză comparativă a performanței pentru cele 3 variante si respectiv a furnizarii prompturilor folosite (in format text, NU imagini, si intrebare si raspuns, ordonate succesiv) in interactiunea cu unelte de tip LLM (e.g. ChatGPT, CoPilot, Grok, Gemini, etc.). Indicati unealta folosita + versiunea acesteia. Trebuie sa se puna accent si pe modificarile de mână ale codurilor dezvoltate, nu doar pe explicarea unor coduri generate automat: | ||
| + | * 12p 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 200, 600 și 1000 pentru N) si pentru comentarea / explicarea acestor grafice in README. | ||
| + | * 12p pentru explicații oferite în README pentru versiunile **blas**, **neopt**, si **opt_m**. Aceste explicatii trebuiesc scrise de voi si nu copiate din unelte online. | ||
| + | * 12p pentru oferirea (succesiunii) de prompturi folosite pentru obtinerea versiunilor de cod **blas**, **neopt**, si **opt_m** precum si detalierea in README a motivelor pentru care a fost utilizata succesiunea aleasa spre o solutie eficienta a fiecarei variante de cod | ||
| + | * 4p pentru oferirea unei explicații în README privind motivul existentei buclei de dimensiune N pentru ultimele trei operatii cu matrice din enuntul problemei | ||
| - | În fișierul de log veți nota, folosind nivelul ''info()'', toate intrările și ieșirile în/din metodele clasei ''Marketplace''. În cazul metodelor care au parametrii de intrare, informația afișată la intrarea în funcție va afișa și valorile parametrilor. | + | Depunctări posibile: |
| - | Fișierul va fi implementat folosind [[https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler | RotatingFileHandler]]: astfel se poate specifica o dimensiune maximă a fișierului de log și un număr maxim de copii istorice. RotatingFileHandler ne permite să ținem un istoric al logurilor, fișierele fiind stocate sub forma "file.log", "file.log.1", "file.log.2", ... "file.log.max". | + | * **blas**: |
| + | * 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** | ||
| + | * î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ă si prompturi LLM** | ||
| + | * graficele nu au legendă / unități de măsură sau nu sunt explicate/descrise corespunzator in readme (intre -2p si -5p) | ||
| + | * lipsesc parțial sau complet timpii de rulare (intre -1p si -5p) | ||
| + | * lipsesc parțial sau total comentariile din REAME cerute explicit in enunt (intre -1p si -10p) | ||
| + | * graficele nu conțin toate datele cerute în enunț (intre -2p si -5p) | ||
| + | * prompturi identice cu ale altor submisii (-45p) | ||
| + | * **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) | ||
| - | Vă încurajăm să folosiți fișierul de log și pentru a înregistra [[https://docs.python.org/3/library/logging.html#logging.Logger.error | erori]] detectate. | + | ===== Precizări încărcare / Moodle ===== |
| - | În mod implicit, timestamp-ul logurilor folosește timpul mașinii pe care rulează aplicația (local time). Acest lucru nu este de dorit în practică deoarece nu putem compara loguri de pe mașini aflate în zone geografice diferite. Din acest motiv, timestampul este ținut în format UTC/GMT. | + | Arhiva temei va fi încărcată pe [[https://curs.upb.ro/2023/mod/assign/view.php?id=172248|Moodle]]. |
| - | Asigurați-vă că folosiți gmtime, și nu localtime. Pentru aceasta trebuie să folosiți metoda [[https://docs.python.org/3/library/logging.html#logging.Formatter.formatTime | formatTime]]. | + | |
| - | O descriere completă a cum puteți utiliza modului de logging este prezentă în categoria [[https://docs.python.org/3/howto/logging.html | HOWTO]] a documentației. | + | Structura arhivei va fi următoarea: |
| + | <code> | ||
| + | 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 | ||
| + | LLMprompts | ||
| + | grafice | ||
| + | ... | ||
| + | </code> | ||
| - | ===== Precizări încărcare ===== | + | 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, LLMprompts, grafice) vor fi verificate ulterior. | ||
| + | ===== Precizări și recomandări ===== | ||
| - | Arhiva temei va fi încărcată pe [[https://curs.upb.ro/2022/mod/assign/view.php?id=156013|moodle]] | + | /* |
| + | Reply Vlad 2021: added valgrind pt memory checks | ||
| + | Pentru asistentii care propun tema 2 din 2021!!! | ||
| - | <hidden> | + | Adaugati ca si la alte teme (vedeti tema1) o lista cu cateva depunctari comune (e.g. memleaks). |
| - | [[https://vmchecker.cs.pub.ro/ui/#ASC|vmchecker]]. | + | E.g. Vor fi depuntari intre -0.0 (warning) si -1.0 in functie de gravitate, pentru urmatoarele probleme: |
| - | </hidden> | + | * memleaks |
| + | * cod comentat | ||
| + | * etc | ||
| + | Sau, ca sa nu fie on the negative bias, puteti spune la precizari: | ||
| - | /* Arhiva temei (fişier .zip) va fi uploadată pe site-ul cursului şi trebuie să conţină: */ | + | Verificati codul vostru nu numai pentru corectitudine ci si pt memleaks (dati link catre vreun tool). De asemenea, este foarte important si aspectul codului, si in acest sens este bine sa aveti comentarii sugestive, organizare consistenta, etc. |
| - | Arhiva trebuie să conțină: | + | */ |
| - | * fișierele temei: ''marketplace.py'', ''producer.py'', ''consumer.py'' | + | |
| - | * alte fișiere ''.py'' folosite în dezvoltare | + | |
| - | * ''README'' | + | |
| - | * (opțional) directorul ''.git'' redenumit în ''git'' | + | |
| - | <note tip>Pentru a documenta realizarea temei, vă recomandăm să folosiți template-ul de [[https://gitlab.cs.pub.ro/asc/asc-public/-/blob/master/assignments/README.example.md|aici]] | + | /* |
| - | </note> | + | <note warning>Timpul maxim pentru rularea celor 3 teste din fișierul **input** pe partiția **haswell** folosind oricare din cele 3 variante este de 2 minute. Această limită de timp se referă la rularea întregului program, nu doar la partea intensiv computațională.</note> |
| + | */ | ||
| - | ===== Punctare ===== | + | /* |
| + | <note> Pentru a avea mai multe detalii despre sursa problemelor de acces la memorie semnalate de tool-ul memcheck din valgrind puteți folosi flag-ul de compilare -g pentru includerea simbolurilor de debug. </note> | ||
| + | */ | ||
| - | <note important>Tema va fi verificată automat, folosind infrastructura de testare, pe baza unor teste definite în directorul ''tests''. </note> | + | * Pentru a simplifica implementarea puteți presupune că N este multiplu de 40 și că este mai mic sau egal cu 1200. |
| + | * **În compararea rezultatelor se va permite o eroare absolută de maxim $10^{-6}$.** | ||
| + | * În cazul variantei **opt_m** complexitatea trebuie să fie aceeași cu cea din varianta **neopt**. | ||
| + | * Formatul arhivei trebuie să fie **zip**. | ||
| + | * Punctajul maxim obtinut de tester este 50p. Restul de 50p vor fi atribuite prin corectarea manuala a documentatiilor voastre (README, cod, grafice, prompturi, etc.) | ||
| - | Tema se va implementa **Python>=3.7**. | + | <note important>Pentru a evita aglomerarea cozii se recomandă rularea de teste pentru valori ale lui N mai mici sau egale cu 1200. </note> |
| - | Notarea va consta în 80 pct acordate egale între testele funcționale, 10 pct acordate pentru unitteste și 10 pct acordate pentru fișierul de logging. Depunctări posibile sunt: | + | <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> |
| - | * folosirea incorectă a variabilelor de sincronizare (ex: lock care nu protejează toate accesele la o variabilă partajată, notificări care se pot pierde) (-2 pct) | + | |
| - | * prezența print-urilor de debug (maxim -10 pct în funcție de gravitate) | + | |
| - | * folosirea lock-urilor globale (-10 pct) | + | |
| - | * folosirea variabilelor globale/statice (-5 pct) | + | |
| - | * Variabilele statice pot fi folosite doar pentru constante | + | |
| - | * folosirea inutilă a variabilelor de sincronizare (ex: se protejează operații care sunt deja thread-safe) (-5 pct) | + | |
| - | * alte ineficiențe (ex: creare obiecte inutile, alocare obiecte mai mari decât e necesar, etc.) (-5 pct) | + | |
| - | * lipsa organizării codului, implementare încâlcită și nemodulară, cod duplicat, funcții foarte lungi (între -1pct și -5 pct în funcție de gravitate) | + | |
| - | * cod înghesuit/ilizibil, inconsistenţa stilului - vedeți secțiunea Pylint | + | |
| - | * pentru code-style recomandăm ghidul oficial [[https://www.python.org/dev/peps/pep-0008/|PEP-8]] | + | |
| - | * cod comentat/nefolosit (-1 pct) | + | |
| - | * lipsa comentariilor utile din cod (-5 pct) | + | |
| - | * fişier README sumar (până la -5 pct) | + | |
| - | * nerespectarea formatului .zip al arhivei (-2 pct) | + | |
| - | * alte situaţii nespecificate, dar considerate inadecvate având în vedere obiectivele temei; în special situațiile de modificare a interfeței oferite | + | |
| - | Se acordă bonus 5 pct pentru adăugarea directorului ''.git'' și utilizarea versionării în cadrul repository-ului. | + | <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> squeue </code> pentru a vedea câte job-uri aveți pornite, și apoi să utilizați comanda <code>scancel <job_id> </code> pentru a opri un job. |
| - | + | ||
| - | <note warning> | + | |
| - | Temele vor fi testate împotriva plagiatului. Orice tentativă de copiere va fi depunctată conform [[asc:regulament|regulamentului]]. | + | |
| </note> | </note> | ||
| - | ==== Pylint ==== | ||
| - | Vom testa sursele voastre cu [[https://www.pylint.org/|pylint]] configurat conform fișierului **''pylintrc''** din cadrul repo-ului dedicat temei. Atenție, __rulăm pylint doar pe modulele completate și adăugate de voi__, nu și pe cele ale testerului. | + | <note important> |
| + | **Pentru întrebări sau nelămuriri legate de temă folosiți [[https://curs.upb.ro/2024/mod/forum/view.php?id=115671|forumul temei]]. | ||
| + | ** | ||
| - | Deoarece apar diferențe de scor între versiuni diferite de pylint, vom testa temele doar cu [[https://www.pylint.org/#install| ultima versiune]]. Vă recomandăm să o folosiți și voi tot pe aceasta. | + | 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. |
| - | Vom face depunctări de până la -5pct dacă verificarea făcută cu pylint vă dă un scor mai mic de 8. | + | **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> | ||
| - | ==== Observații ==== | + | <note warning> |
| - | + | Temele vor fi testate împotriva plagiatului, atat partea de cod cat si cea de prompturi LLM. Orice tentativă de copiere va fi depunctată conform [[asc:regulament|regulamentului]]. | |
| - | * Pot exista depunctări mai mari decât este specificat în secţiunea [[ #notare | Notare]] pentru implementări care nu respectă obiectivele temei și pentru situatii care nu sunt acoperite în mod automat de către sistemul de testare | + | Rezultatele notării automate este orientativă și poate fi afectată de corectarea manuală, de detaliile oferite in readme si respectiv de succesiunea de prompturi oferite so a motivelor pentru care ati ales sa folositi aceaste prompturi (este recomandat sa face acest lucru in readme). |
| - | * Implementarea şi folosirea metodelor oferite în schelet este obligatorie | + | </note> |
| - | * Puteți adăuga variabile/metode/clase, însă nu puteți schimba antetul metodelor oferite în schelet | + | |
| - | * Bug-urile de sincronizare, prin natura lor sunt nedeterministe; o temă care conţine astfel de bug-uri poate obţine punctaje diferite la rulări succesive; în acest caz punctajul temei va fi cel dat de tester în momentul corectării | + | |
| - | * Recomandăm testarea temei în cât mai multe situații de load al sistemului și pe cât mai multe sisteme pentru a descoperi bug-urile de sincronizare | + | |
| ===== Resurse necesare realizării temei ===== | ===== Resurse necesare realizării temei ===== | ||
| - | Pentru a clona [[https://gitlab.cs.pub.ro/asc/asc-public | repo-ul]] și a accesa resursele temei 1: | + | Pentru a clona [[https://gitlab.cs.pub.ro/asc/asc-public | repo-ul]] și a accesa resursele temei 3: |
| <code bash> | <code bash> | ||
| student@asc:~$ git clone https://gitlab.cs.pub.ro/asc/asc-public.git | student@asc:~$ git clone https://gitlab.cs.pub.ro/asc/asc-public.git | ||
| - | student@asc:~$ cd asc/assignments | + | student@asc:~$ cd asc-public/assignments/3-optimizari |
| - | student@asc:~/assignments$ cd 1-marketplace | + | |
| </code> | </code> | ||
| - | ===== Suport, întrebări și clarificări ===== | + | Pentru a valida corectitudinea rezultatelor puteti folosi fisierele output referinta din directorul **references**. |
| - | Pentru întrebări sau nelămuriri legate de temă folosiți [[https://curs.upb.ro/2022/mod/forum/view.php?id=144437|forumul temei]]. | + | /* |
| - | + | [[https://infrastructure.pages.upb.ro/wiki/docs/grid | Ghid pentru folosirea gridului instituțional]] | |
| - | <note important> | + | */ |
| - | Orice intrebare 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. | + | <hidden> |
| - | + | ||
| - | **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> | + | |
| + | </hidden> | ||