requires Directive
12.5. requires Directive#
The declarative requires directive can be used to specify features that an implementation must provide to compile and execute correctly.
In the following example the unified_shared_memory clause of the requires directive ensures that the host and all devices accessible through OpenMP provide a unified address space for memory that is shared by all devices.
The example illustrates the use of the requires directive specifying unified shared memory in file scope, before any device directives or device routines. No map clause is needed for the p structure on the device (and its address &p , for the C++ code, is the same address on the host and device). However, scalar variables referenced within the target construct still have a default data-sharing attribute of firstprivate. The q scalar is incremented on the device, and its change is not updated on the host.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: requires.1
* type: C++
* version: omp_5.0
*/
#include <iostream>
using namespace std;
#pragma omp requires unified_shared_memory
typedef struct mypoints
{
double res;
double data[500];
} mypoints_t;
void do_something_with_p(mypoints_t *p, int q);
int main()
{
mypoints_t p;
int q=0;
#pragma omp target // no map clauses needed
{ // q is firstprivate
q++;
do_something_with_p(&p,q);
}
cout<< p.res << " " << q << endl; // output 1 0
return 0;
}
void do_something_with_p(mypoints_t *p, int q)
{
p->res = q;
for(int i=0;i<sizeof(p->data)/sizeof(double);i++)
p->data[i]=q*i;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: requires.1
! type: F-free
! version: omp_5.0
module data
!$omp requires unified_shared_memory
type,public :: mypoints
double precision :: res
double precision :: data(500)
end type
end module
program main
use data
type(mypoints) :: p
integer :: q=0
!$omp target !! no map clauses needed
q = q + 1 !! q is firstprivate
call do_something_with_p(p,q)
!$omp end target
write(*,'(f5.0,i5)') p%res, q !! output 1. 0
end program
subroutine do_something_with_p(p,q)
use data
type(mypoints) :: p
integer :: q
p%res = q;
do i=1,size(p%data)
p%data(i)=q*i
enddo
end subroutine