ccm_allreduce

CCM reduction, results returned to all tasks

Routine:

ccm_allreduce

Purpose:

Gather data from all tasks in a parallel application and perform an operation, such as addition, finding minimum, or maximum on the data. All tasks have the reduced data after the call.

Minimal calling sequence:

call ccm_allreduce(xin,xout,oper)

Required Arguments:

xin :: integer, real, double precision, complex, logical, character (scaler or array), intent (in)
The values in xin are sent from each task and reduced.
xout :: integer, real, double precision, complex, logical, character (scaler or array), intent (out)
The reduced values returned to each task in the parallel application. Xout is overwritten on all tasks.
oper :: character (len= *), intent (in)
The reduction operation can be one of the following
Operation Meaning Works for data types
"+" or "sum" or "SUM" Addition reals, integers, complex
"min" or "MIN" Minimum value reals, integers
"max" or "MAX" Maximum value reals, integers
"*" or "prod"or "PROD" Product reals, integers, complex
"and" or "AND" Logical and logical
"or" or "OR" Logical or logical
"xor" or "XOR" Logical xor logical
"and" or "AND" bit-wise and integer
"or" or "OR" bit-wise or integer
"xor" or "XOR" bit-wise xor integer

Call with all Optional Arguments:

call ccm_allreduce(xin,xout,oper,constraint,the_err)
constraint :: integer,intent (in)
Value Meaning
ccm_reproducible Force the reduction operation to return
the same value whenever the function is
applied on the same arguments appearing
in the same order.
ccm_fast Potentially use a faster reduction operation
that may violate the reproducability condition
given above.
the_error:: integer, intent (out)
Error code 0 = success, != 0 failure.
See Specifying Optional Arguments for the syntax for using optional arguments.

Notes:

Xin can be any intrinsic Fortran data type: integer, real, double precision, complex, logical or, character. It can be a scaler or an array. For arrays, the operation is element wise. Xout must be large enough to hold the data that is sent.

First Example:


program ccm_allreduce_x1
    use ccm
    implicit none
    integer time_info_array(8),hour,min,sec,millisec,ierr,numprocs,myid
    integer gtime_info_array(8)
    real local_time,gtime_min,gtime_sum,gtime_max
    call ccm_init(myid,numprocs)
    call date_and_time(values=time_info_array)
    hour=time_info_array(5)
    min=time_info_array(6)
    sec=time_info_array(7)
    millisec=time_info_array(8)
    local_time=(hour*60+min)*60+sec+millisec/1000.0
    gtime_sum=0.0
    call ccm_allreduce(local_time,gtime_sum,"+")
    call ccm_allreduce(local_time,gtime_min,"min")
    call ccm_allreduce(local_time,gtime_max,"max")
    call ccm_allreduce(time_info_array,gtime_info_array,"+")
    if(myid .eq. numprocs-1)then
        write(*,*)"min  # seconds from midnight is     ",gtime_min
        write(*,*)"average  # seconds from midnight is ",gtime_sum/numprocs
        write(*,*)"max  # seconds from midnight is     ",gtime_max
        write(*,*)"average of hours        ",gtime_info_array(5)/numprocs
        write(*,*)"average of minutes      ",gtime_info_array(6)/numprocs
        write(*,*)"average of seconds      ",gtime_info_array(7)/numprocs
        write(*,*)"average of milliseconds ",gtime_info_array(8)/numprocs
    endif
    call ccm_barrier(2.0)
    if(myid .eq. 0)then
        write(*,*)"min  # seconds from midnight is     ",gtime_min
        write(*,*)"average  # seconds from midnight is ",gtime_sum/numprocs
        write(*,*)"max  # seconds from midnight is     ",gtime_max
        write(*,*)"average of hours        ",gtime_info_array(5)/numprocs
        write(*,*)"average of minutes      ",gtime_info_array(6)/numprocs
        write(*,*)"average of seconds      ",gtime_info_array(7)/numprocs
        write(*,*)"average of milliseconds ",gtime_info_array(8)/numprocs
    endif
    call ccm_close()
end program

Example output on 4 processors


[ccm_host:~/ccm/source]% ccm_allreduce_x1
 min  # seconds from midnight is       58320.3
 average  # seconds from midnight is   58320.3
 max  # seconds from midnight is       58320.3
 average of hours          16
 average of minutes        12
 average of seconds        0
 average of milliseconds   319
 min  # seconds from midnight is       58320.3
 average  # seconds from midnight is   58320.3
 max  # seconds from midnight is       58320.3
 average of hours          16
 average of minutes        12
 average of seconds        0
 average of milliseconds   319
 [ccm_host:~/ccm/source] % 

The call to ccm_init initializes the communication package and obtains the number of tasks in the application and the id for each task. The program gets the time and converts it to a real value, local_time. All tasks set gtime_sum=0. The application calls ccm_allreduce with local_time as input, first to get the global minimum, then the sum and finally the maximum on all tasks. The program calls ccm_allreduce with an integer array, time_info_array, as input and using the "+" operation. This returns the sum of the time information from each task in an array. Output is printed on the last and zeroth task. The call to ccm_close closes the communication package.

Second Example:


program ccm_allreduce_x2
    use ccm
    implicit none
    double precision :: xin(2),xout(2)
    integer :: myid,nunprocs
    integer :: constraint,the_err
    call ccm_init(myid,nunprocs)
    xout=myid
    xin(1)=myid+0.01**(mod(myid,15))
    xin(2)=-1
    constraint=ccm_fast
    call ccm_allreduce(xin(1:1),xout(1:1),"+",constraint,the_err)
    if(myid .eq. 0)then
        write(*,*)"xout= ",xout
    endif
    constraint=ccm_reproducible
    call ccm_allreduce(xin(1:1),xout(1:1),"+",constraint,the_err)
    if(myid .eq. nunprocs-1)then
        write(*,*)"xout= ",xout
    endif
    call ccm_close()
end program

Example output on 4 processors


[ccm_host:~/ccm/source]% ccm_allreduce_x2
 xout=   7.01010084152222  0.000000000000000
 xout=   7.01010084152222  3.00000000000000
[ccm_host:~/ccm/source] % 

The call to ccm_init initializes the communication package and sets myid to the id of each task. Xout is set equal to myid and the first element of xin is set to a function of myid and the second to -1. The application does a sum operation with the result printed on task 0. Only the first value of xout is changed because the application sends only a single element, xin(1:1). The program uses the "fast" protocol in the first call to ccm_reduce. The program uses the "reproducible" protocol in the second call to ccm_reduce and prints output on the last task. The reproducible protocol will always return the same result for a given set of inputs. This may not happen with the fast protocol.

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