├── Makefile ├── main.f90 ├── README.md ├── LICENSE └── nvtx.f90 /Makefile: -------------------------------------------------------------------------------- 1 | all: nvtx_example 2 | 3 | FC=pgf90 4 | #FC=gfortran 5 | 6 | nvtx_example:: main.f90 nvtx.f90 7 | $(FC) -o nvtx_example nvtx.f90 main.f90 -L/usr/local/cuda/lib64 -lnvToolsExt 8 | 9 | clean: 10 | rm nvtx_example main.o nvtx.o nvtx.mod 11 | -------------------------------------------------------------------------------- /main.f90: -------------------------------------------------------------------------------- 1 | program main 2 | use nvtx 3 | character(len=4) :: itcount 4 | 5 | ! First range with standard color 6 | call nvtxStartRange("First label") 7 | 8 | do n=1,14 9 | ! Create custom label for each marker 10 | write(itcount,'(i4)') n 11 | 12 | ! Range with custom color 13 | call nvtxStartRange("Label "//itcount,n) 14 | 15 | print *,"Generate label",n 16 | ! Add sleep to make markers big 17 | call sleep(1) 18 | 19 | call nvtxEndRange 20 | end do 21 | 22 | call nvtxEndRange 23 | end program main 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #NVTX_example 2 | 3 | **Recent versions of the NVIDIA HPC SDK provide a built-in module that is equivalent to the one 4 | in this repro. You just need to load the module nvtx in your source (use nvtx) and link with -cudalib=nvtx** 5 | 6 | 7 | How to call NVTX from Fortran: 8 | 9 | https://devblogs.nvidia.com/customize-cuda-fortran-profiling-nvtx/ 10 | 11 | Updated code, it will work with PGI, XLF and Gfortran compilers. 12 | 13 | If you are using nvprof from CUDA 10.x and you are getting an error: 14 | ======== Error: incompatible CUDA driver version. 15 | 16 | you will need to add "--openmp-profiling off" to the command line. 17 | 18 | NVTX markers from Fortran work with the new Nsight tools shipped in CUDA 10.1 Update 2. 19 | 20 | To capture a trace run: 21 | nsys profile -o outputfile ./a.out 22 | 23 | To visualize the trace: 24 | nsight-sys full_path_to_outputfile 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 maxcuda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /nvtx.f90: -------------------------------------------------------------------------------- 1 | module nvtx 2 | 3 | use iso_c_binding 4 | implicit none 5 | 6 | integer,private :: col(7) = [ int(Z'0000ff00'), int(Z'000000ff'), int(Z'00ffff00'), int(Z'00ff00ff'), int(Z'0000ffff'), int(Z'00ff0000'), int(Z'00ffffff')] 7 | character,private,target :: tempName(256) 8 | 9 | type, bind(C):: nvtxEventAttributes 10 | integer(C_INT16_T):: version=1 11 | integer(C_INT16_T):: size=48 ! 12 | integer(C_INT):: category=0 13 | integer(C_INT):: colorType=1 ! NVTX_COLOR_ARGB = 1 14 | integer(C_INT):: color 15 | integer(C_INT):: payloadType=0 ! NVTX_PAYLOAD_UNKNOWN = 0 16 | integer(C_INT):: reserved0 17 | integer(C_INT64_T):: payload ! union uint,int,double 18 | integer(C_INT):: messageType=1 ! NVTX_MESSAGE_TYPE_ASCII = 1 19 | type(C_PTR):: message ! ascii char 20 | end type 21 | 22 | interface nvtxRangePush 23 | ! push range with custom label and standard color 24 | subroutine nvtxRangePushA(name) bind(C, name='nvtxRangePushA') 25 | use iso_c_binding 26 | character(kind=C_CHAR) :: name(256) 27 | end subroutine 28 | 29 | ! push range with custom label and custom color 30 | subroutine nvtxRangePushEx(event) bind(C, name='nvtxRangePushEx') 31 | use iso_c_binding 32 | import:: nvtxEventAttributes 33 | type(nvtxEventAttributes):: event 34 | end subroutine 35 | end interface 36 | 37 | interface nvtxRangePop 38 | subroutine nvtxRangePop() bind(C, name='nvtxRangePop') 39 | end subroutine 40 | end interface 41 | 42 | contains 43 | 44 | subroutine nvtxStartRange(name,id) 45 | character(kind=c_char,len=*) :: name 46 | integer, optional:: id 47 | type(nvtxEventAttributes):: event 48 | character(kind=c_char,len=256) :: trimmed_name 49 | integer:: i 50 | 51 | trimmed_name=trim(name)//c_null_char 52 | 53 | ! move scalar trimmed_name into character array tempName 54 | do i=1,LEN(trim(name)) + 1 55 | tempName(i) = trimmed_name(i:i) 56 | enddo 57 | 58 | 59 | if ( .not. present(id)) then 60 | call nvtxRangePush(tempName) 61 | else 62 | event%color=col(mod(id,7)+1) 63 | event%message=c_loc(tempName) 64 | call nvtxRangePushEx(event) 65 | end if 66 | end subroutine 67 | 68 | subroutine nvtxEndRange 69 | call nvtxRangePop 70 | end subroutine 71 | 72 | end module nvtx 73 | --------------------------------------------------------------------------------