Commit 5bc04652 authored by Andreas Marek's avatar Andreas Marek
Browse files

Matrix redistribute for ELPA 2

parent 91dc0018
......@@ -57,7 +57,19 @@
&_&
&2stage_&
&PRECISION&
&_impl (obj, a, ev, q) result(success)
&_impl (obj, &
#ifdef REDISTRIBUTE_MATRIX
aExtern, &
#else
a, &
#endif
ev, &
#ifdef REDISTRIBUTE_MATRIX
qExtern) result(success)
#else
q) result(success)
#endif
use matrix_plot
use elpa_abstract_impl
use elpa_utilities
......@@ -69,6 +81,9 @@
use elpa_omp
#ifdef HAVE_HETEROGENOUS_CLUSTER_SUPPORT
use simd_kernel
#endif
#ifdef REDISTRIBUTE_MATRIX
use elpa_scalapack_interfaces
#endif
use iso_c_binding
implicit none
......@@ -81,6 +96,21 @@
logical :: useQRActual
#endif
integer(kind=c_int) :: kernel, kernelByUser
#ifdef REDISTRIBUTE_MATRIX
#ifdef USE_ASSUMED_SIZE
MATH_DATATYPE(kind=C_DATATYPE_KIND), intent(inout), target :: aExtern(obj%local_nrows,*)
MATH_DATATYPE(kind=C_DATATYPE_KIND), optional, intent(out), target :: qExtern(obj%local_nrows,*)
#else
MATH_DATATYPE(kind=C_DATATYPE_KIND), intent(inout), target :: aExtern(obj%local_nrows,obj%local_ncols)
#ifdef HAVE_SKEWSYMMETRIC
MATH_DATATYPE(kind=C_DATATYPE_KIND), optional, target, intent(out) :: qExtern(obj%local_nrows,2*obj%local_ncols)
#else
MATH_DATATYPE(kind=C_DATATYPE_KIND), optional, target, intent(out) :: qExtern(obj%local_nrows,obj%local_ncols)
#endif
#endif
#else /* REDISTRIBUTE_MATRIX */
#ifdef USE_ASSUMED_SIZE
MATH_DATATYPE(kind=C_DATATYPE_KIND), intent(inout) :: a(obj%local_nrows,*)
......@@ -93,6 +123,14 @@
MATH_DATATYPE(kind=C_DATATYPE_KIND), optional, target, intent(out) :: q(obj%local_nrows,obj%local_ncols)
#endif
#endif
#endif /* REDISTRIBUTE_MATRIX */
#ifdef REDISTRIBUTE_MATRIX
MATH_DATATYPE(kind=rck), pointer :: a(:,:)
MATH_DATATYPE(kind=rck), pointer :: q(:,:)
#endif
real(kind=C_DATATYPE_KIND), intent(inout) :: ev(obj%na)
MATH_DATATYPE(kind=C_DATATYPE_KIND), allocatable :: hh_trans(:,:)
......@@ -131,6 +169,22 @@
integer(kind=ik) :: na, nev, nblk, matrixCols, &
mpi_comm_rows, mpi_comm_cols, &
mpi_comm_all, check_pd, error, matrixRows
#ifdef REDISTRIBUTE_MATRIX
integer(kind=ik) :: nblkInternal, matrixOrder
character(len=1) :: layoutInternal, layoutExternal
integer(kind=BLAS_KIND) :: external_blacs_ctxt, external_blacs_ctxt_
integer(kind=BLAS_KIND) :: np_rows_, np_cols_, my_prow_, my_pcol_
integer(kind=BLAS_KIND) :: np_rows__, np_cols__, my_prow__, my_pcol__
integer(kind=BLAS_KIND) :: sc_desc_(1:9), sc_desc(1:9)
integer(kind=BLAS_KIND) :: na_rows_, na_cols_, info_, blacs_ctxt_
integer(kind=ik) :: mpi_comm_rows_, mpi_comm_cols_
integer(kind=MPI_KIND) :: mpi_comm_rowsMPI_, mpi_comm_colsMPI_
character(len=1), parameter :: matrixLayouts(2) = [ 'C', 'R' ]
MATH_DATATYPE(kind=rck), allocatable, target :: aIntern(:,:)
MATH_DATATYPE(kind=C_DATATYPE_KIND), allocatable, target :: qIntern(:,:)
#endif
logical :: do_bandred, do_tridiag, do_solve_tridi, &
do_trans_to_band, do_trans_to_full
......@@ -140,6 +194,7 @@
integer(kind=c_int) :: simdSetAvailable(NUMBER_OF_INSTR)
#endif
integer(kind=ik) :: global_index
logical :: reDistributeMatrix, doRedistributeMatrix
#if REALCASE == 1
#undef GPU_KERNEL
......@@ -164,6 +219,7 @@
&PRECISION&
&")
reDistributeMatrix = .false.
#ifdef WITH_OPENMP
! store the number of OpenMP threads used in the calling function
......@@ -179,7 +235,11 @@
success = .true.
#ifdef REDISTRIBUTE_MATRIX
if (present(qExtern)) then
#else
if (present(q)) then
#endif
obj%eigenvalues_only = .false.
else
obj%eigenvalues_only = .true.
......@@ -191,7 +251,6 @@
matrixCols = obj%local_ncols
matrixRows = obj%local_nrows
call obj%get("mpi_comm_rows",mpi_comm_rows,error)
if (error .ne. ELPA_OK) then
print *,"Problem getting option. Aborting..."
......@@ -226,6 +285,160 @@
call obj%timer%stop("mpi_communication")
#ifdef REDISTRIBUTE_MATRIX
doRedistributeMatrix = .false.
if (obj%is_set("internal_nblk") == 1) then
if (obj%is_set("matrix_order") == 1) then
reDistributeMatrix = .true.
else
reDistributeMatrix = .false.
if (my_pe == 0) then
write(error_unit,*) 'Warning: Matrix re-distribution is not used, since you did not set the matrix_order'
write(error_unit,*) ' Only task 0 prints this warning'
endif
endif
endif
if (reDistributeMatrix) then
! get the block-size to be used
call obj%get("internal_nblk", nblkInternal, error)
if (error .ne. ELPA_OK) then
print *,"Problem getting option. Aborting..."
stop
endif
call obj%get("matrix_order", matrixOrder, error)
if (error .ne. ELPA_OK) then
print *,"Problem getting option. Aborting..."
stop
endif
layoutExternal=matrixLayouts(matrixOrder)
if (nblkInternal == nblk) then
doRedistributeMatrix = .false.
else
doRedistributeMatrix = .true.
endif
endif
if (doRedistributeMatrix) then
! create a new internal blacs discriptor
! matrix will still be distributed over the same process grid
! as input matrices A and Q where
external_blacs_ctxt = int(mpi_comm_all,kind=BLAS_KIND)
! construct current descriptor
if (obj%is_set("blacs_context") == 0) then
call obj%set("blacs_context", int(external_blacs_ctxt,kind=c_int), error)
if (error .NE. ELPA_OK) then
stop "A"
endif
endif
sc_desc(1) = 1
sc_desc(2) = external_blacs_ctxt
sc_desc(3) = obj%na
sc_desc(4) = obj%na
sc_desc(5) = obj%nblk
sc_desc(6) = obj%nblk
sc_desc(7) = 0
sc_desc(8) = 0
sc_desc(9) = obj%local_nrows
layoutInternal = 'C'
! and np_rows and np_cols
call obj%get("mpi_comm_rows",mpi_comm_rows,error)
call mpi_comm_size(int(mpi_comm_rows,kind=MPI_KIND), np_rowsMPI, mpierr)
call obj%get("mpi_comm_cols",mpi_comm_cols,error)
call mpi_comm_size(int(mpi_comm_cols,kind=MPI_KIND), np_colsMPI, mpierr)
np_rows = int(np_rowsMPI,kind=c_int)
np_cols = int(np_colsMPI,kind=c_int)
blacs_ctxt_ = int(mpi_comm_all,kind=BLAS_KIND)
! we get new blacs context and the local process grid coordinates
call BLACS_Gridinit(blacs_ctxt_, layoutInternal, int(np_rows,kind=BLAS_KIND), int(np_cols,kind=BLAS_KIND))
call BLACS_Gridinfo(blacs_ctxt_, np_rows_, np_cols_, my_prow_, my_pcol_)
if (np_rows /= np_rows_) then
print *, "BLACS_Gridinfo returned different values for np_rows as set by BLACS_Gridinit"
stop 1
endif
if (np_cols /= np_cols_) then
print *, "BLACS_Gridinfo returned different values for np_cols as set by BLACS_Gridinit"
stop 1
endif
call mpi_comm_split(int(mpi_comm_all,kind=MPI_KIND), int(my_pcol_,kind=MPI_KIND), &
int(my_prow_,kind=MPI_KIND), mpi_comm_rowsMPI_, mpierr)
mpi_comm_rows_ = int(mpi_comm_rowsMPI_,kind=c_int)
call mpi_comm_split(int(mpi_comm_all,kind=MPI_KIND), int(my_prow_,kind=MPI_KIND), &
int(my_pcol_,kind=MPI_KIND), mpi_comm_colsMPI_, mpierr)
mpi_comm_cols_ = int(mpi_comm_colsMPI_,kind=c_int)
if (int(np_rows_,kind=c_int) /= np_rows) then
print *, "BLACS_Gridinfo returned different values for np_rows as set by BLACS_Gridinit"
stop
endif
if (int(np_cols_,kind=c_int) /= np_cols) then
print *, "BLACS_Gridinfo returned different values for np_cols as set by BLACS_Gridinit"
stop
endif
! now we can set up the the blacs descriptor
sc_desc_(:) = 0
na_rows_ = numroc(int(na,kind=BLAS_KIND), int(nblkInternal,kind=BLAS_KIND), my_prow_, 0_BLAS_KIND, np_rows_)
na_cols_ = numroc(int(na,kind=BLAS_KIND), int(nblkInternal,kind=BLAS_KIND), my_pcol_, 0_BLAS_KIND, np_cols_)
info_ = 0
call descinit(sc_desc_, int(na,kind=BLAS_KIND), int(na,kind=BLAS_KIND), int(nblkInternal,kind=BLAS_KIND), &
int(nblkInternal,kind=BLAS_KIND), 0_BLAS_KIND, 0_BLAS_KIND, &
blacs_ctxt_, na_rows_, info_)
if (info_ .ne. 0) then
write(error_unit,*) 'Error in BLACS descinit! info=',info_
write(error_unit,*) 'the internal re-distribution of the matrices failed!'
call MPI_ABORT(int(mpi_comm_all,kind=MPI_KIND), 1_MPI_KIND, mpierr)
endif
! allocate the memory for the redistributed matrices
allocate(aIntern(na_rows_,na_cols_))
#ifdef HAVE_SKEWSYMMETRIC
allocate(qIntern(na_rows_,2*na_cols_))
#else
allocate(qIntern(na_rows_,na_cols_))
#endif
call scal_PRECISION_GEMR2D &
(int(na,kind=BLAS_KIND), int(na,kind=BLAS_KIND), aExtern, 1_BLAS_KIND, 1_BLAS_KIND, sc_desc, aIntern, &
1_BLAS_KIND, 1_BLAS_KIND, sc_desc_, blacs_ctxt_)
!call scal_PRECISION_GEMR2D &
!(int(na,kind=BLAS_KIND), int(na,kind=BLAS_KIND), qExtern, 1_BLAS_KIND, 1_BLAS_KIND, sc_desc, qIntern, &
!1_BLAS_KIND, 1_BLAS_KIND, sc_desc_, blacs_ctxt_)
!map all important new variables to be used from here
nblk = nblkInternal
matrixCols = na_cols_
matrixRows = na_rows_
mpi_comm_cols = mpi_comm_cols_
mpi_comm_rows = mpi_comm_rows_
a => aIntern(1:matrixRows,1:matrixCols)
q => qIntern(1:matrixRows,1:matrixCols)
else
a => aExtern(1:matrixRows,1:matrixCols)
q => qExtern(1:matrixRows,1:matrixCols)
endif
#endif /* REDISTRIBUTE_MATRIX */
! special case na = 1
if (na .eq. 1) then
#if REALCASE == 1
......@@ -1146,6 +1359,50 @@
call omp_set_num_threads(omp_threads_caller)
#endif
#ifdef REDISTRIBUTE_MATRIX
! redistribute back if necessary
if (doRedistributeMatrix) then
!if (layoutInternal /= layoutExternal) then
! ! maybe this can be skiped I now the process grid
! ! and np_rows and np_cols
! call obj%get("mpi_comm_rows",mpi_comm_rows,error)
! call mpi_comm_size(int(mpi_comm_rows,kind=MPI_KIND), np_rowsMPI, mpierr)
! call obj%get("mpi_comm_cols",mpi_comm_cols,error)
! call mpi_comm_size(int(mpi_comm_cols,kind=MPI_KIND), np_colsMPI, mpierr)
! np_rows = int(np_rowsMPI,kind=c_int)
! np_cols = int(np_colsMPI,kind=c_int)
! ! we get new blacs context and the local process grid coordinates
! call BLACS_Gridinit(external_blacs_ctxt, layoutInternal, int(np_rows,kind=BLAS_KIND), int(np_cols,kind=BLAS_KIND))
! call BLACS_Gridinfo(int(external_blacs_ctxt,KIND=BLAS_KIND), np_rows__, &
! np_cols__, my_prow__, my_pcol__)
!endif
!call scal_PRECISION_GEMR2D &
!(int(na,kind=BLAS_KIND), int(na,kind=BLAS_KIND), aIntern, 1_BLAS_KIND, 1_BLAS_KIND, sc_desc_, aExtern, &
!1_BLAS_KIND, 1_BLAS_KIND, sc_desc, external_blacs_ctxt)
call scal_PRECISION_GEMR2D &
(int(na,kind=BLAS_KIND), int(na,kind=BLAS_KIND), qIntern, 1_BLAS_KIND, 1_BLAS_KIND, sc_desc_, qExtern, &
1_BLAS_KIND, 1_BLAS_KIND, sc_desc, external_blacs_ctxt)
!clean MPI communicators and blacs grid
!of the internal re-distributed matrix
call mpi_comm_free(mpi_comm_rowsMPI_, mpierr)
call mpi_comm_free(mpi_comm_colsMPI_, mpierr)
call blacs_gridexit(blacs_ctxt_)
endif
#endif /* REDISTRIBUTE_MATRIX */
call obj%timer%stop("elpa_solve_evp_&
&MATH_DATATYPE&
&_2stage_&
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment