TABLE OF CONTENTS


ABINIT/m_nvtx [ Modules ]

[ Top ] [ 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