ccm_gather

CCM gather

Routine:

ccm_gather

Purpose:

Send data from all tasks to a single task. By default, the zeroth task in the parallel application receives the data. Xout is overwritten on the receiving task.

Minimal calling sequence:

call ccm_gather(xin,xout)

Required Arguments:

xin :: integer, real, double precision, complex, logical, character array,intent (inout)
The values in xin will be gathered to one task from all other tasks in a parallel application.
xout :: integer, real, double precision, complex, logical, character array,intent (inout)
The values in xin will be gathered to one task from all other tasks in a parallel application and placed in xout. Xout is overwritten on the zeroth or root task.

Call with all Optional Arguments:

call ccm_gather(xin,xout,root,the_err)
root :: integer,intent (in)
The number of the task that gathers the data, defaults to the zeroth task of the parallel application.
the_err :: integer, intent (out)
Error code 0 = success, != 0 failure.
See Specifying Optional Arguments for the syntax for using optional arguments.

Notes:

Xin and xout can be any intrinsic Fortran data type: integer, real, double precision, complex, logical or, character. Xin can be a scaler or an array. If xin is an array then the entire array will be transmitted. It must be the same size on all tasks. Xout must be an array.

First example:


program ccm_gather_x1
    use ccm
    implicit none
    integer :: myid,numprocs,igot,i
    integer ,allocatable :: to_get(:),to_send(:)
    real local_time,global_time
    call ccm_init(myid,numprocs)
    allocate(to_get(numprocs))
    to_get=0
    call ccm_gather(myid,to_get)
    if(myid .eq. 0)write(*,*)to_get
    allocate(to_send(2))
    to_get=0
    to_send(1)=myid
    to_send(2)=-1
    call ccm_gather(to_send(1:1),to_get,root=2)
    if(myid .eq. 2)write(*,*)to_get
    call ccm_close()
end program

Example output on 4 processors


[ccm_host:~/ccm/source]% ccm_gather_x1
   0  1  2  3
   0  1  2  3
[ccm_host:~/ccm/source] % 

The call to ccm_init initializes the communication package and sets myid and numprocs. The program gathers values to an array and prints them. The second time this is done the values are put into the first element of an array and then that element is gathered to task 2 and printed. Ccm_close is called to close the package.

Second Example:


program ccm_gather_x2
    use ccm
    implicit none
    real :: i40(40),i3d(5,4,2),got(8),back(5,4,2)
    real,allocatable :: rs(:,:),tmp(:,:,:),tmp2(:,:)
    integer:: order(3),new_shape(3)
    integer:: myid,numprocs,i,j,k
    do i=1,40
        i40(i)=i
    enddo
    i3d=reshape(i40,shape(i3d))
    call ccm_init(myid,numprocs)
    if(myid .eq. 0)then
        write(*,*)"3d array of bounds ",shape(i3d)
        do k=1,2
            write(*,*)"plane ",k
            do i=1,5
                write(*,"(4f5.0)")(i3d(i,j,k),j=1,4)
            enddo
        enddo
    endif
    back=0
!
    call ccm_barrier(0.95,.true.)
    allocate(rs(2,5))
    order=(/1,2,3/)
    new_shape=(/5,4,2/)
    call ccm_scatter(reshape(i3d,shape=new_shape,order=order),rs)
    if(myid .eq. 0)write(*,"(/3i3,5x,3i3)")order,new_shape
    do i=1,2
        if(i.eq. 1)then
            write(*,"(i4,(5f5.0))")myid,(rs(i,j),j=1,5)
        else
            write(*,"(4x,(5f5.0))")(rs(i,j),j=1,5)
        endif
    enddo
    call ccm_barrier(0.95,.true.)
    call ccm_gather(rs,back)
    if(myid .eq. 0)then
        write(*,*)"difference =",sum(abs(back-i3d))
    endif
    call ccm_barrier(0.95,.true.)
    deallocate(rs)
    allocate(rs(10,1))
    order=(/3,1,2/)
    new_shape=(/2,5,4/)
    call ccm_scatter(reshape(i3d,shape=new_shape,order=order),rs)
    if(myid .eq. 0)write(*,"(/3i3,5x,3i3)")order,new_shape
    write(*,"(i4,(10f5.0))")myid,(rs(i,1),i=1,10)
    allocate(tmp2(10,4))
    call ccm_barrier(0.95,.true.)
    call ccm_gather(rs,tmp2)
    if(myid .eq. 0)then
        back=reshape(reshape(tmp2,(/4,10/),order=(/2,1/)),shape(back))
        write(*,*)"difference =",sum(abs(back-i3d))
    endif
    call ccm_barrier(0.95,.true.)
    order=(/3,1,2/)
    new_shape=(/5,4,2/)
    call ccm_scatter(reshape(i3d,shape=new_shape,order=order),rs)
    if(myid .eq. 0)write(*,"(/3i3,5x,3i3)")order,new_shape
    write(*,"(i4,(10f5.0))")myid,(rs(i,1),i=1,10)
    deallocate(tmp2)
    allocate(tmp2(20,2))
    call ccm_barrier(0.95,.true.)
    call ccm_gather(rs,tmp2)
    if(myid .eq. 0)then
        back=reshape(reshape(tmp2,(/2,20/),order=(/2,1/)),shape(back))
        write(*,*)"difference =",sum(abs(back-i3d))
    endif   
    call ccm_barrier(0.95,.true.)
    deallocate(rs)
    allocate(rs(5,2))
    order=(/2,3,1/)
    new_shape=(/5,4,2/)
    call ccm_scatter(reshape(i3d,shape=new_shape,order=order),rs)
    if(myid .eq. 0)write(*,"(/3i3,5x,3i3)")order,new_shape
    do j=1,2
        if(j.eq. 1)then
            write(*,"(i4,(5f5.0))")myid,(rs(i,j),i=1,5)
        else
            write(*,"(4x,(5f5.0))")(rs(i,j),i=1,5)
        endif
    enddo
    deallocate(tmp2)
    allocate(tmp2(5,8))
    call ccm_barrier(0.95,.true.)
    call ccm_gather(rs,tmp2)
    if(myid .eq. 0)then
        back=reshape(reshape(tmp2,(/8,5/),order=(/2,1/)),shape(back))
        write(*,*)"difference =",sum(abs(back-i3d))
    endif       
    call ccm_barrier(0.95,.true.)
    deallocate(rs)
    allocate(rs(5,2))
    order=(/2,1,3/)
    new_shape=(/5,4,2/)
    call ccm_scatter(reshape(i3d,shape=new_shape,order=order),rs)
    if(myid .eq. 0)write(*,"(/3i3,5x,3i3)")order,new_shape
    do j=1,2
        if(j.eq. 1)then
            write(*,"(i4,(5f5.0))")myid,(rs(i,j),i=1,5)
        else
            write(*,"(4x,(5f5.0))")(rs(i,j),i=1,5)
        endif
    enddo
    allocate(tmp(5,4,2))
    call ccm_barrier(0.95,.true.)
    call ccm_gather(rs,tmp)
    if(myid .eq. 0)then
       back=reshape(reshape(tmp,(/4,5,2/),order=(/2,1,3/)),shape(back))
       write(*,*)"difference =",sum(abs(back-i3d))
    endif       
    call ccm_barrier(0.95,.true.)
    deallocate(rs)
    call ccm_close()
