Reduction

Tasking

C | Fortran-90

in_reduction

Definition

The in_reduction clause specifies that a task participates in a reduction defined by an enclosing region for a matching list item that appears in a task_reduction clause or a reduction clause with the task modifier. If the construct in which the in_reduction clause appears is:

  • task: the generated task becomes the participating task. For each list item, a private copy may be created as if the private clause had been used.
  • target: the target task becomes the participating task. For each list item, a private copy will be created in the data environment of the target task as if the private clause had been used, and this private copy will be implicitly mapped into the device data environment of the target device.

At the end of the task region, if a private copy was created its value is combined with a copy created by a reduction scoping clause or with the original list item.

Copy

Feedback

in_reduction(identifier : list)

Parameters

identifier

The identifier indicating the reduction operation to apply. It is either a user-defined operator or one of the following operators:

  • +: sum.
  • -: difference.
  • *: product.
  • &: bit-wise and.
  • |: bit-wise or.
  • ^: bit-wise exclusive or.
  • &&: logical and.
  • ||: logical or.
  • min: minimum.
  • max: maximum.
list

The list of reduction variables, separated with commas.

Example

Copy

Feedback

#include <stdio.h>
#include <stdlib.h>
#include <omp.h>

/**
 * @brief Illustrates how to use the in_reduction clause.
 * @details This example consists in calculating the sum of all elements of an
 * array.
 **/
int main(int argc, char* argv[])
{
    // Use 2 threads when creating OpenMP parallel regions
    omp_set_num_threads(2);

    int total = 0;
    const int ARRAY_SIZE = 100;
    int* myArray = malloc(sizeof(int) * ARRAY_SIZE);
    if(myArray == NULL)
    {
        printf("Cannot allocate the array \"myArray\".\n");
        return EXIT_FAILURE;
    }

    // Initialise the array
    for(int i = 0; i < ARRAY_SIZE; i++)
    {
        myArray[i] = i;
    }

    // Calculate the sum of all elements

    // 1st method: a parallel loop via tasks
    #pragma omp parallel reduction(task, +: total)
    {
        #pragma omp single
        {
            for(int i = 0; i < ARRAY_SIZE; i++)
            {
                #pragma omp task in_reduction(+: total)
                {
                    total += myArray[i];
                }
            }
        }
    }
    printf("The sum of all array elements with the 1st method is equal to %d.\n", total);

    // 2nd method: a taskgroup
    total = 0;
    #pragma omp parallel
    {
        #pragma omp single
        {
            #pragma omp taskgroup task_reduction(+: total)
            {
                for(int i = 0; i < ARRAY_SIZE; i++)
                {
                    #pragma omp task in_reduction(+: total)
                    total += myArray[i];
                }
            }
        }
    }
    printf("The sum of all array elements with the 2nd method is equal to %d.\n", total);

    free(myArray);

    return EXIT_SUCCESS;
}