TABLE OF CONTENTS
- ABINIT/m_xomp
- m_xomp/xomp_get_default_device
- m_xomp/xomp_get_initial_device
- m_xomp/xomp_get_mapped_ptr
- m_xomp/xomp_get_max_threads
- m_xomp/xomp_get_num_cores_node
- m_xomp/xomp_get_num_devices
- m_xomp/xomp_get_num_threads
- m_xomp/xomp_get_thread_num
- m_xomp/xomp_in_parallel
- m_xomp/xomp_is_initial_device
- m_xomp/xomp_set_default_device
- m_xomp/xomp_set_num_threads
- m_xomp/xomp_show_info
- m_xomp/xomp_target_is_present
ABINIT/m_xomp [ Modules ]
NAME
m_xomp
FUNCTION
Thin wrappers and tools for OpenMP parallelization.
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
16 #if defined HAVE_CONFIG_H 17 #include "config.h" 18 #endif 19 20 #include "abi_common.h" 21 22 MODULE m_xomp 23 24 use defs_basis, only : std_out 25 use, intrinsic :: iso_c_binding, only : c_ptr, c_size_t, c_int, c_null_ptr 26 #ifdef HAVE_OPENMP 27 use omp_lib 28 #endif 29 30 implicit none 31 32 private 33 34 public :: xomp_show_info 35 public :: xomp_get_max_threads 36 public :: xomp_get_thread_num 37 public :: xomp_get_num_threads 38 public :: xomp_set_num_threads 39 public :: xomp_in_parallel 40 public :: xomp_get_num_cores_node 41 ! OpenMP 5.0 GPU device routines 42 public :: xomp_set_default_device 43 public :: xomp_get_default_device 44 public :: xomp_get_initial_device 45 public :: xomp_get_num_devices 46 public :: xomp_is_initial_device 47 public :: xomp_target_is_present 48 ! OpenMP 5.1 GPU device routine 49 public :: xomp_get_mapped_ptr 50 51 52 !---------------------------------------------------------------------- 53 54 CONTAINS !=========================================================================================================================
m_xomp/xomp_get_default_device [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_default_device
FUNCTION
Wrapper for omp_get_default_device
OUTPUT
(integer) id of default offload device (ie: GPU, accelerator) on which "target" regions will be run on. -1 if no offload device is used.
SOURCE
372 function xomp_get_default_device() 373 374 !Arguments ------------------------------------ 375 !scalars 376 integer :: xomp_get_default_device 377 378 ! ************************************************************************* 379 380 #ifdef HAVE_OPENMP_OFFLOAD 381 xomp_get_default_device = omp_get_default_device() 382 #else 383 xomp_get_default_device = -1 384 #endif 385 386 end function xomp_get_default_device
m_xomp/xomp_get_initial_device [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_initial_device
FUNCTION
Wrapper for omp_get_initial_device
OUTPUT
(integer) id of OpenMP device which targets host rather than acclerator devices.
SOURCE
404 function xomp_get_initial_device() 405 406 !Arguments ------------------------------------ 407 !scalars 408 integer :: xomp_get_initial_device 409 410 ! ************************************************************************* 411 412 #ifdef HAVE_OPENMP_OFFLOAD 413 xomp_get_initial_device = omp_get_initial_device() 414 #else 415 xomp_get_initial_device = -1 416 #endif 417 418 end function xomp_get_initial_device
m_xomp/xomp_get_mapped_ptr [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_mapped_ptr
FUNCTION
Wrapper for omp_get_mapped_ptr
INPUTS
ptr = C pointer, likely matching a Fortran array wrapped in c_loc
OUTPUT
(c_ptr) Pointer to device memory matching given input ptr
SOURCE
548 function xomp_get_mapped_ptr(ptr) result(gpu_ptr) 549 550 !Arguments ------------------------------------ 551 type(c_ptr),intent(in) :: ptr 552 integer :: device_id, rc 553 type(c_ptr) :: gpu_ptr 554 555 ! ************************************************************************* 556 557 #ifdef HAVE_OPENMP_OFFLOAD 558 device_id = xomp_get_default_device() 559 if(xomp_target_is_present(ptr)) then 560 #ifdef HAVE_OPENMP_GET_MAPPED_PTR 561 gpu_ptr = omp_get_mapped_ptr(ptr, device_id) 562 #else 563 gpu_ptr = c_null_ptr 564 #endif 565 else 566 gpu_ptr = c_null_ptr 567 end if 568 #else 569 gpu_ptr = c_null_ptr 570 ! this macro is called before m_errors is compiled 571 ! ABI_UNUSED(device_id) 572 ! ABI_UNUSED(rc) 573 if (.FALSE.) write(std_out,*)device_id 574 if (.FALSE.) write(std_out,*)rc 575 ABI_UNUSED_A(ptr) 576 #endif 577 578 end function xomp_get_mapped_ptr
m_xomp/xomp_get_max_threads [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_max_threads
FUNCTION
Wrapper for omp_get_max_threads.
OUTPUT
Return the maximum number of threads used for the current parallel region that does not use the clause num_threads. Return 1 if OMP is disabled.
SOURCE
120 function xomp_get_max_threads() 121 122 !Arguments ------------------------------------ 123 integer :: xomp_get_max_threads 124 125 ! ************************************************************************* 126 127 #ifdef HAVE_OPENMP 128 xomp_get_max_threads = omp_get_max_threads() 129 #else 130 xomp_get_max_threads = 1 131 #endif 132 133 end function xomp_get_max_threads
m_xomp/xomp_get_num_cores_node [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_num_cores_node
FUNCTION
Wrapper for omp_get_num_procs
OUTPUT
Return the maximum number of cores in one shared memory system Return 0 if OMP is disabled.
SOURCE
300 function xomp_get_num_cores_node() 301 302 !Arguments ------------------------------------ 303 !scalars 304 integer :: xomp_get_num_cores_node 305 306 ! ************************************************************************* 307 308 #ifdef HAVE_OPENMP 309 xomp_get_num_cores_node=omp_get_thread_limit() 310 !We test if thread_limit has been set (if not it should be a large value) 311 ! In 2012, 4096 cores is the biggest known shared memory system 312 if(xomp_get_num_cores_node > 4096) then 313 !so if not set, we used system 'num procs' values which should be the default case 314 xomp_get_num_cores_node=omp_get_num_procs() 315 end if 316 #else 317 xomp_get_num_cores_node=0 318 #endif 319 320 end function xomp_get_num_cores_node
m_xomp/xomp_get_num_devices [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_num_devices
FUNCTION
Wrapper for omp_get_num_devices
OUTPUT
(integer) id of OpenMP device which targets host rather than acclerator devices.
SOURCE
436 function xomp_get_num_devices() 437 438 !Arguments ------------------------------------ 439 !scalars 440 integer :: xomp_get_num_devices 441 442 ! ************************************************************************* 443 444 #ifdef HAVE_OPENMP_OFFLOAD 445 xomp_get_num_devices = omp_get_num_devices() 446 #else 447 xomp_get_num_devices = 0 448 #endif 449 450 end function xomp_get_num_devices
m_xomp/xomp_get_num_threads [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_num_threads
FUNCTION
Wrapper for omp_get_num_threads. The omp_get_num_threads function returns the number of threads in the team currently executing the parallel region from which it is called. The function binds to the closest enclosing PARALLEL directive. The omp_set_num_threads subroutine and the OMP_NUM_THREADS environment variable control the number of threads in a team. If you do not explicitly set the number of threads, the run-time environment will use the number of online processors on the machine by default. If you call omp_get_num_threads from a serial portion of your program or from a nested parallel region that is serialized, the function returns 1.
INPUTS
[open_parallel]= If .TRUE., a temporary OMP parallel region will be open and omp_get_num_threads will be called inside this region. Default to .FALSE. so that we have consistent with the OMP API.
SOURCE
190 function xomp_get_num_threads(open_parallel) result(nthreads) 191 192 !Arguments ------------------------------------ 193 !scalars 194 logical,optional,intent(in) :: open_parallel 195 integer :: nthreads 196 197 !Local variables------------------------------- 198 !scalars 199 logical :: do_open 200 201 ! ************************************************************************* 202 203 do_open = .FALSE.; if (PRESENT(open_parallel)) do_open = open_parallel 204 205 #ifdef HAVE_OPENMP 206 if (do_open .and. .not.xomp_in_parallel()) then 207 !$OMP PARALLEL 208 !$OMP SINGLE 209 nthreads = omp_get_num_threads() 210 !$OMP END SINGLE 211 !$OMP END PARALLEL 212 else 213 nthreads = omp_get_num_threads() 214 end if 215 216 #else 217 nthreads = 1 218 #endif 219 220 end function xomp_get_num_threads
m_xomp/xomp_get_thread_num [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_get_thread_num
FUNCTION
Wrapper for omp_get_thread_num Returns a unique thread identification number within the current team. In a sequential parts of the program, omp_get_thread_num always returns 0. In parallel regions the return value varies from 0 to omp_get_num_threads-1 inclusive. The return value of the master thread of a team is always 0.
SOURCE
151 function xomp_get_thread_num() 152 153 !Arguments ------------------------------------ 154 !scalars 155 integer :: xomp_get_thread_num 156 157 ! ************************************************************************* 158 159 #ifdef HAVE_OPENMP 160 xomp_get_thread_num = omp_get_thread_num() 161 #else 162 xomp_get_thread_num = 0 163 #endif 164 165 end function xomp_get_thread_num
m_xomp/xomp_in_parallel [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_in_parallel
FUNCTION
This function returns true if are currently running in parallel, false otherwise
SOURCE
269 function xomp_in_parallel() result(ans) 270 271 !Arguments------------------------- 272 logical :: ans 273 274 ! ************************************************************************* 275 276 #ifdef HAVE_OPENMP 277 ans = omp_in_parallel() 278 #else 279 ans = .FALSE. 280 #endif 281 282 end function xomp_in_parallel
m_xomp/xomp_is_initial_device [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_is_initial_device
FUNCTION
Wrapper for omp_is_initial_device
OUTPUT
(integer) id of OpenMP device which targets host rather than acclerator devices.
SOURCE
468 function xomp_is_initial_device() 469 470 !Arguments ------------------------------------ 471 !scalars 472 logical :: xomp_is_initial_device 473 474 ! ************************************************************************* 475 476 #ifdef HAVE_OPENMP_OFFLOAD 477 xomp_is_initial_device = omp_is_initial_device() 478 #else 479 xomp_is_initial_device = .true. 480 #endif 481 482 end function xomp_is_initial_device
m_xomp/xomp_set_default_device [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_set_default_device
FUNCTION
Wrapper for omp_set_default_device
INPUTS
device_id = id of offload device (ie: GPU, accelerator) to be used
SOURCE
337 subroutine xomp_set_default_device(device_id) 338 339 !Arguments ------------------------------------ 340 !scalars 341 integer,intent(in) :: device_id 342 343 ! ************************************************************************* 344 345 #ifdef HAVE_OPENMP_OFFLOAD 346 call omp_set_default_device(device_id) 347 #else 348 ! this macro is being called before m_errors is available 349 ! ABI_UNUSED(device_id) 350 if (.FALSE.) write(std_out,*)device_id 351 #endif 352 353 end subroutine xomp_set_default_device
m_xomp/xomp_set_num_threads [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_set_num_threads
FUNCTION
Specifies the number of threads used by default in subsequent parallel sections, if those do not specify a num_threads clause. The argument of xomp_set_num_threads shall be a positive integer.
INPUTS
nthreads = number of threads
SIDE EFFECTS
See description.
SOURCE
241 subroutine xomp_set_num_threads(nthreads) 242 243 !Arguments ------------------------------------ 244 !scalars 245 integer,intent(in) :: nthreads 246 247 ! ************************************************************************* 248 249 #ifdef HAVE_OPENMP 250 call omp_set_num_threads(nthreads) 251 #else 252 if (.FALSE.) write(std_out,*) nthreads 253 #endif 254 255 end subroutine xomp_set_num_threads
m_xomp/xomp_show_info [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_show_info
FUNCTION
Printout of the most important OMP environment variables.
INPUTS
unit=unit number for writing. The named constant dev_null defined in defs_basis can be used to avoid any printing.
OUTPUT
(only writing)
SOURCE
75 subroutine xomp_show_info(unit) 76 77 !Arguments------------------------- 78 integer,optional,intent(in) :: unit 79 80 !Local variables------------------- 81 integer :: my_unt 82 83 ! ************************************************************************* 84 85 my_unt = std_out; if (PRESENT(unit)) my_unt=unit 86 87 #ifdef HAVE_OPENMP 88 write(my_unt,'(/,a)') " ==== OpenMP parallelism is ON ====" 89 write(my_unt,'(a,i0)') "- Max_threads: ",xomp_get_max_threads() 90 write(my_unt,'(a,i0)') "- Num_threads: ",xomp_get_num_threads(open_parallel=.True.) 91 write(my_unt,'(a,i0)') "- Num_procs: ",omp_get_num_procs() 92 write(my_unt,'(a,l1)') "- Dynamic: ",omp_get_dynamic() 93 !write(my_unt,'(a,l1)') "- Nested: ",omp_get_nested() 94 !write(my_unt,'(a,i0)')"- Thread_limit: ",omp_get_thread_limit() 95 !write(my_unt,'(a,i0)')"- Max_active_levels: ",omp_get_max_active_levels() 96 #else 97 write(my_unt,'(/,a)') " ==== OpenMP parallelism is OFF ====" 98 #endif 99 100 write(my_unt,*)"" 101 102 end subroutine xomp_show_info
m_xomp/xomp_target_is_present [ Functions ]
[ Top ] [ m_xomp ] [ Functions ]
NAME
xomp_target_is_present
FUNCTION
Wrapper for omp_target_is_present
INPUTS
ptr = C pointer, likely matching a Fortran array wrapped in c_loc
OUTPUT
(logical) .true. if given ptr has an associate pointer in device memory, .false. otherwise
SOURCE
503 function xomp_target_is_present(ptr) 504 505 !Arguments ------------------------------------ 506 type(c_ptr),intent(in) :: ptr 507 508 logical :: xomp_target_is_present 509 integer(kind=c_int) :: device_id, rc 510 511 ! ************************************************************************* 512 513 #ifdef HAVE_OPENMP_OFFLOAD 514 device_id = xomp_get_default_device() 515 rc = omp_target_is_present(ptr, device_id) 516 xomp_target_is_present = .true. 517 if(rc==0) xomp_target_is_present = .false. 518 #else 519 xomp_target_is_present = .false. 520 ! this macro is called before m_errors is compiled 521 ! ABI_UNUSED(device_id) 522 ! ABI_UNUSED(rc) 523 if (.FALSE.) write(std_out,*)device_id 524 if (.FALSE.) write(std_out,*)rc 525 ABI_UNUSED_A(ptr) 526 #endif 527 528 end function xomp_target_is_present