end program

Example output on 4 processors


[ccm_home:~/ccm/source] % ccm_gather_x2
 3d array of bounds   5  4  2
 plane   1
   1.   6.  11.  16.
   2.   7.  12.  17.
   3.   8.  13.  18.
   4.   9.  14.  19.
   5.  10.  15.  20.
 plane   2
  21.  26.  31.  36.
  22.  27.  32.  37.
  23.  28.  33.  38.
  24.  29.  34.  39.
  25.  30.  35.  40.

  1  2  3       5  4  2
   0   1.   3.   5.   7.   9.
       2.   4.   6.   8.  10.
   1  11.  13.  15.  17.  19.
      12.  14.  16.  18.  20.
   2  21.  23.  25.  27.  29.
      22.  24.  26.  28.  30.
   3  31.  33.  35.  37.  39.
      32.  34.  36.  38.  40.
 difference =  0.000000

  3  1  2       2  5  4
   0   1.   5.   9.  13.  17.  21.  25.  29.  33.  37.
   1   2.   6.  10.  14.  18.  22.  26.  30.  34.  38.
   2   3.   7.  11.  15.  19.  23.  27.  31.  35.  39.
   3   4.   8.  12.  16.  20.  24.  28.  32.  36.  40.
 difference =  0.000000

  3  1  2       5  4  2
   0   1.   3.   5.   7.   9.  11.  13.  15.  17.  19.
   1  21.  23.  25.  27.  29.  31.  33.  35.  37.  39.
   2   2.   4.   6.   8.  10.  12.  14.  16.  18.  20.
   3  22.  24.  26.  28.  30.  32.  34.  36.  38.  40.
 difference =  0.000000

  2  3  1       5  4  2
   0   1.   9.  17.  25.  33.
       2.  10.  18.  26.  34.
   1   3.  11.  19.  27.  35.
       4.  12.  20.  28.  36.
   2   5.  13.  21.  29.  37.
       6.  14.  22.  30.  38.
   3   7.  15.  23.  31.  39.
       8.  16.  24.  32.  40.
 difference =  0.000000

  2  1  3       5  4  2
   0   1.   5.   9.  13.  17.
       2.   6.  10.  14.  18.
   1   3.   7.  11.  15.  19.
       4.   8.  12.  16.  20.
   2  21.  25.  29.  33.  37.
      22.  26.  30.  34.  38.
   3  23.  27.  31.  35.  39.
      24.  28.  32.  36.  40.
 difference =  0.000000
[ccm_home:~/ccm/source] % 

This example is based on the example given for ccm_scatter. The call to ccm_init initializes the communication package. The program starts with the root task holding a 40 element 3d array that contains the values 1-40. Scatter is used along the Fortran 90 reshape routine to produce various spreads of the data to tasks. Task zero prints the order and shape that are input to the reshape function. All tasks print the received data. Gather is then used along with reshape to reproduce the original array on the zeroth process. Note: the values printed above were rearranged in give the "proper" order, 0,1,2,3.



Error conditions:

If the error checking level is set to ccm_checksize the following error condition(s) are checked: These conditions may lead to a Underling communications error if not detected.
Back to API and user's guide