Commit a67a1dd2b58c27862714a21269b2f77b69304b74

Authored by kmazouzi
1 parent 5a17f58adf
Exists in master

rewrite error with fmax

Showing 4 changed files with 108 additions and 128 deletions Side-by-side Diff

lab3/Makefile View file @ a67a1dd
1 1 GCC = gcc
2   -CFLAGS = -O3 -fopenmp
  2 +CFLAGS = -O3 -fopenmp
  3 +LDFLAG = -lm
3 4 OMP_FLAG = -fopenmp
4 5 RM = rm -rf
5 6 MPI = mpicc
6 7  
7 8  
... ... @@ -12,13 +13,13 @@
12 13  
13 14  
14 15 ser_heat2D: ser_heat2D.o
15   - $(GCC) $(CFLAGS) -o $@ $^
  16 + $(GCC) $(CFLAGS) -o $@ $^ $(LDFLAG)
16 17  
17 18 omp_heat2D: omp_heat2D.o
18   - $(GCC) $(CFLAGS) -o $@ $^
  19 + $(GCC) $(CFLAGS) -o $@ $^ $(LDFLAG)
19 20  
20 21 mpi_heat2D:
21   - $(MPI) $(MPI_FLAG) mpi_heat2D.c -o $@
  22 + $(MPI) $(MPI_FLAG) mpi_heat2D.c -o $@ $(LDFLAG)
22 23  
23 24  
24 25  
lab3/mpi_heat2D.c View file @ a67a1dd
1 1 /****************************************************************************
2 2 * DESCRIPTION:
3   - * Serial HEAT2D Example - C Version
  3 + * MPI HEAT2D Example - C Version
4 4 * This example is based on a simplified
5 5 * two-dimensional heat equation domain decomposition. The initial
6 6 * temperature is computed to be high in the middle of the domain and
7 7  
... ... @@ -53,10 +53,12 @@
53 53 #define RING 100
54 54 #define ITER_PRINT 100
55 55 #define PRINT_DATA 1
56   -#define MAX_ITER 1000
  56 +#define _MAX_ITER 1000
57 57 #define _EPSILON 0.01
58 58  
59 59  
  60 +
  61 +
60 62 float update(int rank,int size, int nx,int ny, float *u, float *unew);
61 63 void inidat(int rank, int size, int nx, int ny, float *u, float *unew);
62 64 void prtdat(int rank, int size, int nx, int ny, float *u,const char *fnam);
63 65  
64 66  
... ... @@ -65,14 +67,13 @@
65 67  
66 68  
67 69 int main(int argc, char *argv[])
68   -{
  70 +{
69 71 int N=NN,M=MM;
70   -
71   - int rank,size;
72   -
73 72 float EPSILON=_EPSILON;
74   -
75   -
  73 + int MAX_ITER= _MAX_ITER;
  74 +
  75 + int size,rank;
  76 +
76 77 /* INITIALIZE MPI */
77 78 MPI_Init(&argc, &argv);
78 79  
79 80  
... ... @@ -83,17 +84,16 @@
83 84 //Only Rank 0 read application parameters
84 85 if(rank==0) {
85 86  
86   - if(argc !=3)
87   - {
88   - fprintf(stderr,"usage %s N EPSILON\n ", argv[0]);
89   - fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance\n");
90   - fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1\n");
91   - return -1;
92   - }
93   -
  87 + if(argc !=4)
  88 + {
  89 + fprintf(stderr,"usage %s N EPSILON MAX_ITER\n ", argv[0]);
  90 + fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance, MAX_ITER is max iteration\n");
  91 + fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1, MAX_ITER=1000\n");
  92 + return -1;
  93 + }
94 94 N = M = atoi(argv[1]);
95 95 EPSILON = atof(argv[2]);
96   -
  96 + MAX_ITER = atoi (argv[3]);
97 97 if(N % size!=0)
98 98 {
99 99 fprintf(stderr,"Grid Size MUST be divisible by the number of processors !");
100 100  
... ... @@ -106,9 +106,12 @@
106 106 MPI_Barrier(MPI_COMM_WORLD);
107 107  
108 108 //Exchange N
109   - MPI_Bcast(&N , 1, MPI_FLOAT, 0 , MPI_COMM_WORLD);
  109 + MPI_Bcast(&N , 1, MPI_INT, 0 , MPI_COMM_WORLD);
110 110 //Exchange EPSILON
111 111 MPI_Bcast(&EPSILON , 1, MPI_FLOAT, 0 , MPI_COMM_WORLD);
  112 +
  113 + //Exchange MAX_ITER
  114 + MPI_Bcast(&MAX_ITER , 1, MPI_INT, 0 , MPI_COMM_WORLD);
112 115  
113 116 //local size
114 117 M = (N-2) / size + 2 ;
... ... @@ -153,7 +156,7 @@
153 156 * by no more than EPSILON.
154 157 **/
155 158  
156   - while(globaldiff> EPSILON) {
  159 + while(globaldiff> EPSILON && iter < MAX_ITER) {
157 160  
158 161 diff= update(rank,size,M,N, u, unew);
159 162  
... ... @@ -169,6 +172,7 @@
169 172 printf("Processor #%d, iteration %d, epsilon = %f\n ", rank,iter,globaldiff);
170 173 iter++;
171 174 }
  175 +
172 176  
173 177 prtdat(rank,size,M,N, u, "final.dat");
174 178 free(u);
... ... @@ -215,10 +219,7 @@
215 219 for (iy = 1; iy < ny-1; iy++) {
216 220 unew[ix*ny+iy] = (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] + u[ix*ny+iy+1] + u[ix*ny+iy-1] )/4.0
217 221 ;
218   - if (diff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] ))
219   - {
220   - diff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] );
221   - }
  222 + diff = fmax( diff, fabs(unew[ix*ny+iy] - u[ix*ny+iy]));
