elpa2_template.X90 7.07 KB
Newer Older
1
!    This file is part of ELPA.
Andreas Marek's avatar
Andreas Marek committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
!
!    The ELPA library was originally created by the ELPA consortium,
!    consisting of the following organizations:
!
!    - Max Planck Computing and Data Facility (MPCDF), formerly known as
!      Rechenzentrum Garching der Max-Planck-Gesellschaft (RZG),
!    - Bergische Universität Wuppertal, Lehrstuhl für angewandte
!      Informatik,
!    - Technische Universität München, Lehrstuhl für Informatik mit
!      Schwerpunkt Wissenschaftliches Rechnen ,
!    - Fritz-Haber-Institut, Berlin, Abt. Theorie,
!    - Max-Plack-Institut für Mathematik in den Naturwissenschaften,
!      Leipzig, Abt. Komplexe Strukutren in Biologie und Kognition,
!      and
!    - IBM Deutschland GmbH
!
!    This particular source code file contains additions, changes and
!    enhancements authored by Intel Corporation which is not part of
!    the ELPA consortium.
!
!    More information can be found here:
!    http://elpa.mpcdf.mpg.de/
!
!    ELPA is free software: you can redistribute it and/or modify
!    it under the terms of the version 3 of the license of the
!    GNU Lesser General Public License as published by the Free
!    Software Foundation.
!
!    ELPA is distributed in the hope that it will be useful,
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU Lesser General Public License for more details.
!
!    You should have received a copy of the GNU Lesser General Public License
!    along with ELPA.  If not, see <http://www.gnu.org/licenses/>
!
!    ELPA reflects a substantial effort on the part of the original
!    ELPA consortium, and we ask you to respect the spirit of the
!    license that we chose: i.e., please contribute any changes you
!    may have back to the original ELPA library distribution, and keep
!    any derivatives of ELPA under the same license that we chose for
!    the original distribution, the GNU Lesser General Public License.
!
!
! ELPA1 -- Faster replacements for ScaLAPACK symmetric eigenvalue routines
!
! Copyright of the original code rests with the authors inside the ELPA
! consortium. The copyright of any additional modifications shall rest
! with their original authors, but shall adhere to the licensing terms
! distributed along with the original code in the file "COPYING".
 function solve_evp_&
53 54 55 56 57 58 59 60 61 62
  &MATH_DATATYPE&
  &_&
  &2stage_&
  &PRECISION &
  (na, nev, a, lda, ev, q, ldq, nblk, matrixCols, mpi_comm_rows, mpi_comm_cols, mpi_comm_all,   &
#if REALCASE == 1
   THIS_ELPA_KERNEL_API, useQR,   &
#endif
#if COMPLEXCASE == 1
   THIS_ELPA_KERNEL_API,          &
63
#endif
64
   useGPU) result(success)
65

66
#ifdef HAVE_DETAILED_TIMINGS
Andreas Marek's avatar
Cleanup  
Andreas Marek committed
67
   use timings
68
#else
Andreas Marek's avatar
Cleanup  
Andreas Marek committed
69
   use timings_dummy
70 71
#endif
   use iso_c_binding
72
   use elpa
73 74
   use elpa_mpi

75
   implicit none
76

77 78 79
   logical, intent(in), optional             :: useGPU
#if REALCASE == 1
   logical, intent(in), optional             :: useQR
80
#endif
81 82 83 84 85 86 87 88 89 90 91
   integer(kind=c_int), intent(in), optional :: THIS_ELPA_KERNEL_API

   integer(kind=c_int), intent(in)           :: na, nev, lda, ldq, matrixCols, mpi_comm_rows, &
                                                mpi_comm_cols, mpi_comm_all
   integer(kind=c_int), intent(in)           :: nblk

#ifdef USE_ASSUMED_SIZE
   MATH_DATATYPE(kind=C_DATATYPE_KIND), intent(inout) :: a(lda,*), q(ldq,*)
#else
   MATH_DATATYPE(kind=C_DATATYPE_KIND), intent(inout) :: a(lda,matrixCols), q(ldq,matrixCols)
#endif
92
   real(kind=C_DATATYPE_KIND), intent(inout)          :: ev(na)
93

94 95
   integer(kind=c_int)                       :: my_prow, my_pcol, mpierr
   logical                                   :: success
96

97
   integer(kind=c_int)                       :: successInternal
98
   class(elpa_t), pointer                    :: e
99

