The main documentation of the Read_Harwell_Boeing_ELL_Matrix Procedure contains additional explanation of this code listing.
subroutine Read_Harwell_Boeing_ELL_Matrix (ELLM, RHS_MV, Solution_MV, & Guess_MV, Row_Structure, & Column_Structure, Unit, status) ! Input variables. type(integer), intent(in), optional :: Unit ! Input unit. ! Output variables. ! ELL_Matrix to be initialized. type(ELL_Matrix_type), intent(out) :: ELLM type(Status_type), intent(out), optional :: status ! Exit status. ! Row and Column Base_Structures. type(Base_Structure_type), intent(inout), target :: Row_Structure, & Column_Structure ! RHS mathematic vector (RHSVAL). type(Mathematic_Vector_type), optional :: RHS_MV ! Guess mathematic vector (SGUESS). type(Mathematic_Vector_type), optional :: Guess_MV ! Solution mathematic vector (XEXACT). type(Mathematic_Vector_type), optional :: Solution_MV ! Internal variables. type(integer) :: A_Unit ! Actual output unit. type(Status_type), dimension(33) :: allocate_status ! Allocation Status. type(Status_type) :: consolidated_status ! Consolidated Status. type(integer) :: Max_Nonzeros ! Maximum number of nonzero elements/row. type(integer) :: Max_Nonzeros_PE ! Maximum number of nonzero elements/row, ! set to zero on non-IO PEs. ! Line 1: type(character,name_length) :: Name ! Matrix name (TITLE). type(character,8) :: Key ! Key for matrix (KEY). ! Line 2: Number of lines in the file, for... type(integer) :: NTotal_Lines ! Total, not including ! header (TOTCRD). type(integer) :: NEntries_of_Columns_Lines ! Entries of Columns ! (PTRCRD). type(integer) :: NRows_of_Entries_Lines ! Rows of Entries (INDCRD). type(integer) :: NValues_Lines ! Numerical values (VALCRD). type(integer) :: NRHS_Lines ! Right-hand sides, ! including starting ! guesses and solution ! vectors (RHSCRD). ! Line 3: type(character,3) :: Matrix_Type ! Matrix type (MXTYPE). type(integer) :: NRows ! Number of rows (NROW). type(integer) :: NColumns ! Number of Columns (NCOL). type(integer) :: NEntries ! Number of nonzero entries in ! the matrix (NNZERO). type(integer) :: NElemental_Matrices ! Number of elemental matrices ! (NELTVL). ! Line 4: Format strings for... type(character,16) :: Entries_of_Columns_Format ! Entries of Columns ! (PTRFMT). type(character,16) :: Rows_of_Entries_Format ! Rows of Entries (INDFMT). type(character,20) :: Values_Format ! Values (VALFMT). type(character,20) :: RHS_Format ! RHS values (RHSFMT). ! Line 5: type(character,3) :: RHS_Type ! RHS type (RHSTYP). type(integer) :: NRHS ! Number of RHS vectors, not ! including solution or guess ! vectors (NRHS). type(integer) :: NRHS_Nonzero_Rows ! Number of RHS nonzero rows ! (NRHSIX). ! Data: type(integer,1) :: Entries_of_Columns ! Entry numbers of each column ! (POINTR). type(integer,1) :: Rows_of_Entries ! Row numbers of each Entry ! (ROWIND). type(real,1) :: Values_CSC ! Numerical values for the ! Compressed Sparse Column ! (CSC) matrix (VALUES). type(real,2) :: Values ! Numerical values for the ! ELL matrix (VALUES). type(integer,2) :: Columns ! Column indices for the ! ELL matrix (). type(real,2) :: Values_PE ! Numerical values for the ! ELL matrix on this PE ! (VALUES). type(integer,2) :: Columns_PE ! Column indices for the ! ELL matrix on this PE ! (). type(real,1) :: RHS_Values_PE ! RHS vector for each PE ! (RHSVAL). type(real,1) :: Solution_PE ! Solution vector for each PE ! (XEXACT). type(real,1) :: Guess_PE ! Initial guess vector for each ! PE (SGUESS). ! Temporary structures for input. type(real,1) :: Temporary_BNV type(Assembled_Vector_type) :: Temporary_AV type(Distributed_Vector_type) :: Temporary_DV ! Other internal variables. type(integer,1) :: Row_Length_Vector ! Row lengths on all the PEs. type(integer,1) :: Column_Length_Vector ! Column lengths on all the PEs. type(character,name_length) :: Locus_Name ! Structure locus name. type(integer) :: column, column_PE, entry, row ! Loop parameters. type(integer,1) :: ELL_Column ! Current ELL column number. type(integer,1) :: Nonzeros_per_Row ! Number of nonzero entries ! per row. !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ! Verify requirements. ! ELLM, Row_Structure, Column_Structure have not been initialized. VERIFY(.not.Initialized(ELLM),5) VERIFY(.not.Initialized(Row_Structure),5) VERIFY(.not.Initialized(Column_Structure),5) ! Set unit number. if (PRESENT(Unit)) then A_Unit = Unit else A_Unit = 5 end if ! Allocations and initializations. call Initialize (allocate_status) call Initialize (consolidated_status) ! Read in the header block. if (this_is_IO_PE) then Name = ' ' read (A_Unit,100) Name(1:72), Key read (A_Unit,101) NTotal_Lines, NEntries_of_Columns_Lines, & NRows_of_Entries_Lines, NValues_Lines, NRHS_Lines read (A_Unit,102) Matrix_Type, NRows, NColumns, NEntries, & NElemental_Matrices read (A_Unit,103) Entries_of_Columns_Format, Rows_of_Entries_Format,& Values_Format, RHS_Format if (NRHS_Lines > 0) then read (A_Unit,104) RHS_Type, NRHS, NRHS_Nonzero_Rows else RHS_Type = 'F ' NRHS = 0 NRHS_Nonzero_Rows = 0 end if end if ! Format statements. 100 format (a72, a8) 101 format (5i14) 102 format (a3, 11x, 4i14) 103 format (2a16, 2a20) 104 format ( a3, 11x, 2i14 ) ! Broadcast needed information (could put this into a ! smaller number of broadcasts (by type) later). call Broadcast (Matrix_Type) call Broadcast (NColumns) call Broadcast (NElemental_Matrices) call Broadcast (NEntries) call Broadcast (NRHS) call Broadcast (NRHS_Lines) call Broadcast (NRows) call Broadcast (NValues_Lines) call Broadcast (RHS_Type) ! Input checks. ! Can only read real, unsymmetric, assembled matrices. VERIFY(Matrix_Type=='RUA' .or. Matrix_Type=='rua',2) ! Can only read assembled matrices (warn on this only because ! often-used SPARSKIT routines do this incorrectly). WARN_IF(NElemental_Matrices/=0,2) ! Can read at most one right-hand-side vector. VERIFY(NRHS<=1,2) ! Cannot read sparse-storage RHS vectors. VERIFY(.not.(NRHS_Lines>0 .and. RHS_Type(1:1)/='F'),2) ! Gots to be a matrix. VERIFY(NValues_Lines>0,2) ! Set Row and Column Structures (divide evenly among the PEs). call Initialize (Row_Length_Vector, NPEs) call Generate_Even_Distribution (Row_Length_Vector, NRows) Locus_Name = 'Rows' call Initialize (Row_Structure, Row_Length_Vector, Locus_Name, & allocate_status(1)) call Initialize (Column_Length_Vector, NPEs) call Generate_Even_Distribution (Column_Length_Vector, NColumns) Locus_Name = 'Columns' call Initialize (Column_Structure, Column_Length_Vector, Locus_Name, & allocate_status(2)) ! Read in matrix structure. call Initialize (Entries_of_Columns, NColumns+1, allocate_status(3)) call Initialize (Rows_of_Entries, NEntries, allocate_status(4)) if (this_is_IO_PE) then read (A_Unit,Entries_of_Columns_Format) Entries_of_Columns read (A_Unit,Rows_of_Entries_Format) Rows_of_Entries end if ! Determine Max_Nonzeros. call Initialize (Nonzeros_per_Row, NRows, allocate_status(5)) if (this_is_IO_PE) then do entry = 1, NEntries Nonzeros_per_Row(Rows_of_Entries(entry)) = & Nonzeros_per_Row(Rows_of_Entries(entry)) + 1 end do Max_Nonzeros = MAXVAL(Nonzeros_per_Row) end if call Broadcast (Max_Nonzeros) call Finalize (Nonzeros_per_Row, allocate_status(6)) ! Initialize temporary BNA ELL structure - on non-IO PEs, this is a ! dummy, unused structure. if (this_is_IO_PE) then Max_Nonzeros_PE = Max_Nonzeros else Max_Nonzeros_PE = 1 end if call Initialize (Values, NRows, Max_Nonzeros_PE, allocate_status(7)) call Initialize (Columns, NRows, Max_Nonzeros_PE, allocate_status(8)) ! Read matrix values. call Initialize (Values_CSC, NEntries, allocate_status(9)) if (this_is_IO_PE) then read (A_Unit,Values_Format) Values_CSC end if ! Convert to ELL structure. call Initialize (ELL_Column, NRows, allocate_status(10)) if (this_is_IO_PE) then ELL_Column = 0 do column = 1, NColumns do entry = Entries_of_Columns(column), Entries_of_Columns(column+1)-1 row = Rows_of_Entries(entry) ELL_Column(row) = ELL_Column(row) + 1 Values(row,ELL_Column(row)) = Values_CSC(entry) Columns(row,ELL_Column(row)) = column end do end do else ELL_Column = 1 end if ! Max_Nonzeros matches ELL_Column. VERIFY(MAXVAL(ELL_Column)==Max_Nonzeros_PE,7) call Finalize (ELL_Column, allocate_status(11)) call Finalize (Values_CSC, allocate_status(12)) call Finalize (Entries_of_Columns, allocate_status(13)) call Finalize (Rows_of_Entries, allocate_status(14)) ! Distribute matrix to PEs. call Initialize (Values_PE, Row_Length_Vector(this_PE), Max_Nonzeros, & allocate_status(15)) call Initialize (Columns_PE, Row_Length_Vector(this_PE), Max_Nonzeros, & allocate_status(16)) do column = 1, Max_Nonzeros if (this_is_IO_PE) then column_PE = column else column_PE = 1 end if call Distribute (Values_PE(:,column), Values(:,column_PE), & Row_Length_Vector) call Distribute (Columns_PE(:,column), Columns(:,column_PE), & Row_Length_Vector) end do call Finalize (Values, allocate_status(17)) call Finalize (Columns, allocate_status(18)) ! Initialize matrix structure and set. call Initialize (ELLM, Max_Nonzeros, Row_Structure, & Column_Structure, Name, allocate_status(19)) call Set_Values (ELLM, Values_PE, Columns_PE) call Finalize (Values_PE, allocate_status(20)) call Finalize (Columns_PE, allocate_status(21)) ! Read Right-Hand Sides. if (NRHS > 0) then if (PRESENT(RHS_MV)) then call Initialize (Temporary_BNV, NRows, allocate_status(22)) call Initialize (Temporary_AV, Row_Structure, 1, & status=allocate_status(23)) call Initialize (Temporary_DV, Row_Structure, 1, & status=allocate_status(24)) call Initialize (RHS_Values_PE, Row_Length_Vector(this_PE), & status=allocate_status(25)) call Initialize (RHS_MV, Row_Structure, 'RHS: '//Name, & allocate_status(26)) if (this_is_IO_PE) then read (A_Unit,RHS_Format) Temporary_BNV end if Temporary_AV = Temporary_BNV Temporary_DV = Temporary_AV RHS_Values_PE = Temporary_DV RHS_MV = RHS_Values_PE end if ! Read starting guesses. if (RHS_Type(2:2) == 'G' .and. PRESENT(Guess_MV)) then call Initialize (Guess_PE, Column_Length_Vector(this_PE), & status=allocate_status(27)) call Initialize (Guess_MV, Column_Structure, 'Guess: '//Name, & allocate_status(28)) if (this_is_IO_PE) then read (A_Unit,RHS_Format) Temporary_BNV end if Temporary_AV = Temporary_BNV Temporary_DV = Temporary_AV Guess_PE = Temporary_DV Guess_MV = Guess_PE end if ! Read solution vectors. if (RHS_Type(3:3) == 'X' .and. PRESENT(Solution_MV)) then call Initialize (Solution_PE, Column_Length_Vector(this_PE), & status=allocate_status(29)) call Initialize (Solution_MV, Column_Structure, 'Solution: '//Name, & allocate_status(30)) if (this_is_IO_PE) then read (A_Unit,RHS_Format) Temporary_BNV end if Temporary_AV = Temporary_BNV Temporary_DV = Temporary_AV Solution_PE = Temporary_DV Solution_MV = Solution_PE end if ! Clean up. call Finalize (Temporary_BNV, allocate_status(31)) call Finalize (Temporary_AV, allocate_status(32)) call Finalize (Temporary_DV, allocate_status(33)) end if ! Process status variables. consolidated_status = allocate_status if (PRESENT(status)) then WARN_IF(Error(consolidated_status), 5) status = consolidated_status else VERIFY(Normal(consolidated_status), 5) end if call Finalize (consolidated_status) call Finalize (allocate_status) ! Verify guarantees. VERIFY(Valid_State(ELLM),5) ! ELL_Matrix is now valid. return end subroutine Read_Harwell_Boeing_ELL_Matrix