222 223 }
223 224  
224 225 }
lab3/omp_heat2D.c View file @ a67a1dd
1 1 /****************************************************************************
2 2 * DESCRIPTION:
3   - * Serial HEAT2D Example - C Version
  3 + * OpenMP HEAT2D Example - C Version
4 4 * This example is based on a simplified
5 5 * two-dimensional heat equation domain decomposition. The initial
6 6 * temperature is computed to be high in the middle of the domain and
7 7  
8 8  
9 9  
10 10  
11 11  
... ... @@ -23,20 +23,20 @@
23 23 u[Central] = (1/4) * ( u[North] + u[South] + u[East] + u[West] )
24 24  
25 25 ****************************************************************************/
26   -#include <stdio.h>
  26 +
  27 +#include <stdio.h>
27 28 #include <stdlib.h>
28 29 #include <math.h>
29   -#include <omp.h>
30 30  
31 31 #define NN 50
32 32 #define MM 50
33 33  
34 34 #define ITER_PRINT 100
  35 +#define _MAX_ITER 400
35 36 #define PRINT_DATA 1
  37 +#define _EPSILON 0.01
36 38  
37   -#define _EPSILON 0.001
38 39  
39   -
40 40 float update(int nx,int ny, float *u, float *unew);
41 41 void inidat(int nx, int ny, float *u, float *unew);
42 42 void prtdat(int nx, int ny, float *u,const char *fnam);
43 43  
44 44  
45 45  
46 46  
47 47  
... ... @@ -46,22 +46,24 @@
46 46  
47 47 int main(int argc, char *argv[])
48 48 {
49   -
50   - float diff=1.0;
51   - float EPSILON=_EPSILON;
52 49 int N=NN,M=MM;
  50 + float EPSILON=_EPSILON;
  51 + int MAX_ITER= _MAX_ITER;
53 52  
54   - if(argc !=3)
  53 + if(argc !=4)
55 54 {
56   - fprintf(stderr,"usage %s N EPSILON\n ", argv[0]);
57   - fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance\n");
58   - fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1\n");
  55 + fprintf(stderr,"usage %s N EPSILON MAX_ITER\n ", argv[0]);
  56 + fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance, MAX_ITER is max iteration\n");
  57 + fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1, MAX_ITER=1000\n");
59 58 return -1;
60 59 }
61 60  
62 61 N = M = atoi(argv[1]);
63 62 EPSILON = atof(argv[2]);
  63 + MAX_ITER = atoi (argv[3]);
64 64  
  65 + float diff=1.0;
  66 +
65 67 float *u = (float *)malloc(N * M * sizeof(float));
66 68 float *unew = (float *)malloc(N * M * sizeof(float));
67 69  
68 70  
69 71  
... ... @@ -73,12 +75,13 @@
73 75  
74 76 printf ( "\n" );
75 77 printf ( "HEATED_PLATE\n" );
76   - printf ( " Parallel OpenMP version, using %d Threads\n",omp_get_max_threads() );
  78 + printf ( " OpenMP version\n" );
77 79 printf ( " A program to solve for the steady state temperature distribution\n" );
78 80 printf ( " over a rectangular plate.\n" );
79   - printf ( " Spatial grid of %d by %d points.\n\n", M, N );
  81 + printf ( "\n" );
  82 + printf ( " Spatial grid of %d by %d points.\n", M, N );
  83 + printf ( " The iteration will end until tolerance <= %f\n\n",EPSILON);
80 84  
81   -
82 85 /* Initialize grid and create input file */
83 86 printf("Initializing grid\n");
84 87  
... ... @@ -86,7 +89,7 @@
86 89  
87 90 prtdat(N, M,u, "initial.dat");
88 91  
89   - printf("Start computing\n");
  92 + printf("Start computing\n\n");
90 93  
91 94 int iter=0;
92 95  
93 96  
94 97  
95 98  
96 99  
... ... @@ -95,16 +98,20 @@
95 98 * by no more than EPSILON.
96 99 * */
97 100  
98   - while(diff> EPSILON) {
  101 + while(diff> EPSILON && iter <MAX_ITER) {
99 102  
100   - diff = update(N, M, u, unew);
  103 + diff= update(N, M, u, unew);
101 104  
102 105 if(iter%ITER_PRINT==0)
103   - printf("Iteration %d, diff = %f\n ", iter,diff);
104 106  
  107 + printf("Iteration %d, diff = %e\n ", iter,diff);
  108 +
105 109 iter++;
106 110 }
107 111  
  112 + if(diff>EPSILON)
  113 + printf("***Not converged MAX_ITERATION %d reached\n***", MAX_ITER);
  114 +
108 115 prtdat(N, M, u, "final.dat");
109 116  
110 117 free(u);
111 118  
112 119  
113 120  
114 121  
115 122  
... ... @@ -121,57 +128,27 @@
121 128 int ix, iy;
122 129 float diff=0.0;
123 130  
124   -#pragma omp parallel for shared(nx,ny,u,unew) private (ix,iy)
  131 +#pragma omp parallel for shared(nx,ny,u,unew) private (ix,iy) reduction(max:diff)
125 132 for (ix = 1; ix < nx-1; ix++) {
126 133 for (iy = 1; iy < ny-1; iy++) {
127 134 unew[ix*ny+iy] =
128 135 (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] +
129   - u[ix*ny+iy+1] + u[ix*ny+iy-1] )/4.0;
130   -
  136 + u[ix*ny+iy+1] + u[ix*ny+iy-1] )*0.25;
  137 + diff = fmax( diff, fabs(unew[ix*ny+iy] - u[ix*ny+iy]));
131 138 }
132 139 }
  140 +
