I am writing sequences of floating points from Fortran into binary files and want to read them in Python. All works fine with single and double precision floats (kind=4) and (kind=8), but when I attempt to move to a real(kind=16) variable type, suddenly things no longer work (data array filled with zeros). I read here: python read 16 bytes long double from binary file That a workaround is needed for the np.fromfile function. I implemented the suggested change but am still not getting the right result. Mwe Python and Fortran code is below. I tried this both with Python 2.7 + Numpy 1.8 and Python 3.4 + Numpy 1.14 to the same effect. I also checked and the generated file seems to have the right amount of data (480 bytes for 30 floats with 16 bytes). Any help will be welcome!
Python reader:
import numpy as np
inputfilename = "fortranData.bin"
dp = 8
nVals = 30
with open(inputfilename, 'rb') as f:
# both work fine for 4 or 8 byte floats (32 and 64)
# but not for 16 byte floats (np.float128)
data = np.fromfile(f, dtype=np.float64)
data = np.frombuffer(f.read(dp*nVals), dtype=np.float64, count=nVals)
print(data)
Fortran writer (compiled with gfortran 4.8.6 on Ubuntu 14.04)
program test
implicit none
integer, parameter :: dp=8
integer, parameter :: outFileUnit=51, nPts=10, nDim=3
character(len=100) :: binaryFile="fortranData.bin"
real(kind=dp), dimension(nPts,nDim) :: data
integer :: i, j
! - generate data -
do i=1, nPts
do j=1, nDim
data(i,j) = (i-1)*nDim + j
enddo
enddo
! - open file and write data -
open(unit=outFileUnit, file=binaryFile, form='unformatted', access='direct', &
status='replace', recl=nDim*sizeof(data(1,1)))
do i=1, nPts
write(outFileUnit, rec=i) data(i,:)
enddo
end program test
EDIT: as requested, here's a few lines of the data at the top of the fortranData.bin file:
$od fortranData.bin
0000000 000000 000000 000000 000000 000000 000000 000000 037777
0000020 000000 000000 000000 000000 000000 000000 000000 040000
0000040 000000 000000 000000 000000 000000 000000 100000 040000
0000060 000000 000000 000000 000000 000000 000000 000000 040001
0000100 000000 000000 000000 000000 000000 000000 040000 040001
0000120 000000 000000 000000 000000 000000 000000 100000 040001