The main documentation of the Output_ELL_Matrix Procedure contains additional explanation of this code listing.
subroutine Output_ELL_Matrix (ELLM, Row_First, Row_Last, Unit, Indent)
! Input variables.
! Variable to be output.
type(ELL_Matrix_type), intent(inout) :: ELLM
type(integer), intent(in), optional :: Row_First ! Extents of value data
type(integer), intent(in), optional :: Row_Last ! to be output.
type(integer), intent(in), optional :: Unit ! Output unit.
type(integer), optional :: Indent ! Indentation.
! Internal variables.
type(integer) :: Buffer_Loc ! Buffer location.
type(integer) :: Buffer_Size ! Output buffer size.
type(integer) :: Buffer_Skip ! Buffer increment.
type(integer) :: i_global, i_local ! Loop counters.
type(integer) :: A_Row_First ! Actual first row value.
type(integer) :: A_Row_Last ! Actual last row value.
type(integer) :: A_Unit ! Actual output unit.
type(integer) :: A_Indent ! Actual indentation.
type(character,80) :: Blanks ! A line of blanks.
type(character,80) :: ELLM_Name ! Name of the ELLM.
type(character,80) :: Output_1 ! Output buffer.
type(character,80,1) :: Output_Buffer ! Output buffer vector.
type(real) :: ELLM_Average, ELLM_Frobenius_Norm, & ! Get Value variables.
ELLM_Infinity_Norm, ELLM_Maximum, &
ELLM_Minimum, ELLM_One_Norm, &
ELLM_Sum, ELLM_Two_Norm_Estimate
type(real), dimension(2) :: ELLM_Two_Norm_Range
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! Verify requirements.
VERIFY(Valid_State(ELLM),5) ! ELLM is valid.
! Set unit number.
if (PRESENT(Unit)) then
A_Unit = Unit
else
A_Unit = 6
end if
! Set indentation.
if (PRESENT(Indent)) then
A_Indent = Indent
else
A_Indent = 0
end if
Blanks = ' '
! These are evaluated on all PEs -- NOT inside an IO PE block --
! because they contain validity checks on ELLM and thus require
! global communication.
ELLM_Name = Name(ELLM)
ELLM_Average = Average(ELLM)
ELLM_Infinity_Norm = Infinity_Norm(ELLM)
ELLM_Maximum = Maximum(ELLM)
ELLM_Minimum = Minimum(ELLM)
ELLM_One_Norm = One_Norm(ELLM)
ELLM_Frobenius_Norm = Frobenius_Norm(ELLM)
ELLM_Sum = Sum(ELLM)
ELLM_Two_Norm_Estimate = Two_Norm_Estimate(ELLM)
ELLM_Two_Norm_Range = Two_Norm_Range(ELLM)
! Output Identification Info.
if (this_is_IO_PE) then
write (A_Unit,100) Blanks(1:A_Indent), 'ELL Matrix Information:'
write (A_Unit,101) Blanks(1:A_Indent+2), 'Name = ', &
TRIM(ELLM_Name)
write (A_Unit,102) Blanks(1:A_Indent+2), 'Initialized = ', &
Initialized(ELLM)
write (A_Unit,103) Blanks(1:A_Indent+2), 'Dimensionality =', &
ELLM%Dimensionality
write (A_Unit,103) Blanks(1:A_Indent+2), 'Max_Nonzeros =', &
ELLM%Max_Nonzeros
write (A_Unit,104) Blanks(1:A_Indent+2), 'Average =', &
ELLM_Average
write (A_Unit,104) Blanks(1:A_Indent+2), 'Maximum =', &
ELLM_Maximum
write (A_Unit,104) Blanks(1:A_Indent+2), 'Minimum =', &
ELLM_Minimum
write (A_Unit,104) Blanks(1:A_Indent+2), 'Sum =', &
ELLM_Sum
write (A_Unit,104) Blanks(1:A_Indent+2), 'Infinity_Norm =', &
ELLM_Infinity_Norm
write (A_Unit,104) Blanks(1:A_Indent+2), 'One_Norm =', &
ELLM_One_Norm
write (A_Unit,104) Blanks(1:A_Indent+2), 'Two_Norm_Estimate =', &
ELLM_Two_Norm_Estimate
write (A_Unit,105) Blanks(1:A_Indent+2), 'Two_Norm_Range =', &
ELLM_Two_Norm_Range
write (A_Unit,104) Blanks(1:A_Indent+2), 'Frobenius_Norm =', &
ELLM_Frobenius_Norm
end if
! Output internal structure info.
call Output (ELLM%Row_Structure, A_Unit, 'Row', A_Indent+2)
call Output (ELLM%Column_Structure, A_Unit, 'Column', A_Indent+2)
! Output internal values.
if (this_is_IO_PE) then
write (A_Unit,100) Blanks(1:A_Indent), ' Internal Values:'
end if
! Set up local limits in terms of global limits.
if (PRESENT(Row_First)) then
A_Row_First = Row_First
else
A_Row_First = 1
end if
if (PRESENT(Row_Last)) then
A_Row_Last = Row_Last
else
A_Row_Last = Length_Total(ELLM%Row_Structure)
end if
A_Row_First = MAX(A_Row_First, First_PE(ELLM%Row_Structure))
A_Row_Last = MIN(A_Row_Last, Last_PE(ELLM%Row_Structure))
! Output Values.
Buffer_Size = MAX(0, ((ELLM%Max_Nonzeros + 2) / 3) &
* (A_Row_Last - A_Row_First + 1))
call Initialize (Output_Buffer, Buffer_Size)
if (Buffer_Size /= 0) then
Buffer_Skip = (ELLM%Max_Nonzeros + 2) / 3
Buffer_Loc = 1
do i_global = A_Row_First, A_Row_Last
i_local = i_global - First_PE(ELLM%Row_Structure) + 1
write (Output_Buffer(Buffer_Loc:Buffer_Loc+Buffer_Skip-1),106) &
'PE:', this_PE, ', Values(', i_global, ',:) =', &
ELLM%Values(i_local,:)
Buffer_Loc = Buffer_Loc + Buffer_Skip
end do
end if
! Add indentation and output.
do Buffer_loc = 1, Buffer_Size
Output_1 = Output_Buffer(Buffer_loc)
Output_Buffer(Buffer_loc) = Blanks(1:A_Indent) // Output_1
end do
call Parallel_Write (Output_Buffer, A_Unit)
! Output Columns.
if (this_is_IO_PE) then
write (A_Unit,*) ' '
end if
if (Buffer_Size /= 0) then
Buffer_Skip = (ELLM%Max_Nonzeros + 2) / 3
Buffer_Loc = 1
do i_global = A_Row_First, A_Row_Last
i_local = i_global - First_PE(ELLM%Row_Structure) + 1
write (Output_Buffer(Buffer_Loc:Buffer_Loc+Buffer_Skip-1),107) &
'PE:', this_PE, ', Columns(', i_global, ',:) =', &
ELLM%Columns(i_local,:)
Buffer_Loc = Buffer_Loc + Buffer_Skip
end do
end if
! Add indentation and output.
do Buffer_loc = 1, Buffer_Size
Output_1 = Output_Buffer(Buffer_loc)
Output_Buffer(Buffer_loc) = Blanks(1:A_Indent) // Output_1
end do
call Parallel_Write (Output_Buffer, A_Unit)
! Clean up.
call Finalize (Output_Buffer)
! Format statements. With these formats, this should work up to
! (10^6 - 1) PEs.
100 format (/, 2a, /)
101 format (3a)
102 format (2a, l2)
103 format (2a, i12, :, 3(',', i12, :), a)
104 format (2a, ' ', 1p, e13.5e3)
105 format (2a, ' (', 1p, e13.5e3, ',', e13.5e3, ')')
106 format (2x, a, i5, a, i12, a, 1p, e13.5e3, :, &
2(',', e13.5e3, :), ',', /, &
(36x, e13.5e3, :, 2(',', e13.5e3, :), ','))
107 format (2x, a, i5, a, i11, a, i13, :, &
2(',', i13, :), ',', /, &
(36x, i13, :, 2(',', i13, :), ','))
! Verify guarantees - none.
return
end subroutine Output_ELL_Matrix