• Non ci sono risultati.

Appendice A File “

N/A
N/A
Protected

Academic year: 2021

Condividi "Appendice A File “"

Copied!
12
0
0

Testo completo

(1)

Appendice A

File “EsempioAssistantV1.ast”:

/************************************************************************ Esempio di applicazione parallela per la validazione del modello ASSISTANT

Versione iniziale dell'applicazione di esempio con implementazioni task parallel (FARM) e data parallel (MAP) dei moduli Elabora e Presenta e realizzazione sequenziale dei moduli Genera.

Tesi di Gabriele Mencagli <[email protected]>

************************************************************************/ //Versione del programma con Switching delle implementazioni parallele //realizzate mediante replicazione dei PARMOD:

//Dimensione dei vettori di input e delle righe della matrice di output //dell'applicazione:

#define N 5000

//Lunghezza degli stream prodotti dai moduli Genera_*: #define STREAMLENGTH 500

//I tempi di attesa successivi sono espressi in microsecondi: //Intervallo tra la generazione di due item di Genera_1: #define WAITGEN1 80000

//Intervallo tra la generazione di due item di Genera_2: #define WAITGEN2 70000

//Intervallo tra la generazione di due item di Genera_3: #define WAITGEN3 60000

//I tempi di attesa successivi sono espressi in secondi: //Tempo di attesa per la funzione F eseguita da Elabora: #define WAITFFUNCTION 5

//Tempo di attesa per il calcolo della matrice eseguito da Presenta: #define WAITMATRIXCOMPUTATION 120

//I tempi di attesa successivi sono espressi in microsecondi:

//Tempo di attesa per il calcolo di una riga della matrice eseguito da //Presenta:

#define WAITROWMATRIXCOMPUTATION 24000 //Define utili:

#define TASK_PARALLEL 0 #define DATA_PARALLEL 1

//Main dell'applicazione di esempio per la validazione di ASSISTANT: generic main() {

stream long[N] input1Elabora; stream long[N] input2Elabora; stream long[N] input1ElaboraFarm; stream long[N] input2ElaboraFarm;

(2)

stream long[N] input1ElaboraMap; stream long[N] input2ElaboraMap; stream long[N] outputElaboraFarm; stream long[N] outputElaboraMap; stream long[N] input2Presenta;

stream long[N] outputElaboraPerFarm; stream long[N] input2PresentaFarm; stream long[N] outputElaboraPerMap; stream long[N] input2PresentaMap; stream long[N][N] outputPresentaFarm; stream long[N][N] outputPresentaMap; stream long switchingControl1; stream long switchingControl2; Genera1(output_stream input1Elabora); Genera2(output_stream input2Elabora); Genera3(output_stream input2Presenta); EnvControl1(output_stream switchingControl1); EnvControl2(output_stream switchingControl2);

Switching1(input_stream input1Elabora, input2Elabora, switchingControl1 output_stream input1ElaboraFarm,

input2ElaboraFarm, input1ElaboraMap, input2ElaboraMap); ElaboraFarm(input_stream input1ElaboraFarm, input2ElaboraFarm

output_stream outputElaboraFarm);

ElaboraMap(input_stream input1ElaboraMap, input2ElaboraMap output_stream outputElaboraMap);

Switching2(input_stream outputElaboraFarm, outputElaboraMap, input2Presenta, switchingControl2 output_stream

outputElaboraPerFarm, input2PresentaFarm, outputElaboraPerMap, input2PresentaMap);

PresentaFarm(input_stream outputElaboraPerFarm, input2PresentaFarm output_stream outputPresentaFarm);

PresentaMap(input_stream outputElaboraPerMap, input2PresentaMap output_stream outputPresentaMap);

Stampa(input_stream outputPresentaFarm, outputPresentaMap); }

//Definizione del modulo sequenziale Genera1. Nel documento è indicato //che e' un PARMOD per adesso lo consideriamo un sequenziale:

Genera1(output_stream long input1Elabora[N]) {

generaArray1(output_stream input1Elabora); }

