## Reduction problem

General OpenMP discussion

### Reduction problem

Hi,
i have just started learning openmp and a got an example in the web but when i run the program the result is not what i expected. The variable reduction didn´t happened. Can anyone help me? The sum variable should return 9.666667. In the web example this program runned in a pentium D and i have a pentium 4 HT.

Thanks in advance

/*
* combined.c
*
* This program combines what we saw before. It calculates e and pi
* and then integrates the x^2. We also print out the elapsed time in
* ms at several points in our program. We have replaced the function y=x^2
* with a more complex polynomial 3x^3 + 2x^2 + x.
*/

#include <stdio.h>
#include <time.h>

#define num_steps 10000000 /* steps to use in taylor expansions */
#define int_steps (1<<30) /* steps to use in integration */

int main(int argc, char *argv[])
{
double start, stop; /* times of beginning and end of procedure */

/* Values for part 1 */
double e, pi, factorial, product;
int i;

/* Values for part 2 */
double sum;
double x;

/* start the timer */
start = clock();

#pragma omp parallel reduction(+: sum)
{
#pragma omp sections nowait
{
#pragma omp section
{
/* First we calculate e from its taylor expansion */
printf("e started at %.0f\n", clock()-start);
e = 1;
factorial = 1;
for (i = 1; i<num_steps; i++) {
factorial *= i;
e += 1.0/factorial;
}
printf("e done at %.0f\n", clock()-start);
}
#pragma omp section
{
/* Then we calculate pi from its taylor expansion */
printf("pi started at %.0f\n", clock()-start);

pi = 0;
for (i = 0; i < num_steps*20; i++) {
pi += 1.0/(i*4.0 + 1.0);
pi -= 1.0/(i*4.0 + 3.0);
}
pi = pi * 4.0;
printf("pi done at %.0f\n", clock()-start);
}
} /* sections */

/* Now we integrate the function */
printf("integration started at %.0f\n", clock()-start);
sum = 0;

#pragma omp for nowait
for (i = 0; i<int_steps; i++) {
x = 2.0 * (double)i / (double)(int_steps); /* value of x */
sum += ( 3*x*x*x + 2*x*x + x ) / int_steps;
}

#pragma omp single /* we only need to print this once */
printf("integration done at %.0f\n", clock()-start);

#pragma omp barrier
/* make sure all threads are caught up before we do the multiplication */
product = e * pi;

} /* omp parallel */

/* we're done so stop the timer */
stop = clock();
printf("Values: e*pi = %f, integral = %f\n", product, sum);
printf("Total elapsed time: %.3f seconds\n", (stop-start)/1000);

return 0;
}
Pedro

### Re: Reduction problem

It works fine for me on two different platforms running linux:

Values: e*pi = 8.539734, integral = 9.666667

The particular processor shouldn't matter.

-- Larry
lfm

Posts: 135
Joined: Sun Oct 21, 2007 4:58 pm
Location: OpenMP ARB

### Re: Reduction problem

Hi Larry,

that´s what i got running the program, i am using windows xp and intel compiler. To compile the program i use the command icl /O2 /Qopenmp combined_mp.c. As you can see the integral value is wrong, probably the program is adding a value from a wrong memory lcoation. Individually, the threads split the operation but in the end they do not have their sum value added.

e started at 0
pi started at 0
pi done at 8109
integration started at 8109
e done at 8656
integration started at 8656
integration done at 16781
Values: e*pi = 8.539734, integral = 1061976560575886200000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000.000000
Total elapsed time: 17.015 seconds
Pedro

### Re: Reduction problem

OK, I can try it on windows maybe later tonight.

-- Larry
lfm

Posts: 135
Joined: Sun Oct 21, 2007 4:58 pm
Location: OpenMP ARB

### Re: Reduction problem

I had found out what was wrong, this is the correct code.

/*
* combined.c
*
* This program combines what we saw before. It calculates e and pi
* and then integrates the x^2. We also print out the elapsed time in
* ms at several points in our program. We have replaced the function y=x^2
* with a more complex polynomial 3x^3 + 2x^2 + x.
*/

#include <stdio.h>
#include <time.h>

#define num_steps 10000000 /* steps to use in taylor expansions */
#define int_steps (1<<30) /* steps to use in integration */

int main(int argc, char *argv[])
{
double start, stop; /* times of beginning and end of procedure */

/* Values for part 1 */
double e, pi, factorial, product;
int i;
int id;

/* Values for part 2 */
double sum;
double x;

/* start the timer */
start = clock();

#pragma omp parallel private(x) shared(sum)
{
#pragma omp sections nowait
{
#pragma omp section
{
/* First we calculate e from its taylor expansion */
printf("e started at %.0f\n", clock()-start);
e = 1;
factorial = 1;
for (i = 1; i<num_steps; i++) {
factorial *= i;
e += 1.0/factorial;
}
printf("e done at %.0f\n", clock()-start);
}
#pragma omp section
{
/* Then we calculate pi from its taylor expansion */
printf("pi started at %.0f\n", clock()-start);

pi = 0;
for (i = 0; i < num_steps*20; i++) {
pi += 1.0/(i*4.0 + 1.0);
pi -= 1.0/(i*4.0 + 3.0);
}
pi = pi * 4.0;
printf("pi done at %.0f\n", clock()-start);
}
} /* sections */

/* Now we integrate the function */
printf("integration started at %.0f\n", clock()-start);
sum = 0;

#pragma omp for nowait reduction(+: sum)
for (i = 0; i<int_steps; i++) {
x = 2.0 * (double)i / (double)(int_steps); /* value of x */
sum += ( 3*x*x*x + 2*x*x + x ) / int_steps;
}

#pragma omp single /* we only need to print this once */
printf("integration done at %.0f\n", clock()-start);

#pragma omp barrier
/* make sure all threads are caught up before we do the multiplication */
product = e * pi;

} /* omp parallel */

/* we're done so stop the timer */
stop = clock();
printf("Values: e*pi = %f, integral = %f\n", product, sum);
printf("Total elapsed time: %.3f seconds\n", (stop-start)/1000);

return 0;
}
Pedro

Return to Using OpenMP

### Who is online

Users browsing this forum: Google [Bot] and 2 guests