133 141  
134   - //compute reduction
135   -
136   -
137   - float mydiff;
138   -
139   -/**
140   - * IMPLEMENT OMP REDUCE MAX
141   - */
142   -
143   -#pragma omp parallel shared(nx,ny,u,unew, diff) private (ix,iy,mydiff)
144   - {
145   - mydiff=0.0;
146   -#pragma omp for
147   - for (ix = 1; ix < nx-1; ix++) {
148   - for (iy = 1; iy < ny-1; iy++) {
149   - if (mydiff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] ))
150   - {
151   - mydiff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] );
152   - }
153   - }
154   - }
155   -
156   -
157   -#pragma omp critical
158   - {
159   - if (diff < mydiff )
160   - {
161   - diff = mydiff;
162   - }
163   - }
164   -
165 142 /*
166 143 * COPY OLD DATA
167 144 */
168   -#pragma omp for
  145 +#pragma omp parallel for
169 146 for (ix = 1; ix < nx-1; ix++) {
170 147 for (iy = 1; iy < ny-1; iy++) {
171 148 u[ix*ny+iy] = unew[ix*ny+iy];
172 149 }
173 150 }
174   - }
  151 +
175 152  
176 153 return diff;
177 154 }
... ... @@ -194,7 +171,7 @@
194 171 #pragma omp for
195 172 for (ix = 1; ix < nx-1; ix++)
196 173 for (iy = 1; iy < ny-1; iy++) {
197   - u[ix*ny+iy]=5.0;
  174 + u[ix*ny+iy]=0.0;
198 175 }
199 176  
200 177 //boundary left
... ... @@ -221,7 +198,7 @@
221 198 //boundary top
222 199 #pragma omp for
223 200 for (iy = 0; iy < ny; iy++){
224   - u[iy]=0.0;
  201 + u[iy]=100.0;
225 202  
226 203 }
227 204  
lab3/ser_heat2D.c View file @ a67a1dd
... ... @@ -31,8 +31,8 @@
31 31 #define MM 50
32 32  
33 33 #define ITER_PRINT 100
  34 +#define _MAX_ITER 400
