837 node_of_domain, job_type)
841 INTENT(INOUT) :: submatrix
844 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
845 INTEGER,
INTENT(IN) :: job_type
847 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_submatrices'
849 CHARACTER :: matrix_type
850 INTEGER :: block_node, block_offset, col, col_offset, col_size, dest_node, groupid, handle, &
851 iblock, icol, idomain, index_col, index_ec, index_er, index_row, index_sc, index_sr, &
852 inode, ldesc, mynode, nblkcols_tot, nblkrows_tot, ndomains, ndomains2, nnodes, &
853 recv_size2_total, recv_size_total, row, row_size, send_size2_total, send_size_total, &
854 smcol, smrow, start_data
855 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_col, first_row, offset2_block, offset_block, &
856 recv_data2, recv_offset2_cpu, recv_offset_cpu, recv_size2_cpu, recv_size_cpu, send_data2, &
857 send_offset2_cpu, send_offset_cpu, send_size2_cpu, send_size_cpu
858 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: recv_descriptor, send_descriptor
859 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
860 LOGICAL :: found, transp
861 REAL(kind=
dp) :: antifactor
862 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_data, send_data
863 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block_p
872 CALL timeset(routinen, handle)
874 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows_tot, nblkcols_total=nblkcols_tot)
875 ndomains = nblkcols_tot
879 CALL group%set_handle(groupid)
884 ALLOCATE (send_descriptor(ldesc, nnodes))
885 ALLOCATE (recv_descriptor(ldesc, nnodes))
886 send_descriptor(:, :) = 0
890 DO idomain = 1, ndomains
892 dest_node = node_of_domain(idomain)
896 IF (idomain > 1) index_sr = domain_map%index1(idomain - 1)
897 index_er = domain_map%index1(idomain) - 1
899 DO index_row = index_sr, index_er
901 row = domain_map%pairs(index_row, 1)
906 IF (idomain > 1) index_sc = domain_map%index1(idomain - 1)
907 index_ec = domain_map%index1(idomain) - 1
914 DO index_col = index_sc, index_ec
917 col = domain_map%pairs(index_col, 1)
924 row, col, block_node)
925 IF (block_node == mynode)
THEN
928 send_descriptor(1, dest_node + 1) = send_descriptor(1, dest_node + 1) + 1
929 send_descriptor(2, dest_node + 1) = send_descriptor(2, dest_node + 1) + &
941 CALL group%alltoall(send_descriptor, recv_descriptor, ldesc)
943 ALLOCATE (send_size_cpu(nnodes), send_offset_cpu(nnodes))
944 send_offset_cpu(1) = 0
945 send_size_cpu(1) = send_descriptor(2, 1)
947 send_size_cpu(inode) = send_descriptor(2, inode)
948 send_offset_cpu(inode) = send_offset_cpu(inode - 1) + &
949 send_size_cpu(inode - 1)
951 send_size_total = send_offset_cpu(nnodes) + send_size_cpu(nnodes)
953 ALLOCATE (recv_size_cpu(nnodes), recv_offset_cpu(nnodes))
954 recv_offset_cpu(1) = 0
955 recv_size_cpu(1) = recv_descriptor(2, 1)
957 recv_size_cpu(inode) = recv_descriptor(2, inode)
958 recv_offset_cpu(inode) = recv_offset_cpu(inode - 1) + &
959 recv_size_cpu(inode - 1)
961 recv_size_total = recv_offset_cpu(nnodes) + recv_size_cpu(nnodes)
963 ALLOCATE (send_size2_cpu(nnodes), send_offset2_cpu(nnodes))
964 send_offset2_cpu(1) = 0
965 send_size2_cpu(1) = 2*send_descriptor(1, 1)
967 send_size2_cpu(inode) = 2*send_descriptor(1, inode)
968 send_offset2_cpu(inode) = send_offset2_cpu(inode - 1) + &
969 send_size2_cpu(inode - 1)
971 send_size2_total = send_offset2_cpu(nnodes) + send_size2_cpu(nnodes)
973 ALLOCATE (recv_size2_cpu(nnodes), recv_offset2_cpu(nnodes))
974 recv_offset2_cpu(1) = 0
975 recv_size2_cpu(1) = 2*recv_descriptor(1, 1)
977 recv_size2_cpu(inode) = 2*recv_descriptor(1, inode)
978 recv_offset2_cpu(inode) = recv_offset2_cpu(inode - 1) + &
979 recv_size2_cpu(inode - 1)
981 recv_size2_total = recv_offset2_cpu(nnodes) + recv_size2_cpu(nnodes)
983 DEALLOCATE (send_descriptor)
984 DEALLOCATE (recv_descriptor)
987 ALLOCATE (send_data(send_size_total))
988 ALLOCATE (recv_data(recv_size_total))
989 ALLOCATE (send_data2(send_size2_total))
990 ALLOCATE (recv_data2(recv_size2_total))
991 ALLOCATE (offset_block(nnodes))
992 ALLOCATE (offset2_block(nnodes))
996 DO idomain = 1, ndomains
998 dest_node = node_of_domain(idomain)
1002 IF (idomain > 1) index_sr = domain_map%index1(idomain - 1)
1003 index_er = domain_map%index1(idomain) - 1
1005 DO index_row = index_sr, index_er
1007 row = domain_map%pairs(index_row, 1)
1012 IF (idomain > 1) index_sc = domain_map%index1(idomain - 1)
1013 index_ec = domain_map%index1(idomain) - 1
1020 DO index_col = index_sc, index_ec
1023 col = domain_map%pairs(index_col, 1)
1030 row, col, block_node)
1031 IF (block_node == mynode)
THEN
1034 col_offset = row_size*col_size
1035 start_data = send_offset_cpu(dest_node + 1) + &
1036 offset_block(dest_node + 1)
1037 send_data(start_data + 1:start_data + col_offset) = reshape(block_p, [col_offset])
1038 offset_block(dest_node + 1) = offset_block(dest_node + 1) + col_offset
1040 send_data2(send_offset2_cpu(dest_node + 1) + &
1041 offset2_block(dest_node + 1) + 1) = row
1042 send_data2(send_offset2_cpu(dest_node + 1) + &
1043 offset2_block(dest_node + 1) + 2) = col
1044 offset2_block(dest_node + 1) = offset2_block(dest_node + 1) + 2
1055 CALL group%alltoall(send_data, send_size_cpu, send_offset_cpu, &
1056 recv_data, recv_size_cpu, recv_offset_cpu)
1058 CALL group%alltoall(send_data2, send_size2_cpu, send_offset2_cpu, &
1059 recv_data2, recv_size2_cpu, recv_offset2_cpu)
1061 DEALLOCATE (send_size_cpu, send_offset_cpu)
1062 DEALLOCATE (send_size2_cpu, send_offset2_cpu)
1063 DEALLOCATE (send_data)
1064 DEALLOCATE (send_data2)
1065 DEALLOCATE (offset_block)
1066 DEALLOCATE (offset2_block)
1069 CALL dbcsr_get_info(matrix, col_blk_size=col_blk_size, row_blk_size=row_blk_size)
1070 ndomains2 =
SIZE(submatrix)
1071 IF (ndomains2 /= ndomains)
THEN
1072 cpabort(
"wrong submatrix size")
1075 submatrix(:)%nnodes = nnodes
1076 submatrix(:)%group = group
1077 submatrix(:)%nrows = 0
1078 submatrix(:)%ncols = 0
1080 ALLOCATE (first_row(nblkrows_tot), first_col(nblkcols_tot))
1081 submatrix(:)%domain = -1
1082 DO idomain = 1, ndomains
1083 dest_node = node_of_domain(idomain)
1084 IF (dest_node == mynode)
THEN
1085 submatrix(idomain)%domain = idomain
1086 submatrix(idomain)%nbrows = 0
1087 submatrix(idomain)%nbcols = 0
1092 IF (idomain > 1) index_sr = domain_map%index1(idomain - 1)
1093 index_er = domain_map%index1(idomain) - 1
1094 DO index_row = index_sr, index_er
1095 row = domain_map%pairs(index_row, 1)
1096 first_row(row) = submatrix(idomain)%nrows + 1
1097 submatrix(idomain)%nrows = submatrix(idomain)%nrows + row_blk_size(row)
1098 submatrix(idomain)%nbrows = submatrix(idomain)%nbrows + 1
1100 ALLOCATE (submatrix(idomain)%dbcsr_row(submatrix(idomain)%nbrows))
1101 ALLOCATE (submatrix(idomain)%size_brow(submatrix(idomain)%nbrows))
1105 IF (idomain > 1) index_sr = domain_map%index1(idomain - 1)
1106 index_er = domain_map%index1(idomain) - 1
1107 DO index_row = index_sr, index_er
1108 row = domain_map%pairs(index_row, 1)
1109 submatrix(idomain)%dbcsr_row(smrow) = row
1110 submatrix(idomain)%size_brow(smrow) = row_blk_size(row)
1119 IF (idomain > 1) index_sc = domain_map%index1(idomain - 1)
1120 index_ec = domain_map%index1(idomain) - 1
1126 DO index_col = index_sc, index_ec
1128 col = domain_map%pairs(index_col, 1)
1132 first_col(col) = submatrix(idomain)%ncols + 1
1133 submatrix(idomain)%ncols = submatrix(idomain)%ncols + col_blk_size(col)
1134 submatrix(idomain)%nbcols = submatrix(idomain)%nbcols + 1
1137 ALLOCATE (submatrix(idomain)%dbcsr_col(submatrix(idomain)%nbcols))
1138 ALLOCATE (submatrix(idomain)%size_bcol(submatrix(idomain)%nbcols))
1145 IF (idomain > 1) index_sc = domain_map%index1(idomain - 1)
1146 index_ec = domain_map%index1(idomain) - 1
1152 DO index_col = index_sc, index_ec
1154 col = domain_map%pairs(index_col, 1)
1158 submatrix(idomain)%dbcsr_col(smcol) = col
1159 submatrix(idomain)%size_bcol(smcol) = col_blk_size(col)
1163 ALLOCATE (submatrix(idomain)%mdata( &
1164 submatrix(idomain)%nrows, &
1165 submatrix(idomain)%ncols))
1166 submatrix(idomain)%mdata(:, :) = 0.0_dp
1167 DO inode = 1, nnodes
1169 DO iblock = 1, recv_size2_cpu(inode)/2
1171 row = recv_data2(recv_offset2_cpu(inode) + (iblock - 1)*2 + 1)
1172 col = recv_data2(recv_offset2_cpu(inode) + (iblock - 1)*2 + 2)
1174 IF ((first_col(col) /= -1) .AND. (first_row(row) /= -1))
THEN
1176 start_data = recv_offset_cpu(inode) + block_offset + 1
1177 DO icol = 0, col_blk_size(col) - 1
1178 submatrix(idomain)%mdata(first_row(row): &
1179 first_row(row) + row_blk_size(row) - 1, &
1180 first_col(col) + icol) = &
1181 recv_data(start_data:start_data + row_blk_size(row) - 1)
1182 start_data = start_data + row_blk_size(row)
1185 IF (matrix_type == dbcsr_type_symmetric .OR. &
1186 matrix_type == dbcsr_type_antisymmetric)
THEN
1189 IF (matrix_type == dbcsr_type_antisymmetric)
THEN
1190 antifactor = -1.0_dp
1192 start_data = recv_offset_cpu(inode) + block_offset + 1
1193 DO icol = 0, col_blk_size(col) - 1
1194 submatrix(idomain)%mdata(first_row(col) + icol, &
1196 first_col(row) + row_blk_size(row) - 1) = &
1197 antifactor*recv_data(start_data: &
1198 start_data + row_blk_size(row) - 1)
1199 start_data = start_data + row_blk_size(row)
1201 ELSE IF (matrix_type == dbcsr_type_no_symmetry)
THEN
1203 cpabort(
"matrix type is NYI")
1207 block_offset = block_offset + col_blk_size(col)*row_blk_size(row)
1213 DEALLOCATE (recv_size_cpu, recv_offset_cpu)
1214 DEALLOCATE (recv_size2_cpu, recv_offset2_cpu)
1215 DEALLOCATE (recv_data)
1216 DEALLOCATE (recv_data2)
1218 DEALLOCATE (first_row, first_col)
1220 CALL timestop(handle)
1237 INTENT(IN) :: submatrix
1238 TYPE(
dbcsr_type),
INTENT(IN) :: distr_pattern
1240 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_dbcsr_from_submatrices'
1242 CHARACTER :: matrix_type
1243 INTEGER :: block_offset, col, col_offset, colsize, dest_node, groupid, handle, iblock, icol, &
1244 idomain, inode, irow_subm, ldesc, mynode, nblkcols_tot, nblkrows_tot, ndomains, &
1245 ndomains2, nnodes, recv_size2_total, recv_size_total, row, rowsize, send_size2_total, &
1246 send_size_total, smroff, start_data, unit_nr
1247 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: offset2_block, offset_block, recv_data2, &
1248 recv_offset2_cpu, recv_offset_cpu, recv_size2_cpu, recv_size_cpu, send_data2, &
1249 send_offset2_cpu, send_offset_cpu, send_size2_cpu, send_size_cpu
1250 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: recv_descriptor, send_descriptor
1251 INTEGER,
DIMENSION(:),
POINTER :: col_blk_size, row_blk_size
1253 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_data, send_data
1254 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: new_block
1255 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block_p
1261 CALL timeset(routinen, handle)
1265 IF (logger%para_env%is_source())
THEN
1271 CALL dbcsr_get_info(matrix, nblkrows_total=nblkrows_tot, nblkcols_total=nblkcols_tot)
1272 ndomains = nblkcols_tot
1273 ndomains2 =
SIZE(submatrix)
1275 IF (ndomains /= ndomains2)
THEN
1276 cpabort(
"domain mismatch")
1282 CALL group%set_handle(groupid)
1285 IF (matrix_type /= dbcsr_type_no_symmetry)
THEN
1286 cpabort(
"only non-symmetric matrices so far")
1293 block_p(:, :) = 0.0_dp
1301 ALLOCATE (send_descriptor(ldesc, nnodes))
1302 ALLOCATE (recv_descriptor(ldesc, nnodes))
1303 send_descriptor(:, :) = 0
1306 DO idomain = 1, ndomains
1308 IF (submatrix(idomain)%domain > 0)
THEN
1310 DO irow_subm = 1, submatrix(idomain)%nbrows
1312 IF (submatrix(idomain)%nbcols /= 1)
THEN
1313 cpabort(
"corrupt submatrix structure")
1316 row = submatrix(idomain)%dbcsr_row(irow_subm)
1317 col = submatrix(idomain)%dbcsr_col(1)
1319 IF (col /= idomain)
THEN
1320 cpabort(
"corrupt submatrix structure")
1325 row, idomain, dest_node)
1327 send_descriptor(1, dest_node + 1) = send_descriptor(1, dest_node + 1) + 1
1328 send_descriptor(2, dest_node + 1) = send_descriptor(2, dest_node + 1) + &
1329 submatrix(idomain)%size_brow(irow_subm)* &
1330 submatrix(idomain)%size_bcol(1)
1339 CALL group%alltoall(send_descriptor, recv_descriptor, ldesc)
1341 ALLOCATE (send_size_cpu(nnodes), send_offset_cpu(nnodes))
1342 send_offset_cpu(1) = 0
1343 send_size_cpu(1) = send_descriptor(2, 1)
1344 DO inode = 2, nnodes
1345 send_size_cpu(inode) = send_descriptor(2, inode)
1346 send_offset_cpu(inode) = send_offset_cpu(inode - 1) + &
1347 send_size_cpu(inode - 1)
1349 send_size_total = send_offset_cpu(nnodes) + send_size_cpu(nnodes)
1351 ALLOCATE (recv_size_cpu(nnodes), recv_offset_cpu(nnodes))
1352 recv_offset_cpu(1) = 0
1353 recv_size_cpu(1) = recv_descriptor(2, 1)
1354 DO inode = 2, nnodes
1355 recv_size_cpu(inode) = recv_descriptor(2, inode)
1356 recv_offset_cpu(inode) = recv_offset_cpu(inode - 1) + &
1357 recv_size_cpu(inode - 1)
1359 recv_size_total = recv_offset_cpu(nnodes) + recv_size_cpu(nnodes)
1361 ALLOCATE (send_size2_cpu(nnodes), send_offset2_cpu(nnodes))
1362 send_offset2_cpu(1) = 0
1363 send_size2_cpu(1) = 2*send_descriptor(1, 1)
1364 DO inode = 2, nnodes
1365 send_size2_cpu(inode) = 2*send_descriptor(1, inode)
1366 send_offset2_cpu(inode) = send_offset2_cpu(inode - 1) + &
1367 send_size2_cpu(inode - 1)
1369 send_size2_total = send_offset2_cpu(nnodes) + send_size2_cpu(nnodes)
1371 ALLOCATE (recv_size2_cpu(nnodes), recv_offset2_cpu(nnodes))
1372 recv_offset2_cpu(1) = 0
1373 recv_size2_cpu(1) = 2*recv_descriptor(1, 1)
1374 DO inode = 2, nnodes
1375 recv_size2_cpu(inode) = 2*recv_descriptor(1, inode)
1376 recv_offset2_cpu(inode) = recv_offset2_cpu(inode - 1) + &
1377 recv_size2_cpu(inode - 1)
1379 recv_size2_total = recv_offset2_cpu(nnodes) + recv_size2_cpu(nnodes)
1381 DEALLOCATE (send_descriptor)
1382 DEALLOCATE (recv_descriptor)
1385 ALLOCATE (send_data(send_size_total))
1386 ALLOCATE (recv_data(recv_size_total))
1387 ALLOCATE (send_data2(send_size2_total))
1388 ALLOCATE (recv_data2(recv_size2_total))
1389 ALLOCATE (offset_block(nnodes))
1390 ALLOCATE (offset2_block(nnodes))
1392 offset2_block(:) = 0
1394 DO idomain = 1, ndomains
1396 IF (submatrix(idomain)%domain > 0)
THEN
1399 DO irow_subm = 1, submatrix(idomain)%nbrows
1401 row = submatrix(idomain)%dbcsr_row(irow_subm)
1402 col = submatrix(idomain)%dbcsr_col(1)
1404 rowsize = submatrix(idomain)%size_brow(irow_subm)
1405 colsize = submatrix(idomain)%size_bcol(1)
1409 row, idomain, dest_node)
1413 DO icol = 1, colsize
1414 start_data = send_offset_cpu(dest_node + 1) + &
1415 offset_block(dest_node + 1) + &
1417 send_data(start_data + 1:start_data + rowsize) = &
1418 submatrix(idomain)%mdata(smroff + 1:smroff + rowsize, icol)
1419 col_offset = col_offset + rowsize
1421 offset_block(dest_node + 1) = offset_block(dest_node + 1) + &
1424 send_data2(send_offset2_cpu(dest_node + 1) + &
1425 offset2_block(dest_node + 1) + 1) = row
1426 send_data2(send_offset2_cpu(dest_node + 1) + &
1427 offset2_block(dest_node + 1) + 2) = col
1428 offset2_block(dest_node + 1) = offset2_block(dest_node + 1) + 2
1430 smroff = smroff + rowsize
1439 CALL group%alltoall(send_data, send_size_cpu, send_offset_cpu, &
1440 recv_data, recv_size_cpu, recv_offset_cpu)
1442 CALL group%alltoall(send_data2, send_size2_cpu, send_offset2_cpu, &
1443 recv_data2, recv_size2_cpu, recv_offset2_cpu)
1445 DEALLOCATE (send_size_cpu, send_offset_cpu)
1446 DEALLOCATE (send_size2_cpu, send_offset2_cpu)
1447 DEALLOCATE (send_data)
1448 DEALLOCATE (send_data2)
1449 DEALLOCATE (offset_block)
1450 DEALLOCATE (offset2_block)
1453 CALL dbcsr_get_info(matrix, col_blk_size=col_blk_size, row_blk_size=row_blk_size)
1454 DO inode = 1, nnodes
1456 DO iblock = 1, recv_size2_cpu(inode)/2
1458 row = recv_data2(recv_offset2_cpu(inode) + (iblock - 1)*2 + 1)
1459 col = recv_data2(recv_offset2_cpu(inode) + (iblock - 1)*2 + 2)
1461 start_data = recv_offset_cpu(inode) + block_offset + 1
1462 ALLOCATE (new_block(row_blk_size(row), col_blk_size(col)))
1463 DO icol = 1, col_blk_size(col)
1464 new_block(:, icol) = &
1465 recv_data(start_data:start_data + row_blk_size(row) - 1)
1466 start_data = start_data + row_blk_size(row)
1469 DEALLOCATE (new_block)
1470 block_offset = block_offset + col_blk_size(col)*row_blk_size(row)
1474 DEALLOCATE (recv_size_cpu, recv_offset_cpu)
1475 DEALLOCATE (recv_size2_cpu, recv_offset2_cpu)
1476 DEALLOCATE (recv_data)
1477 DEALLOCATE (recv_data2)
1481 CALL timestop(handle)