Intel® oneAPI DPC++/C++ Compiler Developer Guide and Reference

ID 767253
Date 7/13/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

fopenmp-declare-target-scalar-defaultmap, Qopenmp-declare-target-scalar-defaultmap

Determines which implicit data-mapping/sharing rules are applied for a scalar variable referenced in a target pragma.

Syntax

Linux:

-fopenmp-declare-target-scalar-defaultmap=keyword

Windows:

/Qopenmp-declare-target-scalar-defaultmap:keyword

Arguments

keyword

Is the rule to be applied for a scalar variable referenced in a target pragma.TARGET directive.. Possible values are:

default

Specifies that the compiler should apply implicit data-mapping/sharing rules according to the OpenMP* specification.

Thus, if a scalar variable referenced in a target construct appears in a to or link clause in a declare target pragma that does not have a device_type (nohost) clause, and the target construct's clauses do not define explicit data-mapping/sharing rules for this variable, then the compiler should treat it as if it had appeared in a map clause with a map-type of tofrom.

firstprivate

Specifies that when a scalar variable referenced in a target construct appears in a to or link clause in a declare target pragma that does not have a device_type (nohost) clause, and the target construct's clauses do not define explicit data-mapping/sharing rules for this variable, then the scalar variable should not be mapped, but instead it has an implicit data-sharing attribute of firstprivate.

Default

-fopenmp-declare-target-scalar-defaultmap=default
or /Qopenmp-declare-target-scalar-defaultmap:default

The compiler applies implicit data-mapping/sharing rules according to OpenMP specification.

Description

This option determines which implicit data-mapping/sharing rules are applied for a scalar variable referenced in a target pragma, when that scalar variable appears in a declare target pragma that has a to or link clause, but not clause device_type (nohost).

It tells the compiler to assume that a scalar declare target variable with implicit data-mapping/sharing referenced in a target construct has the same value before the target construct (in the host environment) and at the beginning the target region (in the device environment). This may enable some optimizations in the host code invoking the target region for execution.

The option only affects data-mapping/sharing rules for scalar variables referenced in a target construct that do not appear in one of the target clauses map, is_device_ptr, or has_device_addr.

For more information about implicit data-mapping/sharing rules, see the OpenMP 5.2 specification. For example, see section 5.8.1 in that specification.

IDE Equivalent

None

Alternate Options

None

Examples

Consider the following:

#pragma omp declare target
int N;
#pragma omp end declare target
...
void program() {
#pragma omp target teams distribute parallel for
  for (int i = 0; i < N; ++i) ...
}

Specifying -fopenmp-declare-target-scalar-defaultmap=firstprivate (or /Qopenmp-declare-target-scalar-defaultmap:firstprivate) or an explicit 'firstprivate(N)' lets the compiler generate efficient host code that issues the most appropriate number of teams and threads to execute the iterations of the distribute parallel for loop, assuming that N does not change its value between the beginning of the target region and the beginning of the distribute parallel for region.

If the compiler option (or 'firstprivate(N)') is not used, then the value of N in the host code (before the target construct) may be different from the value of N in the for statement. To compute the right number of teams/threads on the host the value of N must be transferred from the device to the host, which may result in a performance penalty.

The option may not behave correctly for all OpenMP programs. In particular, it may behave incorrectly for programs that allow different values of the same declare target scalar variables on entry to target regions.

For example, consider the following:

#include <stdio.h>

#pragma omp declare target
int x = 0; /* host 'x' is 0, target 'x' is 0 */
#pragma omp end declare target

int main() {
  x = -1;

  /* host 'x' is -1, target 'x' is 0 */
#pragma omp target
  x = 1;

  /* host 'x' is -1, target 'x' is 1 */
#pragma omp target
  printf("target: %d == 1\n", x);

#pragma omp target update from(x)

  /* host 'x' is 1, target 'x' is 1 */
  printf("host: %d == 1\n", x);

  return 0;
}

The following is the correct output for the above code:

target: 1 == 1
host: 1 == 1

However, this is the output when option -fopenmp-declare-target-scalar-defaultmap=firstprivate (or /Qopenmp-declare-target-scalar-defaultmap:firstprivate) is specified:

target: -1 == 1
host: 0 == 1