The main documentation of the Gather Procedure contains additional explanation of this code listing.
define([GATHER_ROUTINE],[ pushdef([TYPE], [$1]) pushdef([DIM], [$2]) pushdef([Gather_TYPE_DIM], expand(Gather_TYPE_DIM)) subroutine Gather_TYPE_DIM (Output, Input, Index, Trace) ! Input variables. ! Distributed vector (bare naked vector) to be gathered. type(TYPE,1,np), intent(in) :: Input type(integer,DIM,np), intent(in), optional :: Index ! Indirect reference ! indices. ! Input/Output variable. type(Trace_type), intent(inout), optional :: Trace ! Setup information. ! Output variable. type(TYPE,DIM,np), intent(out) :: Output ! Gathered variable. ! Internal variable. ifdef([USE_PGSLIB],[ type(integer,DIM) :: Index_tmp ! Index temporary. type(logical,DIM) :: Mask_tmp ! Index mask temporary. ],[ ifelse(DIM, [1], [], [ type(integer) :: column ! Loop parameter. ]) type(integer) :: row ! Loop parameter. ]) !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! Verify requirements. ! Either the Trace or the Index, or both, must be present. VERIFY(PRESENT(Index) .or. PRESENT(Trace),5) ! Initialize the Trace. if (PRESENT(Trace)) then if (.not. Initialized(Trace)) then VERIFY(PRESENT(Index),5) call Initialize (Trace, Index, SIZE(Input)) end if end if ! Do the global gather. ifdef([USE_PGSLIB],[ ! PGSLib parallel gather. if (PRESENT(Trace)) then call PGSLib_Gather (Output, Input, Trace%Index[]DIM, & Trace%Trace, Trace%Mask[]DIM) else ifelse(DIM, [1], [ call Initialize (Index_tmp, SIZE(Index)) call Initialize (Mask_tmp, SIZE(Index)) ], [ call Initialize (Index_tmp, SIZE(Index,1), SIZE(Index,2)) call Initialize (Mask_tmp, SIZE(Index,1), SIZE(Index,2)) ]) Index_tmp = Index Mask_tmp = Index_tmp /= 0 call PGSLib_Gather (Output, Input, Index_tmp, Mask=Mask_tmp) call Finalize (Index_tmp) call Finalize (Mask_tmp) end if ],[ ! Serial gather. if (PRESENT(Trace)) then ifelse(DIM, [1], [ do row = 1, SIZE(Output, 1) if (Trace%Index1(row) /= 0) then Output(row) = Input(Trace%Index1(row)) end if end do ],[ do column = 1, SIZE(Output, 2) do row = 1, SIZE(Output, 1) if (Trace%Index2(row,column) /= 0) then Output(row,column) = Input(Trace%Index2(row,column)) end if end do end do ]) else ifelse(DIM, [1], [ do row = 1, SIZE(Output, 1) if (Index(row) /= 0) then Output(row) = Input(Index(row)) end if end do ],[ do column = 1, SIZE(Output, 2) do row = 1, SIZE(Output, 1) if (Index(row,column) /= 0) then Output(row,column) = Input(Index(row,column)) end if end do end do ]) end if ]) ! Verify guarantees - none. return end subroutine Gather_TYPE_DIM popdef([TYPE]) popdef([DIM]) popdef([Gather_TYPE_DIM]) ]) forloop([Dim],[1],[2],[ fortext([Type],[real integer logical],[ GATHER_ROUTINE(Type, Dim) ]) ])