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
118contains
119
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
144#ifdef HAVE_MPI
145 integer(MPI_OFFSET_KIND) :: offset
146 integer :: amode
147#endif
148
150
151 assert(np > 0)
152
153#ifdef HAVE_MPI
154 offset = (xlocal-1)*sizeof_ff+64
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()
164 if (mpi_err == 0) then
165 call mpi_file_set_atomicity(file_handle, .true., mpi_err)
166 call mpi_file_seek(file_handle, offset, mpi_seek_set, mpi_err)
167 end if
168 ierr = mpi_err
169#endif
170
172 end subroutine io_binary_parallel_start
173
174 ! ------------------------------------------------------
175
176 subroutine io_binary_parallel_end(file_handle)
177 type(mpi_file), intent(inout) :: file_handle
179 push_sub(io_binary_parallel_end)
180
181#ifdef HAVE_MPI
182 call mpi_file_close(file_handle, mpi_err)
183 call io_incr_close_count()
184#endif
185
188
189
190 ! ------------------------------------------------------
191
192 subroutine try_dread_binary(fname, np, ff, ierr, offset)
193 character(len=*), intent(in) :: fname
194 integer(int64), intent(in) :: np
195 complex(real64), intent(out) :: ff(:)
196 integer, intent(out) :: ierr
197 integer(int64), optional, intent(in) :: offset
198
199 integer(int64) :: read_np, file_size
200 integer :: number_type, iio
201 real(real64), allocatable :: read_ff(:)
202 character(kind=c_char), dimension(c_str_len(fname)) :: cname
203
204
205 push_sub(try_dread_binary)
206
207 iio = 0
208 cname = string_f_to_c(fname)
209 call get_info_binary(read_np, number_type, file_size, ierr, iio, cname)
210 call io_incr_counters(iio)
211
212 ! if the type of the file is real, then read real numbers and convert to complex
213 if (number_type /= type_double_complex) then
214 if (debug%info) then
215 write(message(1),'(a,i2,a,i2)') "Debug: Found type = ", number_type, " instead of ", type_double_complex
216 call messages_info(1)
217 end if
218
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
229 end subroutine try_dread_binary
230
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), 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 if (debug%info) then
253 write(message(1),'(a,i2,a,i2)') "Debug: Found type = ", number_type, " instead of ", type_double_complex
254 call messages_info(1)
255 end if
256 safe_allocate(read_ff(1:np))
257 call dread_parallel(fname, comm, xlocal, np, read_ff, ierr)
258 ff = read_ff
259 safe_deallocate_a(read_ff)
260 else
261 ierr = -1
262 end if
263 ! ierr will be 0 if dread_parallel succeeded
264
265 pop_sub(try_dread_parallel)
266 end subroutine try_dread_parallel
267
268 !------------------------------------------------------
269
270 subroutine io_binary_get_info(fname, np, file_size, ierr)
271 character(len=*), intent(in) :: fname
272 integer(int64), intent(out) :: np
273 integer(int64), intent(out) :: file_size
274 integer, intent(out) :: ierr
275
276 integer :: type, iio
277
278 push_sub(io_binary_get_info)
279
280 iio = 0
281 call get_info_binary(np, type, file_size, ierr, iio, string_f_to_c(fname))
282 call io_incr_counters(iio)
283
284 pop_sub(io_binary_get_info)
285 end subroutine io_binary_get_info
287 ! ------------------------------------------------------
288 integer pure function logical_to_integer(flag) result(iflag)
289 logical, intent(in) :: flag
290 iflag = 0
291 if (flag) iflag = 1
292 end function logical_to_integer
293
294#include "complex.F90"
295#include "io_binary_f_inc.F90"
296
297#include "undef.F90"
298
299#include "real.F90"
300#include "io_binary_f_inc.F90"
301
302#include "undef.F90"
303
304#include "integer.F90"
305#include "io_binary_f_inc.F90"
306
307#include "undef.F90"
308
309#include "integer8.F90"
310#include "io_binary_f_inc.F90"
311
312end module io_binary_oct_m
313
314!! Local Variables:
315!! mode: f90
316!! coding: utf-8
317!! 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:114
int true(void)