| /* C / C++'s logical AND and OR operators take any scalar argument |
| which compares (un)equal to 0 - the result 1 or 0 and of type int. |
| |
| In this testcase, the int result is again converted to an integer complex |
| type. |
| |
| While having a floating-point/complex array element with || and && can make |
| sense, having a complex reduction variable is odd but valid. |
| |
| Test: int complex reduction variable + int complex array. */ |
| |
| #define N 1024 |
| _Complex char rcc[N]; |
| _Complex short rcs[N]; |
| _Complex int rci[N]; |
| _Complex long long rcl[N]; |
| |
| int |
| reduction_or () |
| { |
| _Complex char orc = 0; |
| _Complex short ors = 0; |
| _Complex int ori = 0; |
| _Complex long orl = 0; |
| |
| #pragma omp parallel reduction(||: orc) |
| for (int i=0; i < N; ++i) |
| orc = orc || rcl[i]; |
| |
| #pragma omp parallel for reduction(||: ors) |
| for (int i=0; i < N; ++i) |
| ors = ors || rci[i]; |
| |
| #pragma omp parallel for simd reduction(||: ori) |
| for (int i=0; i < N; ++i) |
| ori = ori || rcs[i]; |
| |
| #pragma omp parallel loop reduction(||: orl) |
| for (int i=0; i < N; ++i) |
| orl = orl || rcc[i]; |
| |
| return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl); |
| } |
| |
| int |
| reduction_or_teams () |
| { |
| _Complex char orc = 0; |
| _Complex short ors = 0; |
| _Complex int ori = 0; |
| _Complex long orl = 0; |
| |
| #pragma omp teams distribute parallel for reduction(||: orc) |
| for (int i=0; i < N; ++i) |
| orc = orc || rcc[i]; |
| |
| #pragma omp teams distribute parallel for simd reduction(||: ors) |
| for (int i=0; i < N; ++i) |
| ors = ors || rcs[i]; |
| |
| #pragma omp teams distribute parallel for reduction(||: ori) |
| for (int i=0; i < N; ++i) |
| ori = ori || rci[i]; |
| |
| #pragma omp teams distribute parallel for simd reduction(||: orl) |
| for (int i=0; i < N; ++i) |
| orl = orl || rcl[i]; |
| |
| return __real__ (orc + ors + ori + orl) + __imag__ (orc + ors + ori + orl); |
| } |
| |
| int |
| reduction_and () |
| { |
| _Complex char andc = 1; |
| _Complex short ands = 1; |
| _Complex int andi = 1; |
| _Complex long andl = 1; |
| |
| #pragma omp parallel reduction(&&: andc) |
| for (int i=0; i < N; ++i) |
| andc = andc && rcc[i]; |
| |
| #pragma omp parallel for reduction(&&: ands) |
| for (int i=0; i < N; ++i) |
| ands = ands && rcs[i]; |
| |
| #pragma omp parallel for simd reduction(&&: andi) |
| for (int i=0; i < N; ++i) |
| andi = andi && rci[i]; |
| |
| #pragma omp parallel loop reduction(&&: andl) |
| for (int i=0; i < N; ++i) |
| andl = andl && rcl[i]; |
| |
| return __real__ (andc + ands + andi + andl) |
| + __imag__ (andc + ands + andi + andl); |
| } |
| |
| int |
| reduction_and_teams () |
| { |
| _Complex char andc = 1; |
| _Complex short ands = 1; |
| _Complex int andi = 1; |
| _Complex long andl = 1; |
| |
| #pragma omp teams distribute parallel for reduction(&&: andc) |
| for (int i=0; i < N; ++i) |
| andc = andc && rcl[i]; |
| |
| #pragma omp teams distribute parallel for simd reduction(&&: ands) |
| for (int i=0; i < N; ++i) |
| ands = ands && rci[i]; |
| |
| #pragma omp teams distribute parallel for reduction(&&: andi) |
| for (int i=0; i < N; ++i) |
| andi = andi && rcs[i]; |
| |
| #pragma omp teams distribute parallel for simd reduction(&&: andl) |
| for (int i=0; i < N; ++i) |
| andl = andl && rcc[i]; |
| |
| return __real__ (andc + ands + andi + andl) |
| + __imag__ (andc + ands + andi + andl); |
| } |
| |
| int |
| main () |
| { |
| for (int i = 0; i < N; ++i) |
| { |
| rcc[i] = 0; |
| rcs[i] = 0; |
| rci[i] = 0; |
| rcl[i] = 0; |
| } |
| |
| if (reduction_or () != 0) |
| __builtin_abort (); |
| if (reduction_or_teams () != 0) |
| __builtin_abort (); |
| if (reduction_and () != 0) |
| __builtin_abort (); |
| if (reduction_and_teams () != 0) |
| __builtin_abort (); |
| |
| rcc[10] = 1.0; |
| rcs[15] = 1.0i; |
| rci[10] = 1.0; |
| rcl[15] = 1.0i; |
| |
| if (reduction_or () != 4) |
| __builtin_abort (); |
| if (reduction_or_teams () != 4) |
| __builtin_abort (); |
| if (reduction_and () != 0) |
| __builtin_abort (); |
| if (reduction_and_teams () != 0) |
| __builtin_abort (); |
| |
| for (int i = 0; i < N; ++i) |
| { |
| rcc[i] = 1; |
| rcs[i] = 1i; |
| rci[i] = 1; |
| rcl[i] = 1 + 1i; |
| } |
| |
| if (reduction_or () != 4) |
| __builtin_abort (); |
| if (reduction_or_teams () != 4) |
| __builtin_abort (); |
| if (reduction_and () != 4) |
| __builtin_abort (); |
| if (reduction_and_teams () != 4) |
| __builtin_abort (); |
| |
| rcc[10] = 0.0; |
| rcs[15] = 0.0; |
| rci[10] = 0.0; |
| rcl[15] = 0.0; |
| |
| if (reduction_or () != 4) |
| __builtin_abort (); |
| if (reduction_or_teams () != 4) |
| __builtin_abort (); |
| if (reduction_and () != 0) |
| __builtin_abort (); |
| if (reduction_and_teams () != 0) |
| __builtin_abort (); |
| |
| return 0; |
| } |