1// RUN: %libomp-cxx-compile-and-run
2
3/*
4
5This test is imported from SOLLVE: 5.0/task/test_task_depend_iterator.cpp
6SOLLVE page: https://github.com/SOLLVE/sollve_vv
7
8OpenMP API Version 5.0 Nov 2020
9
10This test is for the iterator modifier when used with the task depend
11clause. This modifier should create an iterator that expands to multiple values
12inside the clause they appear. In this particular test case the iterator expands into
13several values creating several dependencies at the same time.
14
15*/
16
17#include <omp.h>
18#include <algorithm>
19#include <cstdlib>
20#include <iostream>
21#include <thread>
22#include <vector>
23#include "omp_testsuite.h"
24
25#define N 1024
26#define FROM 64
27#define LENGTH 128
28
29int test_omp_task_depend_iterator() {
30 int ptr[] = {0, 4, 5, 6, 7, 8, 9, 10, 11};
31 int cols[] = {1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 8};
32 std::vector<int> threadOrder;
33 bool threadOrderError = false;
34#pragma omp parallel num_threads(8)
35 {
36#pragma omp single
37 {
38 for (int i = 0; i < 8; ++i) {
39 int pos = ptr[i], size = ptr[i + 1] - ptr[i];
40#pragma omp task depend(iterator(it = 0 : size), in : ptr[cols[pos + it]]) depend(out : ptr[i])
41 {
42#pragma omp critical
43 {
44 threadOrder.push_back(i);
45 } // end critical section
46 } // end task depend
47 }
48 } // end single
49 } // end parallel
50
51 // store the indices of the execution order of generated tasks in idx[]
52 std::vector<int>::iterator idx[8];
53 for (int i = 0; i < 8; ++i)
54 idx[i] = std::find (threadOrder.begin(), threadOrder.end(), i);
55
56 // verify that dependencies are met in the order
57 if (idx[0] != threadOrder.begin())
58 threadOrderError |= true;
59 if (idx[1] > idx[5] || idx[2] > idx[5])
60 threadOrderError |= true;
61 if (idx[3] > idx[6] || idx[4] > idx[6])
62 threadOrderError |= true;
63 if (idx[5] > idx[7] || idx[6] > idx[7])
64 threadOrderError |= true;
65
66 std::sort(threadOrder.begin(), threadOrder.end());
67 for(int i = 0; i < 8; ++i)
68 threadOrderError = (threadOrder[i] != i) || threadOrderError;
69
70 // FALSE If dependencies between tasks were not enforced in the correct order.
71 return !threadOrderError;
72}
73
74
75
76int main() {
77 int i;
78 int num_failed=0;
79
80 for(i = 0; i < REPETITIONS; i++) {
81 if(!test_omp_task_depend_iterator()) {
82 num_failed++;
83 }
84 }
85 return num_failed;
86}
87

source code of openmp/runtime/test/tasking/omp_task_depend_iterator.cpp