blob: 6be3c9b7dfbf50c3828660f7dbb1747619f6bb61 [file] [edit]
// RUN: %libomp-compile -fopenmp-version=61 && %libomp-run \
// RUN: | FileCheck %s --match-full-lines
// Flatten changes which iterations a worksharing loop assigns to which
// thread. With schedule(static,1) and two threads:
// * without flatten, the outer loop (2 iterations) is distributed
// * with flatten, the product space (4 iterations) is distributed
// Results are printed per thread after the parallel region so FileCheck
// is not racy.
#ifndef HEADER
#define HEADER
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
enum { NThreads = 2, MaxIters = 4 };
static void dump(const char *tag, int count[NThreads],
int pairs[NThreads][MaxIters][2]) {
printf("%s\n", tag);
for (int t = 0; t < NThreads; ++t) {
printf("tid=%d count=%d\n", t, count[t]);
for (int k = 0; k < count[t]; ++k)
printf("tid=%d i=%d j=%d\n", t, pairs[t][k][0], pairs[t][k][1]);
}
}
int main() {
int count[NThreads];
int pairs[NThreads][MaxIters][2];
count[0] = count[1] = 0;
#pragma omp parallel for schedule(static, 1) num_threads(2)
#pragma omp flatten
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j) {
int t = omp_get_thread_num();
int c = count[t]++;
pairs[t][c][0] = i;
pairs[t][c][1] = j;
}
dump("with-flatten", count, pairs);
count[0] = count[1] = 0;
#pragma omp parallel for schedule(static, 1) num_threads(2)
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j) {
int t = omp_get_thread_num();
int c = count[t]++;
pairs[t][c][0] = i;
pairs[t][c][1] = j;
}
dump("without-flatten", count, pairs);
return EXIT_SUCCESS;
}
#endif /* HEADER */
// Flattened product space has 4 iterations; static,1 with 2 threads gives
// each thread 2 chunks: (0,0)+(1,0) and (0,1)+(1,1).
// CHECK: with-flatten
// CHECK-NEXT: tid=0 count=2
// CHECK-NEXT: tid=0 i=0 j=0
// CHECK-NEXT: tid=0 i=1 j=0
// CHECK-NEXT: tid=1 count=2
// CHECK-NEXT: tid=1 i=0 j=1
// CHECK-NEXT: tid=1 i=1 j=1
// Without flatten the outer loop has 2 iterations, so each thread gets one
// value of i and both j.
// CHECK: without-flatten
// CHECK-NEXT: tid=0 count=2
// CHECK-NEXT: tid=0 i=0 j=0
// CHECK-NEXT: tid=0 i=0 j=1
// CHECK-NEXT: tid=1 count=2
// CHECK-NEXT: tid=1 i=1 j=0
// CHECK-NEXT: tid=1 i=1 j=1