//Definizione del modulo sequenziale Genera2. Nel documento è indicato //che e' un PARMOD per adesso lo consideriamo un sequenziale:

Genera2(output_stream long input2Elabora[N]) {

generaArray2(output_stream input2Elabora); }

//Definizione del modulo sequenziale Genera3. Nel documento è indicato //che e' un PARMOD per adesso lo consideriamo sequenziale:

Genera3(output_stream long input2Presenta[N]) {

generaArray3(output_stream input2Presenta); }

//Proc che genera uno stream di lunghezza STREAMLENGTH di vettori di N //long random:

proc generaArray1(output_stream long v[N]) inc<"stdlib.h", "unistd.h", "time.h">

(3)

//Definisco il seed utilizzato per la generazione dei numeri //pseudocasuali dei vettori di input:

time_t tempo;

tempo = time(&tempo); srand(((int) tempo) + 1); long vettore[N];

for(int count = 0; count < STREAMLENGTH; count++){

for(int i = 0; i < N; i++) vettore[i] = 1 + (long) (100.0*rand()/(RAND_MAX + 1.0));

//Attendo per un certo tempo in modo da simulare una //specifico tempo di interpartenza:

usleep(WAITGEN1);

assist_out(v, vettore); }

}c++$

//Proc che genera uno stream di lunghezza STREAMLENGTH di vettori di N //long random:

proc generaArray2(output_stream long v[N]) inc<"stdlib.h", "unistd.h", "time.h"> $c++{

//Definisco il seed utilizzato per la generazione dei numeri //pseudocasuali dei vettori di input:

time_t tempo;

tempo = time(&tempo); srand(((int) tempo) + 2); long vettore[N];

for(int count = 0; count < STREAMLENGTH; count++){

for(int i = 0; i < N; i++) vettore[i] = 1 + (long) (100.0*rand()/(RAND_MAX + 1.0));

//Attendo per un certo tempo in modo da simulare una //specifico tempo di interpartenza:

usleep(WAITGEN2);

assist_out(v, vettore); }

}c++$

//Proc che genera uno stream di lunghezza STREAMLENGTH di vettori di N //long random:

proc generaArray3(output_stream long v[N]) inc<"stdlib.h", "unistd.h", "time.h"> $c++{

//Definisco il seed utilizzato per la generazione dei numeri //pseudocasuali dei vettori di input:

time_t tempo;

tempo = time(&tempo); srand(((int) tempo) + 3); long vettore[N];

for(int count = 0; count < STREAMLENGTH; count++){

for(int i = 0; i < N; i++) vettore[i] = 1 + (long) (100.0*rand()/(RAND_MAX + 1.0));

//Attendo per un certo tempo in modo da simulare una //specifico tempo di interpartenza:

usleep(WAITGEN3);

assist_out(v, vettore); }

}c++$

//Definizione del modulo sequenziale che produce gli eventi esterni per //il primo switching:

EnvControl1(output_stream long switchingControl1){ env_switch(output_stream switchingControl1); }

(4)

//Definizione del modulo sequenziale che produce gli eventi esterni per //il secondo switching:

EnvControl2(output_stream long switchingControl2){ env_switch(output_stream switchingControl2); }

//Proc che genera gli eventi esterni: proc env_switch(output_stream long event) inc<"fstream","iostream">

$c++{

int choice;

bool scelta = false; bool finito = false; while(!finito){

while(!scelta){

cout << "Scegli lo switching da eseguire:" << endl; cout << "0 - TASK PARALLEL" << endl;

cout << "1 - DATA PARALLEL" << endl; cout << "2 - ESCI" << endl;

cin >> choice;

if((choice == 0)||(choice == 1)||(choice == 2)) scelta = true;

}

if(choice == 2) finito = true; else assist_out(event, choice); scelta = false;

} }c++$

//PARMOD ONE che stampa le matrici ricevute da Presenta su un file: parmod Stampa(input_stream long outputPresentaFarm[N][N], long outputPresentaMap[N][N]){

