Utilities
Contents
12.13. Utilities#
This section contains examples of utility routines and features.
12.13.1. Timing Routines#
The omp_get_wtime routine can be used to measure the elapsed wall clock time (in seconds) of code execution in a program. The routine is thread safe and can be executed by multiple threads concurrently. The precision of the timer can be obtained by a call to the omp_get_wtick routine. The following example shows a use case.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: get_wtime.1
* type: C
*/
#include <stdio.h>
#include <unistd.h>
#include <omp.h>
void work_to_be_timed()
{
sleep(2);
}
int main()
{
double start, end;
start = omp_get_wtime();
work_to_be_timed(); // any parallel or serial codes
end = omp_get_wtime();
printf("Work took %f seconds\n", end - start);
printf("Precision of the timer is %f (sec)\n", omp_get_wtick());
return 0;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: get_wtime.1
! type: F-free
subroutine work_to_be_timed
use, intrinsic :: iso_c_binding, only: c_int
interface
subroutine fsleep(sec) bind(C, name="sleep")
import c_int
integer(c_int), value :: sec
end subroutine
end interface
call fsleep(2)
end subroutine
program do_work
use omp_lib
implicit none
double precision :: start, end
start = omp_get_wtime()
call work_to_be_timed ! any parallel or serial codes
end = omp_get_wtime()
print *, "Work took", end - start, "seconds"
print *, "Precision of the timer is", omp_get_wtick(), "(sec)"
end program
12.13.2. Environment Display#
The OpenMP version number and the values of ICVs associated with the relevant environment variables can be displayed at runtime by setting the OMP_DISPLAY_ENV environment variable to either TRUE or VERBOSE. The information is displayed once by the runtime.
A more flexible or controllable approach is to call the omp_display_env API routine at any desired point of a code to display the same information. This OpenMP 5.1 API routine takes a single verbose argument. A value of 0 or .false. (for C/C++ or Fortran) indicates the required OpenMP ICVs associated with environment variables be displayed, and a value of 1 or .true. (for C/C++ or Fortran) will include vendor-specific ICVs that can be modified by environment variables.
The following example illustrates the conditional execution of the API omp_display_env routine. Typically it would be invoked in various debug modes of an application. An important use case is to have a single MPI process (e.g., rank = 0) of a hybrid (MPI+OpenMP) code execute the routine, instead of all MPI processes, as would be done by setting the OMP_DISPLAY_ENV to TRUE or VERBOSE.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: display_env.1
* type: C
* version: omp_5.1
*/
#include <omp.h>
//implementers: customize debug routines for app debugging
int debug(){ return 1; }
int debug_omp_verbose(){ return 0; }
int main()
{
if( debug() ) omp_display_env( debug_omp_verbose() );
// ...
return 0;
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: display_env.1
! type: F-free
! version: omp_5.1
!implementers: customize debug routines for app debugging
function debug()
logical :: debug
debug = .true.
end function
function debug_omp_verbose()
logical :: debug_omp_verbose
debug_omp_verbose = .false.
end function
program display_omp_environment
use omp_lib
logical :: debug, debug_omp_verbose
if( debug() ) call omp_display_env( debug_omp_verbose() )
!! ...
end program
A sample output from the execution of the code might look like:
OPENMP DISPLAY ENVIRONMENT BEGIN
_OPENMP='202011'
[host] OMP_AFFINITY_FORMAT='(null)'
[host] OMP_ALLOCATOR='omp_default_mem_alloc'
[host] OMP_CANCELLATION='FALSE'
[host] OMP_DEFAULT_DEVICE='0'
[host] OMP_DISPLAY_AFFINITY='FALSE'
[host] OMP_DISPLAY_ENV='FALSE'
[host] OMP_DYNAMIC='FALSE'
[host] OMP_MAX_ACTIVE_LEVELS='1'
[host] OMP_MAX_TASK_PRIORITY='0'
[host] OMP_NESTED: deprecated; max-active-levels-var=1
[host] OMP_NUM_THREADS: value is not defined
[host] OMP_PLACES: value is not defined
[host] OMP_PROC_BIND: value is not defined
[host] OMP_SCHEDULE='static'
[host] OMP_STACKSIZE='4M'
[host] OMP_TARGET_OFFLOAD=DEFAULT
[host] OMP_THREAD_LIMIT='0'
[host] OMP_TOOL='enabled'
[host] OMP_TOOL_LIBRARIES: value is not defined
OPENMP DISPLAY ENVIRONMENT END
12.13.3. error Directive#
The error directive provides a consistent method for C, C++, and Fortran to emit a fatal or warning message at compilation or execution time, as determined by a severity or an at clause, respectively. When severity(fatal) is present, the compilation or execution is aborted. Without any clauses the default behavior is as if at(compilation) and severity(fatal) were specified.
The C, C++, and Fortran examples below show all the cases for reporting messages.
//%compiler: clang
//%cflags: -fopenmp
/*
* name: error.1
* type: C
* version: omp_5.2
*/
#include <stdio.h>
#include <omp.h>
int main(){
#pragma omp metadirective \
when(implementation={vendor(gnu)}: nothing ) \
otherwise(error at(compilation) severity(fatal) \
message("GNU compiler required."))
if( omp_get_num_procs() < 3 ){
#pragma omp error at(runtime) severity(fatal) \
message("3 or more procs required.")
}
#pragma omp parallel master
{
// Give notice about master deprecation at compile time and run time.
#pragma omp error at(compilation) severity(warning) \
message("Notice: master is deprecated.")
#pragma omp error at(runtime) severity(warning) \
message("Notice: masked used next release.")
printf(" Hello from thread number 0.\n");
}
}
!!%compiler: gfortran
!!%cflags: -fopenmp
! name: error.1
! type: F-free
! version: omp_5.2
program main
use omp_lib
!$omp metadirective &
!$omp& when( implementation={vendor(gnu)}: nothing ) &
!$omp& otherwise( error at(compilation) severity(fatal) &
!$omp& message( "GNU compiler required." ) )
if( omp_get_num_procs() < 3 ) then
!$omp error at(runtime) severity(fatal) &
!$omp& message("3 or more procs required.")
endif
!$omp parallel master
!! Give notice about master deprecation at compile time and run time.
!$omp error at(compilation) severity(warning) &
!$omp& message("Notice: master is deprecated.")
!$omp error at(runtime) severity(warning) &
!$omp& message("Notice: masked to be used in next release.")
print*," Hello from thread number 0."
!$omp end parallel master
end program