@@ -2044,6 +2044,92 @@ The list contains variables, which may include array sections.
20442044 return 0;
20452045 }
20462046
2047+ .. challenge ::
2048+
2049+ In the previous implementation of the Fibonacci generator code, we noticed that the values of
2050+ Fibonacci numbers are computed several times during recursion. This situation can be avoided by using
2051+ task dependencies, as in the following graph which shows the dependencies that we can create explicitl
2052+ for the Fibonacci number 6:
2053+
2054+
2055+ .. code-block :: text
2056+
2057+ fib[6]
2058+ depends on fib[5] and fib[4]
2059+ |
2060+ v
2061+ fib[5]
2062+ depends on fib[4] and fib[3]
2063+ |
2064+ v
2065+ fib[4]
2066+ depends on fib[3] and fib[2]
2067+ / \
2068+ v v
2069+ fib[3] fib[2]
2070+ depends on fib[2] and fib[1] depends on fib[1] and fib[0]
2071+ | \ | \
2072+ v v v v
2073+ fib[2] fib[1] fib[1] fib[0]
2074+ depends on fib[1] and fib[0]
2075+ | \
2076+ v v
2077+ fib[1] fib[0]
2078+
2079+
2080+ Base values:
2081+ fib[1] = 1
2082+ fib[0] = 0
2083+
2084+ Write a code for the Fibonacci numbers generator but now using task dependencies.
2085+
2086+ .. solution ::
2087+
2088+ .. code-block :: c
2089+ :linenos:
2090+
2091+ // On cluster Kebnekaise
2092+ // ml foss
2093+ // export OMP_NUM_THREADS=4
2094+ // gcc -O3 -march=native -fopenmp -o test.x fibonacci_task_dependencies.c -lm
2095+ #include <stdio.h>
2096+ #include <stdlib.h>
2097+ #include <omp.h>
2098+
2099+ int main(int argc, char* argv[]) {
2100+ int n = (argc > 1) ? atoi(argv[1]) : 40;
2101+ unsigned long long *fib = malloc((n+1) * sizeof(unsigned long long));
2102+
2103+ #pragma omp parallel
2104+ {
2105+ #pragma omp single
2106+ {
2107+ // Base cases
2108+ #pragma omp task depend(out: fib[0])
2109+ { fib[0] = 0; }
2110+
2111+ #pragma omp task depend(out: fib[1])
2112+ { fib[1] = 1; }
2113+
2114+ // Create tasks for F(2) .. F(n)
2115+ for (int i = 2; i <= n; i++) {
2116+ #pragma omp task depend(in: fib[i-1], fib[i-2]) depend(out: fib[i])
2117+ {
2118+ fib[i] = fib[i-1] + fib[i-2];
2119+ }
2120+ }
2121+
2122+ // Wait until fib[n] is available
2123+ #pragma omp taskwait
2124+ printf("fib(%d) = %llu\n", n, fib[n]);
2125+ }
2126+ }
2127+
2128+ free(fib);
2129+ return 0;
2130+ }
2131+
2132+
20472133
20482134
20492135 taskloop Construct (OpenMP 4.5)
0 commit comments