TABLE OF CONTENTS
ABINIT/m_nvtx [ Modules ]
NAME
m_nvtx
FUNCTION
Provide profiling helper routine to annotate execution ranges on both CPU and GPU The code below is just a wrapper around the Nvidia NVTX (version 3) library. It is borrowed from https://developer.nvidia.com/blog/customize-cuda-fortran-profiling-nvtx/ This module should (TBC) only be activated when GPU execution is enabled.
COPYRIGHT
Copyright (C) 2010-2024 ABINIT group 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
19 #if defined HAVE_CONFIG_H 20 #include "config.h" 21 #endif 22 23 24 module m_nvtx 25 use, intrinsic :: iso_c_binding 26 implicit none 27 28 integer,private,parameter :: nbcol=19 29 integer(kind=C_INT32_T),private :: col(nbcol) = [ & 30 & int(Z'0000ff00',kind=C_INT32_T), & ! GREEN 31 & int(Z'000000ff',kind=C_INT32_T), & ! BLUE 32 & int(Z'00ffff00',kind=C_INT32_T), & ! YELLOW 33 & int(Z'00ff00ff',kind=C_INT32_T), & ! PURPLE 34 & int(Z'0000ffff',kind=C_INT32_T), & ! CYAN 35 & int(Z'00ff0000',kind=C_INT32_T), & ! READ 36 & int(Z'00ff8000',kind=C_INT32_T), & ! ORANGE 37 & int(Z'000080ff',kind=C_INT32_T), & ! LIGHT BLUE 38 & int(Z'00ff80ff',kind=C_INT32_T), & ! PINK 39 & int(Z'0080ff80',kind=C_INT32_T), & ! LIGHT GREEN 40 & int(Z'00b832ff',kind=C_INT32_T), & 41 & int(Z'00f9fa7d',kind=C_INT32_T), & ! LIGHT YELLOW 42 & int(Z'00f96c56',kind=C_INT32_T), & 43 & int(Z'0094b5dc',kind=C_INT32_T), & 44 & int(Z'00cc99ff',kind=C_INT32_T), & ! LIGHT PURPLE 45 & int(Z'00a50201',kind=C_INT32_T), & ! DARK RED 46 & int(Z'0001a4a5',kind=C_INT32_T), & ! KIND OF CYAN 47 & int(Z'00d8fb08',kind=C_INT32_T), & ! FLASHY YELLOW 48 & int(Z'0090aacc',kind=C_INT32_T) ] 49 character,private,target :: tempName(256) 50 51 type, bind(C):: nvtxEventAttributes 52 integer(C_INT16_T):: version=1 53 integer(C_INT16_T):: size=48 ! 54 integer(C_INT):: category=0 55 integer(C_INT):: colorType=1 ! NVTX_COLOR_ARGB = 1 56 integer(C_INT):: color 57 integer(C_INT):: payloadType=0 ! NVTX_PAYLOAD_UNKNOWN = 0 58 integer(C_INT):: reserved0 59 integer(C_INT64_T):: payload ! union uint,int,double 60 integer(C_INT):: messageType=1 ! NVTX_MESSAGE_TYPE_ASCII = 1 61 type(C_PTR):: message ! ascii char 62 end type nvtxEventAttributes 63 64 #ifdef HAVE_GPU_MARKERS 65 66 interface nvtxRangePush 67 ! push range with custom label and standard color 68 #if defined HAVE_GPU_CUDA 69 subroutine nvtxRangePushA(name) bind(C, name='nvtxRangePushA') 70 #elif defined HAVE_GPU_HIP 71 subroutine nvtxRangePushA(name) bind(C, name='roctxRangePushA') 72 #endif 73 use, intrinsic :: iso_c_binding 74 character(kind=C_CHAR) :: name(256) 75 end subroutine nvtxRangePushA 76 #ifdef HAVE_GPU_CUDA 77 ! push range with custom label and custom color 78 subroutine nvtxRangePushEx(event) bind(C, name='nvtxRangePushEx') 79 use, intrinsic :: iso_c_binding 80 import:: nvtxEventAttributes 81 type(nvtxEventAttributes):: event 82 end subroutine nvtxRangePushEx 83 #endif 84 end interface nvtxRangePush 85 86 interface nvtxRangePop 87 #if defined HAVE_GPU_CUDA 88 subroutine nvtxRangePop() bind(C, name='nvtxRangePop') 89 #elif defined HAVE_GPU_HIP 90 subroutine nvtxRangePop() bind(C, name='roctxRangePop') 91 #endif 92 end subroutine nvtxRangePop 93 end interface nvtxRangePop 94 95 interface 96 ! start profiling 97 subroutine nvtxProfilerStart() bind(C, name='cudaProfilerStart') 98 end subroutine nvtxProfilerStart 99 ! stop profiling 100 subroutine nvtxProfilerStop() bind(C, name='cudaProfilerStop') 101 end subroutine nvtxProfilerStop 102 103 end interface 104 105 contains 106 107 subroutine nvtxStartRange(name,id) 108 109 implicit none 110 111 character(kind=c_char,len=*) :: name 112 integer, optional:: id 113 type(nvtxEventAttributes):: event 114 character(kind=c_char,len=256) :: trimmed_name 115 integer:: i 116 117 trimmed_name=trim(name)//c_null_char 118 119 ! move scalar trimmed_name into character array tempName 120 do i=1,LEN(trim(name)) + 1 121 tempName(i) = trimmed_name(i:i) 122 enddo 123 124 #if defined HAVE_GPU_CUDA 125 if ( .not. present(id)) then 126 call nvtxRangePush(tempName) 127 else 128 event%color=col(mod(id,nbcol)+1) 129 event%message=c_loc(tempName) 130 call nvtxRangePushEx(event) 131 end if 132 #elif defined HAVE_GPU_HIP 133 call nvtxRangePush(tempName) 134 #endif 135 136 end subroutine nvtxStartRange 137 138 subroutine nvtxEndRange 139 call nvtxRangePop 140 end subroutine nvtxEndRange 141 142 #endif 143 144 end module m_nvtx