474 INTEGER,
INTENT(IN),
OPTIONAL :: ncol, start_col
476 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_init_random'
478 INTEGER :: handle, icol_global, icol_local, irow_local, my_ncol, my_start_col, ncol_global, &
479 ncol_local, nrow_global, nrow_local
480 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
481 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: buff
482 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
483 POINTER :: local_data
484 REAL(kind=
dp),
DIMENSION(3, 2),
SAVE :: &
485 seed = reshape([1.0_dp, 2.0_dp, 3.0_dp, 4.0_dp, 5.0_dp, 6.0_dp], [3, 2])
488 CALL timeset(routinen, handle)
491 CALL matrix%matrix_struct%para_env%bcast(seed, 0)
494 extended_precision=.true., seed=seed)
496 cpassert(.NOT. matrix%use_sp)
498 CALL cp_fm_get_info(matrix, nrow_global=nrow_global, ncol_global=ncol_global, &
499 nrow_local=nrow_local, ncol_local=ncol_local, &
500 local_data=local_data, &
501 row_indices=row_indices, col_indices=col_indices)
504 IF (
PRESENT(start_col)) my_start_col = start_col
505 my_ncol = matrix%matrix_struct%ncol_global
506 IF (
PRESENT(ncol)) my_ncol = ncol
508 IF (ncol_global < (my_start_col + my_ncol - 1)) &
509 cpabort(
"ncol_global>=(my_start_col+my_ncol-1)")
511 ALLOCATE (buff(nrow_global))
517 DO icol_local = 1, ncol_local
518 cpassert(col_indices(icol_local) > icol_global)
520 CALL rng%reset_to_next_substream()
521 icol_global = icol_global + 1
522 IF (icol_global == col_indices(icol_local))
EXIT
525 DO irow_local = 1, nrow_local
526 local_data(irow_local, icol_local) = buff(row_indices(irow_local))
539 CALL rng%get(ig=seed)
541 CALL timestop(handle)
788 start_col, n_rows, n_cols, alpha, beta, transpose)
790 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(in) :: new_values
791 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
792 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: alpha, beta
793 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
795 INTEGER :: i, i0, j, j0, ncol, ncol_block, &
796 ncol_global, ncol_local, nrow, &
797 nrow_block, nrow_global, nrow_local, &
799 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
801 REAL(kind=
dp) :: al, be
802 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: full_block
804 al = 1.0_dp; be = 0.0_dp; i0 = 1; j0 = 1; tr_a = .false.
808 cpassert(.NOT. fm%use_sp)
810 IF (
PRESENT(alpha)) al = alpha
811 IF (
PRESENT(beta)) be = beta
812 IF (
PRESENT(start_row)) i0 = start_row
813 IF (
PRESENT(start_col)) j0 = start_col
814 IF (
PRESENT(transpose)) tr_a = transpose
816 nrow =
SIZE(new_values, 2)
817 ncol =
SIZE(new_values, 1)
819 nrow =
SIZE(new_values, 1)
820 ncol =
SIZE(new_values, 2)
822 IF (
PRESENT(n_rows)) nrow = n_rows
823 IF (
PRESENT(n_cols)) ncol = n_cols
825 full_block => fm%local_data
828 nrow_global=nrow_global, ncol_global=ncol_global, &
829 nrow_block=nrow_block, ncol_block=ncol_block, &
830 nrow_local=nrow_local, ncol_local=ncol_local, &
831 row_indices=row_indices, col_indices=col_indices)
833 IF (al == 1.0 .AND. be == 0.0)
THEN
835 this_col = col_indices(j) - j0 + 1
836 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
838 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
840 full_block(i, j) = new_values(this_col, row_indices(i))
844 this_row = row_indices(i) - i0 + 1
845 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
846 full_block(i, j) = new_values(this_col, this_row)
851 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
853 full_block(i, j) = new_values(row_indices(i), this_col)
857 this_row = row_indices(i) - i0 + 1
858 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
859 full_block(i, j) = new_values(this_row, this_col)
868 this_col = col_indices(j) - j0 + 1
869 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
872 this_row = row_indices(i) - i0 + 1
873 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
874 full_block(i, j) = al*new_values(this_col, this_row) + &
880 this_row = row_indices(i) - i0 + 1
881 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
882 full_block(i, j) = al*new_values(this_row, this_col) + &
971 start_col, n_rows, n_cols, transpose)
973 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(out) :: target_m
974 INTEGER,
INTENT(in),
OPTIONAL :: start_row, start_col, n_rows, n_cols
975 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
977 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_get_submatrix'
979 INTEGER :: handle, i, i0, j, j0, ncol, ncol_global, &
980 ncol_local, nrow, nrow_global, &
981 nrow_local, this_col, this_row
982 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
984 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: full_block
987 CALL timeset(routinen, handle)
989 i0 = 1; j0 = 1; tr_a = .false.
991 cpassert(.NOT. fm%use_sp)
993 IF (
PRESENT(start_row)) i0 = start_row
994 IF (
PRESENT(start_col)) j0 = start_col
995 IF (
PRESENT(transpose)) tr_a = transpose
997 nrow =
SIZE(target_m, 2)
998 ncol =
SIZE(target_m, 1)
1000 nrow =
SIZE(target_m, 1)
1001 ncol =
SIZE(target_m, 2)
1003 IF (
PRESENT(n_rows)) nrow = n_rows
1004 IF (
PRESENT(n_cols)) ncol = n_cols
1006 para_env => fm%matrix_struct%para_env
1008 full_block => fm%local_data
1009#if defined(__parallel)
1011 IF (
SIZE(target_m, 1)*
SIZE(target_m, 2) /= 0)
THEN
1012 CALL dcopy(
SIZE(target_m, 1)*
SIZE(target_m, 2), [0.0_dp], 0, target_m, 1)
1017 nrow_global=nrow_global, ncol_global=ncol_global, &
1018 nrow_local=nrow_local, ncol_local=ncol_local, &
1019 row_indices=row_indices, col_indices=col_indices)
1021 DO j = 1, ncol_local
1022 this_col = col_indices(j) - j0 + 1
1023 IF (this_col >= 1 .AND. this_col <= ncol)
THEN
1025 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
1026 DO i = 1, nrow_local
1027 target_m(this_col, row_indices(i)) = full_block(i, j)
1030 DO i = 1, nrow_local
1031 this_row = row_indices(i) - i0 + 1
1032 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
1033 target_m(this_col, this_row) = full_block(i, j)
1038 IF (i0 == 1 .AND. nrow_global == nrow)
THEN
1039 DO i = 1, nrow_local
1040 target_m(row_indices(i), this_col) = full_block(i, j)
1043 DO i = 1, nrow_local
1044 this_row = row_indices(i) - i0 + 1
1045 IF (this_row >= 1 .AND. this_row <= nrow)
THEN
1046 target_m(this_row, this_col) = full_block(i, j)
1054 CALL para_env%sum(target_m)
1056 CALL timestop(handle)
1136 REAL(kind=
dp),
INTENT(OUT) :: a_max
1137 INTEGER,
INTENT(OUT),
OPTIONAL :: ir_max, ic_max
1139 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_maxabsval'
1141 INTEGER :: handle, i, ic_max_local, ir_max_local, &
1142 j, mepos, ncol_local, nrow_local, &
1144 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: ic_max_vec, ir_max_vec
1145 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1147 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: a_max_vec
1148 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: my_block
1149 REAL(kind=
sp),
DIMENSION(:, :),
POINTER :: my_block_sp
1151 CALL timeset(routinen, handle)
1153 my_block => matrix%local_data
1154 my_block_sp => matrix%local_data_sp
1156 CALL cp_fm_get_info(matrix, nrow_local=nrow_local, ncol_local=ncol_local, &
1157 row_indices=row_indices, col_indices=col_indices)
1159 IF (matrix%use_sp)
THEN
1160 a_max = real(maxval(abs(my_block_sp(1:nrow_local, 1:ncol_local))),
dp)
1162 a_max = maxval(abs(my_block(1:nrow_local, 1:ncol_local)))
1165 IF (
PRESENT(ir_max))
THEN
1166 num_pe = matrix%matrix_struct%para_env%num_pe
1167 mepos = matrix%matrix_struct%para_env%mepos
1168 ALLOCATE (ir_max_vec(0:num_pe - 1))
1169 ir_max_vec(0:num_pe - 1) = 0
1170 ALLOCATE (ic_max_vec(0:num_pe - 1))
1171 ic_max_vec(0:num_pe - 1) = 0
1172 ALLOCATE (a_max_vec(0:num_pe - 1))
1173 a_max_vec(0:num_pe - 1) = 0.0_dp
1176 IF ((ncol_local > 0) .AND. (nrow_local > 0))
THEN
1177 DO i = 1, ncol_local
1178 DO j = 1, nrow_local
1179 IF (matrix%use_sp)
THEN
1180 IF (abs(my_block_sp(j, i)) > my_max)
THEN
1181 my_max = real(my_block_sp(j, i),
dp)
1186 IF (abs(my_block(j, i)) > my_max)
THEN
1187 my_max = my_block(j, i)
1195 a_max_vec(mepos) = my_max
1196 ir_max_vec(mepos) = row_indices(ir_max_local)
1197 ic_max_vec(mepos) = col_indices(ic_max_local)
1201 CALL matrix%matrix_struct%para_env%sum(a_max_vec)
1202 CALL matrix%matrix_struct%para_env%sum(ir_max_vec)
1203 CALL matrix%matrix_struct%para_env%sum(ic_max_vec)
1206 DO i = 0, num_pe - 1
1207 IF (a_max_vec(i) > my_max)
THEN
1208 ir_max = ir_max_vec(i)
1209 ic_max = ic_max_vec(i)
1213 DEALLOCATE (ir_max_vec, ic_max_vec, a_max_vec)
1214 cpassert(ic_max > 0)
1215 cpassert(ir_max > 0)
1219 CALL matrix%matrix_struct%para_env%max(a_max)
1221 CALL timestop(handle)
1382 SUBROUTINE cp_fm_to_fm_matrix(source, destination)
1384 TYPE(
cp_fm_type),
INTENT(IN) :: source, destination
1386 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_to_fm_matrix'
1388 INTEGER :: handle, npcol, nprow
1390 CALL timeset(routinen, handle)
1392 nprow = source%matrix_struct%context%num_pe(1)
1393 npcol = source%matrix_struct%context%num_pe(2)
1397 destination%matrix_struct))
THEN
1398 IF (source%use_sp .AND. destination%use_sp)
THEN
1399 IF (
SIZE(source%local_data_sp, 1) /=
SIZE(destination%local_data_sp, 1) .OR. &
1400 SIZE(source%local_data_sp, 2) /=
SIZE(destination%local_data_sp, 2)) &
1401 CALL cp_abort(__location__, &
1402 "Cannot copy full matrix <"//trim(source%name)// &
1403 "> to full matrix <"//trim(destination%name)// &
1404 ">. The local_data blocks have different sizes.")
1405 CALL scopy(
SIZE(source%local_data_sp, 1)*
SIZE(source%local_data_sp, 2), &
1406 source%local_data_sp, 1, destination%local_data_sp, 1)
1407 ELSE IF (source%use_sp .AND. .NOT. destination%use_sp)
THEN
1408 IF (
SIZE(source%local_data_sp, 1) /=
SIZE(destination%local_data, 1) .OR. &
1409 SIZE(source%local_data_sp, 2) /=
SIZE(destination%local_data, 2)) &
1410 CALL cp_abort(__location__, &
1411 "Cannot copy full matrix <"//trim(source%name)// &
1412 "> to full matrix <"//trim(destination%name)// &
1413 ">. The local_data blocks have different sizes.")
1414 destination%local_data = real(source%local_data_sp,
dp)
1415 ELSE IF (.NOT. source%use_sp .AND. destination%use_sp)
THEN
1416 IF (
SIZE(source%local_data, 1) /=
SIZE(destination%local_data_sp, 1) .OR. &
1417 SIZE(source%local_data, 2) /=
SIZE(destination%local_data_sp, 2)) &
1418 CALL cp_abort(__location__, &
1419 "Cannot copy full matrix <"//trim(source%name)// &
1420 "> to full matrix <"//trim(destination%name)// &
1421 ">. The local_data blocks have different sizes.")
1422 destination%local_data_sp = real(source%local_data,
sp)
1424 IF (
SIZE(source%local_data, 1) /=
SIZE(destination%local_data, 1) .OR. &
1425 SIZE(source%local_data, 2) /=
SIZE(destination%local_data, 2)) &
1426 CALL cp_abort(__location__, &
1427 "Cannot copy full matrix <"//trim(source%name)// &
1428 "> to full matrix <"//trim(destination%name)// &
1429 ">. The local_data blocks have different sizes.")
1430 CALL dcopy(
SIZE(source%local_data, 1)*
SIZE(source%local_data, 2), &
1431 source%local_data, 1, destination%local_data, 1)
1434 cpabort(
"Data structures of source and target full matrix are not equivalent")
1437 CALL timestop(handle)
1645 TYPE(
cp_fm_type),
INTENT(IN) :: source, destination
1649 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_start_copy_general'
1651 INTEGER :: dest_p_i, dest_q_j, global_rank, global_size, handle, i, j, k, mpi_rank, &
1652 ncol_block_dest, ncol_block_src, ncol_local_recv, ncol_local_send, ncols, &
1653 nrow_block_dest, nrow_block_src, nrow_local_recv, nrow_local_send, nrows, p, q, &
1654 recv_rank, recv_size, send_rank, send_size
1655 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: all_ranks, dest2global, dest_p, dest_q, &
1656 recv_count, send_count, send_disp, &
1657 source2global, src_p, src_q
1658 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: dest_blacs2mpi
1659 INTEGER,
DIMENSION(2) :: dest_block, dest_block_tmp, dest_num_pe, &
1660 src_block, src_block_tmp, src_num_pe
1661 INTEGER,
DIMENSION(:),
POINTER :: recv_col_indices, recv_row_indices, &
1662 send_col_indices, send_row_indices
1666 CALL timeset(routinen, handle)
1670 nrow_local_send =
SIZE(source%local_data, 1)
1671 ncol_local_send =
SIZE(source%local_data, 2)
1672 ALLOCATE (info%send_buf(nrow_local_send*ncol_local_send))
1674 DO j = 1, ncol_local_send
1675 DO i = 1, nrow_local_send
1677 info%send_buf(k) = source%local_data(i, j)
1682 IF (source%use_sp) cpabort(
"only DP kind implemented")
1683 IF (destination%use_sp) cpabort(
"only DP kind implemented")
1685 NULLIFY (recv_dist, send_dist)
1686 NULLIFY (recv_col_indices, recv_row_indices, send_col_indices, send_row_indices)
1689 global_size = para_env%num_pe
1690 global_rank = para_env%mepos
1696 IF (
ASSOCIATED(destination%matrix_struct))
THEN
1697 recv_dist => destination%matrix_struct
1698 recv_rank = recv_dist%para_env%mepos
1703 IF (
ASSOCIATED(source%matrix_struct))
THEN
1704 send_dist => source%matrix_struct
1705 send_rank = send_dist%para_env%mepos
1711 ALLOCATE (all_ranks(0:global_size - 1))
1713 CALL para_env%allgather(send_rank, all_ranks)
1714 IF (
ASSOCIATED(recv_dist))
THEN
1715 ALLOCATE (source2global(0:count(all_ranks /=
mp_proc_null) - 1))
1716 DO i = 0, global_size - 1
1718 source2global(all_ranks(i)) = i
1723 CALL para_env%allgather(recv_rank, all_ranks)
1724 IF (
ASSOCIATED(send_dist))
THEN
1725 ALLOCATE (dest2global(0:count(all_ranks /=
mp_proc_null) - 1))
1726 DO i = 0, global_size - 1
1728 dest2global(all_ranks(i)) = i
1732 DEALLOCATE (all_ranks)
1739 IF (global_rank == 0)
THEN
1741 CALL para_env%irecv(src_block,
mp_any_source, recv_req(1), tag=src_tag)
1742 CALL para_env%irecv(dest_block,
mp_any_source, recv_req(2), tag=dest_tag)
1743 CALL para_env%irecv(src_num_pe,
mp_any_source, recv_req(3), tag=src_tag)
1744 CALL para_env%irecv(dest_num_pe,
mp_any_source, recv_req(4), tag=dest_tag)
1747 IF (
ASSOCIATED(send_dist))
THEN
1748 IF ((send_rank == 0))
THEN
1750 src_block_tmp = [send_dist%nrow_block, send_dist%ncol_block]
1751 CALL para_env%isend(src_block_tmp, 0, send_req(1), tag=src_tag)
1752 CALL para_env%isend(send_dist%context%num_pe, 0, send_req(2), tag=src_tag)
1756 IF (
ASSOCIATED(recv_dist))
THEN
1757 IF ((recv_rank == 0))
THEN
1758 dest_block_tmp = [recv_dist%nrow_block, recv_dist%ncol_block]
1759 CALL para_env%isend(dest_block_tmp, 0, send_req(3), tag=dest_tag)
1760 CALL para_env%isend(recv_dist%context%num_pe, 0, send_req(4), tag=dest_tag)
1764 IF (global_rank == 0)
THEN
1767 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1768 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1) &
1770 CALL para_env%irecv(info%src_blacs2mpi,
mp_any_source, recv_req(5), tag=src_tag)
1771 CALL para_env%irecv(dest_blacs2mpi,
mp_any_source, recv_req(6), tag=dest_tag)
1774 IF (
ASSOCIATED(send_dist))
THEN
1775 IF ((send_rank == 0))
THEN
1776 CALL para_env%isend(send_dist%context%blacs2mpi(:, :), 0, send_req(5), tag=src_tag)
1780 IF (
ASSOCIATED(recv_dist))
THEN
1781 IF ((recv_rank == 0))
THEN
1782 CALL para_env%isend(recv_dist%context%blacs2mpi(:, :), 0, send_req(6), tag=dest_tag)
1786 IF (global_rank == 0)
THEN
1791 CALL para_env%bcast(src_block, 0)
1792 CALL para_env%bcast(dest_block, 0)
1793 CALL para_env%bcast(src_num_pe, 0)
1794 CALL para_env%bcast(dest_num_pe, 0)
1795 info%src_num_pe(1:2) = src_num_pe(1:2)
1796 info%nblock_src(1:2) = src_block(1:2)
1797 IF (global_rank /= 0)
THEN
1798 ALLOCATE (info%src_blacs2mpi(0:src_num_pe(1) - 1, 0:src_num_pe(2) - 1), &
1799 dest_blacs2mpi(0:dest_num_pe(1) - 1, 0:dest_num_pe(2) - 1) &
1802 CALL para_env%bcast(info%src_blacs2mpi, 0)
1803 CALL para_env%bcast(dest_blacs2mpi, 0)
1805 recv_size = dest_num_pe(1)*dest_num_pe(2)
1806 send_size = src_num_pe(1)*src_num_pe(2)
1807 info%send_size = send_size
1825 IF (
ASSOCIATED(recv_dist))
THEN
1827 col_indices=recv_col_indices &
1829 info%recv_col_indices => recv_col_indices
1830 info%recv_row_indices => recv_row_indices
1831 nrow_block_src = src_block(1)
1832 ncol_block_src = src_block(2)
1833 ALLOCATE (recv_count(0:send_size - 1), info%recv_disp(0:send_size - 1), info%recv_request(0:send_size - 1))
1836 nrow_local_recv = recv_dist%nrow_locals(recv_dist%context%mepos(1))
1837 ncol_local_recv = recv_dist%ncol_locals(recv_dist%context%mepos(2))
1838 info%nlocal_recv(1) = nrow_local_recv
1839 info%nlocal_recv(2) = ncol_local_recv
1841 ALLOCATE (src_p(nrow_local_recv), src_q(ncol_local_recv))
1842 DO i = 1, nrow_local_recv
1845 src_p(i) = mod(((recv_row_indices(i) - 1)/nrow_block_src), src_num_pe(1))
1847 DO j = 1, ncol_local_recv
1849 src_q(j) = mod(((recv_col_indices(j) - 1)/ncol_block_src), src_num_pe(2))
1853 DO q = 0, src_num_pe(2) - 1
1854 ncols = count(src_q == q)
1855 DO p = 0, src_num_pe(1) - 1
1856 nrows = count(src_p == p)
1858 recv_count(info%src_blacs2mpi(p, q)) = nrows*ncols
1861 DEALLOCATE (src_p, src_q)
1865 ALLOCATE (info%recv_buf(sum(recv_count(:))))
1866 info%recv_disp(0) = 0
1867 DO i = 1, send_size - 1
1868 info%recv_disp(i) = info%recv_disp(i - 1) + recv_count(i - 1)
1872 DO k = 0, send_size - 1
1873 IF (recv_count(k) > 0)
THEN
1874 CALL para_env%irecv(info%recv_buf(info%recv_disp(k) + 1:info%recv_disp(k) + recv_count(k)), &
1875 source2global(k), info%recv_request(k))
1878 DEALLOCATE (source2global)
1882 IF (
ASSOCIATED(send_dist))
THEN
1884 col_indices=send_col_indices &
1886 nrow_block_dest = dest_block(1)
1887 ncol_block_dest = dest_block(2)
1888 ALLOCATE (send_count(0:recv_size - 1), send_disp(0:recv_size - 1), info%send_request(0:recv_size - 1))
1891 nrow_local_send = send_dist%nrow_locals(send_dist%context%mepos(1))
1892 ncol_local_send = send_dist%ncol_locals(send_dist%context%mepos(2))
1896 ALLOCATE (dest_p(nrow_local_send), dest_q(ncol_local_send))
1898 DO i = 1, nrow_local_send
1900 dest_p(i) = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1902 DO j = 1, ncol_local_send
1903 dest_q(j) = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1907 DO q = 0, dest_num_pe(2) - 1
1908 ncols = count(dest_q == q)
1909 DO p = 0, dest_num_pe(1) - 1
1910 nrows = count(dest_p == p)
1911 send_count(dest_blacs2mpi(p, q)) = nrows*ncols
1914 DEALLOCATE (dest_p, dest_q)
1917 ALLOCATE (info%send_buf(sum(send_count(:))))
1919 DO k = 1, recv_size - 1
1920 send_disp(k) = send_disp(k - 1) + send_count(k - 1)
1925 DO j = 1, ncol_local_send
1927 dest_q_j = mod(((send_col_indices(j) - 1)/ncol_block_dest), dest_num_pe(2))
1928 DO i = 1, nrow_local_send
1929 dest_p_i = mod(((send_row_indices(i) - 1)/nrow_block_dest), dest_num_pe(1))
1930 mpi_rank = dest_blacs2mpi(dest_p_i, dest_q_j)
1931 send_count(mpi_rank) = send_count(mpi_rank) + 1
1932 info%send_buf(send_disp(mpi_rank) + send_count(mpi_rank)) = source%local_data(i, j)
1937 DO k = 0, recv_size - 1
1938 IF (send_count(k) > 0)
THEN
1939 CALL para_env%isend(info%send_buf(send_disp(k) + 1:send_disp(k) + send_count(k)), &
1940 dest2global(k), info%send_request(k))
1943 DEALLOCATE (send_count, send_disp, dest2global)
1945 DEALLOCATE (dest_blacs2mpi)
1949 CALL timestop(handle)
2225 INTEGER,
INTENT(IN) :: unit
2227 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_write_unformatted'
2229 INTEGER :: handle, j, max_block, &
2230 ncol_global, nrow_global
2232#if defined(__parallel)
2233 INTEGER :: i, i_block, icol_local, &
2235 iprow, irow_local, &
2238 INTEGER,
DIMENSION(9) :: desc
2239 REAL(kind=
dp),
DIMENSION(:),
POINTER :: vecbuf
2240 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: newdat
2242 INTEGER,
EXTERNAL :: numroc
2245 CALL timeset(routinen, handle)
2246 CALL cp_fm_get_info(fm, nrow_global=nrow_global, ncol_global=ncol_global, ncol_block=max_block, &
2249#if defined(__parallel)
2250 num_pe = para_env%num_pe
2251 mepos = para_env%mepos
2255 CALL ictxt_loc%gridinit(para_env,
'R', 1, num_pe)
2256 CALL descinit(desc, nrow_global, ncol_global, rb, max_block, 0, 0, ictxt_loc%get_handle(), nrow_global, info)
2258 associate(nprow => ictxt_loc%num_pe(1), npcol => ictxt_loc%num_pe(2), &
2259 myprow => ictxt_loc%mepos(1), mypcol => ictxt_loc%mepos(2))
2260 in = numroc(ncol_global, max_block, mypcol, 0, npcol)
2262 ALLOCATE (newdat(nrow_global, max(1, in)))
2265 CALL pdgemr2d(nrow_global, ncol_global, fm%local_data, 1, 1, &
2266 fm%matrix_struct%descriptor, &
2267 newdat, 1, 1, desc, ictxt_loc%get_handle())
2269 ALLOCATE (vecbuf(nrow_global*max_block))
2270 vecbuf = huge(1.0_dp)
2272 DO i = 1, ncol_global, max(max_block, 1)
2273 i_block = min(max_block, ncol_global - i + 1)
2274 CALL infog2l(1, i, desc, nprow, npcol, myprow, mypcol, &
2275 irow_local, icol_local, iprow, ipcol)
2276 IF (ipcol == mypcol)
THEN
2278 vecbuf((j - 1)*nrow_global + 1:nrow_global*j) = newdat(:, icol_local + j - 1)
2282 IF (ipcol == 0)
THEN
2285 IF (ipcol == mypcol)
THEN
2286 CALL para_env%send(vecbuf(:), 0, tag)
2288 IF (mypcol == 0)
THEN
2289 CALL para_env%recv(vecbuf(:), ipcol, tag)
2295 WRITE (unit) vecbuf((j - 1)*nrow_global + 1:nrow_global*j)
2303 CALL ictxt_loc%gridexit()
2310 DO j = 1, ncol_global
2311 WRITE (unit) fm%local_data(:, j)
2316 CALL timestop(handle)
2329 INTEGER,
INTENT(IN) :: unit
2330 CHARACTER(LEN=*),
INTENT(IN),
OPTIONAL ::
header, value_format
2332 CHARACTER(LEN=*),
PARAMETER :: routinen =
'cp_fm_write_formatted'
2334 CHARACTER(LEN=21) :: my_value_format
2335 INTEGER :: handle, i, j, max_block, &
2336 ncol_global, nrow_global
2337 TYPE(mp_para_env_type),
POINTER :: para_env
2338#if defined(__parallel)
2339 INTEGER :: i_block, icol_local, &
2341 iprow, irow_local, &
2342 mepos, num_pe, rb, tag, k, &
2344 INTEGER,
DIMENSION(9) :: desc
2345 REAL(kind=dp),
DIMENSION(:),
POINTER :: vecbuf
2346 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: newdat
2347 TYPE(cp_blacs_type) :: ictxt_loc
2348 INTEGER,
EXTERNAL :: numroc
2351 CALL timeset(routinen, handle)
2352 CALL cp_fm_get_info(fm, nrow_global=nrow_global, ncol_global=ncol_global, ncol_block=max_block, &
2355 IF (
PRESENT(value_format))
THEN
2356 cpassert(len_trim(adjustl(value_format)) < 11)
2357 my_value_format =
"(I10, I10, "//trim(adjustl(value_format))//
")"
2359 my_value_format =
"(I10, I10, ES24.12)"
2364 WRITE (unit,
"(A2, A8, A10, A24)")
"#",
"Row",
"Column", adjustl(
"Value")
2367#if defined(__parallel)
2368 num_pe = para_env%num_pe
2369 mepos = para_env%mepos
2373 CALL ictxt_loc%gridinit(para_env,
'R', 1, num_pe)
2374 CALL descinit(desc, nrow_global, ncol_global, rb, max_block, 0, 0, ictxt_loc%get_handle(), nrow_global, info)
2376 associate(nprow => ictxt_loc%num_pe(1), npcol => ictxt_loc%num_pe(2), &
2377 myprow => ictxt_loc%mepos(1), mypcol => ictxt_loc%mepos(2))
2378 in = numroc(ncol_global, max_block, mypcol, 0, npcol)
2380 ALLOCATE (newdat(nrow_global, max(1, in)))
2383 CALL pdgemr2d(nrow_global, ncol_global, fm%local_data, 1, 1, &
2384 fm%matrix_struct%descriptor, &
2385 newdat, 1, 1, desc, ictxt_loc%get_handle())
2387 ALLOCATE (vecbuf(nrow_global*max_block))
2388 vecbuf = huge(1.0_dp)
2392 DO i = 1, ncol_global, max(max_block, 1)
2393 i_block = min(max_block, ncol_global - i + 1)
2394 CALL infog2l(1, i, desc, nprow, npcol, myprow, mypcol, &
2395 irow_local, icol_local, iprow, ipcol)
2396 IF (ipcol == mypcol)
THEN
2398 vecbuf((j - 1)*nrow_global + 1:nrow_global*j) = newdat(:, icol_local + j - 1)
2402 IF (ipcol == 0)
THEN
2405 IF (ipcol == mypcol)
THEN
2406 CALL para_env%send(vecbuf(:), 0, tag)
2408 IF (mypcol == 0)
THEN
2409 CALL para_env%recv(vecbuf(:), ipcol, tag)
2415 DO k = (j - 1)*nrow_global + 1, nrow_global*j
2416 WRITE (unit=unit, fmt=my_value_format) irow, icol, vecbuf(k)
2418 IF (irow > nrow_global)
THEN
2430 CALL ictxt_loc%gridexit()
2437 DO j = 1, ncol_global
2438 DO i = 1, nrow_global
2439 WRITE (unit=unit, fmt=my_value_format) i, j, fm%local_data(i, j)
2445 CALL timestop(handle)