36#include "./base/base_uses.f90"
42 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'bse_matvec'
68 INTEGER :: homo = 0, virt = 0, n_ov = 0, &
69 n_ri_loc = 0, block_cols = -1
70 REAL(kind=
dp) :: alpha = 0.0_dp, w_fac = 0.0_dp
71 LOGICAL :: do_abba = .false.
72 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: row_count, row_displ
73 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eps_diff
74 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: b_ia, b_bar_ia, b_bar_ij, b_ab
99 SUBROUTINE bse_matvec_create(mv_env, fm_S_ia, fm_S_bar_ij, fm_S_ab, fm_S_bar_ia, eps_reduced, &
100 homo, virt, alpha, w_fac, do_abba, unit_nr, block_cols)
103 TYPE(
cp_fm_type),
INTENT(IN) :: fm_s_ia, fm_s_bar_ij, fm_s_ab, &
105 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eps_reduced
106 INTEGER,
INTENT(IN) :: homo, virt
107 REAL(kind=
dp),
INTENT(IN) :: alpha, w_fac
108 LOGICAL,
INTENT(IN) :: do_abba
109 INTEGER,
INTENT(IN) :: unit_nr
110 INTEGER,
INTENT(IN),
OPTIONAL :: block_cols
112 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_matvec_create'
114 CHARACTER(LEN=12) :: n_idle_str, n_ri_str, npe_str
115 INTEGER :: a, handle, i, n_ri, n_ri_slab, &
117 REAL(kind=
dp) :: mem_slabs_gb, n_slab_entries
119 CALL timeset(routinen, handle)
123 IF (
PRESENT(block_cols)) mv_env%block_cols = block_cols
124 mv_env%n_ov = homo*virt
127 mv_env%do_abba = do_abba
128 mv_env%para_env => fm_s_ia%matrix_struct%para_env
131 grid_2d=[mv_env%para_env%num_pe, 1])
135 n_row_block = contiguous_row_block(mv_env%n_ov, mv_env%para_env%num_pe)
136 ALLOCATE (mv_env%row_count(mv_env%para_env%num_pe), mv_env%row_displ(mv_env%para_env%num_pe))
137 DO i = 1, mv_env%para_env%num_pe
138 mv_env%row_displ(i) = min(mv_env%n_ov, (i - 1)*n_row_block)
139 mv_env%row_count(i) = min(mv_env%n_ov, i*n_row_block) - mv_env%row_displ(i)
143 ALLOCATE (mv_env%eps_diff(mv_env%n_ov))
146 mv_env%eps_diff(
ia_of_occ_virt(i, a, virt)) = eps_reduced(homo + a) - eps_reduced(i)
151 CALL slice_slab(mv_env, fm_s_ia, virt, homo, mv_env%B_ia, mv_env%n_ri_loc)
152 IF (w_fac /= 0.0_dp)
THEN
153 CALL slice_slab(mv_env, fm_s_bar_ij, homo, homo, mv_env%B_bar_ij, n_ri_slab)
154 cpassert(n_ri_slab == mv_env%n_ri_loc)
155 CALL slice_slab(mv_env, fm_s_ab, virt, virt, mv_env%B_ab, n_ri_slab)
156 cpassert(n_ri_slab == mv_env%n_ri_loc)
158 CALL slice_slab(mv_env, fm_s_bar_ia, virt, homo, mv_env%B_bar_ia, n_ri_slab)
159 cpassert(n_ri_slab == mv_env%n_ri_loc)
164 IF (mv_env%para_env%num_pe > n_ri .AND. unit_nr > 0)
THEN
165 WRITE (npe_str,
'(I0)') mv_env%para_env%num_pe
166 WRITE (n_ri_str,
'(I0)') n_ri
167 WRITE (n_idle_str,
'(I0)') mv_env%para_env%num_pe - n_ri
168 CALL cp_warn(__location__, &
169 "BSE iterative solver: more MPI ranks ("//trim(npe_str)// &
170 ") than RI basis functions ("//trim(n_ri_str)//
"); "// &
171 trim(n_idle_str)//
" ranks hold no RI slice and idle in the kernel application.")
174 IF (unit_nr > 0)
THEN
176 n_slab_entries = real(homo*virt,
dp)
177 IF (w_fac /= 0.0_dp)
THEN
178 n_slab_entries = n_slab_entries + real(homo,
dp)**2 + real(virt,
dp)**2
179 IF (do_abba) n_slab_entries = n_slab_entries + real(homo*virt,
dp)
181 mem_slabs_gb = n_slab_entries*real(mv_env%n_ri_loc,
dp)*8.0e-9_dp
182 WRITE (unit_nr,
'(T2,A4,T7,A,T71,I10)')
'BSE|', &
183 'Max. number of RI functions per MPI rank', mv_env%n_ri_loc
184 WRITE (unit_nr,
'(T2,A4,T7,A,T67,F14.3)')
'BSE|', &
185 'Memory of the RI slabs per MPI rank (GB)', mem_slabs_gb
188 CALL timestop(handle)
198 PURE FUNCTION contiguous_row_block(n_ov, npe)
RESULT(n_row_block)
200 INTEGER,
INTENT(IN) :: n_ov, npe
201 INTEGER :: n_row_block
203 n_row_block = (n_ov + npe - 1)/npe
205 END FUNCTION contiguous_row_block
218 SUBROUTINE slice_slab(mv_env, fm_slab, n_fast, n_slow, slab_loc, n_ri_loc)
222 INTEGER,
INTENT(IN) :: n_fast, n_slow
223 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :), &
224 INTENT(OUT) :: slab_loc
225 INTEGER,
INTENT(OUT) :: n_ri_loc
227 CHARACTER(LEN=*),
PARAMETER :: routinen =
'slice_slab'
229 INTEGER :: handle, n_ri, npair, p
233 CALL timeset(routinen, handle)
237 cpassert(npair == n_fast*n_slow)
243 nrow_global=n_ri, ncol_global=npair, nrow_block=1, &
245 CALL cp_fm_create(fm_sliced, fm_struct, name=
"fm_slab_ri_sliced")
248 fm_slab%matrix_struct%context)
251 ALLOCATE (slab_loc(n_fast, n_slow, n_ri_loc))
253 slab_loc(:, :, p) = reshape(fm_sliced%local_data(p, 1:npair), [n_fast, n_slow])
257 CALL timestop(handle)
259 END SUBROUTINE slice_slab
269 IF (
ALLOCATED(mv_env%row_count))
DEALLOCATE (mv_env%row_count)
270 IF (
ALLOCATED(mv_env%row_displ))
DEALLOCATE (mv_env%row_displ)
271 IF (
ALLOCATED(mv_env%eps_diff))
DEALLOCATE (mv_env%eps_diff)
272 IF (
ALLOCATED(mv_env%B_ia))
DEALLOCATE (mv_env%B_ia)
273 IF (
ALLOCATED(mv_env%B_bar_ia))
DEALLOCATE (mv_env%B_bar_ia)
274 IF (
ALLOCATED(mv_env%B_bar_ij))
DEALLOCATE (mv_env%B_bar_ij)
275 IF (
ALLOCATED(mv_env%B_ab))
DEALLOCATE (mv_env%B_ab)
277 NULLIFY (mv_env%para_env)
290 INTEGER,
INTENT(IN) :: ncol_global
296 nrow_global=mv_env%n_ov, ncol_global=ncol_global, &
297 nrow_block=contiguous_row_block(mv_env%n_ov, mv_env%para_env%num_pe), &
322 INTEGER,
INTENT(IN) :: first_col, ncol
324 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: fm_bz
325 INTEGER,
INTENT(IN),
OPTIONAL :: first_col_bz
327 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_matvec_apply'
329 INTEGER :: col, col_shift_b, handle, handle2, ia, &
330 iloc, k, me, n_work_bufs, nb, nb_max, &
332 INTEGER,
DIMENSION(:),
POINTER :: row_indices
334 REAL(kind=
dp) :: mem_avail_gb
335 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: r_loc
336 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:),
TARGET :: babz_buf, ra_buf, rb_buf, z_buf
337 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: bjaz_ab, t_pk
338 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
339 POINTER :: b_ia_2d, babz_wide, ra, rb, z, z_wide
340 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :, :), &
341 POINTER :: babz_3d, ra_3d, rb_3d, z_3d
343 CALL timeset(routinen, handle)
345 do_b =
PRESENT(fm_bz)
348 cpassert(mv_env%do_abba)
351 IF (
PRESENT(first_col_bz)) col_shift_b = first_col_bz - first_col
353 CALL cp_fm_get_info(fm_z, nrow_local=nrow_local, row_indices=row_indices)
356 me = mv_env%para_env%mepos + 1
357 cpassert(nrow_local == mv_env%row_count(me))
358 cpassert(nrow_local == 0 .OR. row_indices(1) == mv_env%row_displ(me) + 1)
359 ALLOCATE (r_loc(nrow_local))
367 IF (mv_env%block_cols > 0)
THEN
369 nb_max = min(ncol, mv_env%block_cols)
373 IF (mem_avail_gb > 0.0_dp)
THEN
374 nb_max = int(min(real(ncol,
dp), &
375 mem_fraction*mem_avail_gb*1.0e9_dp/(8.0_dp*real(n_work_bufs,
dp)*real(mv_env%n_ov,
dp))))
378 nb_max = max(nb_max, 1)
380 ALLOCATE (z_buf(mv_env%n_ov*nb_max), ra_buf(mv_env%n_ov*nb_max), babz_buf(mv_env%n_ov*nb_max))
382 ALLOCATE (rb_buf(mv_env%n_ov*nb_max), bjaz_ab(mv_env%virt, mv_env%virt))
384 ALLOCATE (t_pk(mv_env%n_ri_loc, nb_max))
385 b_ia_2d(1:mv_env%n_ov, 1:mv_env%n_ri_loc) => mv_env%B_ia
387 DO col = first_col, first_col + ncol - 1, nb_max
388 nb = min(nb_max, first_col + ncol - col)
391 z(1:mv_env%n_ov, 1:nb) => z_buf(1:mv_env%n_ov*nb)
392 z_3d(1:mv_env%virt, 1:mv_env%homo, 1:nb) => z_buf(1:mv_env%n_ov*nb)
393 z_wide(1:mv_env%virt, 1:mv_env%homo*nb) => z_buf(1:mv_env%n_ov*nb)
394 ra(1:mv_env%n_ov, 1:nb) => ra_buf(1:mv_env%n_ov*nb)
395 ra_3d(1:mv_env%virt, 1:mv_env%homo, 1:nb) => ra_buf(1:mv_env%n_ov*nb)
396 babz_3d(1:mv_env%virt, 1:mv_env%homo, 1:nb) => babz_buf(1:mv_env%n_ov*nb)
397 babz_wide(1:mv_env%virt, 1:mv_env%homo*nb) => babz_buf(1:mv_env%n_ov*nb)
399 rb(1:mv_env%n_ov, 1:nb) => rb_buf(1:mv_env%n_ov*nb)
400 rb_3d(1:mv_env%virt, 1:mv_env%homo, 1:nb) => rb_buf(1:mv_env%n_ov*nb)
404 CALL timeset(routinen//
"_gather", handle2)
406 CALL mv_env%para_env%allgatherv(fm_z%local_data(1:nrow_local, col + k - 1), z(:, k), &
407 mv_env%row_count, mv_env%row_displ)
409 CALL timestop(handle2)
412 CALL timeset(routinen//
"_exchange", handle2)
414 IF (mv_env%alpha /= 0.0_dp .AND. mv_env%n_ri_loc > 0)
THEN
415 CALL dgemm(
'T',
'N', mv_env%n_ri_loc, nb, mv_env%n_ov, 1.0_dp, b_ia_2d, mv_env%n_ov, z, mv_env%n_ov, &
416 0.0_dp, t_pk, mv_env%n_ri_loc)
417 CALL dgemm(
'N',
'N', mv_env%n_ov, nb, mv_env%n_ri_loc, mv_env%alpha, b_ia_2d, mv_env%n_ov, t_pk, mv_env%n_ri_loc, &
418 0.0_dp, ra, mv_env%n_ov)
420 IF (do_b) rb(:, :) = ra(:, :)
421 CALL timestop(handle2)
423 CALL timeset(routinen//
"_W", handle2)
424 IF (mv_env%w_fac /= 0.0_dp)
THEN
425 DO p = 1, mv_env%n_ri_loc
427 CALL dgemm(
'T',
'N', mv_env%virt, mv_env%homo*nb, mv_env%virt, 1.0_dp, mv_env%B_ab(:, :, p), mv_env%virt, &
428 z_wide, mv_env%virt, 0.0_dp, babz_wide, mv_env%virt)
430 CALL dgemm(
'N',
'N', mv_env%virt, mv_env%homo, mv_env%homo, -mv_env%w_fac, babz_3d(:, :, k), mv_env%virt, &
431 mv_env%B_bar_ij(:, :, p), mv_env%homo, 1.0_dp, ra_3d(:, :, k), mv_env%virt)
436 CALL dgemm(
'N',
'T', mv_env%virt, mv_env%virt, mv_env%homo, 1.0_dp, mv_env%B_ia(:, :, p), mv_env%virt, &
437 z_3d(:, :, k), mv_env%virt, 0.0_dp, bjaz_ab, mv_env%virt)
438 CALL dgemm(
'N',
'N', mv_env%virt, mv_env%homo, mv_env%virt, -mv_env%w_fac, bjaz_ab, mv_env%virt, &
439 mv_env%B_bar_ia(:, :, p), mv_env%virt, 1.0_dp, rb_3d(:, :, k), mv_env%virt)
444 CALL timestop(handle2)
447 CALL timeset(routinen//
"_reduce", handle2)
450 CALL mv_env%para_env%sum_scatter(ra(:, k:k), r_loc, mv_env%row_count)
451 DO iloc = 1, nrow_local
452 ia = row_indices(iloc)
453 fm_az%local_data(iloc, col + k - 1) = r_loc(iloc) + mv_env%eps_diff(ia)*z(ia, k)
456 CALL mv_env%para_env%sum_scatter(rb(:, k:k), r_loc, mv_env%row_count)
457 fm_bz%local_data(1:nrow_local, col + col_shift_b + k - 1) = r_loc(1:nrow_local)
460 CALL timestop(handle2)
463 DEALLOCATE (z_buf, ra_buf, babz_buf, t_pk)
465 DEALLOCATE (rb_buf, bjaz_ab)
468 CALL timestop(handle)
483 INTEGER,
INTENT(IN) :: precond_kind
484 REAL(kind=
dp),
DIMENSION(:),
INTENT(OUT) :: diag
486 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_matvec_diagonal'
488 INTEGER :: a, handle, i, ia, p
490 CALL timeset(routinen, handle)
494 DO p = 1, mv_env%n_ri_loc
495 DO i = 1, mv_env%homo
496 DO a = 1, mv_env%virt
498 diag(ia) = diag(ia) + mv_env%alpha*mv_env%B_ia(a, i, p)**2
499 IF (mv_env%w_fac /= 0.0_dp)
THEN
500 diag(ia) = diag(ia) - mv_env%w_fac*mv_env%B_bar_ij(i, i, p)*mv_env%B_ab(a, a, p)
505 CALL mv_env%para_env%sum(diag)
507 diag(:) = diag(:) + mv_env%eps_diff(:)
509 CALL timestop(handle)
526 INTEGER,
DIMENSION(:),
INTENT(IN) :: ia_list
527 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: a_sub
528 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT), &
531 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_matvec_subblock'
533 INTEGER :: handle, k, l, n_sub, p
534 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: a_virt, i_occ
535 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: b_pk
537 CALL timeset(routinen, handle)
539 n_sub =
SIZE(ia_list)
540 ALLOCATE (i_occ(n_sub), a_virt(n_sub), b_pk(max(mv_env%n_ri_loc, 1), n_sub))
542 i_occ(k) =
occ_of_ia(ia_list(k), mv_env%virt)
543 a_virt(k) =
virt_of_ia(ia_list(k), mv_env%virt)
548 IF (mv_env%alpha /= 0.0_dp .AND. mv_env%n_ri_loc > 0)
THEN
550 DO p = 1, mv_env%n_ri_loc
552 b_pk(p, k) = mv_env%B_ia(a_virt(k), i_occ(k), p)
555 CALL dgemm(
'T',
'N', n_sub, n_sub, mv_env%n_ri_loc, mv_env%alpha, b_pk,
SIZE(b_pk, 1), b_pk,
SIZE(b_pk, 1), &
556 0.0_dp, a_sub, n_sub)
558 IF (
PRESENT(b_sub)) b_sub(:, :) = a_sub(:, :)
560 IF (mv_env%w_fac /= 0.0_dp)
THEN
561 DO p = 1, mv_env%n_ri_loc
564 a_sub(k, l) = a_sub(k, l) - mv_env%w_fac*mv_env%B_bar_ij(i_occ(l), i_occ(k), p)*mv_env%B_ab(a_virt(l), a_virt(k), p)
567 IF (
PRESENT(b_sub))
THEN
570 b_sub(k, l) = b_sub(k, l) - mv_env%w_fac*mv_env%B_ia(a_virt(k), i_occ(l), p)*mv_env%B_bar_ia(a_virt(l), i_occ(k), p)
577 CALL mv_env%para_env%sum(a_sub)
578 IF (
PRESENT(b_sub))
CALL mv_env%para_env%sum(b_sub)
580 a_sub(k, k) = a_sub(k, k) + mv_env%eps_diff(ia_list(k))
583 DEALLOCATE (i_occ, a_virt, b_pk)
585 CALL timestop(handle)
602 INTEGER,
INTENT(IN) :: unit_nr
603 TYPE(
cp_fm_type),
INTENT(IN),
OPTIONAL :: fm_b_explicit
605 CHARACTER(LEN=*),
PARAMETER :: routinen =
'bse_matvec_selfcheck'
607 INTEGER :: handle, ia, iloc, k, n_ov, n_unit, ncol, &
609 INTEGER,
DIMENSION(:),
POINTER :: row_indices
610 REAL(kind=
dp) :: dev_a, dev_b, dev_diag
611 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag
612 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mv_result, ref_matrix, ref_result, z
616 CALL timeset(routinen, handle)
620 n_unit = min(n_ov, 8)
625 ALLOCATE (z(n_ov, ncol))
631 z(ia, ncol) = sin(real(ia,
dp))
635 CALL cp_fm_create(fm_z, fm_struct, name=
"fm_Z_selfcheck")
636 CALL cp_fm_create(fm_az, fm_struct, name=
"fm_AZ_selfcheck")
638 IF (
PRESENT(fm_b_explicit))
THEN
639 CALL cp_fm_create(fm_bz, fm_struct, name=
"fm_BZ_selfcheck")
644 CALL cp_fm_get_info(fm_z, nrow_local=nrow_local, row_indices=row_indices)
646 DO iloc = 1, nrow_local
647 fm_z%local_data(iloc, k) = z(row_indices(iloc), k)
651 IF (
PRESENT(fm_b_explicit))
THEN
657 ALLOCATE (ref_matrix(n_ov, n_ov), mv_result(n_ov, ncol), ref_result(n_ov, ncol), diag(n_ov))
661 ref_result(:, :) = matmul(ref_matrix, z)
662 dev_a = maxval(abs(mv_result - ref_result))
666 dev_diag = max(dev_diag, abs(diag(ia) - ref_matrix(ia, ia)))
669 IF (
PRESENT(fm_b_explicit))
THEN
672 ref_result(:, :) = matmul(ref_matrix, z)
673 dev_b = maxval(abs(mv_result - ref_result))
676 IF (unit_nr > 0)
THEN
677 WRITE (unit_nr,
'(T2,A10,T13,A,T59,ES22.6)')
'BSE|DEBUG|', &
678 'Max deviation matvec vs explicit A', dev_a
679 IF (
PRESENT(fm_b_explicit))
THEN
680 WRITE (unit_nr,
'(T2,A10,T13,A,T59,ES22.6)')
'BSE|DEBUG|', &
681 'Max deviation matvec vs explicit B', dev_b
683 WRITE (unit_nr,
'(T2,A10,T13,A,T59,ES22.6)')
'BSE|DEBUG|', &
684 'Max deviation diagonal vs explicit A', dev_diag
687 DEALLOCATE (z, ref_matrix, mv_result, ref_result, diag)
692 CALL timestop(handle)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Matrix-free application of the BSE matrices A and B to trial vectors from RI slabs that are sliced al...
subroutine, public bse_matvec_release(mv_env)
Frees the sliced slabs, the transition energies and the process grid of mv_env.
subroutine, public bse_matvec_subblock(mv_env, ia_list, a_sub, b_sub)
Exact A (and B) on a list of transitions, replicated on every rank, A_kl = δ_kl (ε_a-ε_i) + α sum_P B...
subroutine, public bse_matvec_apply(mv_env, fm_z, first_col, ncol, fm_az, fm_bz, first_col_bz)
Applies A (and B) to ncol trial vectors without forming an N_ov x N_ov object, (A Z)_ia = (ε_a-ε_i) Z...
subroutine, public bse_matvec_diagonal(mv_env, precond_kind, diag)
Diagonal used by the Davidson correction, either ε_a-ε_i or the full diagonal A_ia,...
real(kind=dp), parameter, public mem_fraction
subroutine, public bse_matvec_selfcheck(mv_env, fm_a_explicit, unit_nr, fm_b_explicit)
Debug check of the matrix-free application against the explicit matrices A (and B),...
subroutine, public bse_matvec_create(mv_env, fm_s_ia, fm_s_bar_ij, fm_s_ab, fm_s_bar_ia, eps_reduced, homo, virt, alpha, w_fac, do_abba, unit_nr, block_cols)
Moves the RI slabs onto an npe x 1 process grid, such that every rank owns whole RI slices,...
subroutine, public bse_matvec_vector_struct(mv_env, ncol_global, fm_struct)
Matrix structure of a block of trial vectors: rows ia distributed, all columns local.
Auxiliary routines for GW + Bethe-Salpeter for computing electronic excitations.
pure integer function, public occ_of_ia(ia, virt)
Occupied level of the compound transition index ia = (i-1)*virt + a.
pure integer function, public ia_of_occ_virt(i_occ, a_virt, virt)
Compound transition index ia = (i-1)*virt + a of the pair (i, a): a is the fast index.
pure integer function, public virt_of_ia(ia, virt)
Virtual level of the compound transition index ia = (i-1)*virt + a.
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_to_fm_submat_general(source, destination, nrows, ncols, s_firstrow, s_firstcol, d_firstrow, d_firstcol, global_context)
General copy of a submatrix of fm matrix to a submatrix of another fm matrix. The two matrices can ha...
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
subroutine, public mp_mem_avail_per_rank_gb(comm, mem_avail_gb)
Memory that is currently free on the node, per MPI rank of that node, in GB.
RI slabs of one spin channel, every rank holding n_ri_loc whole RI slices.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
stores all the informations relevant to an mpi environment