topology one pv; do input_section {

guard0: on , , outputPresentaFarm {

distribution outputPresentaFarm broadcast to pv; }

guard1: on , , outputPresentaMap {

distribution outputPresentaMap broadcast to pv; }

} while(true)

virtual_processors { elab0 (in guard0) { VP {

printMatrix(in outputPresentaFarm);

}

}

elab1 (in guard1) { VP { printMatrix(in outputPresentaMap); } } } }

//Modulo sequenziale che effettua la stampa su file delle matrici //calcolate da Presenta:

proc printMatrix(in long outp[N][N]) inc<"fstream","iostream">

$c++{

static int count = 1;

cout << "Il modulo Stampa ha ricevuto la matrice " << count << "/" << STREAMLENGTH << "" << std::endl; ;

(5)

std::ofstream f;

f.open ("FileMatrici.txt", fstream::out|fstream::app);

f << "Scrittura della matrice numero " << count << std::endl; for(int i = 0; i < N; i++){

for(int j = 0; j < N; j++) f << outp[i][j] << " "; f << std::endl;

}

f << std::endl;

//Aggiorno l'indice delle matrici ricevute: count++;

//Controllo la fine dello stream: if (count > STREAMLENGTH){

//Fine della stampa su file:

f << "Fine della stampa delle matrici ricevute" << std::endl; }

f.close(); }c++$

//Proc per inizializzare l'attributo sulla modalita' di switching: proc init_attrib (out long a)

$c++{

//Inizialmente si usa un FARM: a = TASK_PARALLEL;

}c++$

//PARMOD ONE che esegue lo switching del modulo Elabora: parmod Switching1(input_stream long input1Elabora[N], long

input2Elabora[N], long switchingControl1 output_stream long input1ElaboraFarm[N], long input2ElaboraFarm[N], long input1ElaboraMap[N], long input2ElaboraMap[N]){ topology one pv;

attribute long behaviour onto pv; init {

//La modalita' di default e' TASK_PARALLEL: VP {

init_attrib (out behaviour); }

}

do input_section {

guard0: on ,, input1Elabora&&input2Elabora { distribution input1Elabora broadcast to pv;

distribution input2Elabora broadcast to pv; }

guard1: on ,, switchingControl1 {

distribution switchingControl1 broadcast to pv; }

} while(true)

virtual_processors {

elab0 (in guard0 out input1ElaboraFarm, input2ElaboraFarm, input1ElaboraMap, input2ElaboraMap) {

VP {

procSwitch(in input1Elabora, input2Elabora, behaviour output_stream input1ElaboraFarm,

input2ElaboraFarm, input1ElaboraMap, input2ElaboraMap);

}

}

elab1 (in guard1) { VP {

update_TaskMode(in switchingControl1 out behaviour);

}

(6)

}

output_section {

collects input1ElaboraFarm from ANY pv; collects input2ElaboraFarm from ANY pv; collects input1ElaboraMap from ANY pv; collects input2ElaboraMap from ANY pv; }

}

//Definizione della proc procSwitch eseguita dal parmod di Switching: proc procSwitch(in long A[N], long B[N], long mode output_stream long A1[N], long B1[N], long A2[N], long B2[N])

