LCOV - code coverage report
Current view: top level - src/general - elpa_utilities.F90 (source / functions) Hit Total Coverage
Test: coverage_50ab7a7628bba174fc62cee3ab72b26e81f87fe5.info Lines: 16 34 47.1 %
Date: 2018-01-10 09:29:53 Functions: 3 6 50.0 %

          Line data    Source code
       1             : !    This file is part of ELPA.
       2             : !
       3             : !    The ELPA library was originally created by the ELPA consortium,
       4             : !    consisting of the following organizations:
       5             : !
       6             : !    - Max Planck Computing and Data Facility (MPCDF), formerly known as
       7             : !      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
       8             : !    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
       9             : !      Informatik,
      10             : !    - Technische Universität München, Lehrstuhl für Informatik mit
      11             : !      Schwerpunkt Wissenschaftliches Rechnen ,
      12             : !    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
      13             : !    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
      14             : !      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
      15             : !      and
      16             : !    - IBM Deutschland GmbH
      17             : !
      18             : !
      19             : !    More information can be found here:
      20             : !    http://elpa.mpcdf.mpg.de/
      21             : !
      22             : !    ELPA is free software: you can redistribute it and/or modify
      23             : !    it under the terms of the version 3 of the license of the
      24             : !    GNU Lesser General Public License as published by the Free
      25             : !    Software Foundation.
      26             : !
      27             : !    ELPA is distributed in the hope that it will be useful,
      28             : !    but WITHOUT ANY WARRANTY; without even the implied warranty of
      29             : !    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      30             : !    GNU Lesser General Public License for more details.
      31             : !
      32             : !    You should have received a copy of the GNU Lesser General Public License
      33             : !    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
      34             : !
      35             : !    ELPA reflects a substantial effort on the part of the original
      36             : !    ELPA consortium, and we ask you to respect the spirit of the
      37             : !    license that we chose: i.e., please contribute any changes you
      38             : !    may have back to the original ELPA library distribution, and keep
      39             : !    any derivatives of ELPA under the same license that we chose for
      40             : !    the original distribution, the GNU Lesser General Public License.
      41             : !
      42             : !
      43             : ! Copyright of the original code rests with the authors inside the ELPA
      44             : ! consortium. The copyright of any additional modifications shall rest
      45             : ! with their original authors, but shall adhere to the licensing terms
      46             : ! distributed along with the original code in the file "COPYING".
      47             : !
      48             : ! Author: Andreas Marek, MPCDF
      49             : 
      50             : #include "config-f90.h"
      51             : 
      52             : module ELPA_utilities
      53             : 
      54             : #ifdef HAVE_ISO_FORTRAN_ENV
      55             :   use iso_fortran_env, only : output_unit, error_unit
      56             : #endif
      57             :   use, intrinsic :: iso_c_binding
      58             :   implicit none
      59             : 
      60             :   private ! By default, all routines contained are private
      61             : 
      62             :   public :: output_unit, error_unit
      63             :   public :: check_alloc, check_alloc_CUDA_f, check_memcpy_CUDA_f, check_dealloc_CUDA_f
      64             :   public :: map_global_array_index_to_local_index
      65             :   public :: pcol, prow
      66             :   public :: local_index                ! Get local index of a block cyclic distributed matrix
      67             :   public :: least_common_multiple      ! Get least common multiple
      68             : 
      69             : #ifndef HAVE_ISO_FORTRAN_ENV
      70             :   integer, parameter :: error_unit = 0
      71             :   integer, parameter :: output_unit = 6
      72             : #endif
      73             : 
      74             :   !******
      75             :   contains
      76             : 
      77             : #include "prow_pcol.F90"
      78             : 
      79             : !-------------------------------------------------------------------------------
      80             : #include "map_global_to_local.F90"
      81             : 
      82   328825332 :  integer function local_index(idx, my_proc, num_procs, nblk, iflag)
      83             : 
      84             : !-------------------------------------------------------------------------------
      85             : !  local_index: returns the local index for a given global index
      86             : !               If the global index has no local index on the
      87             : !               processor my_proc behaviour is defined by iflag
      88             : !
      89             : !  Parameters
      90             : !
      91             : !  idx         Global index
      92             : !
      93             : !  my_proc     Processor row/column for which to calculate the local index
      94             : !
      95             : !  num_procs   Total number of processors along row/column
      96             : !
      97             : !  nblk        Blocksize
      98             : !
      99             : !  iflag       Controls the behaviour if idx is not on local processor
     100             : !              iflag< 0 : Return last local index before that row/col
     101             : !              iflag==0 : Return 0
     102             : !              iflag> 0 : Return next local index after that row/col
     103             : !-------------------------------------------------------------------------------
     104             :     implicit none
     105             : 
     106             :     integer(kind=c_int) :: idx, my_proc, num_procs, nblk, iflag
     107             : 
     108             :     integer(kind=c_int) :: iblk
     109             : 
     110   328825332 :     iblk = (idx-1)/nblk  ! global block number, 0 based
     111             : 
     112   328825332 :     if (mod(iblk,num_procs) == my_proc) then
     113             : 
     114             :     ! block is local, always return local row/col number
     115             : 
     116   319496832 :     local_index = (iblk/num_procs)*nblk + mod(idx-1,nblk) + 1
     117             : 
     118             :     else
     119             : 
     120             :     ! non local block
     121             : 
     122     9328500 :     if (iflag == 0) then
     123             : 
     124           0 :         local_index = 0
     125             : 
     126             :     else
     127             : 
     128     9328500 :         local_index = (iblk/num_procs)*nblk
     129             : 
     130     9328500 :         if (mod(iblk,num_procs) > my_proc) local_index = local_index + nblk
     131             : 
     132     9328500 :         if (iflag>0) local_index = local_index + 1
     133             :     endif
     134             :     endif
     135             : 
     136   328825332 :  end function local_index
     137             : 
     138     6837144 :  integer function least_common_multiple(a, b)
     139             : 
     140             :     ! Returns the least common multiple of a and b
     141             :     ! There may be more efficient ways to do this, we use the most simple approach
     142             :     implicit none
     143             :     integer(kind=c_int), intent(in) :: a, b
     144             : 
     145     8695416 :     do least_common_multiple = a, a*(b-1), a
     146     1858272 :     if(mod(least_common_multiple,b)==0) exit
     147             :     enddo
     148             :     ! if the loop is left regularly, least_common_multiple = a*b
     149             : 
     150     6837144 :  end function least_common_multiple
     151             : 
     152      130176 :  subroutine check_alloc(function_name, variable_name, istat, errorMessage)
     153             : 
     154             :     implicit none
     155             : 
     156             :     character(len=*), intent(in)    :: function_name
     157             :     character(len=*), intent(in)    :: variable_name
     158             :     integer(kind=c_int), intent(in)    :: istat
     159             :     character(len=*), intent(in)    :: errorMessage
     160             : 
     161      130176 :     if (istat .ne. 0) then
     162           0 :       print *, function_name, ": error when allocating ", variable_name, " ", errorMessage
     163           0 :       stop 1
     164             :     endif
     165      260352 :  end subroutine
     166             : 
     167           0 :  subroutine check_alloc_CUDA_f(file_name, line, successCUDA)
     168             : 
     169             :     implicit none
     170             : 
     171             :     character(len=*), intent(in)    :: file_name
     172             :     integer(kind=c_int), intent(in)    :: line
     173             :     logical                         :: successCUDA
     174             : 
     175           0 :     if (.not.(successCUDA)) then
     176           0 :       print *, file_name, ":", line,  " error in cuda_malloc when allocating "
     177           0 :       stop 1
     178             :     endif
     179           0 :  end subroutine
     180             : 
     181           0 :  subroutine check_dealloc_CUDA_f(file_name, line, successCUDA)
     182             : 
     183             :     implicit none
     184             : 
     185             :     character(len=*), intent(in)    :: file_name
     186             :     integer(kind=c_int), intent(in)    :: line
     187             :     logical                         :: successCUDA
     188             : 
     189           0 :     if (.not.(successCUDA)) then
     190           0 :       print *, file_name, ":", line,  " error in cuda_free when deallocating "
     191           0 :       stop 1
     192             :     endif
     193           0 :  end subroutine
     194             : 
     195           0 :  subroutine check_memcpy_CUDA_f(file_name, line, successCUDA)
     196             : 
     197             :     implicit none
     198             : 
     199             :     character(len=*), intent(in)    :: file_name
     200             :     integer(kind=c_int), intent(in)    :: line
     201             :     logical                         :: successCUDA
     202             : 
     203           0 :     if (.not.(successCUDA)) then
     204           0 :       print *, file_name, ":", line,  " error in cuda_memcpy when copying "
     205           0 :       stop 1
     206             :     endif
     207           0 :  end subroutine
     208             : 
     209             : end module ELPA_utilities

Generated by: LCOV version 1.12