31 USE parallel,
ONLY: getnodeorbs, &
47#include "./base/base_uses.f90"
52 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'smeagol_matrix_utils'
53 LOGICAL,
PARAMETER,
PRIVATE :: debug_this_module = .false.
55 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_iatom_index = 1
56 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_jatom_index = 2
57 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_dbcsr_image_index = 3
58 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_siesta_image_index = 4
59 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_siesta_transp_image_index = 5
60 INTEGER,
PARAMETER,
PRIVATE :: neighbor_list_dim1 = neighbor_list_siesta_transp_image_index
66 PRIVATE :: get_negf_cell_ijk, index_in_canonical_enumeration, number_from_canonical_enumeration, pbc_0_1
67 PRIVATE :: get_number_of_mpi_sendrecv_requests, assign_nonzero_elements_to_requests
70 INTEGER,
PARAMETER,
PRIVATE :: nelements_dbcsr_recv = 1
72 INTEGER,
PARAMETER,
PRIVATE :: nelements_dbcsr_send = 2
73 INTEGER,
PARAMETER,
PRIVATE :: nelements_dbcsr_dim2 = nelements_dbcsr_send
76 INTEGER(kind=int_8),
PARAMETER,
PRIVATE :: max_mpi_packet_size_bytes = 134217728
77 INTEGER(kind=int_8),
PARAMETER,
PRIVATE :: max_mpi_packet_size_dp = max_mpi_packet_size_bytes/int(
dp_size, kind=
int_8)
82 INTEGER,
PARAMETER,
PRIVATE :: max_mpi_rank = 32767
92 INTEGER :: gather_root = 0
97 LOGICAL :: symmetric = .true.
100 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: nnodes_per_proc
109 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: nl_repl
112 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_dbcsr_cell_images_to_merge
114 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dbcsr_cell_image_to_merge
118 INTEGER(kind=int_8),
ALLOCATABLE,
DIMENSION(:, :) :: nelements_per_proc
121 INTEGER(kind=int_8) :: n_nonzero_elements = 0_int_8
122 INTEGER :: nrows = 0, ncols = 0
125 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: n_nonzero_cols
129 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: row_offset
133 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: col_index
135 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: packed_index
137 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: xij
139 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: indxuo
141 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iaorb
143 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: xa
163 sab_nl, para_env, max_ij_cell_image, do_merge, gather_root)
165 INTENT(inout) :: siesta_struct
166 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(in) :: matrix_dbcsr_kp
168 INTEGER,
DIMENSION(:, :, :),
POINTER :: cell_to_index
172 INTEGER,
DIMENSION(2),
INTENT(inout) :: max_ij_cell_image
173 LOGICAL,
INTENT(in) :: do_merge
174 INTEGER,
INTENT(in) :: gather_root
176 CHARACTER(len=*),
PARAMETER :: routinen =
'siesta_struct_create'
178 CHARACTER(len=20) :: str_nelem, str_nelem_max
179 INTEGER :: handle, iatom, icol, icol_blk, icol_local, image, image_j, image_k, irow, &
180 irow_local, natoms, ncells_siesta_total, ncols_blk, ncols_total, nrows_local, &
182 INTEGER(kind=int_8) :: n_nonzero_elements_local
183 INTEGER,
DIMENSION(3) :: max_ijk_cell_image, ncells_siesta
184 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size
185 LOGICAL :: do_distribute, is_root_rank
186 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: particle_coords
187 REAL(kind=
dp),
DIMENSION(3) :: real_cell_shift, scaled_cell_shift
191 CALL timeset(routinen, handle)
192 do_distribute = gather_root < 0
193 is_root_rank = gather_root == para_env%mepos
198 nfullrows_total=nrows_total, nfullcols_total=ncols_total, &
199 nblkcols_total=ncols_blk, col_blk_size=col_blk_size, col_blk_offset=col_blk_offset)
200 IF (debug_this_module)
THEN
201 cpassert(nrows_total == ncols_total)
202 cpassert(gather_root < para_env%num_pe)
205 siesta_struct%gather_root = gather_root
209 CALL qs_subsys_get(subsys, cell=cell, particle_set=particle_set, nparticle=natoms)
210 ALLOCATE (particle_coords(3, natoms))
212 CALL pbc_0_1(particle_coords(1:3, iatom), particle_set(iatom)%r(1:3), cell)
218 max_ijk_cell_image(1:2) = max_ij_cell_image(1:2)
223 max_ijk_cell_image(3) = -1
225 IF (.NOT. do_merge) max_ijk_cell_image(3) = 1
229 ALLOCATE (siesta_struct%nnodes_per_proc(0:para_env%num_pe - 1))
230 CALL replicate_neighbour_list(siesta_struct%nl_repl, &
231 siesta_struct%n_dbcsr_cell_images_to_merge, &
232 siesta_struct%dbcsr_cell_image_to_merge, &
233 siesta_struct%nnodes_per_proc, &
234 max_ijk_cell_image, sab_nl, para_env, particle_coords, cell, cell_to_index, do_merge)
235 max_ij_cell_image(1:2) = max_ijk_cell_image(1:2)
238 ALLOCATE (siesta_struct%nelements_per_proc(0:para_env%num_pe - 1, nelements_dbcsr_dim2))
239 CALL count_remote_dbcsr_elements(siesta_struct%nelements_per_proc, siesta_struct%nnodes_per_proc, &
240 siesta_struct%nl_repl, matrix_dbcsr_kp, siesta_struct%symmetric, para_env, gather_root)
243 n_nonzero_elements_local = sum(siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv))
244 siesta_struct%n_nonzero_elements = n_nonzero_elements_local
248 IF (n_nonzero_elements_local > int(huge(0), kind=
int_8))
THEN
249 WRITE (str_nelem,
'(I0)') n_nonzero_elements_local
250 WRITE (str_nelem_max,
'(I0)') huge(0)
251 CALL cp_abort(__location__, &
252 "The number of non-zero matrix elements per MPI process "//trim(str_nelem)// &
253 " cannot exceed "//trim(str_nelem_max)// &
254 ". Please increase the number of MPI processes to satisfy this SMEAGOL limitation.")
258 IF (n_nonzero_elements_local == 0) n_nonzero_elements_local = 1
261 IF (do_distribute)
THEN
262#if defined(__SMEAGOL)
263 CALL getnodeorbs(nrows_total, para_env%mepos, para_env%num_pe, nrows_local)
265 CALL cp_abort(__location__, &
266 "CP2K was compiled with no SMEAGOL support.")
269 IF (is_root_rank)
THEN
270 nrows_local = nrows_total
277 ncells_siesta(1:3) = 2*max_ijk_cell_image(1:3) + 1
279 IF (do_merge) ncells_siesta(3) = 1
281 ncells_siesta_total = ncells_siesta(1)*ncells_siesta(2)*ncells_siesta(3)
284 siesta_struct%nrows = nrows_local
288 siesta_struct%ncols = nrows_total*ncells_siesta_total
291 IF (nrows_local == 0) nrows_local = 1
293 ALLOCATE (siesta_struct%n_nonzero_cols(nrows_local))
294 ALLOCATE (siesta_struct%row_offset(nrows_local))
295 ALLOCATE (siesta_struct%col_index(n_nonzero_elements_local))
296 ALLOCATE (siesta_struct%packed_index(n_nonzero_elements_local))
299 nrows_local = siesta_struct%nrows
305 CALL get_nonzero_element_indices(siesta_struct%n_nonzero_cols, siesta_struct%row_offset, &
306 siesta_struct%col_index, siesta_struct%packed_index, &
307 siesta_struct%nl_repl, matrix_dbcsr_kp, &
308 siesta_struct%symmetric, para_env, gather_root)
311 ALLOCATE (siesta_struct%indxuo(siesta_struct%ncols))
312 DO icol = 1, ncols_total
313 siesta_struct%indxuo(icol) = icol
315 DO image = 2, ncells_siesta_total
316 siesta_struct%indxuo((image - 1)*ncols_total + 1:image*ncols_total) = siesta_struct%indxuo(1:ncols_total)
320 ALLOCATE (siesta_struct%iaorb(siesta_struct%ncols))
321 DO icol_blk = 1, ncols_blk
323 siesta_struct%iaorb(col_blk_offset(icol_blk):col_blk_offset(icol_blk) + col_blk_size(icol_blk) - 1) = icol_blk
325 DO image = 2, ncells_siesta_total
326 siesta_struct%iaorb((image - 1)*ncols_total + 1:image*ncols_total) = siesta_struct%iaorb(1:ncols_total) + (image - 1)*natoms
330 ALLOCATE (siesta_struct%xa(3, natoms*ncells_siesta_total))
331 DO image_k = 1, ncells_siesta(3)
333 scaled_cell_shift(3) = real(number_from_canonical_enumeration(image_k), kind=
dp)
334 DO image_j = 1, ncells_siesta(2)
335 scaled_cell_shift(2) = real(number_from_canonical_enumeration(image_j), kind=
dp)
336 DO image = 1, ncells_siesta(1)
337 scaled_cell_shift(1) = real(number_from_canonical_enumeration(image), kind=
dp)
339 offset = (((image_k - 1)*ncells_siesta(2) + image_j - 1)*ncells_siesta(1) + image - 1)*natoms
341 siesta_struct%xa(1:3, offset + iatom) = particle_set(iatom)%r(1:3) + real_cell_shift(1:3)
348 ALLOCATE (siesta_struct%xij(3, n_nonzero_elements_local))
349 DO irow_local = 1, nrows_local
350 IF (do_distribute)
THEN
351#if defined(__SMEAGOL)
352 CALL localtoglobalorb(irow_local, para_env%mepos, para_env%num_pe, irow)
354 CALL cp_abort(__location__, &
355 "CP2K was compiled with no SMEAGOL support.")
359 IF (debug_this_module)
THEN
360 cpassert(is_root_rank)
363 offset = siesta_struct%row_offset(irow_local)
364 DO icol_local = offset + 1, offset + siesta_struct%n_nonzero_cols(irow_local)
365 icol = siesta_struct%col_index(icol_local)
366 siesta_struct%xij(1:3, icol_local) = siesta_struct%xa(1:3, siesta_struct%iaorb(icol)) - &
367 siesta_struct%xa(1:3, siesta_struct%iaorb(irow))
371 DEALLOCATE (particle_coords)
373 CALL timestop(handle)
382 INTENT(inout) :: siesta_struct
384 CHARACTER(len=*),
PARAMETER :: routinen =
'siesta_struct_release'
388 CALL timeset(routinen, handle)
390 siesta_struct%gather_root = -1
392 IF (
ALLOCATED(siesta_struct%nnodes_per_proc))
DEALLOCATE (siesta_struct%nnodes_per_proc)
393 IF (
ALLOCATED(siesta_struct%nl_repl))
DEALLOCATE (siesta_struct%nl_repl)
394 IF (
ALLOCATED(siesta_struct%n_dbcsr_cell_images_to_merge))
DEALLOCATE (siesta_struct%n_dbcsr_cell_images_to_merge)
395 IF (
ALLOCATED(siesta_struct%dbcsr_cell_image_to_merge))
DEALLOCATE (siesta_struct%dbcsr_cell_image_to_merge)
396 IF (
ALLOCATED(siesta_struct%nelements_per_proc))
DEALLOCATE (siesta_struct%nelements_per_proc)
398 siesta_struct%n_nonzero_elements = 0
399 siesta_struct%nrows = 0
400 siesta_struct%ncols = 0
402 IF (
ALLOCATED(siesta_struct%n_nonzero_cols))
DEALLOCATE (siesta_struct%n_nonzero_cols)
403 IF (
ALLOCATED(siesta_struct%row_offset))
DEALLOCATE (siesta_struct%row_offset)
404 IF (
ALLOCATED(siesta_struct%col_index))
DEALLOCATE (siesta_struct%col_index)
405 IF (
ALLOCATED(siesta_struct%packed_index))
DEALLOCATE (siesta_struct%packed_index)
407 IF (
ALLOCATED(siesta_struct%xij))
DEALLOCATE (siesta_struct%xij)
408 IF (
ALLOCATED(siesta_struct%indxuo))
DEALLOCATE (siesta_struct%indxuo)
409 IF (
ALLOCATED(siesta_struct%iaorb))
DEALLOCATE (siesta_struct%iaorb)
410 IF (
ALLOCATED(siesta_struct%xa))
DEALLOCATE (siesta_struct%xa)
412 CALL timestop(handle)
423 REAL(kind=
dp),
DIMENSION(:),
INTENT(out) :: matrix_siesta
424 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(in) :: matrix_dbcsr_kp
428 CHARACTER(len=*),
PARAMETER :: routinen =
'convert_dbcsr_to_distributed_siesta'
430 INTEGER :: first_col_minus_one, first_row_minus_one, handle, icol_blk, icol_local, &
431 image_dbcsr, image_ind, image_ind_offset, image_siesta, image_siesta_transp, inode, &
432 inode_proc, iproc, irequest, irow_blk, irow_local, irow_proc, mepos, n_image_ind, &
433 ncols_blk, ncols_local, nnodes_proc, node_offset, nprocs, nrequests_recv, &
434 nrequests_total, nrows_blk, nrows_local
435 INTEGER(kind=int_8) :: n_nonzero_elements_dbcsr, &
436 n_nonzero_elements_siesta, &
437 offset_recv_mepos, offset_send_mepos
438 INTEGER(kind=int_8),
ALLOCATABLE,
DIMENSION(:) :: n_packed_elements_per_proc, &
439 nelements_per_request, &
440 offset_per_proc, offset_per_request
441 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: next_nonzero_element_offset, peer_rank, &
443 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, &
444 row_blk_offset, row_blk_size
445 LOGICAL :: do_distribute, found, is_root_rank, &
447 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_buffer, reorder_recv_buffer, &
449 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: sm_block, sm_block_merged
452 CALL timeset(routinen, handle)
453 matrix_siesta(:) = 0.0_dp
455 mepos = para_env%mepos
456 nprocs = para_env%num_pe
457 do_distribute = siesta_struct%gather_root < 0
458 is_root_rank = siesta_struct%gather_root == mepos
461 nblkrows_total=nrows_blk, nblkcols_total=ncols_blk, &
462 row_blk_size=row_blk_size, col_blk_size=col_blk_size, &
463 row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
464 symmetric = siesta_struct%symmetric
467 n_nonzero_elements_siesta = sum(siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv))
469 n_nonzero_elements_dbcsr = sum(siesta_struct%nelements_per_proc(:, nelements_dbcsr_send))
472 nrequests_recv = get_number_of_mpi_sendrecv_requests(mepos, siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv), &
473 max_mpi_packet_size_dp)
474 nrequests_total = get_number_of_mpi_sendrecv_requests(mepos, siesta_struct%nelements_per_proc(:, nelements_dbcsr_send), &
475 max_mpi_packet_size_dp) + nrequests_recv
477 IF (nrequests_total > 0)
THEN
480 ALLOCATE (requests(nrequests_total))
481 ALLOCATE (peer_rank(nrequests_total), request_tag(nrequests_total))
482 ALLOCATE (offset_per_request(nrequests_total), nelements_per_request(nrequests_total))
487 IF (nrequests_recv > 0)
THEN
488 CALL assign_nonzero_elements_to_requests(offset_per_request(1:nrequests_recv), &
489 nelements_per_request(1:nrequests_recv), &
490 peer_rank(1:nrequests_recv), &
491 request_tag(1:nrequests_recv), &
493 siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv), &
494 max_mpi_packet_size_dp)
496 IF (nrequests_total > nrequests_recv)
THEN
497 CALL assign_nonzero_elements_to_requests(offset_per_request(nrequests_recv + 1:nrequests_total), &
498 nelements_per_request(nrequests_recv + 1:nrequests_total), &
499 peer_rank(nrequests_recv + 1:nrequests_total), &
500 request_tag(nrequests_recv + 1:nrequests_total), &
502 siesta_struct%nelements_per_proc(:, nelements_dbcsr_send), &
503 max_mpi_packet_size_dp)
513 IF (n_nonzero_elements_siesta > 0)
THEN
514 ALLOCATE (recv_buffer(n_nonzero_elements_siesta))
516 DO irequest = 1, nrequests_recv
517 CALL para_env%irecv(recv_buffer(offset_per_request(irequest) + 1: &
518 offset_per_request(irequest) + nelements_per_request(irequest)), &
519 peer_rank(irequest), requests(irequest), request_tag(irequest))
523 ALLOCATE (offset_per_proc(0:nprocs - 1), n_packed_elements_per_proc(0:nprocs - 1))
524 offset_per_proc(0) = 0
525 DO iproc = 1, nprocs - 1
526 offset_per_proc(iproc) = offset_per_proc(iproc - 1) + siesta_struct%nelements_per_proc(iproc - 1, nelements_dbcsr_send)
528 n_packed_elements_per_proc(:) = 0
531 nnodes_proc = siesta_struct%nnodes_per_proc(mepos)
533 node_offset = sum(siesta_struct%nnodes_per_proc(0:mepos)) - nnodes_proc
537 iproc = siesta_struct%gather_root
539 IF (n_nonzero_elements_dbcsr > 0)
THEN
540 ALLOCATE (send_buffer(n_nonzero_elements_dbcsr))
541 send_buffer(:) = 0.0_dp
546 DO inode_proc = 1, nnodes_proc
547 n_image_ind = siesta_struct%n_dbcsr_cell_images_to_merge(inode_proc)
548 IF (n_image_ind > 0)
THEN
549 inode = node_offset + inode_proc
551 irow_blk = siesta_struct%nl_repl(neighbor_list_iatom_index, inode)
552 icol_blk = siesta_struct%nl_repl(neighbor_list_jatom_index, inode)
553 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
554 image_siesta = siesta_struct%nl_repl(neighbor_list_siesta_image_index, inode)
555 image_siesta_transp = siesta_struct%nl_repl(neighbor_list_siesta_transp_image_index, inode)
557 nrows_local = row_blk_size(irow_blk)
558 ncols_local = col_blk_size(icol_blk)
559 first_row_minus_one = row_blk_offset(irow_blk) - 1
560 first_col_minus_one = col_blk_offset(icol_blk) - 1
563 IF (n_image_ind == 1)
THEN
565 image_dbcsr = siesta_struct%dbcsr_cell_image_to_merge(image_ind_offset + 1)
567 row=irow_blk, col=icol_blk, block=sm_block_merged, found=found)
570 ALLOCATE (sm_block_merged(nrows_local, ncols_local))
572 DO image_ind = 1, n_image_ind
573 image_dbcsr = siesta_struct%dbcsr_cell_image_to_merge(image_ind + image_ind_offset)
576 row=irow_blk, col=icol_blk, block=sm_block, found=found)
578 sm_block_merged(1:nrows_local, 1:ncols_local) = sm_block_merged(1:nrows_local, 1:ncols_local) + &
579 sm_block(1:nrows_local, 1:ncols_local)
584 IF (image_siesta > 0)
THEN
585 DO irow_local = 1, nrows_local
586 IF (do_distribute)
THEN
587#if defined(__SMEAGOL)
588 CALL whichnodeorb(irow_local + first_row_minus_one, nprocs, iproc)
590 CALL cp_abort(__location__, &
591 "CP2K was compiled with no SMEAGOL support.")
596 IF (debug_this_module)
THEN
597 cpassert(iproc >= 0 .AND. iproc < nprocs)
598 IF (n_packed_elements_per_proc(iproc) + ncols_local > &
599 siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
600 CALL cp__a(__short_file__, __line__)
604 offset_send_mepos = offset_per_proc(iproc) + n_packed_elements_per_proc(iproc)
605 send_buffer(offset_send_mepos + 1:offset_send_mepos + ncols_local) = sm_block_merged(irow_local, 1:ncols_local)
607 n_packed_elements_per_proc(iproc) = n_packed_elements_per_proc(iproc) + ncols_local
612 IF (image_siesta_transp > 0)
THEN
613 DO icol_local = 1, ncols_local
614 IF (do_distribute)
THEN
615#if defined(__SMEAGOL)
616 CALL whichnodeorb(icol_local + first_col_minus_one, nprocs, iproc)
618 CALL cp_abort(__location__, &
619 "CP2K was compiled with no SMEAGOL support.")
624 IF (debug_this_module)
THEN
625 cpassert(iproc >= 0 .AND. iproc < nprocs)
626 IF (n_packed_elements_per_proc(iproc) + nrows_local > &
627 siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
628 CALL cp__a(__short_file__, __line__)
632 offset_send_mepos = offset_per_proc(iproc) + n_packed_elements_per_proc(iproc)
633 send_buffer(offset_send_mepos + 1:offset_send_mepos + nrows_local) = sm_block_merged(1:nrows_local, icol_local)
635 n_packed_elements_per_proc(iproc) = n_packed_elements_per_proc(iproc) + nrows_local
639 IF (n_image_ind > 1)
THEN
640 DEALLOCATE (sm_block_merged)
644 image_ind_offset = image_ind_offset + siesta_struct%n_dbcsr_cell_images_to_merge(inode_proc)
647 IF (debug_this_module)
THEN
648 DO iproc = 0, nprocs - 1
649 IF (n_packed_elements_per_proc(iproc) /= siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
650 CALL cp__a(__short_file__, __line__)
656 DO irequest = nrequests_recv + 1, nrequests_total
657 CALL para_env%isend(send_buffer(offset_per_request(irequest) + 1: &
658 offset_per_request(irequest) + nelements_per_request(irequest)), &
659 peer_rank(irequest), requests(irequest), request_tag(irequest))
664 offset_recv_mepos = sum(siesta_struct%nelements_per_proc(0:mepos - 1, nelements_dbcsr_recv))
666 offset_recv_mepos = 0
668 offset_send_mepos = offset_per_proc(mepos)
670 IF (debug_this_module)
THEN
671 IF (n_packed_elements_per_proc(mepos) /= siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_recv))
THEN
672 CALL cp__a(__short_file__, __line__)
676 IF (n_packed_elements_per_proc(mepos) > 0)
THEN
677 recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + n_packed_elements_per_proc(mepos)) = &
678 send_buffer(offset_send_mepos + 1:offset_send_mepos + n_packed_elements_per_proc(mepos))
682 IF (nrequests_total > 0)
THEN
685 DEALLOCATE (nelements_per_request, offset_per_request, peer_rank, requests, request_tag)
689 IF (
ALLOCATED(send_buffer))
DEALLOCATE (send_buffer)
690 DEALLOCATE (offset_per_proc, n_packed_elements_per_proc)
699 IF (n_nonzero_elements_siesta > 0)
THEN
700 ALLOCATE (reorder_recv_buffer(n_nonzero_elements_siesta))
701 ALLOCATE (next_nonzero_element_offset(siesta_struct%nrows))
702 next_nonzero_element_offset(:) = 0
703 offset_recv_mepos = 0
705 DO inode = 1,
SIZE(siesta_struct%nl_repl, 2)
706 irow_blk = siesta_struct%nl_repl(neighbor_list_iatom_index, inode)
707 icol_blk = siesta_struct%nl_repl(neighbor_list_jatom_index, inode)
708 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
709 image_siesta = siesta_struct%nl_repl(neighbor_list_siesta_image_index, inode)
710 image_siesta_transp = siesta_struct%nl_repl(neighbor_list_siesta_transp_image_index, inode)
712 nrows_local = row_blk_size(irow_blk)
713 ncols_local = col_blk_size(icol_blk)
714 first_row_minus_one = row_blk_offset(irow_blk) - 1
715 first_col_minus_one = col_blk_offset(icol_blk) - 1
718 IF (image_siesta > 0)
THEN
719 DO irow_local = 1, nrows_local
720 IF (do_distribute)
THEN
721#if defined(__SMEAGOL)
722 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
724 CALL cp_abort(__location__, &
725 "CP2K was compiled with no SMEAGOL support.")
728 IF (is_root_rank)
THEN
729 irow_proc = irow_local + first_row_minus_one
734 IF (irow_proc > 0)
THEN
735 offset_send_mepos = siesta_struct%row_offset(irow_proc) + next_nonzero_element_offset(irow_proc)
736 reorder_recv_buffer(offset_send_mepos + 1:offset_send_mepos + ncols_local) = &
737 recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + ncols_local)
738 offset_recv_mepos = offset_recv_mepos + ncols_local
739 next_nonzero_element_offset(irow_proc) = next_nonzero_element_offset(irow_proc) + ncols_local
745 IF (image_siesta_transp > 0)
THEN
746 DO icol_local = 1, ncols_local
747 IF (do_distribute)
THEN
748#if defined(__SMEAGOL)
749 CALL globaltolocalorb(icol_local + first_col_minus_one, mepos, nprocs, irow_proc)
751 CALL cp_abort(__location__, &
752 "CP2K was compiled with no SMEAGOL support.")
755 IF (is_root_rank)
THEN
756 irow_proc = icol_local + first_col_minus_one
761 IF (irow_proc > 0)
THEN
762 offset_send_mepos = siesta_struct%row_offset(irow_proc) + next_nonzero_element_offset(irow_proc)
763 reorder_recv_buffer(offset_send_mepos + 1:offset_send_mepos + nrows_local) = &
764 recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + nrows_local)
765 offset_recv_mepos = offset_recv_mepos + nrows_local
766 next_nonzero_element_offset(irow_proc) = next_nonzero_element_offset(irow_proc) + nrows_local
772 IF (debug_this_module)
THEN
773 DO irow_local = 1, siesta_struct%nrows
774 IF (siesta_struct%n_nonzero_cols(irow_local) /= next_nonzero_element_offset(irow_local))
THEN
775 CALL cp__a(__short_file__, __line__)
780 DEALLOCATE (next_nonzero_element_offset)
781 DEALLOCATE (recv_buffer)
784 DO irow_local = 1, siesta_struct%nrows
785 offset_recv_mepos = siesta_struct%row_offset(irow_local)
786 DO icol_local = 1, siesta_struct%n_nonzero_cols(irow_local)
787 matrix_siesta(offset_recv_mepos + icol_local) = &
788 reorder_recv_buffer(offset_recv_mepos + siesta_struct%packed_index(offset_recv_mepos + icol_local))
791 DEALLOCATE (reorder_recv_buffer)
794 CALL timestop(handle)
806 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(in) :: matrix_dbcsr_kp
807 REAL(kind=
dp),
DIMENSION(:),
INTENT(in) :: matrix_siesta
811 CHARACTER(len=*),
PARAMETER :: routinen =
'convert_distributed_siesta_to_dbcsr'
813 INTEGER :: first_col_minus_one, first_row_minus_one, handle, icol_blk, icol_local, &
814 image_dbcsr, image_siesta, image_siesta_transp, inode, inode_proc, iproc, irequest, &
815 irow_blk, irow_local, irow_proc, mepos, n_image_ind, ncols_blk, ncols_local, nnodes_proc, &
816 node_offset, nprocs, nrequests_recv, nrequests_total, nrows_blk, nrows_local
817 INTEGER(kind=int_8) :: n_nonzero_elements_dbcsr, &
818 n_nonzero_elements_siesta, &
819 offset_recv_mepos, offset_send_mepos
820 INTEGER(kind=int_8),
ALLOCATABLE,
DIMENSION(:) :: n_packed_elements_per_proc, &
821 nelements_per_request, &
822 offset_per_proc, offset_per_request
823 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: next_nonzero_element_offset, peer_rank, &
825 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, &
826 row_blk_offset, row_blk_size
827 LOGICAL :: do_distribute, found, is_root_rank, &
829 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_buffer, reorder_send_buffer, &
831 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: sm_block
834 CALL timeset(routinen, handle)
835 DO image_dbcsr = 1,
SIZE(matrix_dbcsr_kp)
836 CALL dbcsr_set(matrix_dbcsr_kp(image_dbcsr)%matrix, 0.0_dp)
839 mepos = para_env%mepos
840 nprocs = para_env%num_pe
841 do_distribute = siesta_struct%gather_root < 0
842 is_root_rank = siesta_struct%gather_root == mepos
845 nblkrows_total=nrows_blk, nblkcols_total=ncols_blk, &
846 row_blk_size=row_blk_size, col_blk_size=col_blk_size, &
847 row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
848 symmetric = siesta_struct%symmetric
850 n_nonzero_elements_siesta = sum(siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv))
851 n_nonzero_elements_dbcsr = sum(siesta_struct%nelements_per_proc(:, nelements_dbcsr_send))
853 nrequests_recv = get_number_of_mpi_sendrecv_requests(mepos, siesta_struct%nelements_per_proc(:, nelements_dbcsr_send), &
854 max_mpi_packet_size_dp)
855 nrequests_total = get_number_of_mpi_sendrecv_requests(mepos, siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv), &
856 max_mpi_packet_size_dp) + nrequests_recv
857 IF (nrequests_total > 0)
THEN
858 ALLOCATE (requests(nrequests_total))
859 ALLOCATE (peer_rank(nrequests_total), request_tag(nrequests_total))
860 ALLOCATE (offset_per_request(nrequests_total), nelements_per_request(nrequests_total))
862 IF (nrequests_recv > 0)
THEN
863 CALL assign_nonzero_elements_to_requests(offset_per_request(1:nrequests_recv), &
864 nelements_per_request(1:nrequests_recv), &
865 peer_rank(1:nrequests_recv), &
866 request_tag(1:nrequests_recv), &
868 siesta_struct%nelements_per_proc(:, nelements_dbcsr_send), &
869 max_mpi_packet_size_dp)
871 IF (nrequests_total > nrequests_recv)
THEN
872 CALL assign_nonzero_elements_to_requests(offset_per_request(nrequests_recv + 1:nrequests_total), &
873 nelements_per_request(nrequests_recv + 1:nrequests_total), &
874 peer_rank(nrequests_recv + 1:nrequests_total), &
875 request_tag(nrequests_recv + 1:nrequests_total), &
877 siesta_struct%nelements_per_proc(:, nelements_dbcsr_recv), &
878 max_mpi_packet_size_dp)
882 IF (n_nonzero_elements_dbcsr > 0)
THEN
883 ALLOCATE (recv_buffer(n_nonzero_elements_dbcsr))
885 DO irequest = 1, nrequests_recv
886 CALL para_env%irecv(recv_buffer(offset_per_request(irequest) + 1: &
887 offset_per_request(irequest) + nelements_per_request(irequest)), &
888 peer_rank(irequest), requests(irequest), request_tag(irequest))
891 ALLOCATE (offset_per_proc(0:nprocs - 1), n_packed_elements_per_proc(0:nprocs - 1))
892 offset_per_proc(0) = 0
893 DO iproc = 1, nprocs - 1
894 offset_per_proc(iproc) = offset_per_proc(iproc - 1) + siesta_struct%nelements_per_proc(iproc - 1, nelements_dbcsr_send)
896 n_packed_elements_per_proc(:) = 0
899 node_offset = sum(siesta_struct%nnodes_per_proc(0:mepos - 1))
903 nnodes_proc = siesta_struct%nnodes_per_proc(mepos)
905 IF (n_nonzero_elements_siesta > 0)
THEN
906 ALLOCATE (send_buffer(n_nonzero_elements_siesta))
908 ALLOCATE (reorder_send_buffer(n_nonzero_elements_siesta))
909 DO irow_local = 1, siesta_struct%nrows
910 offset_send_mepos = siesta_struct%row_offset(irow_local)
911 DO icol_local = 1, siesta_struct%n_nonzero_cols(irow_local)
912 reorder_send_buffer(offset_send_mepos + siesta_struct%packed_index(offset_send_mepos + icol_local)) = &
913 matrix_siesta(offset_send_mepos + icol_local)
917 ALLOCATE (next_nonzero_element_offset(siesta_struct%nrows))
918 next_nonzero_element_offset(:) = 0
919 offset_send_mepos = 0
921 DO inode = 1,
SIZE(siesta_struct%nl_repl, 2)
922 irow_blk = siesta_struct%nl_repl(neighbor_list_iatom_index, inode)
923 icol_blk = siesta_struct%nl_repl(neighbor_list_jatom_index, inode)
924 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
925 image_siesta = siesta_struct%nl_repl(neighbor_list_siesta_image_index, inode)
926 image_siesta_transp = siesta_struct%nl_repl(neighbor_list_siesta_transp_image_index, inode)
928 nrows_local = row_blk_size(irow_blk)
929 ncols_local = col_blk_size(icol_blk)
930 first_row_minus_one = row_blk_offset(irow_blk) - 1
931 first_col_minus_one = col_blk_offset(icol_blk) - 1
933 IF (image_siesta > 0)
THEN
934 DO irow_local = 1, nrows_local
935 IF (do_distribute)
THEN
936#if defined(__SMEAGOL)
937 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
939 CALL cp_abort(__location__, &
940 "CP2K was compiled with no SMEAGOL support.")
943 IF (is_root_rank)
THEN
944 irow_proc = irow_local + first_row_minus_one
949 IF (irow_proc > 0)
THEN
950 offset_recv_mepos = siesta_struct%row_offset(irow_proc) + next_nonzero_element_offset(irow_proc)
951 send_buffer(offset_send_mepos + 1:offset_send_mepos + ncols_local) = &
952 reorder_send_buffer(offset_recv_mepos + 1:offset_recv_mepos + ncols_local)
953 offset_send_mepos = offset_send_mepos + ncols_local
954 next_nonzero_element_offset(irow_proc) = next_nonzero_element_offset(irow_proc) + ncols_local
960 IF (image_siesta_transp > 0)
THEN
961 DO icol_local = 1, ncols_local
962 IF (do_distribute)
THEN
963#if defined(__SMEAGOL)
964 CALL globaltolocalorb(icol_local + first_col_minus_one, mepos, nprocs, irow_proc)
966 CALL cp_abort(__location__, &
967 "CP2K was compiled with no SMEAGOL support.")
970 IF (is_root_rank)
THEN
971 irow_proc = icol_local + first_col_minus_one
976 IF (irow_proc > 0)
THEN
977 offset_recv_mepos = siesta_struct%row_offset(irow_proc) + next_nonzero_element_offset(irow_proc)
978 send_buffer(offset_send_mepos + 1:offset_send_mepos + nrows_local) = &
979 reorder_send_buffer(offset_recv_mepos + 1:offset_recv_mepos + nrows_local)
980 offset_send_mepos = offset_send_mepos + nrows_local
981 next_nonzero_element_offset(irow_proc) = next_nonzero_element_offset(irow_proc) + nrows_local
987 IF (debug_this_module)
THEN
988 DO irow_local = 1, siesta_struct%nrows
989 IF (siesta_struct%n_nonzero_cols(irow_local) /= next_nonzero_element_offset(irow_local))
THEN
990 CALL cp__a(__short_file__, __line__)
995 DEALLOCATE (next_nonzero_element_offset)
996 DEALLOCATE (reorder_send_buffer)
998 DO irequest = nrequests_recv + 1, nrequests_total
999 CALL para_env%isend(send_buffer(offset_per_request(irequest) + 1: &
1000 offset_per_request(irequest) + nelements_per_request(irequest)), &
1001 peer_rank(irequest), requests(irequest), request_tag(irequest))
1006 offset_send_mepos = sum(siesta_struct%nelements_per_proc(0:mepos - 1, nelements_dbcsr_recv))
1008 offset_send_mepos = 0
1010 offset_recv_mepos = offset_per_proc(mepos)
1012 IF (debug_this_module)
THEN
1013 IF (siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_recv) /= &
1014 siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_send))
THEN
1015 CALL cp__a(__short_file__, __line__)
1019 IF (siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_send) > 0)
THEN
1020 recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_send)) = &
1021 send_buffer(offset_send_mepos + 1:offset_send_mepos + siesta_struct%nelements_per_proc(mepos, nelements_dbcsr_send))
1025 IF (nrequests_total > 0)
THEN
1028 DEALLOCATE (nelements_per_request, offset_per_request, peer_rank, requests, request_tag)
1031 IF (
ALLOCATED(send_buffer))
DEALLOCATE (send_buffer)
1034 iproc = siesta_struct%gather_root
1035 IF (n_nonzero_elements_dbcsr > 0)
THEN
1036 DO inode_proc = 1, nnodes_proc
1037 n_image_ind = siesta_struct%n_dbcsr_cell_images_to_merge(inode_proc)
1038 IF (n_image_ind > 0)
THEN
1039 inode = node_offset + inode_proc
1041 irow_blk = siesta_struct%nl_repl(neighbor_list_iatom_index, inode)
1042 icol_blk = siesta_struct%nl_repl(neighbor_list_jatom_index, inode)
1043 image_dbcsr = siesta_struct%nl_repl(neighbor_list_dbcsr_image_index, inode)
1044 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
1045 image_siesta = siesta_struct%nl_repl(neighbor_list_siesta_image_index, inode)
1046 image_siesta_transp = siesta_struct%nl_repl(neighbor_list_siesta_transp_image_index, inode)
1048 nrows_local = row_blk_size(irow_blk)
1049 ncols_local = col_blk_size(icol_blk)
1050 first_row_minus_one = row_blk_offset(irow_blk) - 1
1051 first_col_minus_one = col_blk_offset(icol_blk) - 1
1054 row=irow_blk, col=icol_blk, block=sm_block, found=found)
1057 IF (image_siesta > 0)
THEN
1058 DO irow_local = 1, nrows_local
1059 IF (do_distribute)
THEN
1060#if defined(__SMEAGOL)
1061 CALL whichnodeorb(irow_local + first_row_minus_one, nprocs, iproc)
1063 CALL cp_abort(__location__, &
1064 "CP2K was compiled with no SMEAGOL support.")
1068 IF (debug_this_module)
THEN
1069 cpassert(iproc >= 0 .AND. iproc < nprocs)
1070 IF (n_packed_elements_per_proc(iproc) + ncols_local > &
1071 siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
1072 CALL cp__a(__short_file__, __line__)
1076 offset_recv_mepos = offset_per_proc(iproc) + n_packed_elements_per_proc(iproc)
1077 sm_block(irow_local, 1:ncols_local) = recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + ncols_local)
1079 n_packed_elements_per_proc(iproc) = n_packed_elements_per_proc(iproc) + ncols_local
1084 IF (image_siesta_transp > 0)
THEN
1085 DO icol_local = 1, ncols_local
1086 IF (do_distribute)
THEN
1087#if defined(__SMEAGOL)
1088 CALL whichnodeorb(icol_local + first_col_minus_one, nprocs, iproc)
1090 CALL cp_abort(__location__, &
1091 "CP2K was compiled with no SMEAGOL support.")
1095 IF (debug_this_module)
THEN
1096 cpassert(iproc >= 0 .AND. iproc < nprocs)
1097 IF (n_packed_elements_per_proc(iproc) + nrows_local > &
1098 siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
1099 CALL cp__a(__short_file__, __line__)
1103 offset_recv_mepos = offset_per_proc(iproc) + n_packed_elements_per_proc(iproc)
1104 sm_block(1:nrows_local, icol_local) = recv_buffer(offset_recv_mepos + 1:offset_recv_mepos + nrows_local)
1106 n_packed_elements_per_proc(iproc) = n_packed_elements_per_proc(iproc) + nrows_local
1112 IF (debug_this_module)
THEN
1113 DO iproc = 0, nprocs - 1
1114 IF (n_packed_elements_per_proc(iproc) /= siesta_struct%nelements_per_proc(iproc, nelements_dbcsr_send))
THEN
1115 CALL cp__a(__short_file__, __line__)
1120 DEALLOCATE (recv_buffer)
1123 DEALLOCATE (offset_per_proc, n_packed_elements_per_proc)
1125 CALL timestop(handle)
1141 SUBROUTINE get_nnodes_local(nnodes_local, max_ijk_cell_image_local, max_ijk_cell_image, sab_nl, para_env, particle_coords, cell)
1142 INTEGER,
INTENT(out) :: nnodes_local
1143 INTEGER,
DIMENSION(3),
INTENT(out) :: max_ijk_cell_image_local
1144 INTEGER,
DIMENSION(3),
INTENT(inout) :: max_ijk_cell_image
1146 INTENT(in),
POINTER :: sab_nl
1148 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1149 INTENT(in) :: particle_coords
1150 TYPE(
cell_type),
INTENT(in),
POINTER :: cell
1152 CHARACTER(len=*),
PARAMETER :: routinen =
'get_nnodes_local'
1154 INTEGER :: handle, iatom, icoord, jatom
1155 INTEGER,
DIMENSION(3) :: cell_ijk, max_ijk_cell_image_tmp
1156 LOGICAL :: update_ncells
1157 REAL(kind=
dp),
DIMENSION(3) :: r_ij
1159 DIMENSION(:),
POINTER :: nl_iterator
1161 CALL timeset(routinen, handle)
1163 update_ncells = .false.
1165 IF (max_ijk_cell_image(icoord) >= 0)
THEN
1166 max_ijk_cell_image_tmp(icoord) = max_ijk_cell_image(icoord)
1168 max_ijk_cell_image_tmp(icoord) = huge(max_ijk_cell_image_tmp(icoord))
1169 update_ncells = .true.
1174 max_ijk_cell_image_local(:) = 0
1179 CALL get_negf_cell_ijk(cell_ijk, r_ij, r_i=particle_coords(1:3, iatom), r_j=particle_coords(1:3, jatom), cell=cell)
1180 cell_ijk(1:3) = abs(cell_ijk(1:3))
1182 IF (cell_ijk(1) <= max_ijk_cell_image_tmp(1) .AND. cell_ijk(2) <= max_ijk_cell_image_tmp(2) .AND. &
1183 cell_ijk(3) <= max_ijk_cell_image_tmp(3))
THEN
1184 nnodes_local = nnodes_local + 1
1185 max_ijk_cell_image_local(1:3) = max(max_ijk_cell_image_local(1:3), cell_ijk(1:3))
1190 IF (update_ncells)
THEN
1191 max_ijk_cell_image_tmp(1:3) = max_ijk_cell_image_local(1:3)
1192 CALL para_env%max(max_ijk_cell_image_tmp)
1194 IF (max_ijk_cell_image(icoord) < 0)
THEN
1195 max_ijk_cell_image(icoord) = max_ijk_cell_image_tmp(icoord)
1200 CALL timestop(handle)
1201 END SUBROUTINE get_nnodes_local
1218 SUBROUTINE get_nl_nodes_local(nl_local, max_ijk_cell_image_local, max_ijk_cell_image, sab_nl, particle_coords, &
1219 cell, cell_to_index, do_merge, node_merged_indices, k_cells)
1220 INTEGER,
DIMENSION(:, :),
INTENT(out) :: nl_local
1221 INTEGER,
DIMENSION(3),
INTENT(in) :: max_ijk_cell_image_local, &
1224 INTENT(in),
POINTER :: sab_nl
1225 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1226 INTENT(in) :: particle_coords
1227 TYPE(
cell_type),
INTENT(in),
POINTER :: cell
1228 INTEGER,
DIMENSION(:, :, :),
INTENT(in),
POINTER :: cell_to_index
1229 LOGICAL,
INTENT(in) :: do_merge
1230 INTEGER(kind=int_8),
DIMENSION(:),
INTENT(out) :: node_merged_indices
1231 INTEGER,
DIMENSION(:),
INTENT(out) :: k_cells
1233 CHARACTER(len=*),
PARAMETER :: routinen =
'get_nl_nodes_local'
1235 INTEGER :: handle, iatom, icol_blk, image, inode, &
1236 irow_blk, jatom, natoms
1237 INTEGER(kind=8),
DIMENSION(2) :: ncells_siesta_local
1238 INTEGER,
DIMENSION(2) :: ncells_siesta
1239 INTEGER,
DIMENSION(3) :: cell_ijk_abs, cell_ijk_dbcsr, &
1241 LOGICAL :: do_symmetric
1242 REAL(kind=
dp),
DIMENSION(3) :: r_ij
1244 DIMENSION(:),
POINTER :: nl_iterator
1246 CALL timeset(routinen, handle)
1248 natoms =
SIZE(particle_coords, 2)
1250 ncells_siesta(1:2) = 2*max_ijk_cell_image(1:2) + 1
1252 ncells_siesta_local(1:2) = int(2*max_ijk_cell_image_local(1:2) + 1, kind=
int_8)
1257 CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell_ijk_dbcsr, r=r_ij)
1258 CALL get_negf_cell_ijk(cell_ijk_abs, r_ij, r_i=particle_coords(1:3, iatom), r_j=particle_coords(1:3, jatom), cell=cell)
1260 IF (abs(cell_ijk_abs(1)) <= max_ijk_cell_image(1) .AND. abs(cell_ijk_abs(2)) <= max_ijk_cell_image(2) .AND. &
1261 abs(cell_ijk_abs(3)) <= max_ijk_cell_image(3))
THEN
1267 nl_local(neighbor_list_dbcsr_image_index, inode) = image
1269 IF (do_symmetric .AND. iatom > jatom)
THEN
1272 cell_ijk_abs(1:3) = -cell_ijk_abs(1:3)
1278 nl_local(neighbor_list_iatom_index, inode) = irow_blk
1279 nl_local(neighbor_list_jatom_index, inode) = icol_blk
1281 cell_ijk_siesta(1:3) = index_in_canonical_enumeration(cell_ijk_abs(1:3))
1284 node_merged_indices(inode) = (((cell_ijk_siesta(2) - 1)*ncells_siesta_local(1) + cell_ijk_siesta(1) - 1)* &
1285 int(natoms, kind=
int_8) + icol_blk - 1)*int(natoms, kind=
int_8) + int(irow_blk - 1, kind=
int_8)
1286 image = cell_ijk_siesta(1) + ncells_siesta(1)*(cell_ijk_siesta(2) - 1)
1288 node_merged_indices(inode) = ((((cell_ijk_siesta(3) - 1)*ncells_siesta_local(2) + &
1289 cell_ijk_siesta(2) - 1)*ncells_siesta_local(1) + cell_ijk_siesta(1) - 1)* &
1290 int(natoms, kind=
int_8) + icol_blk - 1)*int(natoms, kind=
int_8) + int(irow_blk - 1, kind=
int_8)
1291 image = cell_ijk_siesta(1) + ncells_siesta(1)*(cell_ijk_siesta(2) - 1 + ncells_siesta(2)*(cell_ijk_siesta(3) - 1))
1293 k_cells(inode) = cell_ijk_siesta(3)
1294 nl_local(neighbor_list_siesta_image_index, inode) = image
1296 IF (do_symmetric .AND. irow_blk /= icol_blk)
THEN
1297 cell_ijk_abs(1:3) = -cell_ijk_abs(1:3)
1298 cell_ijk_siesta(1:3) = index_in_canonical_enumeration(cell_ijk_abs(1:3))
1299 IF (do_merge) cell_ijk_siesta(3) = 1
1300 nl_local(neighbor_list_siesta_transp_image_index, inode) = &
1301 cell_ijk_siesta(1) + ncells_siesta(1)*(cell_ijk_siesta(2) - 1 + ncells_siesta(2)*(cell_ijk_siesta(3) - 1))
1303 nl_local(neighbor_list_siesta_transp_image_index, inode) = 0
1309 IF (debug_this_module)
THEN
1310 cpassert(
SIZE(nl_local, 2) == inode)
1313 CALL timestop(handle)
1314 END SUBROUTINE get_nl_nodes_local
1330 SUBROUTINE replicate_neighbour_list(repl_nl, n_dbcsr_cell_images_to_merge, dbcsr_cell_image_to_merge, &
1331 nnodes_per_proc, max_ijk_cell_image, sab_nl, para_env, particle_coords, &
1332 cell, cell_to_index, do_merge)
1333 INTEGER,
ALLOCATABLE,
DIMENSION(:, :), &
1334 INTENT(inout) :: repl_nl
1335 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(inout) :: n_dbcsr_cell_images_to_merge, &
1336 dbcsr_cell_image_to_merge
1337 INTEGER,
DIMENSION(0:),
INTENT(out) :: nnodes_per_proc
1338 INTEGER,
DIMENSION(3),
INTENT(inout) :: max_ijk_cell_image
1340 INTENT(in),
POINTER :: sab_nl
1342 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1343 INTENT(in) :: particle_coords
1344 TYPE(
cell_type),
INTENT(in),
POINTER :: cell
1345 INTEGER,
DIMENSION(:, :, :),
INTENT(in),
POINTER :: cell_to_index
1346 LOGICAL,
INTENT(in) :: do_merge
1348 CHARACTER(len=*),
PARAMETER :: routinen =
'replicate_neighbour_list'
1350 INTEGER :: handle, inode, iproc, kcell_closest, &
1351 nnodes_local, nnodes_merged, &
1352 nnodes_repl, offset_inode
1353 INTEGER(kind=int_8),
ALLOCATABLE,
DIMENSION(:) :: node_merged_indices
1354 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: inodes_orig, k_cells
1355 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: nl_local
1356 INTEGER,
DIMENSION(3) :: max_ijk_cell_image_local
1358 CALL timeset(routinen, handle)
1359 cpassert(.NOT.
ALLOCATED(repl_nl))
1360 cpassert(.NOT.
ALLOCATED(n_dbcsr_cell_images_to_merge))
1361 cpassert(.NOT.
ALLOCATED(dbcsr_cell_image_to_merge))
1363 CALL get_nnodes_local(nnodes_local, max_ijk_cell_image_local, max_ijk_cell_image, sab_nl, para_env, particle_coords, cell)
1365 nnodes_per_proc(:) = 0
1367 IF (nnodes_local > 0)
THEN
1368 ALLOCATE (nl_local(neighbor_list_dim1, nnodes_local))
1369 ALLOCATE (node_merged_indices(nnodes_local))
1370 ALLOCATE (k_cells(nnodes_local))
1371 CALL get_nl_nodes_local(nl_local, max_ijk_cell_image_local, max_ijk_cell_image, sab_nl, particle_coords, cell, &
1372 cell_to_index, do_merge, node_merged_indices, k_cells)
1374 ALLOCATE (inodes_orig(nnodes_local))
1375 CALL sort(node_merged_indices, nnodes_local, inodes_orig)
1378 DO inode = 2, nnodes_local
1379 IF (node_merged_indices(inode) > node_merged_indices(inode - 1)) nnodes_merged = nnodes_merged + 1
1385 nnodes_per_proc(para_env%mepos) = nnodes_merged
1386 CALL para_env%sum(nnodes_per_proc)
1388 nnodes_repl = sum(nnodes_per_proc(:))
1389 ALLOCATE (repl_nl(neighbor_list_dim1, nnodes_repl))
1391 IF (nnodes_local > 0)
THEN
1392 IF (para_env%mepos > 0)
THEN
1393 offset_inode = sum(nnodes_per_proc(0:para_env%mepos - 1))
1398 ALLOCATE (n_dbcsr_cell_images_to_merge(nnodes_merged))
1399 ALLOCATE (dbcsr_cell_image_to_merge(nnodes_local))
1400 n_dbcsr_cell_images_to_merge(:) = 0
1403 repl_nl(:, offset_inode + 1) = nl_local(:, inodes_orig(1))
1404 n_dbcsr_cell_images_to_merge(1) = 1
1405 dbcsr_cell_image_to_merge(1) = nl_local(neighbor_list_dbcsr_image_index, inodes_orig(1))
1406 kcell_closest = k_cells(inodes_orig(1))
1407 DO inode = 2, nnodes_local
1408 IF (node_merged_indices(inode) > node_merged_indices(inode - 1))
THEN
1409 nnodes_merged = nnodes_merged + 1
1410 repl_nl(:, offset_inode + nnodes_merged) = nl_local(:, inodes_orig(inode))
1412 kcell_closest = k_cells(inodes_orig(inode))
1414 IF (abs(k_cells(inodes_orig(inode))) < abs(kcell_closest) .OR. &
1415 (abs(k_cells(inodes_orig(inode))) == abs(kcell_closest) .AND. kcell_closest < 0))
THEN
1416 repl_nl(:, offset_inode + nnodes_merged) = nl_local(:, inodes_orig(inode))
1417 kcell_closest = k_cells(inodes_orig(inode))
1420 dbcsr_cell_image_to_merge(inode) = nl_local(neighbor_list_dbcsr_image_index, inodes_orig(inode))
1421 n_dbcsr_cell_images_to_merge(nnodes_merged) = n_dbcsr_cell_images_to_merge(nnodes_merged) + 1
1424 IF (debug_this_module)
THEN
1425 cpassert(sum(n_dbcsr_cell_images_to_merge) == nnodes_local)
1428 DEALLOCATE (inodes_orig)
1429 DEALLOCATE (node_merged_indices, k_cells)
1430 DEALLOCATE (nl_local)
1433 IF (para_env%num_pe > 1)
THEN
1435 DO iproc = 0, para_env%num_pe - 1
1436 IF (nnodes_per_proc(iproc) > 0)
THEN
1437 CALL para_env%bcast(repl_nl(:, offset_inode + 1:offset_inode + nnodes_per_proc(iproc)), iproc)
1438 offset_inode = offset_inode + nnodes_per_proc(iproc)
1443 CALL timestop(handle)
1444 END SUBROUTINE replicate_neighbour_list
1459 SUBROUTINE count_remote_dbcsr_elements(nelements_per_proc, nnodes_per_proc, nl_repl, matrix_dbcsr_kp, &
1460 symmetric, para_env, gather_root)
1461 INTEGER(kind=int_8),
DIMENSION(0:, :),
INTENT(out) :: nelements_per_proc
1462 INTEGER,
DIMENSION(0:),
INTENT(in) :: nnodes_per_proc
1463 INTEGER,
DIMENSION(:, :),
INTENT(in) :: nl_repl
1464 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(in) :: matrix_dbcsr_kp
1465 LOGICAL,
INTENT(in) :: symmetric
1467 INTEGER,
INTENT(in) :: gather_root
1469 CHARACTER(len=*),
PARAMETER :: routinen =
'count_remote_dbcsr_elements'
1471 INTEGER :: first_row_minus_one, handle, icol_blk, image, image_transp, inode, inode_proc, &
1472 iproc, iproc_orb, irow_blk, irow_local, mepos, ncols_blk, ncols_local, nnodes_proc, &
1473 nprocs, nrows_blk, nrows_local, offset_inode
1474 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, &
1475 row_blk_offset, row_blk_size
1476 LOGICAL :: do_distribute
1478 CALL timeset(routinen, handle)
1479 nelements_per_proc(:, :) = 0
1480 mepos = para_env%mepos
1481 nprocs = para_env%num_pe
1482 do_distribute = gather_root < 0
1483 IF (debug_this_module)
THEN
1484 cpassert(
SIZE(nnodes_per_proc) == nprocs)
1488 nblkrows_total=nrows_blk, nblkcols_total=ncols_blk, &
1489 row_blk_size=row_blk_size, col_blk_size=col_blk_size, &
1490 row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
1493 iproc_orb = gather_root
1494 DO iproc = lbound(nnodes_per_proc, 1), ubound(nnodes_per_proc, 1)
1495 nnodes_proc = nnodes_per_proc(iproc)
1496 DO inode_proc = 1, nnodes_proc
1497 inode = inode_proc + offset_inode
1499 irow_blk = nl_repl(neighbor_list_iatom_index, inode)
1500 icol_blk = nl_repl(neighbor_list_jatom_index, inode)
1501 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
1502 image = nl_repl(neighbor_list_siesta_image_index, inode)
1503 image_transp = nl_repl(neighbor_list_siesta_transp_image_index, inode)
1506 nrows_local = row_blk_size(irow_blk)
1507 first_row_minus_one = row_blk_offset(irow_blk) - 1
1508 ncols_local = col_blk_size(icol_blk)
1509 DO irow_local = 1, nrows_local
1510 IF (do_distribute)
THEN
1511#if defined(__SMEAGOL)
1512 CALL whichnodeorb(irow_local + first_row_minus_one, nprocs, iproc_orb)
1514 CALL cp_abort(__location__, &
1515 "CP2K was compiled with no SMEAGOL support.")
1518 IF (iproc_orb == mepos)
THEN
1519 nelements_per_proc(iproc, nelements_dbcsr_recv) = nelements_per_proc(iproc, nelements_dbcsr_recv) + &
1523 IF (iproc == mepos)
THEN
1524 nelements_per_proc(iproc_orb, nelements_dbcsr_send) = nelements_per_proc(iproc_orb, nelements_dbcsr_send) + &
1531 IF (image_transp > 0)
THEN
1532 nrows_local = col_blk_size(icol_blk)
1533 first_row_minus_one = col_blk_offset(icol_blk) - 1
1534 ncols_local = row_blk_size(irow_blk)
1535 DO irow_local = 1, nrows_local
1536 IF (do_distribute)
THEN
1537#if defined(__SMEAGOL)
1538 CALL whichnodeorb(irow_local + first_row_minus_one, nprocs, iproc_orb)
1540 CALL cp_abort(__location__, &
1541 "CP2K was compiled with no SMEAGOL support.")
1544 IF (iproc_orb == mepos)
THEN
1545 nelements_per_proc(iproc, nelements_dbcsr_recv) = nelements_per_proc(iproc, nelements_dbcsr_recv) + &
1549 IF (iproc == mepos)
THEN
1550 nelements_per_proc(iproc_orb, nelements_dbcsr_send) = nelements_per_proc(iproc_orb, nelements_dbcsr_send) + &
1556 offset_inode = offset_inode + nnodes_proc
1558 CALL timestop(handle)
1559 END SUBROUTINE count_remote_dbcsr_elements
1576 SUBROUTINE get_nonzero_element_indices(n_nonzero_cols, row_offset, col_index, packed_index, &
1577 nl_repl, matrix_dbcsr_kp, symmetric, para_env, gather_root)
1578 INTEGER,
DIMENSION(:),
INTENT(out) :: n_nonzero_cols, row_offset, col_index, &
1580 INTEGER,
DIMENSION(:, :),
INTENT(in) :: nl_repl
1581 TYPE(
dbcsr_p_type),
DIMENSION(:),
INTENT(in) :: matrix_dbcsr_kp
1582 LOGICAL,
INTENT(in) :: symmetric
1584 INTEGER,
INTENT(in) :: gather_root
1586 CHARACTER(len=*),
PARAMETER :: routinen =
'get_nonzero_element_indices'
1588 INTEGER :: first_col_minus_one, first_row_minus_one, handle, icol_blk, icol_local, &
1589 icol_offset, image, image_transp, inode, irow_blk, irow_local, irow_proc, mepos, &
1590 ncols_blk, ncols_local, ncols_total, nnodes, nprocs, nrows_blk, nrows_local, nrows_total
1591 INTEGER,
DIMENSION(:),
POINTER :: col_blk_offset, col_blk_size, &
1592 row_blk_offset, row_blk_size
1593 LOGICAL :: do_distribute, is_root_rank
1595 CALL timeset(routinen, handle)
1596 n_nonzero_cols(:) = 0
1597 mepos = para_env%mepos
1598 nprocs = para_env%num_pe
1599 do_distribute = gather_root < 0
1600 is_root_rank = gather_root == mepos
1603 nblkrows_total=nrows_blk, nblkcols_total=ncols_blk, &
1604 nfullrows_total=nrows_total, nfullcols_total=ncols_total, &
1605 row_blk_size=row_blk_size, col_blk_size=col_blk_size, &
1606 row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
1608 nnodes =
SIZE(nl_repl, 2)
1609 DO inode = 1, nnodes
1610 irow_blk = nl_repl(neighbor_list_iatom_index, inode)
1611 icol_blk = nl_repl(neighbor_list_jatom_index, inode)
1612 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
1613 image = nl_repl(neighbor_list_siesta_image_index, inode)
1614 image_transp = nl_repl(neighbor_list_siesta_transp_image_index, inode)
1617 nrows_local = row_blk_size(irow_blk)
1618 first_row_minus_one = row_blk_offset(irow_blk) - 1
1619 ncols_local = col_blk_size(icol_blk)
1620 DO irow_local = 1, nrows_local
1621 IF (do_distribute)
THEN
1622#if defined(__SMEAGOL)
1623 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
1625 CALL cp_abort(__location__, &
1626 "CP2K was compiled with no SMEAGOL support.")
1629 IF (is_root_rank)
THEN
1630 irow_proc = irow_local + first_row_minus_one
1635 IF (irow_proc > 0)
THEN
1636 n_nonzero_cols(irow_proc) = n_nonzero_cols(irow_proc) + ncols_local
1642 IF (image_transp > 0)
THEN
1643 nrows_local = col_blk_size(icol_blk)
1644 first_row_minus_one = col_blk_offset(icol_blk) - 1
1645 ncols_local = row_blk_size(irow_blk)
1646 DO irow_local = 1, nrows_local
1647 IF (do_distribute)
THEN
1648#if defined(__SMEAGOL)
1649 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
1651 CALL cp_abort(__location__, &
1652 "CP2K was compiled with no SMEAGOL support.")
1655 IF (is_root_rank)
THEN
1656 irow_proc = irow_local + first_row_minus_one
1661 IF (irow_proc > 0)
THEN
1662 n_nonzero_cols(irow_proc) = n_nonzero_cols(irow_proc) + ncols_local
1669 DO irow_local = 1,
SIZE(n_nonzero_cols) - 1
1670 row_offset(irow_local + 1) = row_offset(irow_local) + n_nonzero_cols(irow_local)
1673 n_nonzero_cols(:) = 0
1675 DO inode = 1, nnodes
1676 irow_blk = nl_repl(neighbor_list_iatom_index, inode)
1677 icol_blk = nl_repl(neighbor_list_jatom_index, inode)
1678 cpassert(irow_blk <= icol_blk .OR. (.NOT. symmetric))
1679 image = nl_repl(neighbor_list_siesta_image_index, inode)
1680 image_transp = nl_repl(neighbor_list_siesta_transp_image_index, inode)
1683 nrows_local = row_blk_size(irow_blk)
1684 first_row_minus_one = row_blk_offset(irow_blk) - 1
1685 ncols_local = col_blk_size(icol_blk)
1686 first_col_minus_one = col_blk_offset(icol_blk) + (image - 1)*ncols_total - 1
1687 DO irow_local = 1, nrows_local
1688 IF (do_distribute)
THEN
1689#if defined(__SMEAGOL)
1690 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
1692 CALL cp_abort(__location__, &
1693 "CP2K was compiled with no SMEAGOL support.")
1696 IF (is_root_rank)
THEN
1697 irow_proc = irow_local + first_row_minus_one
1702 IF (irow_proc > 0)
THEN
1703 icol_offset = row_offset(irow_proc) + n_nonzero_cols(irow_proc)
1704 DO icol_local = 1, ncols_local
1705 col_index(icol_offset + icol_local) = first_col_minus_one + icol_local
1707 n_nonzero_cols(irow_proc) = n_nonzero_cols(irow_proc) + ncols_local
1713 IF (image_transp > 0)
THEN
1714 nrows_local = col_blk_size(icol_blk)
1715 first_row_minus_one = col_blk_offset(icol_blk) - 1
1716 ncols_local = row_blk_size(irow_blk)
1717 first_col_minus_one = row_blk_offset(irow_blk) + (image_transp - 1)*nrows_total - 1
1718 DO irow_local = 1, nrows_local
1719 IF (do_distribute)
THEN
1720#if defined(__SMEAGOL)
1721 CALL globaltolocalorb(irow_local + first_row_minus_one, mepos, nprocs, irow_proc)
1723 CALL cp_abort(__location__, &
1724 "CP2K was compiled with no SMEAGOL support.")
1727 IF (is_root_rank)
THEN
1728 irow_proc = irow_local + first_row_minus_one
1733 IF (irow_proc > 0)
THEN
1734 icol_offset = row_offset(irow_proc) + n_nonzero_cols(irow_proc)
1735 DO icol_local = 1, ncols_local
1736 col_index(icol_offset + icol_local) = first_col_minus_one + icol_local
1738 n_nonzero_cols(irow_proc) = n_nonzero_cols(irow_proc) + ncols_local
1744 IF (
SIZE(n_nonzero_cols) > 0)
THEN
1745 DO irow_local = 1,
SIZE(n_nonzero_cols)
1746 CALL sort(col_index(row_offset(irow_local) + 1:row_offset(irow_local) + n_nonzero_cols(irow_local)), &
1747 n_nonzero_cols(irow_local), &
1748 packed_index(row_offset(irow_local) + 1:row_offset(irow_local) + n_nonzero_cols(irow_local)))
1752 CALL timestop(handle)
1753 END SUBROUTINE get_nonzero_element_indices
1766 SUBROUTINE get_negf_cell_ijk(cell_ijk, r_ij, r_i, r_j, cell)
1767 INTEGER,
DIMENSION(3),
INTENT(out) :: cell_ijk
1768 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: r_ij, r_i, r_j
1769 TYPE(
cell_type),
INTENT(in),
POINTER :: cell
1771 REAL(kind=
dp),
DIMENSION(3) :: coords_scaled, r
1773 r(:) = r_ij(:) + r_i(:) - r_j(:)
1775 cell_ijk(:) = nint(coords_scaled(:))
1776 END SUBROUTINE get_negf_cell_ijk
1787 ELEMENTAL FUNCTION index_in_canonical_enumeration(inum)
RESULT(ind)
1788 INTEGER,
INTENT(in) :: inum
1791 INTEGER :: inum_abs, is_non_positive
1793 inum_abs = abs(inum)
1795 is_non_positive = merge(1, 0, inum <= 0)
1800 ind = 2*inum_abs + is_non_positive
1801 END FUNCTION index_in_canonical_enumeration
1812 ELEMENTAL FUNCTION number_from_canonical_enumeration(ind)
RESULT(inum)
1813 INTEGER,
INTENT(in) :: ind
1820 inum = sign(ind/2, -mod(ind, 2))
1821 END FUNCTION number_from_canonical_enumeration
1831 PURE SUBROUTINE pbc_0_1(r_pbc, r, cell)
1832 REAL(kind=
dp),
DIMENSION(3),
INTENT(out) :: r_pbc
1833 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: r
1834 TYPE(
cell_type),
INTENT(in),
POINTER :: cell
1836 REAL(kind=
dp),
DIMENSION(3) :: s
1838 IF (cell%orthorhombic)
THEN
1839 r_pbc(1) = r(1) - cell%hmat(1, 1)*cell%perd(1)*real(floor(cell%h_inv(1, 1)*r(1)),
dp)
1840 r_pbc(2) = r(2) - cell%hmat(2, 2)*cell%perd(2)*real(floor(cell%h_inv(2, 2)*r(2)),
dp)
1841 r_pbc(3) = r(3) - cell%hmat(3, 3)*cell%perd(3)*real(floor(cell%h_inv(3, 3)*r(3)),
dp)
1843 s(1) = cell%h_inv(1, 1)*r(1) + cell%h_inv(1, 2)*r(2) + cell%h_inv(1, 3)*r(3)
1844 s(2) = cell%h_inv(2, 1)*r(1) + cell%h_inv(2, 2)*r(2) + cell%h_inv(2, 3)*r(3)
1845 s(3) = cell%h_inv(3, 1)*r(1) + cell%h_inv(3, 2)*r(2) + cell%h_inv(3, 3)*r(3)
1846 s(1) = s(1) - cell%perd(1)*real(floor(s(1)),
dp)
1847 s(2) = s(2) - cell%perd(2)*real(floor(s(2)),
dp)
1848 s(3) = s(3) - cell%perd(3)*real(floor(s(3)),
dp)
1849 r_pbc(1) = cell%hmat(1, 1)*s(1) + cell%hmat(1, 2)*s(2) + cell%hmat(1, 3)*s(3)
1850 r_pbc(2) = cell%hmat(2, 1)*s(1) + cell%hmat(2, 2)*s(2) + cell%hmat(2, 3)*s(3)
1851 r_pbc(3) = cell%hmat(3, 1)*s(1) + cell%hmat(3, 2)*s(2) + cell%hmat(3, 3)*s(3)
1853 END SUBROUTINE pbc_0_1
1864 PURE FUNCTION get_number_of_mpi_sendrecv_requests(mepos, nelements_per_proc, max_nelements_per_packet)
RESULT(nrequests)
1865 INTEGER,
INTENT(in) :: mepos
1866 INTEGER(kind=int_8),
DIMENSION(0:),
INTENT(in) :: nelements_per_proc
1867 INTEGER(kind=int_8),
INTENT(in) :: max_nelements_per_packet
1868 INTEGER :: nrequests
1873 DO iproc = lbound(nelements_per_proc, 1), ubound(nelements_per_proc, 1)
1875 IF (iproc /= mepos)
THEN
1876 nrequests = nrequests + int(nelements_per_proc(iproc)/max_nelements_per_packet)
1877 IF (mod(nelements_per_proc(iproc), max_nelements_per_packet) > 0)
THEN
1878 nrequests = nrequests + 1
1882 END FUNCTION get_number_of_mpi_sendrecv_requests
1894 SUBROUTINE assign_nonzero_elements_to_requests(element_offset, nelements_per_request, peer_rank, tag, &
1895 mepos, nelements_per_proc, max_nelements_per_packet)
1896 INTEGER(kind=int_8),
DIMENSION(:),
INTENT(out) :: element_offset, nelements_per_request
1897 INTEGER,
DIMENSION(:),
INTENT(out) :: peer_rank, tag
1898 INTEGER,
INTENT(in) :: mepos
1899 INTEGER(kind=int_8),
DIMENSION(0:),
INTENT(in) :: nelements_per_proc
1900 INTEGER(kind=int_8),
INTENT(in) :: max_nelements_per_packet
1902 INTEGER :: iproc, irequest, nrequests, &
1904 INTEGER(kind=int_8) :: element_offset_tmp, nelements
1907 element_offset_tmp = 0
1908 DO iproc = lbound(nelements_per_proc, 1), ubound(nelements_per_proc, 1)
1909 IF (iproc /= mepos)
THEN
1910 nrequests = int(nelements_per_proc(iproc)/max_nelements_per_packet)
1911 IF (mod(nelements_per_proc(iproc), max_nelements_per_packet) > 0) nrequests = nrequests + 1
1912 cpassert(nrequests <= max_mpi_rank + 1)
1913 IF (nrequests > 0)
THEN
1914 nelements = nelements_per_proc(iproc)/nrequests
1915 IF (nelements_per_proc(iproc) - nelements*nrequests > 0) nelements = nelements + 1
1916 cpassert(nelements <= max_nelements_per_packet)
1918 DO irequest = 1, nrequests
1919 element_offset(request_offset + irequest) = (irequest - 1)*nelements + element_offset_tmp
1920 IF (irequest < nrequests)
THEN
1921 nelements_per_request(request_offset + irequest) = nelements
1923 nelements_per_request(request_offset + irequest) = nelements_per_proc(iproc) - nelements*(nrequests - 1)
1925 peer_rank(request_offset + irequest) = iproc
1926 tag(request_offset + irequest) = irequest - 1
1929 request_offset = request_offset + nrequests
1931 element_offset_tmp = element_offset_tmp + nelements_per_proc(iproc)
1934 IF (debug_this_module)
THEN
1935 cpassert(
SIZE(element_offset) == request_offset)
1936 cpassert(
SIZE(nelements_per_request) == request_offset)
1937 cpassert(
SIZE(peer_rank) == request_offset)
1938 cpassert(
SIZE(tag) == request_offset)
1940 END SUBROUTINE assign_nonzero_elements_to_requests
Handles all functions related to the CELL.
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_set(matrix, alpha)
...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp_size
integer, parameter, public dp
Interface to the message passing library MPI.
Helper routines to manipulate with matrices.
pure integer function, public get_index_by_cell(cell, cell_to_index)
Helper routine to obtain index of a DBCSR matrix image by its unit cell replica. Can be used with any...
Define the data structure for the particle information.
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
subroutine, public get_neighbor_list_set_p(neighbor_list_sets, nlist, symmetric)
Return the components of the first neighbor list set.
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Routines to convert sparse matrices between DBCSR (distributed-blocks compressed sparse rows) and SIE...
subroutine, public siesta_struct_release(siesta_struct)
Release a SIESTA matrix structure.
subroutine, public siesta_struct_create(siesta_struct, matrix_dbcsr_kp, subsys, cell_to_index, sab_nl, para_env, max_ij_cell_image, do_merge, gather_root)
Map non-zero matrix blocks between sparse matrices in DBCSR and SIESTA formats.
subroutine, public convert_distributed_siesta_to_dbcsr(matrix_dbcsr_kp, matrix_siesta, siesta_struct, para_env)
Convert matrix from DBCSR to sparse SIESTA format.
subroutine, public convert_dbcsr_to_distributed_siesta(matrix_siesta, matrix_dbcsr_kp, siesta_struct, para_env)
Convert matrix from DBCSR to sparse SIESTA format.
All kind of helpful little routines.
Type defining parameters related to the simulation cell.
stores all the informations relevant to an mpi environment
Sparsity pattern of replicated SIESTA compressed sparse column (CSC) matrices.