100 101
    call timer%start("solve_evp_&
    &MATH_DATATYPE&
102 103
    &_2stage_&
    &PRECISION&
104
    &_legacy_interface")
105 106 107 108 109

    call mpi_comm_rank(mpi_comm_rows,my_prow,mpierr)
    call mpi_comm_rank(mpi_comm_cols,my_pcol,mpierr)

    success = .true.
110
    if (elpa_init(CURRENT_API_VERSION) /= ELPA_OK) then
111 112 113
      print *,  "ELPA API version not supported"
      success = .false.
      return
114 115
    endif

116
    e => elpa_allocate()
117 118

    call e%set("na", na)
119
    call e%set("nev", nev)
120 121 122 123 124 125 126 127
    call e%set("local_nrows", lda)
    call e%set("local_ncols", matrixCols)
    call e%set("nblk", nblk)

    call e%set("mpi_comm_parent", mpi_comm_all)
    call e%set("process_row", my_prow)
    call e%set("process_col", my_pcol)

128
    if (e%setup() .ne. ELPA_OK) then
129
      print *, "Cannot setup ELPA instance"
130 131
      success = .false.
      return
132 133
    endif

134
    call e%set("solver", ELPA_SOLVER_2STAGE, successInternal)
135 136 137 138
    if (successInternal .ne. ELPA_OK) then
      print *, "Cannot set ELPA 1stage solver"
      success = .false.
      return
139 140 141 142
    endif

    if (present(useGPU)) then
      if (useGPU) then
143
        call e%set("gpu", 1, successInternal)
144 145 146 147 148 149
        if (successInternal .ne. ELPA_OK) then
          print *, "Cannot set gpu"
          success = .false.
          return
        endif
      else
150
        call e%set("gpu", 0, successInternal)
151 152
        if (successInternal .ne. ELPA_OK) then
          print *, "Cannot set gpu"
153 154 155 156 157 158
          success = .false.
          return
        endif
      endif
    endif

159
#if REALCASE == 1
160 161
    if (present(useQR)) then
      if (useQR) then
162
        call e%set("qr", 1, successInternal)
163 164 165 166 167
        if (successInternal .ne. ELPA_OK) then
          print *, "Cannot set qr"
          success = .false.
          return
        endif
168
      else
169
        call e%set("qr", 0, successInternal)
170 171 172 173 174
        if (successInternal .ne. ELPA_OK) then
          print *, "Cannot set qr"
          success = .false.
          return
        endif
175 176
      endif
    endif
177
#endif
178

179 180
#if REALCASE == 1
    if (present(THIS_ELPA_KERNEL_API)) then
181
      call e%set("real_kernel",THIS_ELPA_KERNEL_API, successInternal)
182 183
      if (successInternal .ne. ELPA_OK) then
        print *, "Cannot set ELPA2 stage real_kernel"
184 185 186 187
        success = .false.
        return
      endif
    endif
188
#endif
189

190 191
#if COMPLEXCASE == 1
    if (present(THIS_ELPA_KERNEL_API)) then
192
      call e%set("complex_kernel",THIS_ELPA_KERNEL_API, successInternal)
193 194
      if (successInternal .ne. ELPA_OK) then
        print *, "Cannot set ELPA2 stage complex_kernel"
195 196 197
        success = .false.
        return
      endif
198
    endif
199
#endif
200

201
    if (elpa_print_times) then
202
      call e%set("summary_timings", 1,successInternal)
203 204 205 206 207 208 209
      if (successInternal .ne. ELPA_OK) then
        print *, "Cannot set summary_timings"
        success = .false.
        return
      endif
    endif

210
    call e%solve(a(1:lda,1:matrixCols), ev, q(1:ldq,1:matrixCols), successInternal)
211 212 213 214 215
    if (successInternal .ne. ELPA_OK) then
      print *, "Cannot solve with ELPA 2stage"
      success = .false.
      return
    endif
216

217
    if (elpa_print_times) then
218 219 220
      time_evp_fwd   = e%get_double("time_evp_fwd")
      time_evp_solve = e%get_double("time_evp_solve")
      time_evp_back  = e%get_double("time_evp_back")
221 222
    endif

223
    call elpa_deallocate(e)
224

225
    call elpa_uninit()
226

227 228
     call timer%stop("solve_evp_&
     &MATH_DATATYPE&
229 230
     &_2stage_&
     &PRECISION&
231
     &_legacy_interface")
232

233 234 235
   end function

! vim: syntax=fortran