source: CIVL/examples/omp/c_jacobi01.c@ 1aaefd4

main test-branch
Last change on this file since 1aaefd4 was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/* ***********************************************************************
2 This program is part of the
3 OpenMP Source Code Repository
4
5 http://www.pcg.ull.es/ompscr/
6 e-mail: ompscr@etsii.ull.es
7
8 Copyright (c) 2004, OmpSCR Group
9 All rights reserved.
10
11 Redistribution and use in source and binary forms, with or without modification,
12 are permitted provided that the following conditions are met:
13 * Redistributions of source code must retain the above copyright notice,
14 this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
18 * Neither the name of the University of La Laguna nor the names of its contributors
19 may be used to endorse or promote products derived from this software without
20 specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
28 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 OF SUCH DAMAGE.
32
33 FILE: c_jacobi01.c
34 VERSION: 1.1
35 DATE: Oct 2004
36 AUTHORS: Author: Joseph Robicheaux, Kuck and Associates, Inc. (KAI), 1998
37 Modified: Sanjiv Shah, Kuck and Associates, Inc. (KAI), 1998
38 This version: Dieter an Mey, Aachen University (RWTH), 1999 - 2003
39 anmey@rz.rwth-aachen.de
40 http://www.rwth-aachen.de/People/D.an.Mey.html
41 COMMENTS TO: ompscr@etsii.ull.es
42 DESCRIPTION: program to solve a finite difference discretization of Helmholtz equation :
43 (d2/dx2)u + (d2/dy2)u - alpha u = f using Jacobi iterative method.
44 COMMENTS: OpenMP version 1: two parallel regions with one parallel loop each, the naive approach.
45 Directives are used in this code to achieve paralleism.
46 All do loops are parallized with default 'static' scheduling.
47 REFERENCES: http://www.rz.rwth-aachen.de/computing/hpc/prog/par/openmp/jacobi.html
48 BASIC PRAGMAS: parallel for
49 USAGE: ./c_jacobi01.par 5000 5000 0.8 1.0 1000
50 INPUT: n - grid dimension in x direction
51 m - grid dimension in y direction
52 alpha - Helmholtz constant (always greater than 0.0)
53 tol - error tolerance for iterative solver
54 relax - Successice over relaxation parameter
55 mits - Maximum iterations for iterative solver
56 OUTPUT: Residual and error
57 u(n,m) - Dependent variable (solutions)
58 f(n,m) - Right hand side function
59 FILE FORMATS: -
60 RESTRICTIONS: -
61 REVISION HISTORY:
62**************************************************************************/
63#include <omp.h>
64#include <stdio.h>
65#include <math.h>
66#include <stdlib.h>
67//#include "OmpSCR.h"
68
69#define U(i,j) u[(i)*n+(j)]
70#define F(i,j) f[(i)*n+(j)]
71#define NUM_ARGS 6
72#define NUM_TIMERS 1
73
74#define NIN 4
75#define MIN 4
76#define ALPHA 0.1
77#define TOL 0.1
78#define RELAX 2
79#define MITS 2
80
81int n, m, mits;
82double tol, relax, alpha;
83
84void jacobi (int n, int m, double dx, double dy,
85 double alpha, double omega,
86 double *u, double *f,
87 double tol, int maxit );
88
89/******************************************************
90* Initializes data
91* Assumes exact solution is u(x,y) = (1-x^2)*(1-y^2)
92*
93******************************************************/
94void initialize(
95 int n,
96 int m,
97 double alpha,
98 double *dx,
99 double *dy,
100 double *u,
101 double *f)
102{
103 int i,j,xx,yy;
104
105 *dx = 2.0 / (n-1);
106 *dy = 2.0 / (m-1);
107
108 /* Initilize initial condition and RHS */
109 for (j=0; j<m; j++){
110 for (i=0; i<n; i++){
111 xx = -1.0 + *dx * (i-1);
112 yy = -1.0 + *dy * (j-1);
113 U(j,i) = 0.0;
114 F(j,i) = -alpha * (1.0 - xx*xx) * (1.0 - yy*yy)
115 - 2.0 * (1.0 - xx*xx) - 2.0 * (1.0 - yy*yy);
116 }
117 }
118
119}
120
121
122/************************************************************
123* Checks error between numerical and exact solution
124*
125************************************************************/
126void error_check(
127 int n,
128 int m,
129 double alpha,
130 double dx,
131 double dy,
132 double *u,
133 double *f)
134{
135 int i,j;
136 double xx, yy, temp, error;
137
138 dx = 2.0 / (n-1);
139 dy = 2.0 / (n-2);
140 error = 0.0;
141
142 for (j=0; j<m; j++){
143 for (i=0; i<n; i++){
144 xx = -1.0 + dx * (i-1);
145 yy = -1.0 + dy * (j-1);
146 temp = U(j,i) - (1.0 - xx*xx) * (1.0 - yy*yy);
147 error += temp*temp;
148 }
149 }
150
151 error = sqrt(error)/(n*m);
152
153 printf("Solution Error : %g\n", error);
154
155}
156
157
158
159
160int main(int argc, char **argv){
161 double *u, *f, dx, dy;
162 double dt, mflops;
163 int NUMTHREADS;
164// char *PARAM_NAMES[NUM_ARGS] = {"Grid dimension: X dir =", "Grid dimension: Y dir =", "Helmhotlz constant =",
165// "Successive over-relaxation parameter =",
166// "error tolerance for iterative solver =", "Maximum iterations for solver ="};
167// char *TIMERS_NAMES[NUM_TIMERS] = {"Total_time"};
168// char *DEFAULT_VALUES[NUM_ARGS] = {"5000", "5000", "0.8", "1.0", "1e-7", "1000"};
169
170
171
172 NUMTHREADS = 1; //omp_get_num_threads();
173 //OSCR_init (NUMTHREADS, "Jacobi Solver v1", "Use 'jacobi01' <n> <m> <alpha> <relax> <tol> <mits>", NUM_ARGS,
174 // PARAM_NAMES, DEFAULT_VALUES , NUM_TIMERS, NUM_TIMERS, TIMERS_NAMES,
175 // argc, argv);
176
177 n = NIN; // OSCR_getarg_int(1);
178 m = MIN; // OSCR_getarg_int(2);
179 alpha = ALPHA; // OSCR_getarg_double(3);
180 relax = RELAX; // OSCR_getarg_double(4);
181 tol = TOL; // OSCR_getarg_double(5);
182 mits = MITS; // OSCR_getarg_int(6);
183
184 printf("-> %d, %d, %g, %g, %g, %d\n",
185 n, m, alpha, relax, tol, mits);
186
187 u = (double *) malloc(n*m*sizeof(double));
188 f = (double *) malloc(n*m*sizeof(double));
189
190
191 /* arrays are allocated and initialzed */
192 initialize(n, m, alpha, &dx, &dy, u, f);
193
194
195 /* Solve Helmholtz eqiation */
196 //OSCR_timer_start(0);
197 jacobi(n, m, dx, dy, alpha, relax, u,f, tol, mits);
198
199 //OSCR_timer_stop(0);
200 dt = 1; //OSCR_timer_read(0);
201
202 printf(" elapsed time : %12.6f\n", dt);
203 mflops = (0.000001*mits*(m-2)*(n-2)*13) / dt;
204 printf(" MFlops : %12.6g (%d, %d, %d, %g)\n",mflops, mits, m, n, dt);
205
206 error_check(n, m, alpha, dx, dy, u, f);
207
208 //OSCR_report(1, TIMERS_NAMES);
209
210 return 0;
211}
212
213
214
215/*
216 subroutine jacobi (n,m,dx,dy,alpha,omega,u,f,tol,maxit)
217******************************************************************
218* Subroutine HelmholtzJ
219* Solves poisson equation on rectangular grid assuming :
220* (1) Uniform discretization in each direction, and
221* (2) Dirichlect boundary conditions
222*
223* Jacobi method is used in this routine
224*
225* Input : n,m Number of grid points in the X/Y directions
226* dx,dy Grid spacing in the X/Y directions
227* alpha Helmholtz eqn. coefficient
228* omega Relaxation factor
229* f(n,m) Right hand side function
230* u(n,m) Dependent variable/Solution
231* tol Tolerance for iterative solver
232* maxit Maximum number of iterations
233*
234* Output : u(n,m) - Solution
235*****************************************************************
236*/
237void jacobi ( const int n, const int m, double dx, double dy, double alpha,
238 double omega, double *u, double *f, double tol, int maxit )
239{
240 int i,j,k;
241 double error, resid, ax, ay, b;
242
243
244 double *uold;
245
246 /* wegen Array-Kompatibilitaet, werden die Zeilen und Spalten (im Kopf)
247 getauscht, zB uold[spalten_num][zeilen_num]; bzw. wir tuen so, als ob wir das
248 gespiegelte Problem loesen wollen */
249
250 uold = (double *)malloc(sizeof(double) * n *m);
251
252
253
254 ax = 1.0/(dx * dx); /* X-direction coef */
255 ay = 1.0/(dy*dy); /* Y_direction coef */
256 b = -2.0/(dx*dx)-2.0/(dy*dy) - alpha; /* Central coeff */
257
258 error = 10.0 * tol;
259
260 k = 1;
261 while (k <= maxit && error > tol) {
262
263 error = 0.0;
264
265 /* copy new solution into old */
266#pragma omp parallel for private(i)
267 for (j=0; j<m; j++)
268 for (i=0; i<n; i++)
269 uold[i + m*j] = u[i + m*j];
270
271
272 /* compute stencil, residual and update */
273#pragma omp parallel for reduction(+:error) private(i,resid)
274 for (j=1; j<m-1; j++)
275 for (i=1; i<n-1; i++){
276 resid =(
277 ax * (uold[i-1 + m*j] + uold[i+1 + m*j])
278 + ay * (uold[i + m*(j-1)] + uold[i + m*(j+1)])
279 + b * uold[i + m*j] - f[i + m*j]
280 ) / b;
281
282 /* update solution */
283 u[i + m*j] = uold[i + m*j] - omega * resid;
284
285 /* accumulate residual error */
286 error =error + resid*resid;
287
288 }
289
290 /* error check */
291 k++;
292 error = sqrt(error) /(n*m);
293
294 } /* while */
295
296 printf("Total Number of Iterations %d\n", k);
297 printf("Residual %.15f\n\n", error);
298
299 free(uold);
300
301}
302
Note: See TracBrowser for help on using the repository browser.