ccm_gatherv

CCM gather with variable amounts of data

Routine:

ccm_gatherv

Purpose:

Send different amounts of 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_gatherv(xin,xout,to_get)

Required Arguments:

xin :: integer, real, double precision, complex, logical, character array,intent (in)
The values in xin will be gathered from one every task to a single task.
xout :: integer, real, double precision, complex, logical, character array,intent (out)
The values gathered from each task will be placed in xout. Xout is overwritten on the zeroth or root task.
to_get :: integer, rank one array of size equal to the number of tasks in the parallel application,intent (in)
The number of values sent from a given task from each other task.

Call with all Optional Arguments:

call ccm_gatherv(xin,xout,to_get,offset,root,the_err)
offset :: integer, rank one array of size equal to the number of tasks in the parallel application,intent (in)
Location of where the data from a particular task is placed, relative to the beginning of xout. If not given, then the values are placed after each other in the normal order, those from task n+1 after those from task n.
root :: integer,intent (in)
The number of the task that sends the data, defaults to the root 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. Both must be arrays.

First example:


program ccm_gatherv_x1
    use ccm 
    implicit none
    integer :: myid,numprocs,igot,i,j
    integer, allocatable :: xin(:), xout(:)
    integer, allocatable :: to_get(:)
    integer :: to_send
    call ccm_init(myid,numprocs) 
    if(myid .eq. 0)then
        allocate(to_get(0:numprocs-1))
        do i=0,numprocs-1
           to_get(i)=myid+i
        enddo
    else 
    	allocate(to_get(0))
    endif
    call ccm_scatter(to_get,to_send)
    allocate(xin(to_send))
    if(size(xin) .gt. 0)xin=myid
    if(myid .eq. 0)then
        allocate(xout(sum(to_get)))
    else
        allocate(xout(0))
    endif
    call ccm_gatherv(xin,xout,to_get)
    if(myid .eq. 0)write(*,"("" i= "",i4,"" xout= "",20i3)")myid,xout
    call ccm_close()
end program

Example output on 4 processors


[ccm_host:~/ccm/source]% ccm_gatherv_x1
i=    0 xout=   1  2  2  3  3  3
[ccm_host:~/ccm/source] % 

The call to ccm_init initializes the communication package. Task 0 allocates and fills the to_get array. The number of values to be sent from each task is equal to the id. The tasks are given this information by the call to ccm_scatter. The values to be gathered are also set to the id. Space is allocated for the output. The values are gathered with ccm_gatherv and task 0 prints what it has received. The call to ccm_close closes the communication package.

Second example:


program ccm_gatherv_x2
    use ccm
    implicit none
    integer :: myid,numprocs,igot,i,j
    character, allocatable :: xin(:),xout(:)
    integer ,allocatable :: to_send(:),offset(:)
    integer :: to_get
    call ccm_init(myid,numprocs)
    allocate(to_send(numprocs),offset(numprocs))
    to_send=4
    to_get=4
    if(myid .eq. 0)then
        allocate(xin(sum(to_send)))
        do i=1,size(xin)
            xin(i)=char(ichar('a')+mod(i-1,26))
        enddo
        do i=1,numprocs
           offset(i)=(numprocs-i)*to_send(1)
        enddo
        write(*,*)"send array is: ",xin
    else
        allocate(xin(0))
    endif
    allocate(xout(to_get))
    call ccm_scatterv(xin,xout,to_send,offset)
    write(*,"("" i= "",i4,"" xout= "",8a1)")myid,xout   
    if(size(xout) .gt. 0)then
       do i=1,size(xout)
         xout(i)=char(ichar(xout(i))-32)
       enddo
    endif
    call ccm_gatherv(xout,xin,to_send,offset)
    call ccm_barrier(1.0)
    if(myid .eq. 0) write(*,"("" i= "",i4,"" xin is now = "",60a1)")myid,xin
    call ccm_close()
end program

Example output on 4 processors


[ccm_host:~/ccm/source]% ccm_gatherv_x2
 send array is: abcdefghijklmnop
 i=    0 xout= mnop
 i=    1 xout= ijkl
 i=    2 xout= efgh
 i=    3 xout= abcd
 i=    0 xin is now = ABCDEFGHIJKLMNOP
[ccm_host:~/ccm/source] % 

This example is based on the second ccm_scatterv example. The call to ccm_init initializes the communication package. The count and offset arrays are allocated. Each task will receive 4 values. Task 0 fills an array with 16 characters. The program scatters values in reverse order by filling the offset array as shown. Task 3 gets characters from the beginning of the array and task 0 from the end. The program sends the values by using ccm_scatterv. They are printed with task 3 writing the beginning of the alphabet. Each task converts is characters to upper case. The values are gathered back to task zero. This is done by using the same inputs as the scatterv but flipping the xout/xin arrays Task 0 prints the upper case string. The call to ccm_close closes the communication package.

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