2 """Interface for SIONlib
4 This interface wrapps access to SIONlib files for access in Python.
7 from __future__ import (print_function, division)
9 from libc.stdlib cimport malloc, free
10 from libc.stdio cimport FILE
12 from cpython cimport array
13 from array import array
17 from csioninter cimport sion_int32, sion_int64, MPI_Comm, uint64_t
19 from mpi4py import MPI
20 from mpi4py.mpi_c cimport MPI_COMM_WORLD
23 DEFAULT_PAR_MODE = "serial"
32 DEFAULT_CHUNKSIZE = 32
33 DEFAULT_CHUNKSIZES = None
34 DEFAULT_FSBLKSIZE = -1
35 DEFAULT_GLOBALRANK = -1
36 DEFAULT_GLOBALRANKS = None
37 DEFAULT_FILEPTR = None
44 class SIONFile(io.BufferedIOBase):
45 """File-like object for handling SIONlib files"""
46 valid_par_modes = ("serial", "mpi")
48 def __init__(self, par_mode=DEFAULT_PAR_MODE):
52 if par_mode not in self.valid_par_modes:
53 raise AttributeError("invalid attribute self._par_mode = {}".
54 format(self._par_mode))
55 self._par_mode = par_mode
57 def open(self, fname, file_mode):
58 """Open a file for reading or writing."""
60 self._file_mode = file_mode
61 if self._par_mode == "serial":
62 self._sid = sion_open(fname, file_mode)
63 elif self._par_mode == "mpi":
64 self._sid = sion_paropen_mpi(fname, file_mode)
68 """Check whether sion file is closed."""
69 return self._sid == -1
72 """Close sion file."""
73 if self._par_mode == "serial":
75 elif self._par_mode == "mpi":
76 sion_parclose_mpi(self._sid)
81 def write(self, data):
83 sion_fwrite(data, self._sid)
85 def read(self, nitems=DEFAULT_NITEMS):
87 ret = sion_fread(self._sid, nitems)
90 def write_key(self, data, key):
91 """Write key value pair."""
92 sion_fwrite_key(data, key, self._sid)
94 def read_key(self, key, nitems=DEFAULT_NITEMS):
95 """Read value for corresponding key."""
96 ret = sion_fread_key(key, self._sid, nitems)
100 def open(fname, file_mode, par_mode=DEFAULT_PAR_MODE):
101 """Open a file and return a SIONFile instance."""
102 sionfile = SIONFile(par_mode=par_mode)
103 sionfile.open(fname, file_mode)
107 cdef sion_open(fname, file_mode, ntasks=DEFAULT_NTASKS, nfiles=DEFAULT_NFILES,
108 chunksizes=DEFAULT_CHUNKSIZES, fsblksize=DEFAULT_FSBLKSIZE,
109 globalranks=DEFAULT_GLOBALRANKS, fileptr=DEFAULT_FILEPTR):
110 """Open a file and return a sion id."""
111 cdef int _ntasks = ntasks
112 cdef int _nfiles = nfiles
113 cdef sion_int32 _fsblksize = fsblksize
114 cdef int * _globalranks = NULL
115 cdef sion_int64 * _chunksizes = NULL
116 cdef FILE * _fileptr = NULL
118 fname_b = fname.encode()
119 file_mode_b = file_mode.encode()
121 _chunksizes = <sion_int64 * >malloc(_ntasks * sizeof(sion_int64))
122 _globalranks = <int * > malloc(_ntasks * sizeof(int))
124 for rank in range(1):
125 _chunksizes[rank] = DEFAULT_CHUNKSIZE
126 _globalranks[rank] = 0
128 ret = csioninter.sion_open(fname_b, file_mode_b, & _ntasks, & _nfiles,
129 & _chunksizes, & _fsblksize, & _globalranks,
138 cdef sion_close(sid):
140 ret = csioninter.sion_close(sid)
144 cdef sion_paropen_mpi(fname, file_mode, nfiles=DEFAULT_NFILES,
145 gComm=DEFAULT_GCOMM, lComm=DEFAULT_LCOMM,
146 chunksize=DEFAULT_CHUNKSIZE, fsblksize=DEFAULT_FSBLKSIZE,
147 globalrank=DEFAULT_GLOBALRANK, fileptr=DEFAULT_FILEPTR):
148 """Open a file and return a sion id."""
149 cdef int _nfiles = nfiles
150 cdef sion_int32 _fsblksize = fsblksize
151 cdef int _globalrank = globalrank
152 cdef sion_int64 _chunksize = chunksize
153 cdef FILE * _fileptr = NULL
154 cdef MPI_Comm _gComm = NULL
155 cdef MPI_Comm _lComm = NULL
156 cdef char * _newname = NULL
158 fname_b = fname.encode()
159 file_mode_b = file_mode.encode()
161 comm = MPI.COMM_WORLD
162 rank = comm.Get_rank()
163 _gComm = MPI_COMM_WORLD
167 ret = csioninter.sion_paropen_mpi(fname_b, file_mode_b, & _nfiles, _gComm,
168 & _lComm, & _chunksize, & _fsblksize,
169 & _globalrank, & _fileptr, & _newname)
174 cdef sion_parclose_mpi(sid):
175 """Open a file and return a sion id."""
176 ret = csioninter.sion_parclose_mpi(sid)
180 cdef sion_fwrite(data, sid):
181 """Write data to file."""
182 cdef char * _data = NULL
186 bytes_written = csioninter.sion_fwrite(_data, DEFAULT_SIZE, len(data), sid)
191 cdef sion_fread(sid, nitems=DEFAULT_NITEMS):
192 """Read data from file."""
193 cdef size_t _size = DEFAULT_SIZE
194 cdef size_t _nitems = nitems
196 if _nitems == DEFAULT_NITEMS:
197 _nitems = sion_bytes_avail_in_chunk(sid)
199 arr = bytearray(_nitems)
201 bytes_read = csioninter.sion_fread(<char * >arr, _size, _nitems, sid)
203 if bytes_read != len(arr) or bytes_read != _size * _nitems:
204 raise IOError("read not successful")
209 cdef sion_bytes_avail_in_chunk(sid):
210 """Get number of remaining bytes in current chunk."""
211 ret = csioninter.sion_bytes_avail_in_chunk(sid)
216 cpdef sion_fwrite_key(data, key, sid):
217 """Write a key value pair."""
218 cdef char * _data = NULL
222 ret = csioninter.sion_fwrite_key(_data, key, DEFAULT_SIZE, len(data), sid)
227 cpdef sion_fread_key(key, sid, nitems=DEFAULT_NITEMS):
228 """Read value for corresponding key."""
229 cdef size_t _size = DEFAULT_SIZE
230 cdef size_t _nitems = nitems
232 if _nitems == DEFAULT_NITEMS:
233 _nitems = sion_bytes_avail_in_chunk(sid)
235 arr = bytearray(_nitems)
237 bytes_read = csioninter.sion_fread_key(<char * >arr, key, _size, _nitems,
240 if bytes_read != len(arr) or bytes_read != _size * _nitems:
241 raise IOError("read not successful: {} {} {}".format(bytes_read,