path<"/home/p4/mencagli/proveAssistant"> $c++{

//Effettuo lo switching in base alla modalita' attuale: if(mode == TASK_PARALLEL){ assist_out(A1, A); assist_out(B1, B); } if(mode == DATA_PARALLEL){ assist_out(A2, A); assist_out(B2, B); } }c++$

//Definizione della proc update_TaskMode eseguita dal parmod di Switching per modificare la modalita' di elaborazione:

proc update_TaskMode(in long mode out long bev) path<"/home/p4/mencagli/proveAssistant">

$c++{

if(mode == TASK_PARALLEL) cout << "ATTENZIONE MODIFICATA LA

MODALITA' DI ELABORAZIONE PASSAGGIO A TASK PARALLEL" << endl; else cout << "ATTENZIONE MODIFICATA LA MODALITA' DI ELABORAZIONE

PASSAGGIO A DATA PARALLEL" << endl;

cout <<"--- ---" << endl;

//Modifico il comportamento attuale: bev = mode;

}c++$

//Definizione del PARMOD Elabora (Versione FARM):

parmod ElaboraFarm(input_stream long input1ElaboraFarm[N], long input2ElaboraFarm[N] output_stream long outputElaboraFarm[N]) {

topology none pv; do input_section {

guard0: on ,, input1ElaboraFarm&&input2ElaboraFarm { distribution input1ElaboraFarm on_demand to pv;

distribution input2ElaboraFarm on_demand to pv; }

} while(true)

virtual_processors {

elab0 (in guard0 out outputElaboraFarm) { VP {

IteraF(in input1ElaboraFarm, input2ElaboraFarm out outputElaboraFarm);

}

} }

output_section {

collects outputElaboraFarm from ANY pv; }

}

(7)

proc IteraF(in long A[N], long B[N] out long C[N]) path<"/home/p4/mencagli/proveAssistant">

inc<"iostream","Function.h"> obj<"Function.o">

$c++{

//Attendo per un certo tempo in modo da simulare una specifico //tempo di interpartenza:

sleep(WAITFFUNCTION);

for(long i = 0; i < N; i++) C[i] = FunctionF(A[i], B);

cout << "Un worker di Elabora versione FARM ha prodotto un vettore C" << endl;

}c++$

//Definizione del PARMOD Elabora (Versione MAP):

parmod ElaboraMap(input_stream long input1ElaboraMap[N], long input2ElaboraMap[N] output_stream long outputElaboraMap[N]) { topology array [i:N] pv;

attribute long S1[N] scatter S1[*i0] onto pv[i0]; stream long ris;

do input_section {

guard0: on ,, input1ElaboraMap&&input2ElaboraMap {

distribution input1ElaboraMap[*i1] scatter to S1[i1]; distribution input2ElaboraMap broadcast to pv;

}

} while(true)

virtual_processors {

elab0 (in guard0 out ris) { VP i = 0..N-1 {

EseguiF(in S1[i], input2ElaboraMap out ris);

}

} }

output_section {

collects ris from ALL pv[i]{ long el; long local_result[N]; AST_FOR_EACH(el){ local_result[i] = el; } assist_out(outputElaboraMap, local_result); }<>; } }

//Definizione della proc EseguiF eseguita dai VP di Elabora versione MAP; proc EseguiF(in long a, long b[N] out long c)

path<"/home/p4/mencagli/proveAssistant"> inc<"iostream","Function.h">

obj<"Function.o"> $c++{

//Attendo per un certo tempo in modo da simulare una specifico //tempo di interpartenza:

usleep((WAITFFUNCTION * 1000000) / STREAMLENGTH); c = FunctionF(a, b);

cout << "Un worker di Elabora versione MAP ha prodotto un elemento della matrice C" <<endl;

}c++$

//PARMOD ONE che esegue lo switching del modulo Presenta:

parmod Switching2(input_stream long outputElaboraFarm[N], long

outputElaboraMap[N], long input2Presenta[N], long switchingControl2 output_stream long outputElaboraPerFarm[N], long

(8)

input2PresentaMap[N]){ topology one pv;

attribute bool vettorePresente; attribute long behaviour onto pv;

attribute long vettoreGenera[N] onto pv; init {

vettorePresente = false;

//La modalita' di default e' TASK_PARALLEL: VP {

init_attrib (out behaviour); }

}

do input_section {

guard0: on , !vettorePresente, input2Presenta { distribution input2Presenta broadcast to pv; operation {

vettorePresente = true; }<use {vettorePresente}> }

guard1: on ,vettorePresente, outputElaboraFarm { distribution outputElaboraFarm broadcast to pv; operation {

vettorePresente = false; }<use {vettorePresente}> }

guard2: on ,vettorePresente, outputElaboraMap { distribution outputElaboraMap broadcast to pv; operation {

vettorePresente = false; }<use {vettorePresente}> }

guard3: on ,, switchingControl2 {

distribution switchingControl2 broadcast to pv; }

} while(true)

virtual_processors { elab0 (in guard0) { VP {

updateVettore(in input2Presenta out vettoreGenera);

}

}

elab1 (in guard1 out outputElaboraPerFarm, input2PresentaFarm, outputElaboraPerMap, input2PresentaMap) { VP { procSwitch2(in outputElaboraFarm, vettoreGenera, behaviour output_stream outputElaboraPerFarm, input2PresentaFarm, outputElaboraPerMap, input2PresentaMap); } }

elab2 (in guard2) { VP {

procSwitch2(in outputElaboraMap, vettoreGenera, behaviour output_stream

outputElaboraPerFarm, input2PresentaFarm, outputElaboraPerMap, input2PresentaMap);

}

(9)

elab3 (in guard3) { VP {

update_TaskMode(in switchingControl2 out behaviour);

}

} }

output_section {

collects outputElaboraPerFarm from ANY pv; collects input2PresentaFarm from ANY pv; collects outputElaboraPerMap from ANY pv; collects input2PresentaMap from ANY pv; }

}

//Definizione della proc per aggiornare il vettore ricevuto da Genera_3: proc updateVettore(in long input2Presenta[N] out long vettoreGenera[N]) path<"/home/p4/mencagli/proveAssistant">

$c++{

for(int i = 0; i < N; i++) vettoreGenera[i] = input2Presenta[i]; }c++$

//Definizione della proc procSwitch eseguita dal PARMOD di Switching 2: proc procSwitch2(in long C[N], long D[N], long mode output_stream long

C1[N], long D1[N], long C2[N], long D2[N]) path<"/home/p4/mencagli/proveAssistant">

