Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void seriell(int pNorm, int size, double *arr, int skalar);
- /**
- * Funktion: maximumNorm
- * Berechnung des Maximum aus dem Array arr fpr die parallele Abarbeitung
- * @param *arr Das Array aus dem das Maximum ermittelt werden soll
- * @param size Gibt die Größe des Arrays an
- * Rückgabewert: Mithilfe des Rückgabewertes soll der Wert des Maximums für die Parallelisierung zurückgegeben werden
- */
- double maximumNorm(double *arr, int size);
- /**
- * Funktion: maximumNormSeriell
- * Berechnung des Maximum aus dem Array arr fuer die serielle Abarbeitung
- * @param *arr Das Array aus dem das Maximum ermittelt werden soll
- * @param size Gibt die Größe des Arrays an
- * Rückgabewert: Mithilfe des Rückgabewertes soll der Wert des Maximums für die serielle Abarbeitung zurückgegeben werden
- */
- double maximumNormSeriell(double *arr, int size);
- /**
- * Funktion: arrRandom
- * Das Array arr wird mit Zufallszahlen zwischen 0 - 800 befüllt
- * @param *ArrZahlen Array wird mit Zufallszahlen befüllt
- * @param size Gibt die Größe des Arrays an
- * Rückgabewert: void, random Zahlen werden im Array gespeichert
- */
- void arrRandom(double *ArrZahlen, int size);
- /**
- * Funktion: arrayPow
- * Alle Elemente eines Arrays potenzieren
- * @param *ArrZahlen der Array, der potenziert werden soll
- * @param size Länge des Arrays
- * @param pNorm um wieviel potenziert werden soll
- * Rückgabewert: void, potenzierte Zahlen werden im Array gespeichert
- */
- void arrayPow(double *ArrZahlen, int size, int pNorm);
- static int proz = 2; //proz: Anzahl der zu nutzenden Prozesse, SEND: 1 = Send & Recv; 0 = Scatter
- int main()
- {
- MPI_Init(NULL, NULL);
- // Get the number of processes
- int world_size;
- MPI_Comm_size(MPI_COMM_WORLD, &world_size);
- // Get the rank of the process
- int world_rank;
- MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
- int size = 8000, pNorm = 1, skalar; //size = länge des Arrays size*size, Skalar = eingabe ob das Skalar berechnet werden soll oder nicht
- double erg = 0,startTime = 0, endTime = 0, inverseErg = 0, skalarErg = 0;
- double *teilArray = (double *)malloc(size*(size/proz)*sizeof(double)); //Speicherreservierung für die Teil-Arrays der einzelnen Prozesse
- double *sumArray = (double *)malloc(size*(size/proz)*sizeof(double)); //Speicherreservierung für das Ergebnis-Arrays
- double *arr = NULL; //Initialisierung des Start-Arrays
- //Pointer zum Öffnen einer Datei
- if((size > 12000) || (size < 2) || !((size % 2) == 0)){ //Programm beenden, wenn size zu groß oder zu klein gewählt wurde oder nicht durch 2 teilbar ist
- if(world_rank == 0)
- printf("Fehler: size nicht kleiner als 2 oder größer als 12000 wählen und size muss durch 2 ganzzahlig teilbar sein\n");
- free(teilArray);
- free(sumArray);
- MPI_Finalize();
- return 0;
- }
- if(world_rank == 0){ //Start Elternprozess
- arr = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung für das Start-Array
- arrRandom(array, size); //Start-Array füllen mit Zufallszahlen
- printf("1:Summennorm\t2:euklidische Norm\t3:Maximumsnorm\nEingabe: \n");
- scanf("%d", &pNorm); //Eingabe wird auf Variable pNorm gespeichert
- //testen ob Eingabewert auch 1, 2 oder 3 ist
- assert(pNorm > 0); //testen ob pNorm größer 0 ist
- assert(pNorm <= 3); //testen ob pNorm kleiner gleich 2 ist
- if((pNorm < 0) || (pNorm > 3)){ //Programm beenden, wenn keine der vorgegebenen Normen ausgewählt wurde
- if(world_rank == 0)
- printf("Fehler: pNorm muss 1 für Summennorm, 2 für euklidische Norm oder 3 für Maximumsnorm sein\n");
- return 0;
- }
- printf("Skalar berechnen:\t0:Nein\t1:Ja\n");
- scanf("%d", &skalar); //Eingabe wird auf Variable Skalar gespeichert
- if((skalar < 0) || (skalar > 1)){ //Programm beenden, wenn falsche Eingabe für die Skalar Berechnung übergeben wurde
- if(world_rank == 0)
- printf("Fehler: Skalar berechnen 1 für Ja und 2 für Nein\n");
- return 1;
- }
- seriell(pNorm, size, arr, skalar); //Abarbeitung mit nur einem Prozess
- startTime = MPI_Wtime(); //Startzeit merken
- for(int i = 1; i < proz; i++) //An alle Proz senden
- //MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
- MPI_Send(&proz,1,MPI_INT,i,0,MPI_COMM_WORLD);
- for(int i = 0; i < size*(size/proz); i++) //Teil-Array für Elternprozess erstellen
- teilArray[i] = arr[i];
- if(pNorm == 2) //alle Elemente im Array mit 2 potenzieren, wenn pNorm gleich 2 ist
- arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
- }else{ //Start Kindprozess
- //MPI_Recv(void* data,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm communicator,MPI_Status* status)
- MPI_Recv(&proz,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); //p erhalten
- if((pNorm < 0) || (pNorm > 3)){ //Programm beenden, wenn keine der vorgegebenen Normen ausgewählt wurde
- if(world_rank == 0)
- printf("Fehler: pNorm muss 1 für Summennorm, 2 für euklidische Norm oder 3 für Maximumsnorm sein\n");
- //MPI_Finalize();
- return 0;
- }
- if(pNorm == 2) //alle Elemente im Array mit 2 potenzieren, wenn pNorm gleich 2 ist
- arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
- }
- //wenn SEND Flag nicht gesetzt ist, dann Daten per MPI_Scatter() verteilen
- //MPI_Scatter(void* send_data,int send_count,MPI_Datatype send_datatype,void* recv_data,int recv_count,MPI_Datatype recv_datatype,int root,MPI_Comm communicator)
- MPI_Scatter(arr, size*(size/proz), MPI_DOUBLE,teilArray, size*(size/proz), MPI_DOUBLE, 0, MPI_COMM_WORLD);
- if((pNorm == 2)) //Teil-Array aller Prozesse mit 2 potenzieren wenn SEND Flag nicht gesetzt ist und P-Norm gleich 2 ist
- arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
- if(pNorm > 2){ //Maximum der Teil-Arrays finden
- //MPI_Reduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm communicator)
- MPI_Reduce(teilArray, sumArray, size*(size/proz), MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
- }else{ //Teil-Arrays summieren
- //MPI_Reduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm communicator)
- MPI_Reduce(teilArray, sumArray, size*(size/proz), MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
- }
- if(world_rank == 0){ //Elternprozess: Ergebnis Ausgabe
- if(pNorm == 1){
- for(int i = 0; i < size*(size/proz); i++){ //alle Summen aus den Teil-Arrays zusammen addieren
- erg += sumArray[i];
- }
- }else if(pNorm == 2){
- for(int i = 0; i < size*(size/proz); i++){ //alle Summen aus den Teil-Arrays zusammen addieren
- erg += sumArray[i];
- }
- erg = sqrt(erg); //Wurzel aus dem Gesamtergebnis ziehen
- }else{
- erg = maximumNorm(sumArray,size); //max von den teilmaximas finden
- }
- endTime = MPI_Wtime(); //Endzeit festhalten
- printf("Parallel Ergebnis\t: %lf\n",erg); //Ergebnis der parallelen Berechnung der p-Norm auf der Konsole ausgeben
- printf("Parallel Zeit\t\t: %lf\n", endTime - startTime); //Zeitaufwand der Berechnung auf der Konsole ausgeben
- if(skalar){ //Skalarberechnung starten
- inverseErg = 1/erg; //Inverse des Ergebnis berechenen
- for(int i = 0; i < size*size; i++){ //Array mit der Inversen muliplizieren und auf skalarErg aufsummieren
- skalarErg += arr[i]*inverseErg;
- }
- printf("Parallel Skalar\t\t: %lf\n", skalarErg); //Ergebnis des Skalars auf der Konsole ausgeben
- }
- }
- free(teilArray); //Teil-Arrays der Prozesse freigeben
- free(sumArray); //Ergebnis-Arrays freigeben
- MPI_Finalize(); //MPI Umgebung beenden
- return 0;
- }
- void arrayPow(double *ArrZahlen, int size, int pNorm){
- for(int i = 0; i < size*(size/proz); i++){
- ArrZahlen[i] = pow(ArrZahlen[i],pNorm);
- }
- }
- void arrRandom(double *ArrZahlen, int size){
- srand(time(NULL));
- for(int i = 0; i < size*size; i++){
- ArrZahlen[i] = rand()%800;
- // Testfälle definiert, ob die Zufallszahlen nicht unter null oder achthundert überschreiten.
- assert(a[i] >= 0);
- assert(a[i] < 800);
- }
- }
- double maximumNorm(double *arr, int size){
- double ArrZahlen = arr[0];
- for(int i = 1; i < size*(size/proz); i++){
- if(ArrZahlen < arr[i])
- ArrZahlen = arr[i];
- }
- return ArrZahlen;
- }
- double maximumNormSeriell(double *arr, int size){
- double ArrZahlen = arr[0];
- for(int i = 1; i < size*size; i++){
- if(ArrZahlen < arr[i])
- ArrZahlen = arr[i];
- }
- return ArrZahlen;
- }
- void seriell(int pNorm, int size, double *arr, int skalar){
- //FILE Pointer
- double *data = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung zum Übernehmen des Arrays aus dem Hauptprogramm
- double *zwischenErg = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung zum Zwischenspeichern
- for(int i = 0; i < size*size; i++){ //Übertragen der einzelnen Arrayelemente
- data[i] = arr[i];
- }
- double erg = 0, sErg = 0,inverseErg = 0; //Ergebnisvariablen
- double start_time = 0, end_time = 0; //Start- & Endzeit Variablen
- start_time = MPI_Wtime(); //Startzeit speichern
- if(pNorm == 1){
- for(int i = 0; i < size*size; i++){ //errechnen des Ergebnis für p-Norm 1
- erg += data[i]; //aufsummieren der Arrayelemente
- }
- printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
- }else if(pNorm == 2){ //errechnen des Ergebnis für p-Norm 2
- for(int i = 0; i < size*size; i++){
- zwischenErg[i] = pow(data[i],pNorm); //alle Zahlen mit p potenzieren
- }
- for(int i = 0; i < size*size; i++){
- erg += zwischenErg[i]; //aufsummieren der Arrayelemente
- }
- erg = sqrt(erg); //Wurzel aus dem Ergebnis ziehen
- printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
- }else if(pNorm == 3){ //Errechnung des Ergebnis für p-Norm 3
- erg = maximumNormSeriell(data, size); //Funktion im Funktionskopf beschrieben
- printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
- }
- end_time = MPI_Wtime(); //Endzeit speichern
- printf("Seriell Zeit\t\t: %lf\n", end_time - start_time); //Ergebnis der Zeitmessung
- if(skalar){ //Berechnung des Skalarprodukt
- inverseErg = 1/erg; //Inverse des Ergebnis berechenen
- for(int i = 0; i < size*size; i++){
- sErg += data[i]*inverseErg; //Array mit der Inversen muliplizieren und auf skalarErg aufsummieren
- }
- printf("Seriell Skalar\t\t: %lf\n", sErg); //Ergebnis des Skalars ausgeben
- }
- printf("-----------------------------------------------\n");
- free(data); //freigeben von Data
- free(zwischenErg); //freigeben vom Zwischenergebnis
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement