Commit 1a9ab1ff authored by Victor Yu's avatar Victor Yu

Separate RCI from main ELSI repo

parent c23265a7
.Rhistory
*.[oaxd]
*.err
*.json
*.log
*.mod
*.swp
*.tmp
initial_cache.cmake
/bin/
/build/
/include/
/install/
/lib/
variables:
INSTALL_DIR: "/home/gitlab-runner/ci_tmp_rci"
### GNU compilers + OpenMPI + Netlib BLAS, LAPACK, ScaLAPACK ###
gnu:
script:
- module purge
- module load gcc-7.1
- module load cmake-3.0.2
- module load openmpi-3.0.0
- cat ./toolchains/gnu.cmake
- rm -rf build $INSTALL_DIR/gnu
- mkdir build $INSTALL_DIR/gnu
- cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/gnu.cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR/gnu ..
- make -j8
- make install
### Intel compilers + MPI + MKL ###
intel:
script:
- module purge
- module load gcc-7.1
- module load cmake-3.0.2
- module load intel-compilers-18.0
- module load intel-mpi-2018.2
- module load intel-mkl-2018.2
- cat ./toolchains/intel.cmake
- rm -rf build $INSTALL_DIR/intel
- mkdir build $INSTALL_DIR/intel
- cd build
- cmake -DCMAKE_TOOLCHAIN_FILE=../toolchains/intel.cmake -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR/intel ..
- make -j8
- make install
### ELSI_RCI source files ###
LIST(APPEND elsi_rci_src
src/elsi_rci_constants.f90
src/elsi_rci_datatype.f90
src/elsi_rci_ops.f90
src/elsi_rci_precision.f90
src/elsi_rci_setup.f90
src/Davidson/elsi_rci_davidson.f90
src/OMM/elsi_rci_omm.f90
src/OMM/rci_omm_cubic.f90
src/PPCG/elsi_rci_ppcg.f90)
ADD_LIBRARY(elsi_rci ${elsi_rci_src})
TARGET_LINK_LIBRARIES(elsi_rci PRIVATE ${LIBS})
TARGET_INCLUDE_DIRECTORIES(elsi_rci PRIVATE ${INC_PATHS})
INSTALL(TARGETS elsi_rci
EXPORT elsiConfig
DESTINATION ${CMAKE_INSTALL_LIBDIR})
### CMake version ###
CMAKE_MINIMUM_REQUIRED(VERSION 3.0 FATAL_ERROR)
### Project ###
PROJECT(elsi_rci LANGUAGES Fortran)
### CMake modules ###
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
INCLUDE(color_message)
INCLUDE(external_libraries)
### Installation paths ###
IF(PROJECT_BINARY_DIR STREQUAL PROJECT_SOURCE_DIR)
MESSAGE(FATAL_ERROR "${MAGENTA}Build in the source directory is not allowed${COLORRESET}")
ENDIF()
SET(CMAKE_Fortran_MODULE_DIRECTORY "${PROJECT_BINARY_DIR}/include")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
IF(NOT DEFINED CMAKE_INSTALL_INCLUDEDIR)
SET(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "Location to install module and header files")
ENDIF()
IF(NOT DEFINED CMAKE_INSTALL_LIBDIR)
SET(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "Location to install library files")
ENDIF()
MESSAGE(STATUS "ELSI RCI will be installed to: ${CMAKE_INSTALL_PREFIX}")
### Options ###
OPTION(ENABLE_TESTS "Build ELSI_RCI test programs" OFF)
OPTION(BUILD_SHARED_LIBS "Whether to build shared or static libraries" OFF)
SET(LIB_PATHS "" CACHE STRING "List of directories containing libraries to be linked against")
SET(INC_PATHS "" CACHE STRING "List of include directories")
SET(LIBS "" CACHE STRING "List of external libraries to be linked against")
### External libraries ###
STRING(REPLACE "-l" "" LIBS "${LIBS}")
FOREACH(str LIBS LIB_PATHS INC_PATHS)
convert_to_list(${str})
ENDFOREACH()
generate_library_targets(LIB_PATHS LIBS)
### Compilations ###
INCLUDE_DIRECTORIES(${CMAKE_Fortran_MODULE_DIRECTORY})
ADD_SUBDIRECTORY(src)
IF(ENABLE_TESTS)
MESSAGE(STATUS "Enabling test programs")
ENABLE_TESTING()
ADD_SUBDIRECTORY(test)
ENDIF()
Copyright (c) 2015-2018, the ELSI team. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the "ELectronic Structure Infrastructure" project nor
the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ELSI reverse communication interface (RCI) for iterative eigensolvers.
# http://stackoverflow.com/a/19578320
STRING(ASCII 27 Esc)
SET(COLORRESET "${Esc}[m")
SET(COLORBOLD "${Esc}[1m")
SET(RED "${Esc}[31m")
SET(GREEN "${Esc}[32m")
SET(YELLOW "${Esc}[33m")
SET(BLUE "${Esc}[34m")
SET(MAGENTA "${Esc}[35m")
SET(CYAN "${Esc}[36m")
SET(WHITE "${Esc}[37m")
SET(BOLDRED "${Esc}[1;31m")
SET(BOLDGREEN "${Esc}[1;32m")
SET(BOLDYELLOW "${Esc}[1;33m")
SET(BOLDBLUE "${Esc}[1;34m")
SET(BOLDMAGENTA "${Esc}[1;35m")
SET(BOLDCYAN "${Esc}[1;36m")
SET(BOLDWHITE "${Esc}[1;37m")
# Taken from FHI-aims with permission of copyright holders
# Convert a string into a list.
# Do nothing if input is already a list.
MACRO(convert_to_list var)
LIST(LENGTH ${var} _length)
IF(_length EQUAL 1)
STRING(REPLACE " " ";" ${var} ${${var}})
ENDIF()
ENDMACRO()
# Go through directories listed in LIB_PATHS and turn entries of LIBS into targets.
FUNCTION(generate_library_targets _PATHS _LIBRARIES)
FOREACH(LIB ${${_LIBRARIES}})
FIND_LIBRARY(LIB_FULLPATH ${LIB} PATHS ${${_PATHS}})
IF(LIB_FULLPATH)
MESSAGE(STATUS "Found ${LIB_FULLPATH}")
ADD_LIBRARY(${LIB} UNKNOWN IMPORTED)
SET_TARGET_PROPERTIES(${LIB} PROPERTIES IMPORTED_LOCATION ${LIB_FULLPATH})
ELSE()
MESSAGE(FATAL_ERROR "${Magenta}Could not find ${LIB}${ColorReset}")
ENDIF()
UNSET(LIB_FULLPATH CACHE)
ENDFOREACH()
ENDFUNCTION()
### ELSI_RCI source files ###
LIST(APPEND elsi_rci_src
elsi_rci_constants.f90
elsi_rci_datatype.f90
elsi_rci_interface.f90
elsi_rci_ops.f90
elsi_rci_precision.f90
elsi_rci_setup.f90
Davidson/elsi_rci_davidson.f90
OMM/elsi_rci_omm.f90
OMM/rci_omm_cubic.f90
PPCG/elsi_rci_ppcg.f90)
ADD_LIBRARY(elsi_rci ${elsi_rci_src})
INSTALL(TARGETS elsi_rci
EXPORT elsiConfig
DESTINATION ${CMAKE_INSTALL_LIBDIR})
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module provides public-facting interface routines for using ELSI RCI.
!!
module ELSI_RCI
use ELSI_RCI_CONSTANTS
use ELSI_RCI_DATATYPE
use ELSI_RCI_SETUP
use ELSI_RCI_DAVIDSON
use ELSI_RCI_OMM
use ELSI_RCI_PPCG
implicit none
contains
subroutine rci_solve_allocate(r_h, ijob, iS, task)
implicit none
!**** INPUT ***********************************!
type(rci_handle), intent(in) :: r_h
!**** OUTPUT **********************************!
integer, intent(out) :: task
!**** INOUT ***********************************!
integer, intent(inout) :: ijob ! job id
type(rci_instr), intent(inout) :: iS
select case (r_h%solver)
case (RCI_SOLVER_DAVIDSON)
call rci_davidson_allocate(r_h, ijob, iS, task)
case (RCI_SOLVER_OMM)
call rci_omm_allocate(r_h, ijob, iS, task)
case (RCI_SOLVER_PPCG)
call rci_ppcg_allocate(r_h, ijob, iS, task)
end select
end subroutine
subroutine rci_solve_deallocate(r_h, ijob, iS, task)
implicit none
!**** INPUT ***********************************!
type(rci_handle), intent(in) :: r_h
!**** OUTPUT **********************************!
integer, intent(out) :: task
!**** INOUT ***********************************!
integer, intent(inout) :: ijob ! job id
type(rci_instr), intent(inout) :: iS
select case (r_h%solver)
case (RCI_SOLVER_DAVIDSON)
call rci_davidson_deallocate(r_h, ijob, iS, task)
case (RCI_SOLVER_OMM)
call rci_omm_deallocate(r_h, ijob, iS, task)
case (RCI_SOLVER_PPCG)
call rci_ppcg_deallocate(r_h, ijob, iS, task)
end select
end subroutine
subroutine rci_solve(r_h, ijob, iS, task, resvec)
implicit none
!**** INPUT ***********************************!
!**** OUTPUT **********************************!
integer, intent(out) :: task
!**** INOUT ***********************************!
type(rci_handle), intent(inout) :: r_h
integer, intent(inout) :: ijob ! job id
real(r8), intent(inout) :: resvec(:)
type(rci_instr), intent(inout) :: iS
select case (r_h%solver)
case (RCI_SOLVER_DAVIDSON)
call rci_davidson(r_h, ijob, iS, task, resvec)
case (RCI_SOLVER_OMM)
call rci_omm(r_h, ijob, iS, task, resvec)
case (RCI_SOLVER_PPCG)
call rci_ppcg(r_h, ijob, iS, task, resvec)
end select
end subroutine
end module ELSI_RCI
### ELSI RCI tests ###
LIST(APPEND ftest_rci_src
elsi_rci_test.f90
elsi_rci_utils/elsi_rci_read_mat.f90
elsi_rci_utils/elsi_rci_sort.f90
elsi_rci_utils/elsi_rci_timer.f90
elsi_rci_utils/elsi_rci_write_mat.f90
$ENV{MKLROOT}/include/mkl_dfti.f90
test_rci_ev_real_den.f90
# test_rci_ev_real_csc.f90
test_rci_ev_cmplx_den.f90
test_rci_ev_cmplx_pw.f90)
ADD_EXECUTABLE(elsi_rci_test ${ftest_rci_src})
TARGET_LINK_LIBRARIES(elsi_rci_test PRIVATE elsi_rci)
TARGET_LINK_LIBRARIES(elsi_rci_test PRIVATE ${LIBS})
SET_TARGET_PROPERTIES(elsi_rci_test PROPERTIES LINKER_LANGUAGE Fortran)
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This program tests ELSI.
!!
program elsi_rci_test
use ELSI_RCI_PRECISION, only: i4
implicit none
include "mpif.h"
character(len=128) :: arg1 ! ev or dm
character(len=128) :: arg2 ! dense or sparse
character(len=128) :: arg3 ! real or cmplx
character(len=128) :: arg4 ! solver
character(len=128) :: arg5 ! H file
character(len=128) :: arg6 ! S file
integer(kind=i4) :: solver
integer(kind=i4) :: mat_type
! Read command line arguments
if(command_argument_count() >= 5) then
call get_command_argument(1,arg1)
call get_command_argument(2,arg2)
call get_command_argument(3,arg3)
call get_command_argument(4,arg4)
call get_command_argument(5,arg5)
read(arg2,*) mat_type
if (mat_type == 3) then
if(command_argument_count() > 5) then
call test_die()
endif
else
if(command_argument_count() == 6) then
call get_command_argument(6,arg6)
else
call test_die()
endif
endif
read(arg4,*) solver
else
call test_die()
endif
select case(arg1(1:1))
case("e") ! ev
select case(arg2(1:1))
case("0") ! BLACS_DENSE
select case(arg3(1:1))
case("r") ! real
call test_rci_ev_real_den(solver,arg5,arg6)
case("c") ! complex
call test_rci_ev_cmplx_den(solver,arg5,arg6)
case default
call test_die()
end select
case("1") ! PEXSI_CSC
select case(arg3(1:1))
case("r") ! real
! call test_rci_ev_real_csc(solver,arg5,arg6)
case("c") ! complex
call test_die()
case default
call test_die()
end select
case("2") ! SIESTA_CSC
select case(arg3(1:1))
case("r") ! real
! call test_rci_ev_real_csc(solver,arg5,arg6)
case("c") ! complex
call test_die()
case default
call test_die()
end select
case("3") ! Planewave
select case(arg3(1:1))
case("c") ! complex
call test_rci_ev_cmplx_pw(solver,arg5)
case default
call test_die()
end select
case default
call test_die()
end select
case("d") ! dm
call test_die()
case default
call test_die()
end select
contains
subroutine test_die()
implicit none
write(*,"(A)") " ########################################"
write(*,"(A)") " ## ##"
write(*,"(A)") " ## Wrong command line argument(s)!! ##"
write(*,"(A)") " ## ##"
write(*,"(A)") " ## Arg #1: 'ev' or 'dm' ##"
write(*,"(A)") " ## Arg #2: 0 = BLACS_DENSE ##"
write(*,"(A)") " ## 1 = PEXSI_CSC ##"
write(*,"(A)") " ## 2 = SIESTA_CSC ##"
write(*,"(A)") " ## 3 = KSSOLV_PW ##"
write(*,"(A)") " ## Arg #3: 'real' or 'complex' ##"
write(*,"(A)") " ## Arg #4: 1 = RCI_Davidson ##"
write(*,"(A)") " ## 2 = RCI_OMM ##"
write(*,"(A)") " ## 3 = RCI_PPCG ##"
write(*,"(A)") " ## Arg #5: H matrix file ##"
write(*,"(A)") " ## Arg #6: S matrix file ##"
write(*,"(A)") " ## ##"
write(*,"(A)") " ########################################"
stop
end subroutine
end program
! Copyright (c) 2015-2018, the ELSI team.
! All rights reserved.
!
! This file is part of ELSI and is distributed under the BSD 3-clause license,
! which may be found in the LICENSE file in the ELSI root directory.
!>
!! This module contains subroutines to read matrices.
!!
module ELSI_RCI_READ_MAT
use ELSI_RCI_PRECISION, only: r8,i4,i8
implicit none
private
public :: rci_read
public :: rci_read_pw
public :: rci_read_clean
integer(kind=i4), public :: n_basis
integer(kind=i4), public :: n_basis_1D(3)
integer(kind=i4), public :: n_basis_pw
integer(kind=i4), public :: n_electron
integer(kind=i4), public :: n_h_vnl
real(kind=r8), allocatable, public :: h_real(:,:)
real(kind=r8), allocatable, public :: s_real(:,:)
complex(kind=r8), allocatable, public :: h_cmplx(:,:)
complex(kind=r8), allocatable, public :: s_cmplx(:,:)
integer(kind=i4), allocatable, public :: h_idx(:)
complex(kind=r8), allocatable, public :: h_gkin(:)
complex(kind=r8), allocatable, public :: h_vtot(:)
complex(kind=r8), allocatable, public :: h_vnlmat(:,:)
complex(kind=r8), allocatable, public :: h_vnlsign(:)
contains
subroutine rci_read(h_file,s_file,is_real)
implicit none
character(*), intent(in) :: h_file
character(*), intent(in) :: s_file
logical, intent(in) :: is_real
integer(kind=i4) :: i_row
integer(kind=i4) :: i_col
integer(kind=i4) :: header(16)
integer(kind=i4) :: i_val
integer(kind=i4) :: nnz
integer(kind=i8) :: offset
real(kind=r8), allocatable :: h_val_real(:)
real(kind=r8), allocatable :: s_val_real(:)
complex(kind=r8), allocatable :: h_val_cmplx(:)
complex(kind=r8), allocatable :: s_val_cmplx(:)
integer(kind=i4), allocatable :: row_ind(:)
integer(kind=i4), allocatable :: col_ptr(:)
! Open file
open(file=h_file,unit=30,access="stream",form="unformatted")
! Read header
offset = 1
read(unit=30,pos=offset) header
n_basis = header(4)
n_electron = header(5)
nnz = header(6)
if(is_real) then
allocate(h_val_real(nnz))
else
allocate(h_val_cmplx(nnz))
endif
allocate(row_ind(nnz))
allocate(col_ptr(n_basis+1))
! Read column pointer
offset = offset+64
read(unit=30,pos=offset) col_ptr(1:n_basis)
col_ptr(n_basis+1) = nnz+1
offset = offset+n_basis*4
! Read row index
read(unit=30,pos=offset) row_ind
offset = offset+nnz*4
! Read non-zero value
if(is_real) then
read(unit=30,pos=offset) h_val_real
else
read(unit=30,pos=offset) h_val_cmplx
endif
! Close file
close(unit=30)
if(is_real) then
allocate(h_real(n_basis,n_basis))
else
allocate(h_cmplx(n_basis,n_basis))
endif
! Convert to dense and symmetrize
if(is_real) then
i_col = 0
h_real = 0.0_r8
do i_val = 1,nnz
if(i_val == col_ptr(i_col+1) .and. i_col /= n_basis) then
i_col = i_col+1
endif
i_row = row_ind(i_val)
h_real(i_row,i_col) = h_val_real(i_val)
h_real(i_col,i_row) = h_val_real(i_val)
enddo
deallocate(h_val_real)
deallocate(row_ind)
deallocate(col_ptr)
else
i_col = 0
h_cmplx = (0.0_r8,0.0_r8)
do i_val = 1,nnz
if(i_val == col_ptr(i_col+1) .and. i_col /= n_basis) then
i_col = i_col+1
endif
i_row = row_ind(i_val)
h_cmplx(i_row,i_col) = h_val_cmplx(i_val)
h_cmplx(i_col,i_row) = h_val_cmplx(i_val)
enddo
deallocate(h_val_cmplx)
deallocate(row_ind)
deallocate(col_ptr)
endif
! Open file
open(file=s_file,unit=30,access="stream",form="unformatted")
! Read header
offset = 1
read(unit=30,pos=offset) header
n_basis = header(4)
n_electron = header(5)
nnz = header(6)
if(is_real) then
allocate(s_val_real(nnz))
else
allocate(s_val_cmplx(nnz))
endif
allocate(row_ind(nnz))
allocate(col_ptr(n_basis+1))
! Read column pointer
offset = offset+64
read(unit=30,pos=offset) col_ptr(1:n_basis)
col_ptr(n_basis+1) = nnz+1
offset = offset+n_basis*4
! Read row index
read(unit=30,pos=offset) row_ind
offset = offset+nnz*4
! Read non-zero value
if(is_real) then
read(unit=30,pos=offset) s_val_real
else
read(unit=30,pos=offset) s_val_cmplx
endif ! Close file
close(unit=30)
if(is_real) then
allocate(s_real(n_basis,n_basis))
else
allocate(s_cmplx(n_basis,n_basis))
endif
! Convert to dense and symmetrize
if(is_real) then
i_col = 0
s_real = 0.0_r8
do i_val = 1,nnz
if(i_val == col_ptr(i_col+1) .and. i_col /= n_basis) then
i_col = i_col+1
endif
i_row = row_ind(i_val)
s_real(i_row,i_col) = s_val_real(i_val)
s_real(i_col,i_row) = s_val_real(i_val)
enddo
deallocate(s_val_real)
deallocate(row_ind)
deallocate(col_ptr)
else
i_col = 0
s_cmplx = (0.0_r8,0.0_r8)
do i_val = 1,nnz
if(i_val == col_ptr(i_col+1) .and. i_col /= n_basis) then
i_col = i_col+1
endif
i_row = row_ind(i_val)
s_cmplx(i_row,i_col) = s_val_cmplx(i_val)
s_cmplx(i_col,i_row) = s_val_cmplx(i_val)
enddo
deallocate(s_val_cmplx)
deallocate(row_ind)
deallocate(col_ptr)
endif