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