$c++{

//Effettuo lo switching in base alla modalita' attuale: if(mode == TASK_PARALLEL){ assist_out(C1, C); assist_out(D1, D); } if(mode == DATA_PARALLEL){ assist_out(C2, C); assist_out(D2, D); } }c++$

//Definizione del PARMOD Presenta (Versione FARM):

parmod PresentaFarm(input_stream long outputElaboraPerFarm[N], long input2PresentaFarm[N] output_stream long outputPresentaFarm[N][N]) {

topology none pv; do input_section {

guard0: on ,, outputElaboraPerFarm&&input2PresentaFarm { distribution outputElaboraPerFarm on_demand to pv;

distribution input2PresentaFarm on_demand to pv; }

} while(true)

virtual_processors {

elab0 (in guard0 out outputPresentaFarm) { VP {

CalcoloMatrice(in outputElaboraPerFarm,

input2PresentaFarm out outputPresentaFarm);

}

} }

output_section {

collects outputPresentaFarm from ANY pv; }

}

//Definizione della proc CalcoloMatrice eseguita dai VP di Presenta //versione FARM;

(10)

proc CalcoloMatrice(in long C[N], long D[N] out long E[N][N]) path<"/home/p4/mencagli/proveAssistant">

inc<"iostream","Function.h"> obj<"Function.o">

$c++{

//Attendo per un certo tempo in modo da simulare una specifico //tempo di interpartenza: sleep(WAITMATRIXCOMPUTATION); for(int i = 0; i < N; i++){ for(int j = 0; j < N; j++){ E[i][j] = FunctionG(C[i], D[j]); } }

cout << "Un worker di Presenta versione FARM ha prodotto una matrice E" << endl;

}c++$

//Definizione del PARMOD Presenta (Versione MAP):

parmod PresentaMap(input_stream long outputElaboraPerMap[N], long

input2PresentaMap[N] output_stream long outputPresentaMap[N][N]) { topology array [i:N] pv;

attribute long S2[N] scatter S2[*i0] onto pv[i0]; stream long ris[N];

do input_section {

guard0: on ,, outputElaboraPerMap&&input2PresentaMap { distribution outputElaboraPerMap[*i1] scatter to

S2[i1];

distribution input2PresentaMap broadcast to pv; }

} while(true)

virtual_processors {

elab0 (in guard0 out ris) { VP i = 0..N-1 {

ProdottoRowMatrix(in S2[i], input2PresentaMap out ris);

}

} }

output_section {

collects ris from ALL pv[i] {

static long result[N][N]; const long *el;

AST_FOR_EACH(el) { for(int j = 0;j < N;j++) result[i][j]=el[j]; } assist_out(outputPresentaMap,result); }<>; } }

//Definizione della proc ProdottoRowMatrix eseguita dai VP di Presenta //versione MAP:

proc ProdottoRowMatrix(in long c, long d[N] out long e[N]) path<"/home/p4/mencagli/proveAssistant">

inc<"iostream","Function.h"> obj<"Function.o">

$c++{

for(int i = 0; i < N; i++){ e[i] = FunctionG(c, d[i]); }

//Attendo per un certo tempo in modo da simulare una specifico //tempo di interpartenza:

(11)

cout << "Un worker di Presenta versione MAP ha prodotto una riga della matrice E" << endl;

}c++$

File “Function.h”:

/************************************************************************ Esempio di applicazione parallela per la validazione del modello

ASSISTANT

Versione iniziale dell'applicazione di esempio con implementazioni task parallel (FARM) e data parallel (MAP) dei moduli Elabora e Presenta e realizzazione sequenziale dei moduli Genera.

Tesi di Gabriele Mencagli <[email protected]>

************************************************************************/ //Dimensione dei vettori di input e della matrice di output

dell'applicazione: #define N 1000

//Funzione sequenziale F di elaborazione dei dati del modulo Elabora: long FunctionF(long A, long *B);

//Funzione sequenziale G di elaborazione dei dati del modulo Genera: long FunctionG(long C, long D);

File “Function.cpp”:

/************************************************************************ Esempio di applicazione parallela per la validazione del modello

ASSISTANT

Versione iniziale dell'applicazione di esempio con implementazioni task parallel (FARM) e data parallel (MAP) dei moduli Elabora e Presenta e realizzazione sequenziale dei moduli Genera.

Tesi di Gabriele Mencagli <[email protected]>

************************************************************************/ #include <iostream>

#include "Function.h"

//Funzione sequenziale F di elaborazione dei dati del modulo Elabora: long FunctionF(long A, long *B){

//Il calcolo eseguito dalla funzione per adesso e' banale ma si puo' modificare con

//qualcosa di piu' significativo: long count = 0; for(int i = 0; i < N; i++){ count += B[i]; } return A + (count / N); }

(12)

//Funzione sequenziale G di elaborazione dei dati del modulo Genera: long FunctionG(long C, long D){

long result;

//Il calcolo eseguito dalla funzione per adesso e' banale ma si puo' modificare con

//qualcosa di piu' significativo: if(C > D) result = C - D;

else result = D - C; return result;

Riferimenti

Documenti correlati

Plantago crassifolia Forskal - Circummedit - comune in luoghi sabbioso-limosi salsi e ricchi di N organico litorale orientale, rara altrove; (Giunco).. Plantago

% LA SCELTA DELLE MATRICI avviene in finestra_matrix % LA SCELTA DEL FILE AUTOMETRIX avviene in finestra1; % SE:. % nessuna scelta relativa al tipo di file da importare %

Total number

si sviluppi nella sua interezza, “2” se si vuole escludere il pre-processing ed il calcolo della matrice delle impedenze (nel caso in cui si voglia, ad esempio, analizzare più

■ Per accedere ad un file memorizzato su un’unità fisica (di qualunque tipo), è necessario creare un collegamento tra il file oggetto dell'operazione e una variabile di tipo

We shall only be using these general forms of finite fields when discussing the Rijndael block cipher, stream ciphers based on linear feedback shift registers and when we look

• Le operazioni di lettura e scrittura su file ad accesso random fanno uso di un indice che si può spostare con le funzioni lseek (basso livello) e fseek (stream). • Ovviamente non

Per aprire uno stream di output occorre dichiarare che appartiene alla classe ofstream: ofstream out;.. Uno stream che eseguirà operazioni di input ed output deve appartenere