|  | /* 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; | 
|  | } |