-1

The OpenMP manual says

A type name in a declare reduction directive cannot be a function type, an array type, a reference type, or a type qualified with const, volatile or restrict.

What can I do to produce my results into array elements? I started with:

int main()
{
    // create an input array
    static const int snum = 5000;
    int input[snum];
    for(int i=0; i<snum; ++i){
        input[i] = i+1;
    }

    // shared output variables for reduction
    int sum[2];
    sum[0] = 0;
    sum[1] = 0;

#pragma omp parallel for
#pragma omp declare reduction(+:sum[0])
#pragma omp declare reduction(+:sum[1])
    for(int i=0; i<snum; ++i) {
            int* p = input+i;
            if(i%2==0)
                sum[0] += *p;
            else
                sum[1] += *p;
        }
}

This gives a compiler error:

27013152.cpp:16:9: error: ‘#pragma’ is not allowed here
 #pragma omp declare reduction(+:sum[0])
         ^~~
27013152.cpp:17:33: error: ‘sum’ does not name a type
 #pragma omp declare reduction(+:sum[1])
                                 ^~~
27013152.cpp:17:36: error: expected ‘:’ before ‘[’ token
 #pragma omp declare reduction(+:sum[1])
                                    ^
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
YOung
  • 938
  • 2
  • 10
  • 14
  • 1
    What is your problem? I don't get it. The above code won't compile, you can't "do it like this". – luk32 Nov 19 '14 at 10:41
  • What are you going to do? Why don't you split your `input` into two arrays like and reduce each of them? (base on odd or even) – muradin Nov 19 '14 at 15:05
  • Actually,I want to do an aggregation on the table,every column of which is an array.so I need to scan the table and do the aggregation.But Openmp seem doesn't support that using array name after the reduction directive.So,How can I use the openmp to parallelize my aggregation code?thx – YOung Nov 19 '14 at 15:27

2 Answers2

1

You're mistaking the error you're getting. It doesn't mean that you can't do the reduction on alternating elements. It means that you can't do the reduction into an element of an array.

That is, you can't do reduction(+:sum[0]). But you can do the reduction into another scalar variable and then copy into an element of an array afterwards:

void sum_int(const int input[], int num, int *sum)
{
    int sum_even = 0, sum_odd = 0;

    #pragma omp parallel for reduction(+:sum_even) reduction(+:sum_odd)
    for (int i = 0; i < num; i++) {
            if (i % 2 == 0)
                    sum_even += input[i];
            else
                    sum_odd += input[i];
    }

    sum[0] = sum_even;
    sum[1] = sum_odd;
}
mattst88
  • 1,462
  • 13
  • 21
1

Reduction on arrays in C/C++ is now possible since OpenMP 4.5. Basically, you must specify array sections (see Section 2.4, p. 44 of OpenMP 4.5 spec.). Your #pragma specification would look like this:

#pragma omp parallel reduction(+:sum[:2])

Be careful with this however, you have to realize that each thread will allocate its own version of the array section; if you do this on large arrays with many threads, you will make your memory needs explode.

Hugo Raguet
  • 418
  • 3
  • 11