How to read allocatables from unformatted file?

Hi,

My model has some big matrices. To save space, they are stored in sparse matrix format. The data part in the user-defined type is allocatable. I can write these beasts to unformatted file, but how do I read them back? I tried to first write the size of the allocatable and then write the according bunch of matrix elements separately. Later, I first read this number of elements, then I allocate the sparse matrix before reading the elements, and read the set of elements:

The user-defined type:

INTEGER,PARAMETER :: Float = SELECTED_REAL_KIND(12, 60)

TYPE SparseMatrixElement
INTEGER :: i,j
REAL(Float) :: x
END TYPE SparseMatrixElement

TYPE SparseMatrix
INTEGER :: N,NMax ! N is the number of elements, NMax >=N can be used to allocate on beforehand
TYPE(SparseMatrixElement), ALLOCATABLE, DIMENSION(:slight_smile: :: Element
END TYPE SparseMatrix

The code:

 READ(ScratchFile) SparseMatrix%N
     ALLOCATE(SparseMatrix%Element(SparseMatrix%N))
 READ(ScratchFile) SparseMatrix

GFORTRAN tells me:

Error: Data transfer element at (1) cannot have ALLOCATABLE components unless it is processed by a defined input/output procedure.

What to do?

Another issue: In the past, I used to open unformatted files with “RECL=1”, but with GNU Fortran (GCC) 14.0.0 20230625 (experimental) this no longer works. My code complains that 1 byte is too small for its data structures… Is this a feature? This approach used to work and helped me make sure that other models would be able to read the unformatted files too.

Regards,

Arjan

You forgot the matrix component. You should write:
READ(ScratchFile) SparseMatrix%Element(:)

That said your displayed code is confusing, as SparseMatrix is a type, and you are also using the name for a variable.

1 Like

Thanks! That works!

The ambiguity of SparseMatrix being both a type and a variable was caused by my reduction of the actual names used in the code to a readable sample for this forum.

In which context exactly are you doing that? Writing a record that is longer than the specified recl is IMO not standard conforming. Maybe you were using in the past some compiler that was more flexible, but I’m not sure it was a good idea doing that anyway…

I now see that those occasions were with direct access. Maybe that makes a difference. I removed the RECL specifier and now it seems to run.