CCM reduction




Gather data from all tasks in a parallel application to a single task while performing an operation, such as addition, finding minimium, or maximum on the data. By default, the zeroeth task in the parallel application holds the reduced data after the call.

Minimal calling sequence:

call ccm_reduce(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 the "root" or zeroth task in the parallel application. Xout is only overwritten on the receiving task.
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_reduce(xin,xout,oper,constraint,root,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 recudtion operation
that may violate the reproducability condition
given above.
root :: integer, intent (in)
The number of the task that receives the reduced data, defaults to the zeroth task.
the_error:: integer, intent (out)
Error code 0 = success, != 0 failure.
See Specifying Optional Arguments for the syntax for using optional arguments.


Xin can be one of the Fortran data types: integer, real, double precision, complex, logical. It can be a scaler or an array. For arrays, the operation is element wise. On the root task, xout must be large enough to hold the data that is sent.

First Example:

program ccm_reduce_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(num_procs=numprocs)
    call date_and_time(values=time_info_array)
    call ccm_reduce(local_time,gtime_sum,"+")
    call ccm_reduce(local_time,gtime_min,"min")
    call ccm_reduce(local_time,gtime_max,"max")
    call ccm_reduce(time_info_array,gtime_info_array,"+")
    if(gtime_sum .gt. 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
    call ccm_close()
end program

Example output on 4 processors

[ccm_host:~/ccm/source]% ccm_reduce_x1
 min  # seconds from midnight is       48276.2
 average  # seconds from midnight is   48306.8
 max  # seconds from midnight is       48381.2
 average of hours          13
 average of minutes        24
 average of seconds        36
 average of milliseconds   324
[ccm_host:~/ccm/source] % 

The call to ccm_init initializes the communication package. The call to ccm_int contains the optional argument num_procs=numprocs to get the number of tasks in the application. The time is then obtained and converted to a real value, local_time. All tasks set gtime_sum=0. The application calls ccm_reduce with local_time as input, first to get the global minimum, then the sum and finally the maximum on all tasks. The reduced value is returned only to the root task, so after these calls to ccm_reduce gtime_sum will have a nonzero value only the root. The program calls ccm_reduce with an integer array, time_info_array, as input and using the "+" operation. On the root task, we have the sum of the time information from each task returned in an array. The root task prints this information. The call to ccm_close closes the communication package.

Second Example:

program ccm_reduce_x2
    use ccm
    implicit none
    double precision :: xin(2),xout(2)
    integer :: myid
    integer :: constraint,root,the_err
    call ccm_init(myid)
    call ccm_reduce(xin(1:1),xout(1:1),"+",constraint,root,the_err)
    if(myid .eq. root)then
        write(*,*)"xout= ",xout
    call ccm_reduce(xin(1:1),xout(1:1),"+",constraint,root,the_err)
    if(myid .eq. root)then
        write(*,*)"xout= ",xout
    call ccm_close()
end program

Example output on 10 processors

[ccm_host:~/ccm/source]% ccm_reduce_x2
 xout=   46.0101008415222  2.00000000000000
 xout=   46.0101008415222  2.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 returned to task 2. 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. 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