Differences

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

Link to this comparison view

isrm:laboratoare:new:02 [2020/03/01 01:46]
vlad.traista [[01] Grafic throughput]
isrm:laboratoare:new:02 [2021/03/15 13:55] (current)
dragos.niculescu
Line 1: Line 1:
-====== Laborator 02: Plotting, tracing ======+====== Laborator 02: Scripting, plotting, tracing ======
  
  
Line 10: Line 10:
 {{:​isrm:​laboratoare:​02:​schema.png?​600|}} {{:​isrm:​laboratoare:​02:​schema.png?​600|}}
  
-Rularea succesiva cu argumente variabile/​dinamice va putea fi automatizata prin intermediul unui script Bash. In mod ideal, acest script ar trebui sa salveze datele de interes intr-un fisier (.CSV preferabil) pentru a putea fi folosit ulterior pentru a obtine grafice.+Rularea succesiva cu argumente variabile/​dinamice va putea fi automatizata prin intermediul unui script ​''​Bash''​. In mod ideal, acest script ar trebui sa salveze datele de interes intr-un fisier (.CSV preferabil) pentru a putea fi folosit ulterior pentru a obtine grafice.
  
-Pentru realizarea graficelor, ne vom folosi de limbajul [[https://​www.python.org/​downloads/​|Python]],​ de modulul de Python [[https://​matplotlib.org/​|matplotlib]] si de pachetul [[https://​jupyter.org/​|Jupyter Notebook]] pentru o vizualizare mai usoara a graficelor. Jupyter Notebook este o aplicatie care porneste un server web local si care permite rularea de cod (Python, Java, etc) in cadrul unei pagini web locale care poarta numele de notebook.+Pentru realizarea graficelor, ne vom folosi de limbajul [[https://​www.python.org/​downloads/​|Python]],​ de modulul de ''​Python'' ​[[https://​matplotlib.org/​|matplotlib]] si de pachetul [[https://​jupyter.org/​|Jupyter Notebook]] pentru o vizualizare mai usoara a graficelor. ​''​Jupyter Notebook'' ​este o aplicatie care porneste un server web local si care permite rularea de cod (''​Python''​''​Java''​, etc) in cadrul unei pagini web locale care poarta numele de ''​notebook''​.
  
  
-=====  ​Instalare si configurare ​===== +=====  ​Jupyter notebook ​=====
- +
-Pe calculatoare este deja instalat Python 3, astfel ca sunt suficienti urmatorii pasi pentru a instala pachetele necesare: +
- +
-<code bash> +
-student@isrm-vm-2020:​~$ sudo apt-get update +
-student@isrm-vm-2020:​~$ sudo apt-get install python3-pip +
-student@isrm-vm-2020:​~$ pip3 install matplotlib jupyter +
-student@isrm-vm-2020:​~$ sudo ln -s ~/​.local/​bin/​jupyter-notebook /​usr/​bin/​jupyter-notebook +
-</​code>​+
  
 Pentru a lansa aplicatia de Jupyter Notebook, rulati urmatoarea comanda: Pentru a lansa aplicatia de Jupyter Notebook, rulati urmatoarea comanda:
Line 43: Line 34:
  
 Odata intrati pe pagina web, putem trece la crearea unui notebook (butonul **New** -> **Python3**) Odata intrati pe pagina web, putem trece la crearea unui notebook (butonul **New** -> **Python3**)
 +
 +=====  Github classroom =====
 +
 +In cadrul laboratoarelor de ISRM, vom folosi Github classroom pentru a urca rezolvarile exercitiilor,​ pentru a primi feedback pe rezolvari/​interpretari si pentru a primi nota pe laborator.
 +
 +Inainte de a porni cu laboratorul,​ urmati pasii mentionati [[https://​ocw.cs.pub.ro/​courses/​smd/​laboratoare/​00#​github_classroom_repository|aici]].
 +
 +Workflow-ul cu git va fi similar cu cel de [[https://​ocw.cs.pub.ro/​courses/​smd/​laboratoare/​00#​versioning|aici]].
 +
 +Fisierele de interes care vor trebui urcate intr-un pull request de Git incepand cu al treilea laborator sunt urmatoarele:​
 +  * scripturi bash sau alte fisiere prin care automatizati rularea
 +  * fisierele de output in care salvati rezultatele obtinute in urma rularii scripturilor
 +  * graficele (fisiere .png) / notebook-ul Jupyter aferent laboratorului
 +  * un fisier README in care interpretati/​analizati rezultatele obtinute
  
 ===== Plotarea datelor simple ===== ===== Plotarea datelor simple =====
Line 75: Line 80:
 # de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['​x',​ '​y'​] # de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['​x',​ '​y'​]
 # ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['​x'​]. # ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['​x'​].
-sim_data = np.genfromtxt(DATA_FILE,​ delimiter='​ ', skip_header=2,​ names=columns)+# Argumentul dtype setat specifica modul in care vor fi interpretate coloanele (string-urile ca string-uri, float-urile ca float-uri). 
 +# In absenta acestui argument, valorile din coloane vor fi interpretate ca float. 
 +sim_data = np.genfromtxt(DATA_FILE,​ delimiter='​ ', skip_header=2,​ names=columns, dtype=None)
  
 def plot_data(sim_data):​ def plot_data(sim_data):​
Line 104: Line 111:
 {{ :​isrm:​laboratoare:​02:​gnuplot:​plotting_data1.png?​nolink |}} {{ :​isrm:​laboratoare:​02:​gnuplot:​plotting_data1.png?​nolink |}}
  
 +Pentru a include mai multe subgrafice in cadrul aceluiasi grafic, este suficient sa apelam ''​ax.plot''​ pentru fiecare subgrafic nou:
 +
 +<code python>
 +import copy
 +import numpy as np
 +import matplotlib
 +import matplotlib.pyplot as plt
 +
 +# Calea absoluta catre fisierul de date din care citim
 +# TODO - trebuie inlocuita cu calea corecta
 +DATA_FILE = '/​home/​student/​plotting_data1.csv'​
 +columns = ['​x',​ '​y'​]
 +
 +# Citim datele din fisier
 +# Argumentul delimiter precizeaza care este delimitatorul dintre coloane
 +# Argumentul skip_header precizeaza cate linii nu vor fi citite pornind cu inceputul fisierului
 +# Argumentul names este unul foarte util deoarece permite asocierea de nume pentru coloanele din fisier si
 +# de asemenea duce la un acces foarte usor al datelor in script. In acest exemplu, names va fi egal cu ['​x',​ '​y'​]
 +# ceea ce inseamna ca putem accesa valorile din prima coloana prin sim_data['​x'​].
 +# Argumentul dtype setat specifica modul in care vor fi interpretate coloanele (string-urile ca string-uri, float-urile ca float-uri).
 +# In absenta acestui argument, valorile din coloane vor fi interpretate ca float.
 +sim_data = np.genfromtxt(DATA_FILE,​ delimiter='​ ', skip_header=2,​ names=columns,​ dtype=None)
 +
 +def plot_data(sim_data):​
 +    data = copy.deepcopy(sim_data)
 +
 +    # Apelul subplots poate fi folosit pentru a crea mai multe subgrafice in cadrul aceluiasi grafic sau in cadrul unor grafice diferite
 +    # Prin figsize se specifica dimensiunea graficului
 +    fig, ax = plt.subplots(figsize=(12,​12))
 +    # Valori stilistice pentru grafic
 +    ax.grid(color='​b',​ alpha=0.5, linestyle='​dashed',​ linewidth=0.5)
 +    # Denumirile axelor Ox si Oy, precum si titlul graficului
 +    plt.xlabel('​X values'​)
 +    plt.ylabel('​Y values'​)
 +    plt.title('​A very nice looking plot')
 +
 +    # Aici este construit efectiv graficul. Campul label va fi folosit in cadrul legendei graficului
 +    ax.plot(data['​x'​],​ data['​y'​],​ label='​My plot')
 +    ax.plot(data['​y'​],​ data['​x'​],​ label='​My secondary plot')
 +    ax.legend()
 +    ​
 +    plt.show()
 +
 +
 +if __name__ == '​__main__':​
 +    plot_data(sim_data)
 +</​code>​
 ==== Date cu erori ==== ==== Date cu erori ====
  
Line 147: Line 201:
  
 # Citim datele din fisier # Citim datele din fisier
-sim_data = np.genfromtxt(DATA_FILE,​ delimiter='​ ', skip_header=2,​ names=columns)+sim_data = np.genfromtxt(DATA_FILE,​ delimiter='​ ', skip_header=2,​ names=columns, dtype=None)
  
 def plot_data(sim_data):​ def plot_data(sim_data):​
Line 349: Line 403:
 </​code>​ </​code>​
  
-<code bash> 
-awc() { awk "​BEGIN{print $*}"; } 
-for i in `seq 10 2 20`; do awc "$i / 10"; done 
-</​code>​ 
  
 ====  Aritmetica în shell scripting ==== ====  Aritmetica în shell scripting ====
  
-Bash face toate calculele pe integer. ​+Bash face **toate calculele pe integer**, deci nu poate fi folosit pentru a calcula medii (mean, median, standard deviation)  
 <code bash> <code bash>
-x=5; echo $(($x / 3))+x=5; echo $(($x / 3)) 
 +1
 </​code>​ </​code>​
  
 <code bash> <code bash>
-x=24 +x=24 
-y=25 +y=25 
-b=`expr $x = $y`         # Test equality. +b=`expr $x = $y`         # Test equality. 
-echo "b = $b" ​           # 0  ( $x -ne $y ) +echo "b = $b" ​           # 0  ( $x -ne $y ) 
-echo+b = 0 
 </​code>​ </​code>​
 +
  
 Putem folosi utilitarul ''​bc''​ cu pipe pentru calcule în floating point: Putem folosi utilitarul ''​bc''​ cu pipe pentru calcule în floating point:
  
 <code bash> <code bash>
-echo '6.5 / 2.7' | bc +echo '6.5 / 2.7' | bc 
-echo '​scale=3;​ 6.5/​2.7'​ | bc+
 +echo '​scale=3;​ 6.5/​2.7'​ | bc 
 +2.407 
 </​code>​ </​code>​
 +
 +<code bash>
 +$ awc() { awk "​BEGIN{print $*}"; }
 +$ for i in `seq 1 1 4`; do awc "$i + sqrt($i)";​ done
 +2
 +3.41421
 +4.73205
 +6
 +</​code>​
 +
 +
 +
 +===== Procesare multicore ===== 
 +
 +Majoritatea graficelor pe care dorim sa le plotăm se folosesc de același script de simulare pe care îl rulăm cu parametri diferiți, iar la final recoltăm din outputul lui una sau mai multe valori. Dacă simularea nu folosește resurse temporare care pot duce la race conditions, se poate rula în paralel pentru a putea folosi core-urile existente. Utilitarul ''​GNU parallel''​ este potrivit pentru acest job, întrucât detectează automat numărul de core-uri, și are multe opțiuni pentru scriptare (nu toate naturale). ​
 +
 +Exemple simple: ​
 +<code bash> ​
 +$ parallel echo "{1} a{2}" ::: $(seq 1 1 3) ::: $(seq 100 102) 
 +1 a100
 +1 a101
 +1 a102
 +2 a100
 +2 a101
 +2 a102
 +3 a100
 +3 a101
 +3 a102
 +</​code>​
 +
 +Un gotcha este rularea mai multor comenzi shell care este posibilă doar prin înglobarea lor într-o funcție sau script separat:
 +
 +<​code>​
 +
 +$ cat > batch 
 +sleep $1
 +echo $2
 +$ parallel ​ ./batch ::: $(seq 3 -1 1) ::: $(seq 100 102) 
 +100
 +100
 +101
 +102
 +100
 +101
 +101
 +102
 +102
 +</​code>​
 +
 +
 +Un altul este afișarea rezultatelor taskurilor în ordine secvențială,​ nu atunci când se termină fiecare: ​  
 +
 +<​code>​
 +$ parallel -k  bash ./batch ::: $(seq 3 -1 1) ::: $(seq 100 102) 
 +100
 +101
 +102
 +100
 +101
 +102
 +100
 +101
 +102
 +</​code>​
 +
 +
 +Exemplu care poate fi adesea refolosit în acest semestru: ​      
 +
 +<​code>​
 +$ function run_fixed(){
 +    echo  -n "$1 $2 "
 +    ./waf --run "​lab6-7-cw ​ --payloadSize=212 ​ --ns=$1 --nd=$1 --minCw=$2 --maxCw=$2 --pcap=false"​ | tail -n1 
 +}
 +
 +$ export -f run_fixed
 +
 +$ parallel -k run_fixed {1} {2} ::: 4 6 7 20 40 ::: 3 7 15 31 63 127 255 511 1023 2047 4095
 +</​code>​
 +
 +Acest exemplu rulează scriptul ns3 pentru toate combinațiile de parametri minCw si maxCw listate în secventele separate de :::
 +Opțiunea -k asigură afișarea rezultatelor în ordine, chiar dacă în realitate se rulează în paralel pe mai multe core-uri, si unele taskuri se termină mai repede.  ​
 +
 +
 +
  
 ====  [OPȚIONAL] Trasare de grafice cu gnuplot ==== ====  [OPȚIONAL] Trasare de grafice cu gnuplot ====
Line 545: Line 684:
  
 {{:​isrm:​laboratoare:​new:​tcp_tput_evolution.png}} {{:​isrm:​laboratoare:​new:​tcp_tput_evolution.png}}
 +
 +===== [02] Basic shell scripting =====
 +
 +Fișierul ''/​proc/​net/​dev''​ conține toate interfețele de rețea care sunt în sistem. Iată exemplu de cum arată:
 +
 +<code bash>
 +mihai@wormhole:​~$ cat /​proc/​net/​dev
 +Inter-| ​  ​Receive ​                                               |  Transmit
 + face |bytes ​   packets errs drop fifo frame compressed multicast|bytes ​   packets errs drop fifo colls carrier compressed
 + ​ens33:​ 401898492 1164147 ​   0   ​15 ​   0     ​0 ​         0         0 387589434 ​ 843816 ​   0    0    0     ​0 ​      ​0 ​         0
 +    lo: 404014153 1015835 ​   0    0    0     ​0 ​         0         0 404014153 1015835 ​   0    0    0     ​0 ​      ​0 ​         0
 +</​code>​
 +
 +Fișierul ''/​proc/​net/​snmp''​ conține informații despre pachete recepționate de tip TCP/UDP pe sockeții din sistem. Iată un exemplu:
 +
 +<code bash>
 +mihai@wormhole:​~$ cat /​proc/​net/​snmp
 +Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout Re                  asmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
 +Ip: 2 64 1932581 0 4 0 0 0 1925281 1673627 20 8 0 0 0 0 0 0 0
 +Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddr ​                 MaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutA                  ddrMaskReps
 +Icmp: 46 0 0 45 0 0 0 0 0 1 0 0 0 0 41 0 40 0 0 0 0 1 0 0 0 0 0
 +IcmpMsg: InType0 InType3 OutType3 OutType8
 +IcmpMsg: 1 45 40 1
 +Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
 +Tcp: 1 200 120000 -1 4228 2576 2818 50 19 1698398 1812313 1563 5 3074 0
 +Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti
 +Udp: 52986 40 0 21899 0 0 0 198401
 +UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors IgnoredMulti
 +UdpLite: 0 0 0 0 0 0 0 0
 +</​code>​
 +
 +Iterați pe conținutul acestor fișiere și afișați datele într-un format cu coloane. Datele vor fi separate printr-un singur spațiu:
 +
 +<​code>​
 +iface_name packets_receive packets_transmit drops_receive drops_transmit
 +</​code>​
 +
 +<​code>​
 +InUdpDatagrams InUdpErrors TcpInSegs TcpRetransSegs
 +</​code>​
 +
isrm/laboratoare/new/02.1583019963.txt.gz · Last modified: 2020/03/01 01:46 by vlad.traista
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