Error while writing unformatted data to unformatted file

I am attempting to store DP data to a binary file as single precision. The DP data is inside multiple loops in a fortran code called EPW. When I format the data and create the binary file as formatted, the output.bin stores the desired data. However, when I try

open(newunit=file_unit, file='output.bin', status='replace', access='stream', form='unformatted')

and

temp_out=real(SQRT(g2),KIND=sp)
write(file_unit) temp_out

where temp_out is a single-precision real, I get the following error:

unformatted I/O to unit open for formatted transfers, unit 0

But neither the data nor the file_unit is formatted.

I would appreciate any suggestions as to how to avoid this error.

Thanks,

Vahid

Why is it attempting to write on unit 0 (stderr)? Somehow file_unit doesn’t have the correct unit number.

1 Like

Thank you for taking the time to respond.I have declared file_unit as an integer. I assumed that using “newunit” in the open statement would automatically assign a negative number to file_unit. I checked this number after opening and before writing (AI suggestion) and it was -129.

Vahid

Which compiler are you using?

The NEWUNIT= feature should have picked an unused unit different from INPUT_UNIT, OUTPUT_UNIT or ERROR_UNIT, but it’s picking ERROR_UNIT instead.

(To avoid these kind of issues, compilers should assign a negative unused value to the NEWUNIT=variable)

You could try using an explicit unit number (e.g., UNIT = 100) to see what happens.

1 Like

Is the OPEN in the same procedure/scope as where you write? When you said you checked it before the write did you check it at the line above the write or possibly in some other scope? Are you sure the error is from this write statement?

I am using the intel/2023.2.1 module on Rorqual cluster of AllianceCanada. Even though the EPW code was compiled with openmpi, I am running it serially.

Replacing file_unit with 100 results in the following compilation error:

transport.f90(180): error #7838: A scalar default-integer variable is required in this context.   [100]
    open(newunit=100, file='output.bin', status='replace', access='stream', form='unformatted')
-----------------^
compilation aborted for transport.f90 

when using a fixed value it is UNIT=100 not NEWUNIT=100

1 Like

The opening is done inside the first outer loop. The structure is as follows:

1. Outermost loop 1 in file ephwann_shuffle.f90
2. the above calls transport.f90 where the opening and printing is done
3. For first index of loop 1 in transport.f90, open the binary file
4. Three other loops in transport.f90
5. write in the innermost loop

Using Unit=100 did the trick. The code printed the data to binary file.

Thank you for all the help.

1 Like

From your description it sounds like all the I/O is in one routine but that the routine is called multiple times, possibly expecting the LUN unit code to be remembered between calls. But Fortran is not required to save a value between calls unless it has the SAVE attribute or the variable in defined in a module or common block used by the routine. If that reading of your description is correct you need to add the SAVE attribute when defining the FILE_UNIT variable to ensure it retains its value. For example:

  integer,save :: file_unit

Using a fixed value is useful because you do not have to pass the variable or give it a global or saved attribute; it has the drawback the it might collide with other procedures using the file for a different purpose. The value of NEWUNIT is that Fortran does the bookkeeping on what numbers are used already so you can be ensured the number you get back is not in use anywhere else.

The values returned by NEWUNIT are negative and less than -1 (A magic number specifying an error occurred on the OPEN) so there is no conflict with units the user specifies directly as you are doing, which all have to be positive values. So even though it is working now you might want to work through getting a value returned by NEWUNIT to understand the nuances of the feature better.

You are right. Using the save attribute for file_unit and opening it with newunit=file_unit also does the job.

Thank you for taking the time to explain this in detail.