34 35 #define PRINT_DATA 1
35   -
36 36 #define _EPSILON 0.01
37 37  
38 38  
39 39  
40 40  
41 41  
42 42  
43 43  
44 44  
45 45  
... ... @@ -46,47 +46,48 @@
46 46 int main(int argc, char *argv[])
47 47 {
48 48 int N=NN,M=MM;
49   -
50 49 float EPSILON=_EPSILON;
  50 + int MAX_ITER= _MAX_ITER;
51 51  
52   - if(argc !=3)
53   - {
54   - fprintf(stderr,"usage %s N EPSILON\n ", argv[0]);
55   - fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance\n");
56   - fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1\n");
57   - return -1;
58   - }
  52 + if(argc !=4)
  53 + {
  54 + fprintf(stderr,"usage %s N EPSILON MAX_ITER\n ", argv[0]);
  55 + fprintf(stderr,"\t\twhere N is GRID size, EPSILON is Tolerance, MAX_ITER is max iteration\n");
  56 + fprintf(stderr,"\t\texample N = 100, EPSILON = 0.1, MAX_ITER=1000\n");
  57 + return -1;
  58 + }
59 59  
60   - N = M = atoi(argv[1]);
61   - EPSILON = atof(argv[2]);
  60 + N = M = atoi(argv[1]);
  61 + EPSILON = atof(argv[2]);
  62 + MAX_ITER = atoi (argv[3]);
62 63  
63 64 float diff=1.0;
64 65  
65 66 float *u = (float *)malloc(N * M * sizeof(float));
66 67 float *unew = (float *)malloc(N * M * sizeof(float));
67   -
  68 +
68 69 if(u==0 || unew ==0)
69 70 {
70 71 perror("Can't allocated data\n");
71 72 return -1;
72 73 }
73 74  
74   - printf ( "\n" );
75   - printf ( "HEATED_PLATE\n" );
76   - printf ( " Serial version\n" );
77   - printf ( " A program to solve for the steady state temperature distribution\n" );
78   - printf ( " over a rectangular plate.\n" );
79   - printf ( "\n" );
80   - printf ( " Spatial grid of %d by %d points.\n", M, N );
81   - printf ( " The iteration will end until tolerance <= %f\n\n",EPSILON);
  75 + printf ( "\n" );
  76 + printf ( "HEATED_PLATE\n" );
  77 + printf ( " Serial version\n" );
  78 + printf ( " A program to solve for the steady state temperature distribution\n" );
  79 + printf ( " over a rectangular plate.\n" );
  80 + printf ( "\n" );
  81 + printf ( " Spatial grid of %d by %d points.\n", M, N );
  82 + printf ( " The iteration will end until tolerance <= %f\n\n",EPSILON);
82 83  
83 84 /* Initialize grid and create input file */
84 85 printf("Initializing grid\n");
85   -
  86 +
86 87 inidat(N, M,u,unew);
87 88  
88 89 prtdat(N, M,u, "initial.dat");
89   -
  90 +
90 91 printf("Start computing\n\n");
91 92  
92 93 int iter=0;
93 94  
94 95  
95 96  
96 97  
... ... @@ -95,20 +96,23 @@
95 96 * iterate until the new solution unew differs from the old solution u
96 97 * by no more than EPSILON.
97 98 * */
98   -
99   - while(diff> EPSILON) {
100 99  
101   - diff= update(N, M, u, unew);
102   -
  100 + while(diff> EPSILON && iter <MAX_ITER) {
  101 +
  102 + diff= update(N, M, u, unew);
  103 +
103 104 if(iter%ITER_PRINT==0)
104   -
  105 +
105 106 printf("Iteration %d, diff = %e\n ", iter,diff);
106 107  
107 108 iter++;
108 109 }
109 110  
  111 + if(diff>EPSILON)
  112 + printf("***Not converged MAX_ITERATION %d reached\n***", MAX_ITER);
  113 +
110 114 prtdat(N, M, u, "final.dat");
111   -
  115 +
112 116 free(u);
113 117 free(unew);
114 118 }
... ... @@ -125,12 +129,9 @@
125 129  
126 130 for (ix = 1; ix < nx-1; ix++) {
127 131 for (iy = 1; iy < ny-1; iy++) {
128   - unew[ix*ny+iy] = (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] + u[ix*ny+iy+1] + u[ix*ny+iy-1] )/4.0
129   - ;
130   - if (diff < fabs (unew[ix*ny+iy] - u[ix*ny+iy] ))
131   - {
132   - diff = fabs ( unew[ix*ny+iy] - u[ix*ny+iy] );
133   - }
  132 +
  133 + unew[ix*ny+iy] = (u[(ix+1)*ny+iy] + u[(ix-1)*ny+iy] + u[ix*ny+iy+1] + u[ix*ny+iy-1] )*0.25;
  134 + diff = fmax( diff, fabs(unew[ix*ny+iy] - u[ix*ny+iy]));
134 135 }
135 136  
136 137 }
137 138  
... ... @@ -162,10 +163,10 @@
162 163 // interior points
163 164 for (ix = 1; ix < nx-1; ix++)
164 165 for (iy = 1; iy < ny-1; iy++) {
165   - u[ix*ny+iy]=5.0;
  166 + u[ix*ny+iy]=0.0;
166 167 }
167 168  
168   - //boundary left
  169 + //boundary left
