copyprivate Clause
10.12. copyprivate Clause#
The copyprivate clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads. In this example, if the routine is called from the sequential part, its behavior is not affected by the presence of the directives. If it is called from a parallel region, then the actual arguments with which a and b are associated must be private.
The thread that executes the structured block associated with the single construct broadcasts the values of the private variables a, b, x, and y from its implicit task’s data environment to the data environments of the other implicit tasks in the thread team. The broadcast completes before any of the threads have left the barrier at the end of the construct.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: copyprivate.1
* type: C
*/
#include <stdio.h>
float x, y;
#pragma omp threadprivate(x, y)
void init(float a, float b ) {
#pragma omp single copyprivate(a,b,x,y)
{
scanf("%f %f %f %f", &a, &b, &x, &y);
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: copyprivate.1
! type: F-fixed
SUBROUTINE INIT(A,B)
REAL A, B
COMMON /XY/ X,Y
!$OMP THREADPRIVATE (/XY/)
!$OMP SINGLE
READ (11) A,B,X,Y
!$OMP END SINGLE COPYPRIVATE (A,B,/XY/)
END SUBROUTINE INIT
In this example, assume that the input must be performed by the primary thread. Since the masked construct does not support the copyprivate clause, it cannot broadcast the input value that is read. However, copyprivate is used to broadcast an address where the input value is stored.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: copyprivate.2
* type: C
* version: omp_5.1
*/
#include <stdio.h>
#include <stdlib.h>
float read_next( ) {
float * tmp;
float return_val;
#pragma omp single copyprivate(tmp)
{
tmp = (float *) malloc(sizeof(float));
} /* copies the pointer only */
#pragma omp masked
{
scanf("%f", tmp);
}
#pragma omp barrier
return_val = *tmp;
#pragma omp barrier
#pragma omp single nowait
{
free(tmp);
}
return return_val;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: copyprivate.2
! type: F-fixed
! version: omp_5.1
REAL FUNCTION READ_NEXT()
REAL, POINTER :: TMP
!$OMP SINGLE
ALLOCATE (TMP)
!$OMP END SINGLE COPYPRIVATE (TMP) ! copies the pointer only
!$OMP MASKED
READ (11) TMP
!$OMP END MASKED
!$OMP BARRIER
READ_NEXT = TMP
!$OMP BARRIER
!$OMP SINGLE
DEALLOCATE (TMP)
!$OMP END SINGLE NOWAIT
END FUNCTION READ_NEXT
Suppose that the number of lock variables required within a parallel region cannot easily be determined prior to entering it. The copyprivate clause can be used to provide access to shared lock variables that are allocated within that parallel region.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: copyprivate.3
* type: C
*/
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
omp_lock_t *new_lock()
{
omp_lock_t *lock_ptr;
#pragma omp single copyprivate(lock_ptr)
{
lock_ptr = (omp_lock_t *) malloc(sizeof(omp_lock_t));
omp_init_lock( lock_ptr );
}
return lock_ptr;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: copyprivate.3
! type: F-fixed
FUNCTION NEW_LOCK()
USE OMP_LIB ! or INCLUDE "omp_lib.h"
INTEGER(OMP_LOCK_KIND), POINTER :: NEW_LOCK
!$OMP SINGLE
ALLOCATE(NEW_LOCK)
CALL OMP_INIT_LOCK(NEW_LOCK)
!$OMP END SINGLE COPYPRIVATE(NEW_LOCK)
END FUNCTION NEW_LOCK
Note that the effect of the copyprivate clause on a variable with the allocatable attribute is different than on a variable with the pointer attribute. The value of A is copied (as if by intrinsic assignment) and the pointer B is copied (as if by pointer assignment) to the corresponding list items in the other implicit tasks belonging to the parallel region.
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: copyprivate.4
! type: F-fixed
SUBROUTINE S(N)
INTEGER N
REAL, DIMENSION(:), ALLOCATABLE :: A
REAL, DIMENSION(:), POINTER :: B
ALLOCATE (A(N))
!$OMP SINGLE
ALLOCATE (B(N))
READ (11) A,B
!$OMP END SINGLE COPYPRIVATE(A,B)
! Variable A is private and is
! assigned the same value in each thread
! Variable B is shared
!$OMP BARRIER
!$OMP SINGLE
DEALLOCATE (B)
!$OMP END SINGLE NOWAIT
END SUBROUTINE S