Ignore:
Timestamp:
07/15/19 12:29:31 (5 years ago)
Author:
adurocher
Message:

trunk : GPU implementation with OpenACC ( merge from glcp.idris.fr )

File:
1 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/trunk/src/parallel/mpipara.F90

    r892 r953  
    1414  INTEGER,SAVE :: id_mpi ! id for profiling 
    1515 
     16  INTEGER, SAVE :: device_id 
     17 
    1618  INTERFACE allocate_mpi_buffer 
    1719    MODULE PROCEDURE allocate_mpi_buffer_r2, allocate_mpi_buffer_r3,allocate_mpi_buffer_r4 
     
    4648  USE xios 
    4749#endif 
     50  USE abort_mod 
    4851  IMPLICIT NONE 
    4952    CHARACTER(LEN=256) :: required_mode_str 
     
    7578      END SELECT 
    7679       
     80      IF (required_mode==MPI_THREAD_SERIALIZED .OR. required_mode==MPI_THREAD_MULTIPLE) THEN 
     81        CALL abort_acc("mpi_threading_mode /= 'single' .AND. mpi_threading_mode /= 'funneled'") 
     82      ENDIF 
    7783 
    7884      IF (required_mode==MPI_THREAD_SINGLE)     PRINT*,'MPI_INIT_THREAD : MPI_SINGLE_THREAD required' 
     
    120126    ENDIF 
    121127     
     128 
     129#ifdef _OPENACC 
     130    device_id = setDevice(mpi_size, mpi_rank) 
     131    PRINT *, 'GPU device ', device_id 
     132#else 
     133     device_id = -1 
     134#endif 
     135 
    122136  END SUBROUTINE  init_mpipara 
    123137 
     
    233247  END SUBROUTINE free_mpi_buffer_r4 
    234248    
     249#ifdef _OPENACC 
     250  FUNCTION setDevice(nprocs, myrank) 
     251    use iso_c_binding 
     252    use openacc 
     253    USE mpi_mod 
     254    implicit none 
     255     
     256    interface  
     257       function gethostid() bind(C) 
     258       use iso_c_binding 
     259       integer(C_INT) :: gethostid 
     260     end function gethostid 
     261  end interface 
     262   
     263  integer, intent(in) :: nprocs, myrank 
     264  integer :: hostids(nprocs), localprocs(nprocs) 
     265  integer :: hostid, ierr, numdev, mydev, i, numlocal 
     266  integer :: setDevice 
     267 
     268  ! get the hostids so we can determine what other processes are on this node 
     269  hostid = gethostid() 
     270  call mpi_allgather(hostid,1,MPI_INTEGER,hostids,1,MPI_INTEGER, MPI_COMM_WORLD, ierr) 
     271 
     272  ! determine which processors are on this node 
     273  numlocal = 0 
     274  localprocs(:) = 0 
     275  do i = 1, nprocs 
     276     if (hostid == hostids(i)) then 
     277        localprocs(i) = numlocal 
     278        numlocal = numlocal + 1 
     279     end if 
     280  end do 
     281 
     282  ! get the number of device on this node 
     283  numdev = acc_get_num_devices(ACC_DEVICE_NVIDIA) 
     284 
     285  if (numdev < 1) then 
     286     print *, "Error: there are no devices available on this host. ABORTING", myrank 
     287     stop 
     288  end if 
     289 
     290  ! print a warning if the number of devices is less than the number of processes on this node. Having multiple processes share a devices is not recommended 
     291  if (numdev < numlocal) then 
     292     if (localprocs(myrank+1) == 1) then 
     293        ! print warning message only once per node 
     294        print *, "WARNING: the number of process is greater than the number of GPUs.", myrank 
     295     end if 
     296     mydev = mod(localprocs(myrank+1), numdev) 
     297  else 
     298     mydev = localprocs(myrank+1) 
     299  end if 
     300 
     301  call acc_set_device_num(mydev,ACC_DEVICE_NVIDIA) 
     302  call acc_init(ACC_DEVICE_NVIDIA) 
     303  setDevice = acc_get_device_num(ACC_DEVICE_NVIDIA) 
     304END FUNCTION setDevice 
     305 
     306#endif 
     307 
     308      
     309      
    235310END MODULE mpipara 
Note: See TracChangeset for help on using the changeset viewer.