Octopus
io_binary_f.F90
Go to the documentation of this file.
1!! Copyright (C) 2009 X. Andrade
2!! Copyright (C) 2021 S. Ohlmann
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21#include "io_binary.h"
22
23module io_binary_oct_m
24 use debug_oct_m
25 use global_oct_m
26 use io_oct_m
27 use iso_c_binding
29 use mpi_oct_m
30 use string_oct_m
32
33 implicit none
34
35 private
36
37 public :: &
48
49 interface io_binary_write
55 end interface io_binary_write
56
59 end interface io_binary_write_parallel
60
61 interface io_binary_read
67 end interface io_binary_read
68
71 end interface io_binary_read_parallel
72
73 interface
74 subroutine get_info_binary(np, type, file_size, ierr, iio, fname) bind(c)
75 use iso_c_binding
76 integer(c_int64_t), intent(out) :: np
77 integer(c_int), intent(out) :: type
78 integer(c_int64_t), intent(out) :: file_size
79 integer(c_int), intent(out) :: ierr
80 integer(c_int), intent(inout) :: iio
81 character(kind=c_char), intent(in) :: fname(*)
82 end subroutine get_info_binary
83
84 subroutine write_header(np, type, ierr, iio, fname) bind(c, name="io_write_header")
85 use iso_c_binding
86 integer(c_int64_t), intent(in) :: np
87 integer(c_int), intent(in) :: type
88 integer(c_int), intent(out) :: ierr
89 integer(c_int), intent(inout) :: iio
90 character(kind=c_char), intent(in) :: fname(*)
91 end subroutine write_header
92
93 subroutine write_binary(np, ff, type, ierr, iio, nhd, flpe, fname) bind(c, name="write_binary")
94 use iso_c_binding
95 integer(c_int64_t), intent(in) :: np
96 type(c_ptr), value :: ff
97 integer(c_int), intent(in) :: type
98 integer(c_int), intent(out) :: ierr
99 integer(c_int), intent(inout) :: iio
100 integer(c_int), intent(in) :: nhd
101 integer(c_int), intent(in) :: flpe
102 character(kind=c_char), intent(in) :: fname(*)
103 end subroutine write_binary
104
105 subroutine read_binary(np, offset, ff, output_type, ierr, iio, fname) bind(c, name="read_binary")
106 use iso_c_binding
107 integer(c_int64_t), intent(in) :: np
108 integer(c_int64_t), intent(in) :: offset
109 type(c_ptr), value :: ff
110 integer(c_int), intent(in) :: output_type
111 integer(c_int), intent(out) :: ierr
112 integer(c_int), intent(inout) :: iio
113 character(kind=c_char), intent(in) :: fname(*)
114 end subroutine read_binary
115
116 end interface
117
118contains
122 logical pure function io_binary_is_little_endian() result(is_little)
123 implicit none
124 integer, parameter:: I4P = selected_int_kind(9)
125 integer, parameter:: I1P = selected_int_kind(2)
126 integer(I1P) :: int1(1:4)
127
128 int1 = transfer(1_i4p, int1)
129 is_little = (int1(1) == 1_i1p)
130
131 end function io_binary_is_little_endian
132
133 ! ------------------------------------------------------
134 subroutine io_binary_parallel_start(fname, file_handle, comm, xlocal, np, sizeof_ff, is_write, ierr)
135 character(len=*), intent(in) :: fname
136 type(MPI_File), intent(out) :: file_handle
137 type(MPI_Comm), intent(in) :: comm
138 integer(int64), intent(in) :: xlocal
139 integer, intent(in) :: np
140 integer, intent(in) :: sizeof_ff
141 logical, intent(in) :: is_write
142 integer, intent(out) :: ierr
143
144#ifdef HAVE_MPI
145 integer(MPI_OFFSET_KIND) :: offset
146 integer :: amode, mpi_err
147#endif
148
150
151 assert(np > 0)
152
153#ifdef HAVE_MPI
154 offset = (xlocal-1)*sizeof_ff+64
155
156 if (is_write) then
157 amode = ior(mpi_mode_wronly,mpi_mode_append)
158 else
159 amode = mpi_mode_rdonly
160 end if
161 call mpi_file_open(comm, fname, amode, mpi_info_null, file_handle, mpi_err)
162 call io_incr_open_count()
163
164 if (mpi_err == 0) then
165 call mpi_file_set_atomicity(file_handle, .true.)
166 call mpi_file_seek(file_handle, offset, mpi_seek_set)
167 else
168 file_handle = mpi_file_null
169 end if
170 ierr = mpi_err
171#endif
172
174 end subroutine io_binary_parallel_start
175
176 ! ------------------------------------------------------
177
178 subroutine io_binary_parallel_end(file_handle)
179 type(mpi_file), intent(inout) :: file_handle
181 push_sub(io_binary_parallel_end)
182
183#ifdef HAVE_MPI
184 if (file_handle /= mpi_file_null) call mpi_file_close(file_handle)
185 call io_incr_close_count()
186#endif
187
190
191
192 ! ------------------------------------------------------
193
194 subroutine try_dread_binary(fname, np, ff, ierr, offset)
195 character(len=*), intent(in) :: fname
196 integer(int64), intent(in) :: np
197 complex(real64), contiguous, intent(out) :: ff(:)
198 integer, intent(out) :: ierr
199 integer(int64), optional, intent(in) :: offset
200
201 integer(int64) :: read_np, file_size
202 integer :: number_type, iio
203 real(real64), allocatable :: read_ff(:)
204 character(kind=c_char), dimension(c_str_len(fname)) :: cname
205
206
207 push_sub(try_dread_binary)
208
209 iio = 0
210 cname = string_f_to_c(fname)
211 call get_info_binary(read_np, number_type, file_size, ierr, iio, cname)
212 call io_incr_counters(iio)
213
214 ! if the type of the file is real, then read real numbers and convert to complex
215 if (number_type /= type_double_complex) then
216 write(message(1),'(a,i2,a,i2)') "Debug: Found type = ", number_type, " instead of ", type_double_complex
217 call messages_info(1, debug_only=.true.)
219 safe_allocate(read_ff(1:np))
220 call dread_binary(fname, np, read_ff, ierr, offset)
221 ff = read_ff
222 safe_deallocate_a(read_ff)
223 else
224 ierr = -1
225 end if
226 ! ierr will be 0 if dread_binary succeeded
227
228 pop_sub(try_dread_binary)
229 end subroutine try_dread_binary
231 !------------------------------------------------------
232
233 subroutine try_dread_parallel(fname, comm, xlocal, np, ff, ierr)
234 character(len=*), intent(in) :: fname
235 type(mpi_comm), intent(in) :: comm
236 integer(int64), intent(in) :: xlocal
237 integer, intent(in) :: np
238 complex(real64), contiguous, intent(inout) :: ff(:)
239 integer, intent(out) :: ierr
240
241 integer(int64) :: read_np, file_size
242 integer :: number_type, iio
243 real(real64), allocatable :: read_ff(:)
244
245 push_sub(try_dread_parallel)
246
247 iio = 0
248 call get_info_binary(read_np, number_type, file_size, ierr, iio, string_f_to_c(fname))
249 call io_incr_counters(iio)
250 ! if the type of the file is real, then read real numbers and convert to complex
251 if (number_type /= type_double_complex) then
252 write(message(1),'(a,i2,a,i2)') "Debug: Found type = ", number_type, " instead of ", type_double_complex
253 call messages_info(1, debug_only=.true.)
254 safe_allocate(read_ff(1:np))
255 call dread_parallel(fname, comm, xlocal, np, read_ff, ierr)
256 ff = read_ff
257 safe_deallocate_a(read_ff)
258 else
259 ierr = -1
260 end if
261 ! ierr will be 0 if dread_parallel succeeded
262
263 pop_sub(try_dread_parallel)
264 end subroutine try_dread_parallel
265
266 !------------------------------------------------------
267
268 subroutine io_binary_get_info(fname, np, file_size, ierr)
269 character(len=*), intent(in) :: fname
270 integer(int64), intent(out) :: np
271 integer(int64), intent(out) :: file_size
272 integer, intent(out) :: ierr
273
274 integer :: type, iio
275
276 push_sub(io_binary_get_info)
277
278 iio = 0
279 call get_info_binary(np, type, file_size, ierr, iio, string_f_to_c(fname))
280 call io_incr_counters(iio)
281
282 pop_sub(io_binary_get_info)
283 end subroutine io_binary_get_info
284
285 ! ------------------------------------------------------
286 integer pure function logical_to_integer(flag) result(iflag)
287 logical, intent(in) :: flag
288 iflag = 0
289 if (flag) iflag = 1
290 end function logical_to_integer
291
292#include "complex.F90"
293#include "io_binary_f_inc.F90"
294
295#include "undef.F90"
296
297#include "real.F90"
298#include "io_binary_f_inc.F90"
299
300#include "undef.F90"
301
302#include "integer.F90"
303#include "io_binary_f_inc.F90"
304
305#include "undef.F90"
306
307#include "integer8.F90"
308#include "io_binary_f_inc.F90"
310end module io_binary_oct_m
311
312!! Local Variables:
313!! mode: f90
314!! coding: utf-8
315!! End:
subroutine lwrite_binary(fname, np, ff, ierr, nohead, fendian)
subroutine iwrite_binary2(fname, np, ff, ierr, nohead, fendian)
subroutine zread_binary2(fname, np, ff, ierr)
subroutine zread_binary3(fname, np, ff, ierr)
subroutine zwrite_binary4(fname, np, ff, ierr, nohead, fendian)
subroutine dwrite_binary3(fname, np, ff, ierr, nohead, fendian)
subroutine dwrite_binary5(fname, np, ff, ierr, nohead, fendian)
subroutine iread_binary(fname, np, ff, ierr, offset)
subroutine dwrite_binary(fname, np, ff, ierr, nohead, fendian)
logical pure function, public io_binary_is_little_endian()
check endianness Logical output: true is the running architecture uses little endian ordering,...
subroutine iread_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine try_dread_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine io_binary_parallel_start(fname, file_handle, comm, xlocal, np, sizeof_ff, is_write, ierr)
subroutine zwrite_binary3(fname, np, ff, ierr, nohead, fendian)
subroutine lwrite_binary2(fname, np, ff, ierr, nohead, fendian)
subroutine zwrite_binary2(fname, np, ff, ierr, nohead, fendian)
subroutine iwrite_binary5(fname, np, ff, ierr, nohead, fendian)
subroutine iread_binary3(fname, np, ff, ierr)
subroutine dwrite_binary2(fname, np, ff, ierr, nohead, fendian)
subroutine iwrite_binary3(fname, np, ff, ierr, nohead, fendian)
subroutine zread_binary(fname, np, ff, ierr, offset)
subroutine zwrite_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine iwrite_binary4(fname, np, ff, ierr, nohead, fendian)
subroutine dread_binary5(fname, np, ff, ierr)
subroutine dread_binary4(fname, np, ff, ierr)
subroutine dread_binary(fname, np, ff, ierr, offset)
subroutine try_dread_binary(fname, np, ff, ierr, offset)
subroutine iread_binary4(fname, np, ff, ierr)
subroutine zwrite_binary5(fname, np, ff, ierr, nohead, fendian)
subroutine, public dwrite_header(fname, np_global, ierr)
subroutine io_binary_parallel_end(file_handle)
subroutine, public lwrite_header(fname, np_global, ierr)
subroutine zwrite_binary(fname, np, ff, ierr, nohead, fendian)
subroutine, public zwrite_header(fname, np_global, ierr)
subroutine zread_binary5(fname, np, ff, ierr)
subroutine lwrite_binary5(fname, np, ff, ierr, nohead, fendian)
subroutine, public io_binary_get_info(fname, np, file_size, ierr)
subroutine lwrite_binary4(fname, np, ff, ierr, nohead, fendian)
subroutine dread_binary3(fname, np, ff, ierr)
subroutine lwrite_binary3(fname, np, ff, ierr, nohead, fendian)
subroutine lread_binary5(fname, np, ff, ierr)
subroutine lread_binary4(fname, np, ff, ierr)
subroutine iwrite_binary(fname, np, ff, ierr, nohead, fendian)
subroutine zread_parallel(fname, comm, xlocal, np, ff, ierr)
integer pure function logical_to_integer(flag)
subroutine dread_binary2(fname, np, ff, ierr)
subroutine lread_binary2(fname, np, ff, ierr)
subroutine iread_binary5(fname, np, ff, ierr)
subroutine lread_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine lread_binary(fname, np, ff, ierr, offset)
subroutine zread_binary4(fname, np, ff, ierr)
subroutine iwrite_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine lwrite_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine, public iwrite_header(fname, np_global, ierr)
subroutine dwrite_binary4(fname, np, ff, ierr, nohead, fendian)
subroutine iread_binary2(fname, np, ff, ierr)
subroutine lread_binary3(fname, np, ff, ierr)
subroutine dread_parallel(fname, comm, xlocal, np, ff, ierr)
subroutine dwrite_parallel(fname, comm, xlocal, np, ff, ierr)
Definition: io.F90:116
int true(void)