1396 IMPLICIT NONE
1397 include 'mpif.h'
1398 include 'mumps_tags.h'
1399 INTEGER IERR, MASTER
1400 parameter( master = 0 )
1401 INTEGER :: STATUS(MPI_STATUS_SIZE)
1402 TYPE(COMPACT_GRAPH_T), INTENT(IN) :: GCOMP_DIST
1403 INTEGER, INTENT(IN) :: MYID, NPROCS, ICNTL(60), COMM,
1404 & (500)
1405 INTEGER, INTENT(INOUT) :: INFO(80)
1406 TYPE(COMPACT_GRAPH_T) :: GCOMP
1407 INTEGER :: NG, allocok, LP, MPG, I, J, K
1408 INTEGER :: INDX, NB_BLOCK_SENT, MAX_NBBLOCK_loc, NRECV,
1409 & BLOCKSIZE, SIZE_SENT, NB_BLOCKS, NBNONEMPTY,
1410 & FIRSTNONEMPTY, LASTNONEMPTY, NBBLOCK_loc
1411 INTEGER(4) :: IOVFLO
1412 INTEGER(8) :: NZG, NZG_CENT, I8, IBEG8, IEND8,
1413 & SIZEGCOMPALLOCATED
1414 LOGICAL :: LPOK, PROKG
1415 INTEGER(8), ALLOCATABLE, DIMENSION(:) :: IQ
1416 INTEGER, ALLOCATABLE :: REQPTR(:)
1417 INTEGER(8), ALLOCATABLE :: GPTR(:), GPTR_cp(:)
1418 lp = icntl( 1 )
1419 lpok = ((lp.GT.0).AND.(icntl(4).GE.1))
1420 mpg = icntl( 3 )
1421 prokg = ( mpg .GT. 0 .and. myid .eq. master )
1422 prokg = (prokg.AND.(icntl(4).GE.2))
1423 iovflo = huge(iovflo)
1424 blocksize = int(
max(100000_8,int(iovflo,8)/200_8))
1425 nzg = gcomp_dist%NZG
1426 ng = gcomp_dist%NG
1427 CALL mpi_reduce( nzg, nzg_cent, 1, mpi_integer8,
1428 & mpi_sum, master, comm, ierr )
1429 IF (myid.EQ.master) THEN
1430 gcomp%NZG = nzg_cent
1431 gcomp%NG = ng
1432 sizegcompallocated = nzg_cent+int(ng,8)+1_8
1433 gcomp%SIZEADJALLOCATED = sizegcompallocated
1434 ALLOCATE( gcomp%ADJ(sizegcompallocated),
1435 & gcomp%IPE(ng+1),
1436 & gptr( nprocs ),
1437 & gptr_cp( nprocs ),
1438 & reqptr( nprocs-1 ),
1439 & iq(ng+1),stat=allocok)
1440 IF (allocok.NE.0) THEN
1441 info( 1 ) = -7
1443 & nzg_cent + 3_8*int(ng,8)+3_8+3_8*int(nprocs,8)-1_8,
1444 & info(2))
1445 IF ( lpok )
1446 & WRITE(lp, *) " ERROR allocating graph in",
1447 & " MUMPS_AB_GATHER_GRAPH"
1448 ENDIF
1449 ELSE
1450 ALLOCATE( iq(ng+1), stat=allocok)
1451 IF (allocok.NE.0) THEN
1452 info( 1 ) = -7
1453 info( 2 ) = ng+1
1454 IF ( lpok )
1455 & WRITE(lp, *) " ERROR allocating pointers",
1456 & " MUMPS_AB_GATHER_GRAPH"
1457 END IF
1458 ENDIF
1460 & comm, myid )
1461 IF (info(1).LT.0) GOTO 500
1462 firstnonempty = 0
1463 lastnonempty = -1
1464 DO i=1,ng
1465 iq(i) = int(gcomp_dist%IPE(i+1)-gcomp_dist%IPE(i))
1466 IF (iq(i).NE.0) THEN
1467 IF (firstnonempty.EQ.0) firstnonempty=i
1468 lastnonempty = i
1469 ENDIF
1470 ENDDO
1471 nbnonempty = lastnonempty-firstnonempty+1
1472 IF (myid.EQ.master) THEN
1473 DO j=1, ng
1474 gcomp%IPE(j) = 0
1475 ENDDO
1476 j=firstnonempty
1477 IF (nbnonempty.GT.0) THEN
1478 DO i=firstnonempty, lastnonempty
1479 gcomp%IPE(j) = iq(i)
1480 j = j+1
1481 ENDDO
1482 ENDIF
1483 DO i = 1, nprocs - 1
1485 & mpi_integer, i,
1486 & gatherg_nb, comm, status, ierr )
1487 IF (nbnonempty.GT.0) THEN
1489 & mpi_integer, i,
1490 & gatherg_first, comm, status, ierr )
1491 CALL mpi_recv( gcomp%IPE(j), nbnonempty,
1492 & mpi_integer8, i,
1493 & gatherg_ipe, comm, status, ierr )
1494 ENDIF
1495 ENDDO
1496 ELSE
1497 CALL mpi_send( nbnonempty, 1, mpi_integer, master,
1498 & gatherg_nb, comm, ierr )
1499 IF (nbnonempty.GT.0) THEN
1500 CALL mpi_send( firstnonempty, 1, mpi_integer, master,
1501 & gatherg_first, comm, ierr )
1502 CALL mpi_send( iq(firstnonempty), nbnonempty,
1503 & mpi_integer8, master,
1504 & gatherg_ipe, comm, ierr )
1505 ENDIF
1506 ENDIF
1507 IF (myid.EQ.master) THEN
1508 iq(1) = 1_8
1509 DO i=1,ng
1510 iq(i+1) = iq(i) + gcomp%IPE(i)
1511 gcomp%IPE(i) = iq(i)
1512 ENDDO
1513 gcomp%IPE(ng+1) = iq(ng+1)
1514 DEALLOCATE(iq)
1515 ELSE
1516 DEALLOCATE(iq)
1517 ENDIF
1518 IF (myid.EQ.master) THEN
1519 nb_block_sent = 0
1520 max_nbblock_loc = 0
1521 DO i = 1, nprocs - 1
1523 & mpi_integer8, i,
1524 & gatherg_nzg, comm, status, ierr )
1525 nbblock_loc = ceiling(dble(gptr(i+1))/dble(blocksize))
1526 max_nbblock_loc =
max(max_nbblock_loc, nbblock_loc)
1527 nb_block_sent = nb_block_sent + nbblock_loc
1528 ENDDO
1529 gptr( 1 ) = nzg + 1_8
1530 DO i = 2, nprocs
1531 gptr( i ) = gptr( i ) + gptr( i-1 )
1532 END DO
1533 ELSE
1534 CALL mpi_send( nzg, 1, mpi_integer8, master,
1535 & gatherg_nzg, comm, ierr )
1536 ENDIF
1537 IF (myid.EQ.master) THEN
1538 DO i=1, nprocs
1539 gptr_cp(i) = gptr(i)
1540 ENDDO
1541 IF (nzg.GT.0_8) THEN
1542 DO i8=1, nzg
1543 gcomp%ADJ(i8) = gcomp_dist%ADJ(i8)
1544 ENDDO
1545 ENDIF
1546 nb_blocks = 0
1547 DO k = 1, max_nbblock_loc
1548 nrecv = 0
1549 DO i = 1, nprocs - 1
1550 ibeg8 = gptr_cp( i )
1551 IF ( ibeg8 .LT. gptr(i+1)) THEN
1552 nrecv = nrecv + 1
1553 iend8 =
min(ibeg8+int(blocksize,8)-1_8,
1554 & gptr(i+1)-1_8)
1555 gptr_cp( i ) = iend8 + 1_8
1556 size_sent = int(iend8 - ibeg8 + 1_8)
1557 nb_blocks = nb_blocks + 1
1558 CALL mpi_irecv( gcomp%ADJ(ibeg8), size_sent,
1559 & mpi_integer,
1560 & i, gatherg_adj, comm, reqptr(i), ierr )
1561 ELSE
1562 reqptr( i ) = mpi_request_null
1563 ENDIF
1564 END DO
1565 DO i = 1, nrecv
1567 & ( nprocs-1, reqptr, indx,
1568 & status, ierr )
1569 ENDDO
1570 END DO
1571 DEALLOCATE( reqptr )
1572 DEALLOCATE( gptr )
1573 DEALLOCATE( gptr_cp )
1574 ELSE
1575 IF (nzg.EQ.0) GOTO 600
1576 DO i8=1_8, nzg, int(blocksize,8)
1577 size_sent = blocksize
1578 IF (nzg-i8+1_8.LT.int(blocksize,8)) THEN
1579 size_sent = int(nzg-i8+1_8)
1580 ENDIF
1582 & gcomp_dist%ADJ(i8), size_sent,
1583 & mpi_integer, master,
1584 & gatherg_adj, comm, ierr )
1585 ENDDO
1586 ENDIF
1587 GOTO 600
1588 500 CONTINUE
1589 IF (myid.EQ.master) THEN
1590 IF (associated(gcomp%ADJ)) THEN
1591 DEALLOCATE(gcomp%ADJ)
1592 nullify(gcomp%ADJ)
1593 ENDIF
1594 IF (associated(gcomp%IPE)) THEN
1595 DEALLOCATE(gcomp%IPE)
1596 nullify(gcomp%IPE)
1597 ENDIF
1598 ENDIF
1599 600 CONTINUE
1600 IF (allocated(iq)) DEALLOCATE(iq)
1601 RETURN
subroutine mpi_reduce(sendbuf, recvbuf, cnt, datatype, op, root, comm, ierr)
subroutine mpi_send(buf, cnt, datatype, dest, tag, comm, ierr)
subroutine mpi_waitany(cnt, array_of_requests, index, status, ierr)
subroutine mpi_irecv(buf, cnt, datatype, source, tag, comm, ireq, ierr)