How to reduce a struct

General OpenMP discussion

How to reduce a struct

Postby River Seow » Fri Nov 02, 2007 9:24 pm

Dear OMPers,

Recently, I ran into problem of using the reduction clause for a structure. Here is my structure definition:

typedef struct
{
double Rho_product;
double Rho1;
double Rho2;
double Rho1_sq;
double Rho2_sq;
int numPts;
} sums_t;

My current working code below is very slow because of the "critical" part.

#pragma omp parallel for \
default(shared) \
private(k,j,i,x,y,z,R_sq,rho1,rho2) \
schedule(runtime)

for(k=0;k<rhead[0].numSecs;k++)
for(j=0;j<rhead[0].numRows;j++)
for(i=0;i<rhead[0].numCols;i++)
{
x = (float)( i-orig[0].Col+1 ) * pix_try;
y = (float)( j-orig[0].Row+1 ) * pix_try;
z = (float)( k-orig[0].Sec+1 ) * pix_try;
R_sq = x*x + y*y + z*z;
if ( R_sq >= Rmin_sq && R_sq <= Rmax_sq && R_sq <= Rcut_sq )
{
rho1 = map[0][k*SecPxl+j*rhead[0].numCols+i];
rho2 = rho_interp(1, x, y, z);

if ( ((filename[2] != NULL) && positive*rho_interp(2, x, y, z) >= positive*mask_cut)
|| filename[2] == NULL )
#pragma omp critical
calculate_sums ( rho1, rho2, &sums);

}
}

I have tried to use the reduction clause to the sums structure so that I don't need to do the critical part.
When I try
#pragma omp parallel for \
default(shared) \
private(k,j,i,x,y,z,R_sq,rho1,rho2) \
schedule(runtime) \
reduction(+:sums)

error: reduction variable is incompatible with reduction operator
reduction (+:sums)
^
When I try
#pragma omp parallel for \
default(shared) \
private(k,j,i,x,y,z,R_sq,rho1,rho2) \
schedule(runtime) \
reduction(+:sums.numPts)
^
error: reduction variable is incompatible with reduction operator
reduction (+:sums.numPts)

When I try
#pragma omp parallel for \
default(shared) \
private(k,j,i,x,y,z,R_sq,rho1,rho2) \
schedule(runtime) \
reduction(+:(sums.numPts))

error: expected an identifier
reduction (+:(sums.numPts))
^


I am wondering how to reduce an element in a structure? Any hints will be greatly appreciated.

River
River Seow
 

Re: How to reduce a struct

Postby lfm » Tue Nov 27, 2007 2:28 am

Unfortunately you can't reduce a struct or a struct member. User-defined reductions would allow this but they aren't in OpenMP (even in 3.0 draft).
That said, I wouldn't expect critical to be a real bottleneck until you got to a fairly large number of processors; also, your compiler might not use a better algorithm anyway. Are you sure that critical is the problem? You might try some kind of profiling tool if you haven't already.
You could try #pragma atomic, which might well be better if your hardware and compiler have good support for atomic operations. You could also save local sums into an array indexed by thread number, and reduce them at the end, either sequentially or in your own home-grown parallel fashion.
Good luck.

-- Larry


Last bumped by Anonymous on Tue Nov 27, 2007 2:28 am.
lfm
 
Posts: 135
Joined: Sun Oct 21, 2007 4:58 pm
Location: OpenMP ARB


Return to Using OpenMP

Who is online

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