LCOV - code coverage report
Current view: top level - test/Fortran/elpa2/legacy_interface - legacy_real_api.F90 (source / functions) Hit Total Coverage
Test: coverage_50ab7a7628bba174fc62cee3ab72b26e81f87fe5.info Lines: 63 79 79.7 %
Date: 2018-01-10 09:29:53 Functions: 2 2 100.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             : #include "config-f90.h"
      44             : !>
      45             : !> Fortran test programm to demonstrates the use of
      46             : !> ELPA 2 real case library.
      47             : !> If "HAVE_REDIRECT" was defined at build time
      48             : !> the stdout and stderr output of each MPI task
      49             : !> can be redirected to files if the environment
      50             : !> variable "REDIRECT_ELPA_TEST_OUTPUT" is set
      51             : !> to "true".
      52             : !>
      53             : !> By calling executable [arg1] [arg2] [arg3] [arg4]
      54             : !> one can define the size (arg1), the number of
      55             : !> Eigenvectors to compute (arg2), and the blocking (arg3).
      56             : !> If these values are not set default values (500, 150, 16)
      57             : !> are choosen.
      58             : !> If these values are set the 4th argument can be
      59             : !> "output", which specifies that the EV's are written to
      60             : !> an ascii file.
      61             : !>
      62             : !> The complex ELPA 2 kernel is set in this program via
      63             : !> the API call. However, this can be overriden by setting
      64             : !> the environment variable "REAL_ELPA_KERNEL" to an
      65             : !> appropiate value.
      66             : !>
      67         288 : program test_real2_choose_kernel_with_api_double_precision
      68             : 
      69             : !-------------------------------------------------------------------------------
      70             : ! Standard eigenvalue problem - REAL version
      71             : !
      72             : ! This program demonstrates the use of the ELPA module
      73             : ! together with standard scalapack routines
      74             : !
      75             : ! Copyright of the original code rests with the authors inside the ELPA
      76             : ! consortium. The copyright of any additional modifications shall rest
      77             : ! with their original authors, but shall adhere to the licensing terms
      78             : ! distributed along with the original code in the file "COPYING".
      79             : !
      80             : !-------------------------------------------------------------------------------
      81         288 :    use elpa1
      82             :    use elpa2
      83             : 
      84             : 
      85             :    use elpa_utilities, only : error_unit
      86             :    use elpa2_utilities
      87             :    use test_read_input_parameters
      88             :    use test_check_correctness
      89             :    use test_setup_mpi
      90             :    use test_blacs_infrastructure
      91             :    use test_prepare_matrix
      92             :    use test_util
      93             : 
      94             : #ifdef HAVE_REDIRECT
      95             :   use test_redirect
      96             : #endif
      97             : 
      98             :  use test_output_type
      99             :    implicit none
     100             : 
     101             :    !-------------------------------------------------------------------------------
     102             :    ! Please set system size parameters below!
     103             :    ! na:   System size
     104             :    ! nev:  Number of eigenvectors to be calculated
     105             :    ! nblk: Blocking factor in block cyclic distribution
     106             :    !-------------------------------------------------------------------------------
     107             : 
     108             :    integer(kind=ik)           :: nblk
     109             :    integer(kind=ik)           :: na, nev
     110             : 
     111             :    integer(kind=ik)           :: np_rows, np_cols, na_rows, na_cols
     112             : 
     113             :    integer(kind=ik)           :: myid, nprocs, my_prow, my_pcol, mpi_comm_rows, mpi_comm_cols
     114             :    integer(kind=ik)           :: i, mpierr, my_blacs_ctxt, sc_desc(9), info, nprow, npcol
     115             : 
     116             :    integer(kind=ik), external :: numroc
     117             : 
     118         288 :    real(kind=rk8), allocatable :: a(:,:), z(:,:), as(:,:), ev(:)
     119             : 
     120             :    integer(kind=ik)           :: STATUS
     121             : #ifdef WITH_OPENMP
     122             :    integer(kind=ik)           :: omp_get_max_threads,  required_mpi_thread_level, provided_mpi_thread_level
     123             : #endif
     124             :    logical                    :: successELPA, success
     125             :    logical                    :: gpuAvailable
     126             :    type(output_t)             :: write_to_file
     127             :    character(len=8)           :: task_suffix
     128             :    integer(kind=ik)           :: j
     129             : 
     130             : #define DOUBLE_PRECISION_REAL 1
     131             : 
     132         288 :    successELPA   = .true.
     133         288 :    gpuAvailable  = .false.
     134             : 
     135         288 :    call read_input_parameters(na, nev, nblk, write_to_file)
     136             : 
     137             :    !-------------------------------------------------------------------------------
     138             :    !  MPI Initialization
     139         288 :    call setup_mpi(myid, nprocs)
     140             : 
     141             : 
     142         288 :    STATUS = 0
     143             : 
     144             : #define REALCASE
     145             : #include "../../elpa_print_headers.F90"
     146             : 
     147             :    !-------------------------------------------------------------------------------
     148             :    ! Selection of number of processor rows/columns
     149             :    ! We try to set up the grid square-like, i.e. start the search for possible
     150             :    ! divisors of nprocs with a number next to the square root of nprocs
     151             :    ! and decrement it until a divisor is found.
     152             : 
     153         288 :    do np_cols = NINT(SQRT(REAL(nprocs))),2,-1
     154           0 :       if(mod(nprocs,np_cols) == 0 ) exit
     155             :    enddo
     156             :    ! at the end of the above loop, nprocs is always divisible by np_cols
     157             : 
     158         288 :    np_rows = nprocs/np_cols
     159             : 
     160         288 :    if(myid==0) then
     161         192 :       print *
     162         192 :       print '(a)','Standard eigenvalue problem - REAL version'
     163             : #ifdef WITH_GPU_VERSION
     164             :         print *,"with GPU Version"
     165             : #endif
     166         192 :       print *
     167         192 :       print '(3(a,i0))','Matrix size=',na,', Number of eigenvectors=',nev,', Block size=',nblk
     168         192 :       print '(3(a,i0))','Number of processor rows=',np_rows,', cols=',np_cols,', total=',nprocs
     169         192 :       print *
     170         192 :       print *, "This is an example how to determine the ELPA2 kernel with"
     171         192 :       print *, "an api call. Note, however, that setting the kernel via"
     172         192 :       print *, "an environment variable will always take precedence over"
     173         192 :       print *, "everything else! "
     174         192 :       print *
     175         192 :      print *," "
     176             : #ifndef HAVE_ENVIRONMENT_CHECKING
     177             :       print *, " Notice that it is not possible with this build to set the "
     178             :       print *, " kernel via an environment variable! To change this re-install"
     179             :       print *, " the library and have a look at the log files"
     180             : #endif
     181             : 
     182             : #ifndef WITH_FIXED_REAL_KERNEL
     183         192 :       print *, " The settings are: REAL_ELPA_KERNEL_GENERIC_SIMPLE"
     184             : #else /*  WITH_FIXED_REAL_KERNEL */
     185             : 
     186             : #ifdef WITH_REAL_GENERIC_KERNEL
     187             :       print *, " The settings are: REAL_ELPA_KERNEL_GENERIC"
     188             : #endif
     189             : #ifdef WITH_REAL_GENERIC_SIMPLE_KERNEL
     190             :       print *, " The settings are: REAL_ELPA_KERNEL_GENERIC_SIMPLE"
     191             : #endif
     192             : #ifdef WITH_REAL_GENERIC_SSE_ASSEMBLY_KERNEL
     193             :       print *, " The settings are: REAL_ELPA_KERNEL_SSE"
     194             : #endif
     195             : #ifdef WITH_REAL_SSE_BLOCK2_KERNEL
     196             :       print *, " The settings are: REAL_ELPA_KERNEL_SSE_BLOCK2"
     197             : #endif
     198             : #ifdef WITH_REAL_SSE_BLOCK4_KERNEL
     199             :       print *, " The settings are: REAL_ELPA_KERNEL_SSE_BLOCK4"
     200             : #endif
     201             : #ifdef WITH_REAL_SSE_BLOCK6_KERNEL
     202             :       print *, " The settings are: REAL_ELPA_KERNEL_SSE_BLOCK6"
     203             : #endif
     204             : 
     205             : #ifdef WITH_REAL_AVX_BLOCK2_KERNEL
     206             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX_BLOCK2"
     207             : #endif
     208             : #ifdef WITH_REAL_AVX_BLOCK4_KERNEL
     209             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX_BLOCK4"
     210             : #endif
     211             : #ifdef WITH_REAL_AVX_BLOCK6_KERNEL
     212             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX_BLOCK6"
     213             : #endif
     214             : #ifdef WITH_REAL_AVX2_BLOCK2_KERNEL
     215             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX2_BLOCK2"
     216             : #endif
     217             : #ifdef WITH_REAL_AVX2_BLOCK4_KERNEL
     218             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX2_BLOCK4"
     219             : #endif
     220             : #ifdef WITH_REAL_AVX2_BLOCK6_KERNEL
     221             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX2_BLOCK6"
     222             : #endif
     223             : #ifdef WITH_REAL_AVX512_BLOCK2_KERNEL
     224             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX512_BLOCK2"
     225             : #endif
     226             : #ifdef WITH_REAL_AVX512_BLOCK4_KERNEL
     227             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX512_BLOCK4"
     228             : #endif
     229             : #ifdef WITH_REAL_AVX512_BLOCK6_KERNEL
     230             :       print *, " The settings are: REAL_ELPA_KERNEL_AVX512_BLOCK6"
     231             : #endif
     232             : 
     233             : #ifdef WITH_REAL_BGP_KERNEL
     234             :       print *, " The settings are: REAL_ELPA_KERNEL_BGP"
     235             : #endif
     236             : #ifdef WITH_REAL_BGQ_KERNEL
     237             :       print *, " The settings are: REAL_ELPA_KERNEL_BGQ"
     238             : #endif
     239             : #ifdef WITH_GPU_VERSION
     240             :       print *, " The settings are: REAL_ELPA_GPU"
     241             : #endif
     242             : 
     243             : #endif  /*  WITH_FIXED_REAL_KERNEL */
     244             : 
     245         192 :       print *
     246             : 
     247             : 
     248             :    endif
     249             : 
     250             :    !-------------------------------------------------------------------------------
     251             :    ! Set up BLACS context and MPI communicators
     252             :    !
     253             :    ! The BLACS context is only necessary for using Scalapack.
     254             :    !
     255             :    ! For ELPA, the MPI communicators along rows/cols are sufficient,
     256             :    ! and the grid setup may be done in an arbitrary way as long as it is
     257             :    ! consistent (i.e. 0<=my_prow<np_rows, 0<=my_pcol<np_cols and every
     258             :    ! process has a unique (my_prow,my_pcol) pair).
     259             : 
     260             :    call set_up_blacsgrid(mpi_comm_world, np_rows, np_cols, 'C', &
     261         288 :                          my_blacs_ctxt, my_prow, my_pcol)
     262             : 
     263         288 :    if (myid==0) then
     264         192 :      print '(a)','| Past BLACS_Gridinfo.'
     265             :    end if
     266             : 
     267             :    ! All ELPA routines need MPI communicators for communicating within
     268             :    ! rows or columns of processes, these are set in elpa_get_communicators.
     269             : 
     270             :    mpierr = elpa_get_communicators(mpi_comm_world, my_prow, my_pcol, &
     271         288 :                                    mpi_comm_rows, mpi_comm_cols)
     272             : 
     273         288 :    if (myid==0) then
     274         192 :      print '(a)','| Past split communicator setup for rows and columns.'
     275             :    end if
     276             : 
     277             :    call set_up_blacs_descriptor(na ,nblk, my_prow, my_pcol, np_rows, np_cols, &
     278         288 :                                 na_rows, na_cols, sc_desc, my_blacs_ctxt, info)
     279             : 
     280         288 :    if (myid==0) then
     281         192 :      print '(a)','| Past scalapack descriptor setup.'
     282             :    end if
     283             : 
     284             :    !-------------------------------------------------------------------------------
     285             :    ! Allocate matrices and set up a test matrix for the eigenvalue problem
     286         288 :    allocate(a (na_rows,na_cols))
     287         288 :    allocate(z (na_rows,na_cols))
     288         288 :    allocate(as(na_rows,na_cols))
     289             : 
     290         288 :    allocate(ev(na))
     291             : 
     292         288 :    call prepare_matrix_random(na, myid, sc_desc, a, z, as)
     293             : 
     294             :    ! set print flag in elpa1
     295         288 :    elpa_print_times = .true.
     296             : 
     297             :    !-------------------------------------------------------------------------------
     298             :    ! Calculate eigenvalues/eigenvectors
     299             : 
     300         288 :    if (myid==0) then
     301         192 :      print '(a)','| Entering two-stage ELPA solver ... '
     302         192 :      print *
     303             :    end if
     304             : 
     305             : 
     306             :    ! ELPA is called with a kernel specification in the API
     307             : #ifdef WITH_MPI
     308         192 :    call mpi_barrier(mpi_comm_world, mpierr) ! for correct timings only
     309             : #endif
     310             :    successELPA = elpa_solve_evp_real_2stage_double(na, nev, a, na_rows, ev, z, na_rows, nblk, &
     311             :                               na_cols, mpi_comm_rows, mpi_comm_cols, mpi_comm_world, &
     312             : #ifndef WITH_FIXED_REAL_KERNEL
     313         288 :                              REAL_ELPA_KERNEL_GENERIC_SIMPLE)
     314             : #else /* WITH_FIXED_REAL_KERNEL */
     315             : 
     316             : #ifdef WITH_REAL_GENERIC_KERNEL
     317             :                               REAL_ELPA_KERNEL_GENERIC)
     318             : #endif
     319             : 
     320             : #ifdef WITH_REAL_GENERIC_SIMPLE_KERNEL
     321             :                               REAL_ELPA_KERNEL_GENERIC_SIMPLE)
     322             : #endif
     323             : 
     324             : #ifdef WITH_REAL_SSE_ASSEMBLY_KERNEL
     325             :                               REAL_ELPA_KERNEL_SSE)
     326             : #endif
     327             : 
     328             : #ifdef WITH_REAL_SSE_BLOCK6_KERNEL
     329             :                               REAL_ELPA_KERNEL_SSE_BLOCK6)
     330             : #else
     331             : #ifdef WITH_REAL_SSE_BLOCK4_KERNEL
     332             :                               REAL_ELPA_KERNEL_SSE_BLOCK4)
     333             : #else
     334             : #ifdef WITH_REAL_SSE_BLOCK2_KERNEL
     335             :                               REAL_ELPA_KERNEL_SSE_BLOCK2)
     336             : #endif
     337             : #endif
     338             : #endif
     339             : 
     340             : #ifdef WITH_REAL_AVX_BLOCK6_KERNEL
     341             :                               REAL_ELPA_KERNEL_AVX_BLOCK6)
     342             : #else
     343             : #ifdef WITH_REAL_AVX_BLOCK4_KERNEL
     344             :                               REAL_ELPA_KERNEL_AVX_BLOCK4)
     345             : #else
     346             : #ifdef WITH_REAL_AVX_BLOCK2_KERNEL
     347             :                               REAL_ELPA_KERNEL_AVX_BLOCK2)
     348             : #endif
     349             : #endif
     350             : #endif
     351             : 
     352             : #ifdef WITH_REAL_AVX2_BLOCK6_KERNEL
     353             :                               REAL_ELPA_KERNEL_AVX2_BLOCK6)
     354             : #else
     355             : #ifdef WITH_REAL_AVX2_BLOCK4_KERNEL
     356             :                               REAL_ELPA_KERNEL_AVX2_BLOCK4)
     357             : #else
     358             : #ifdef WITH_REAL_AVX2_BLOCK2_KERNEL
     359             :                               REAL_ELPA_KERNEL_AVX2_BLOCK2)
     360             : #endif
     361             : #endif
     362             : #endif
     363             : 
     364             : #ifdef WITH_REAL_AVX512_BLOCK6_KERNEL
     365             :                               REAL_ELPA_KERNEL_AVX512_BLOCK6)
     366             : #else
     367             : #ifdef WITH_REAL_AVX512_BLOCK4_KERNEL
     368             :                               REAL_ELPA_KERNEL_AVX512_BLOCK4)
     369             : #else
     370             : #ifdef WITH_REAL_AVX512_BLOCK2_KERNEL
     371             :                               REAL_ELPA_KERNEL_AVX512_BLOCK2)
     372             : #endif
     373             : #endif
     374             : #endif
     375             : 
     376             : #ifdef WITH_REAL_BGP_KERNEL
     377             :                               REAL_ELPA_KERNEL_BGP)
     378             : #endif
     379             : 
     380             : #ifdef WITH_REAL_BGQ_KERNEL
     381             :                               REAL_ELPA_KERNEL_BGQ)
     382             : #endif
     383             : 
     384             : #ifdef WITH_GPU_VERSION
     385             :                               REAL_ELPA_KERNEL_GPU)
     386             : #endif
     387             : 
     388             : #endif /* WITH_FIXED_REAL_KERNEL */
     389             : 
     390         288 :    if (.not.(successELPA)) then
     391           0 :       write(error_unit,*) "solve_evp_real_2stage produced an error! Aborting..."
     392             : #ifdef WITH_MPI
     393           0 :       call MPI_ABORT(mpi_comm_world, 1, mpierr)
     394             : #else
     395           0 :       call exit(1)
     396             : #endif
     397             :    endif
     398             : 
     399         288 :    if (myid==0) then
     400         192 :      print '(a)','| Two-step ELPA solver complete.'
     401         192 :      print *
     402             :    end if
     403             : 
     404         288 :    if(myid == 0) print *,'Time transform to tridi :',time_evp_fwd
     405         288 :    if(myid == 0) print *,'Time solve tridi        :',time_evp_solve
     406         288 :    if(myid == 0) print *,'Time transform back EVs :',time_evp_back
     407         288 :    if(myid == 0) print *,'Total time (sum above)  :',time_evp_back+time_evp_solve+time_evp_fwd
     408             : 
     409         288 :    if(write_to_file%eigenvectors) then
     410           0 :      write(unit = task_suffix, fmt = '(i8.8)') myid
     411           0 :      open(17,file="EVs_real2_out_task_"//task_suffix(1:8)//".txt",form='formatted',status='new')
     412           0 :      write(17,*) "Part of eigenvectors: na_rows=",na_rows,"of na=",na," na_cols=",na_cols," of na=",na
     413             : 
     414           0 :      do i=1,na_rows
     415           0 :        do j=1,na_cols
     416           0 :          write(17,*) "row=",i," col=",j," element of eigenvector=",z(i,j)
     417             :        enddo
     418             :      enddo
     419           0 :      close(17)
     420             :    endif
     421             : 
     422         288 :    if(write_to_file%eigenvalues) then
     423           0 :       if (myid == 0) then
     424           0 :          open(17,file="Eigenvalues_real2_out.txt",form='formatted',status='new')
     425           0 :          do i=1,na
     426           0 :             write(17,*) i,ev(i)
     427             :          enddo
     428           0 :          close(17)
     429             :       endif
     430             :    endif
     431             : 
     432             :    !-------------------------------------------------------------------------------
     433             :    ! Test correctness of result (using plain scalapack routines)
     434             : 
     435         288 :    status = check_correctness_evp_numeric_residuals(na, nev, as, z, ev, sc_desc, nblk, myid, np_rows, np_cols, my_prow, my_pcol)
     436             : 
     437         288 :    deallocate(a)
     438         288 :    deallocate(as)
     439             : 
     440         288 :    deallocate(z)
     441         288 :    deallocate(ev)
     442             : 
     443             : #ifdef WITH_MPI
     444         192 :    call blacs_gridexit(my_blacs_ctxt)
     445         192 :    call mpi_finalize(mpierr)
     446             : #endif
     447         288 :    call EXIT(STATUS)
     448             : end
     449             : 
     450             : !-------------------------------------------------------------------------------

Generated by: LCOV version 1.12