169 170 for (ix = 1; ix < nx-1; ix++){
170 171 u[ix*ny]=100.0;
171 172  
172 173  
... ... @@ -178,13 +179,13 @@
178 179 }
179 180  
180 181 //boundary down
181   - for (iy = 0; iy < ny; iy++){
  182 + for (iy = 0; iy < ny; iy++){
182 183 u[(nx-1)*(ny)+iy]=100.0;
183 184  
184 185 }
185 186  
186 187 //boundary top
187   - for (iy = 0; iy < ny; iy++){
  188 + for (iy = 0; iy < ny; iy++){
188 189 u[iy]=100.0;
189 190  
190 191 }
191 192  
192 193  
193 194  
194 195  
... ... @@ -199,26 +200,26 @@
199 200 **************************************************************************/
200 201 void prtdat(int nx, int ny, float *u,const char *fname)
201 202 {
202   -
  203 +
203 204 int ix, iy;
204 205 FILE *fp;
205 206  
206 207 if(ITER_PRINT==0)return;
207   -
  208 +
208 209 fp = fopen(fname, "w");
209 210  
210   - // fprintf ( fp, "%d\n", M );
211   - // fprintf ( fp, "%d\n", N );
  211 + // fprintf ( fp, "%d\n", M );
  212 + // fprintf ( fp, "%d\n", N );
212 213  
213 214 for (ix = 0 ; ix < nx; ix++) {
214 215 for (iy =0; iy < ny; iy++) {
215 216  
216 217 fprintf(fp, "%6.2f ", u[ix*ny+iy]);
217 218 }
218   - fputc ( '\n', fp);
  219 + fputc ( '\n', fp);
219 220 }
220 221  
221   - printf (" Data written to the output file %s\n", fname);
  222 + printf (" Data written to the output file %s\n", fname);
222 223 fclose(fp);
223 224 }