Advertisement
Guest User

Untitled

a guest
Mar 25th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.93 KB | None | 0 0
  1. void seriell(int pNorm, int size, double *arr, int skalar);
  2.  
  3. /**
  4. * Funktion: maximumNorm
  5. * Berechnung des Maximum aus dem Array arr fpr die parallele Abarbeitung
  6. * @param *arr Das Array aus dem das Maximum ermittelt werden soll
  7. * @param size Gibt die Größe des Arrays an
  8. * Rückgabewert: Mithilfe des Rückgabewertes soll der Wert des Maximums für die Parallelisierung zurückgegeben werden
  9. */
  10. double maximumNorm(double *arr, int size);
  11.  
  12. /**
  13. * Funktion: maximumNormSeriell
  14. * Berechnung des Maximum aus dem Array arr fuer die serielle Abarbeitung
  15. * @param *arr Das Array aus dem das Maximum ermittelt werden soll
  16. * @param size Gibt die Größe des Arrays an
  17. * Rückgabewert: Mithilfe des Rückgabewertes soll der Wert des Maximums für die serielle Abarbeitung zurückgegeben werden
  18. */
  19. double maximumNormSeriell(double *arr, int size);
  20.  
  21. /**
  22. * Funktion: arrRandom
  23. * Das Array arr wird mit Zufallszahlen zwischen 0 - 800 befüllt
  24. * @param *ArrZahlen Array wird mit Zufallszahlen befüllt
  25. * @param size Gibt die Größe des Arrays an
  26. * Rückgabewert: void, random Zahlen werden im Array gespeichert
  27. */
  28. void arrRandom(double *ArrZahlen, int size);
  29.  
  30. /**
  31. * Funktion: arrayPow
  32. * Alle Elemente eines Arrays potenzieren
  33. * @param *ArrZahlen der Array, der potenziert werden soll
  34. * @param size Länge des Arrays
  35. * @param pNorm um wieviel potenziert werden soll
  36. * Rückgabewert: void, potenzierte Zahlen werden im Array gespeichert
  37. */
  38. void arrayPow(double *ArrZahlen, int size, int pNorm);
  39.  
  40. static int proz = 2; //proz: Anzahl der zu nutzenden Prozesse, SEND: 1 = Send & Recv; 0 = Scatter
  41.  
  42. int main()
  43. {
  44. MPI_Init(NULL, NULL);
  45. // Get the number of processes
  46. int world_size;
  47. MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  48.  
  49. // Get the rank of the process
  50. int world_rank;
  51. MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  52.  
  53. int size = 8000, pNorm = 1, skalar; //size = länge des Arrays size*size, Skalar = eingabe ob das Skalar berechnet werden soll oder nicht
  54. double erg = 0,startTime = 0, endTime = 0, inverseErg = 0, skalarErg = 0;
  55. double *teilArray = (double *)malloc(size*(size/proz)*sizeof(double)); //Speicherreservierung für die Teil-Arrays der einzelnen Prozesse
  56. double *sumArray = (double *)malloc(size*(size/proz)*sizeof(double)); //Speicherreservierung für das Ergebnis-Arrays
  57. double *arr = NULL; //Initialisierung des Start-Arrays
  58. //Pointer zum Öffnen einer Datei
  59.  
  60. 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
  61. if(world_rank == 0)
  62. printf("Fehler: size nicht kleiner als 2 oder größer als 12000 wählen und size muss durch 2 ganzzahlig teilbar sein\n");
  63. free(teilArray);
  64. free(sumArray);
  65. MPI_Finalize();
  66. return 0;
  67. }
  68.  
  69. if(world_rank == 0){ //Start Elternprozess
  70. arr = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung für das Start-Array
  71. arrRandom(array, size); //Start-Array füllen mit Zufallszahlen
  72. printf("1:Summennorm\t2:euklidische Norm\t3:Maximumsnorm\nEingabe: \n");
  73. scanf("%d", &pNorm); //Eingabe wird auf Variable pNorm gespeichert
  74. //testen ob Eingabewert auch 1, 2 oder 3 ist
  75. assert(pNorm > 0); //testen ob pNorm größer 0 ist
  76. assert(pNorm <= 3); //testen ob pNorm kleiner gleich 2 ist
  77. if((pNorm < 0) || (pNorm > 3)){ //Programm beenden, wenn keine der vorgegebenen Normen ausgewählt wurde
  78. if(world_rank == 0)
  79. printf("Fehler: pNorm muss 1 für Summennorm, 2 für euklidische Norm oder 3 für Maximumsnorm sein\n");
  80. return 0;
  81. }
  82. printf("Skalar berechnen:\t0:Nein\t1:Ja\n");
  83. scanf("%d", &skalar); //Eingabe wird auf Variable Skalar gespeichert
  84. if((skalar < 0) || (skalar > 1)){ //Programm beenden, wenn falsche Eingabe für die Skalar Berechnung übergeben wurde
  85. if(world_rank == 0)
  86. printf("Fehler: Skalar berechnen 1 für Ja und 2 für Nein\n");
  87. return 1;
  88. }
  89.  
  90. seriell(pNorm, size, arr, skalar); //Abarbeitung mit nur einem Prozess
  91.  
  92. startTime = MPI_Wtime(); //Startzeit merken
  93.  
  94. for(int i = 1; i < proz; i++) //An alle Proz senden
  95. //MPI_Send(void* data, int count, MPI_Datatype datatype, int destination, int tag, MPI_Comm communicator)
  96. MPI_Send(&proz,1,MPI_INT,i,0,MPI_COMM_WORLD);
  97.  
  98.  
  99. for(int i = 0; i < size*(size/proz); i++) //Teil-Array für Elternprozess erstellen
  100. teilArray[i] = arr[i];
  101.  
  102. if(pNorm == 2) //alle Elemente im Array mit 2 potenzieren, wenn pNorm gleich 2 ist
  103. arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
  104.  
  105. }else{ //Start Kindprozess
  106. //MPI_Recv(void* data,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm communicator,MPI_Status* status)
  107. MPI_Recv(&proz,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD, MPI_STATUS_IGNORE); //p erhalten
  108.  
  109. if((pNorm < 0) || (pNorm > 3)){ //Programm beenden, wenn keine der vorgegebenen Normen ausgewählt wurde
  110. if(world_rank == 0)
  111. printf("Fehler: pNorm muss 1 für Summennorm, 2 für euklidische Norm oder 3 für Maximumsnorm sein\n");
  112. //MPI_Finalize();
  113. return 0;
  114. }
  115.  
  116. if(pNorm == 2) //alle Elemente im Array mit 2 potenzieren, wenn pNorm gleich 2 ist
  117. arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
  118.  
  119. }
  120. //wenn SEND Flag nicht gesetzt ist, dann Daten per MPI_Scatter() verteilen
  121. //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)
  122. MPI_Scatter(arr, size*(size/proz), MPI_DOUBLE,teilArray, size*(size/proz), MPI_DOUBLE, 0, MPI_COMM_WORLD);
  123.  
  124. if((pNorm == 2)) //Teil-Array aller Prozesse mit 2 potenzieren wenn SEND Flag nicht gesetzt ist und P-Norm gleich 2 ist
  125. arrayPow(teilArray, size, pNorm); //Funktionserklärung siehe Funktionskopf
  126.  
  127. if(pNorm > 2){ //Maximum der Teil-Arrays finden
  128. //MPI_Reduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm communicator)
  129. MPI_Reduce(teilArray, sumArray, size*(size/proz), MPI_DOUBLE, MPI_MAX, 0, MPI_COMM_WORLD);
  130. }else{ //Teil-Arrays summieren
  131. //MPI_Reduce(void* send_data,void* recv_data,int count,MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm communicator)
  132. MPI_Reduce(teilArray, sumArray, size*(size/proz), MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  133. }
  134.  
  135. if(world_rank == 0){ //Elternprozess: Ergebnis Ausgabe
  136. if(pNorm == 1){
  137. for(int i = 0; i < size*(size/proz); i++){ //alle Summen aus den Teil-Arrays zusammen addieren
  138. erg += sumArray[i];
  139. }
  140. }else if(pNorm == 2){
  141. for(int i = 0; i < size*(size/proz); i++){ //alle Summen aus den Teil-Arrays zusammen addieren
  142. erg += sumArray[i];
  143. }
  144. erg = sqrt(erg); //Wurzel aus dem Gesamtergebnis ziehen
  145. }else{
  146. erg = maximumNorm(sumArray,size); //max von den teilmaximas finden
  147. }
  148. endTime = MPI_Wtime(); //Endzeit festhalten
  149. printf("Parallel Ergebnis\t: %lf\n",erg); //Ergebnis der parallelen Berechnung der p-Norm auf der Konsole ausgeben
  150. printf("Parallel Zeit\t\t: %lf\n", endTime - startTime); //Zeitaufwand der Berechnung auf der Konsole ausgeben
  151. if(skalar){ //Skalarberechnung starten
  152. inverseErg = 1/erg; //Inverse des Ergebnis berechenen
  153. for(int i = 0; i < size*size; i++){ //Array mit der Inversen muliplizieren und auf skalarErg aufsummieren
  154. skalarErg += arr[i]*inverseErg;
  155. }
  156. printf("Parallel Skalar\t\t: %lf\n", skalarErg); //Ergebnis des Skalars auf der Konsole ausgeben
  157. }
  158.  
  159. }
  160. free(teilArray); //Teil-Arrays der Prozesse freigeben
  161. free(sumArray); //Ergebnis-Arrays freigeben
  162. MPI_Finalize(); //MPI Umgebung beenden
  163. return 0;
  164. }
  165.  
  166. void arrayPow(double *ArrZahlen, int size, int pNorm){
  167. for(int i = 0; i < size*(size/proz); i++){
  168. ArrZahlen[i] = pow(ArrZahlen[i],pNorm);
  169. }
  170. }
  171.  
  172. void arrRandom(double *ArrZahlen, int size){
  173. srand(time(NULL));
  174. for(int i = 0; i < size*size; i++){
  175. ArrZahlen[i] = rand()%800;
  176. // Testfälle definiert, ob die Zufallszahlen nicht unter null oder achthundert überschreiten.
  177. assert(a[i] >= 0);
  178. assert(a[i] < 800);
  179. }
  180. }
  181.  
  182. double maximumNorm(double *arr, int size){
  183. double ArrZahlen = arr[0];
  184. for(int i = 1; i < size*(size/proz); i++){
  185. if(ArrZahlen < arr[i])
  186. ArrZahlen = arr[i];
  187. }
  188. return ArrZahlen;
  189. }
  190.  
  191. double maximumNormSeriell(double *arr, int size){
  192. double ArrZahlen = arr[0];
  193. for(int i = 1; i < size*size; i++){
  194. if(ArrZahlen < arr[i])
  195. ArrZahlen = arr[i];
  196. }
  197. return ArrZahlen;
  198. }
  199.  
  200. void seriell(int pNorm, int size, double *arr, int skalar){
  201. //FILE Pointer
  202. double *data = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung zum Übernehmen des Arrays aus dem Hauptprogramm
  203. double *zwischenErg = (double *)malloc(size*size*sizeof(double)); //Speicherreservierung zum Zwischenspeichern
  204. for(int i = 0; i < size*size; i++){ //Übertragen der einzelnen Arrayelemente
  205. data[i] = arr[i];
  206. }
  207. double erg = 0, sErg = 0,inverseErg = 0; //Ergebnisvariablen
  208. double start_time = 0, end_time = 0; //Start- & Endzeit Variablen
  209.  
  210. start_time = MPI_Wtime(); //Startzeit speichern
  211. if(pNorm == 1){
  212. for(int i = 0; i < size*size; i++){ //errechnen des Ergebnis für p-Norm 1
  213. erg += data[i]; //aufsummieren der Arrayelemente
  214. }
  215. printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
  216. }else if(pNorm == 2){ //errechnen des Ergebnis für p-Norm 2
  217. for(int i = 0; i < size*size; i++){
  218. zwischenErg[i] = pow(data[i],pNorm); //alle Zahlen mit p potenzieren
  219. }
  220. for(int i = 0; i < size*size; i++){
  221. erg += zwischenErg[i]; //aufsummieren der Arrayelemente
  222. }
  223. erg = sqrt(erg); //Wurzel aus dem Ergebnis ziehen
  224. printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
  225. }else if(pNorm == 3){ //Errechnung des Ergebnis für p-Norm 3
  226. erg = maximumNormSeriell(data, size); //Funktion im Funktionskopf beschrieben
  227. printf("Seriell Ergebnis\t: %lf\n", erg); //Ergebnis ausgeben
  228. }
  229. end_time = MPI_Wtime(); //Endzeit speichern
  230. printf("Seriell Zeit\t\t: %lf\n", end_time - start_time); //Ergebnis der Zeitmessung
  231.  
  232. if(skalar){ //Berechnung des Skalarprodukt
  233. inverseErg = 1/erg; //Inverse des Ergebnis berechenen
  234. for(int i = 0; i < size*size; i++){
  235. sErg += data[i]*inverseErg; //Array mit der Inversen muliplizieren und auf skalarErg aufsummieren
  236. }
  237. printf("Seriell Skalar\t\t: %lf\n", sErg); //Ergebnis des Skalars ausgeben
  238. }
  239. printf("-----------------------------------------------\n");
  240.  
  241.  
  242.  
  243. free(data); //freigeben von Data
  244. free(zwischenErg); //freigeben vom Zwischenergebnis
  245. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement