[segyio] 105/376: segyio.mmap support in python

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:16 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit a003dbb01b1b6a5a6b52be77d8c4a9e19a4fe1b4
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Tue Nov 8 10:32:11 2016 +0100

    segyio.mmap support in python
    
    Adds support for memory mapping files in python as an optimisation
    opportunity.
---
 python/segyio/_segyio.c | 15 +++++++++++++++
 python/segyio/segy.py   | 28 ++++++++++++++++++++++++++++
 tests/test_segyio_c.py  | 26 +++++++++++++++++++++++++-
 3 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index d0120c4..93430ee 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -117,6 +117,20 @@ static PyObject *py_FILE_flush(PyObject *self, PyObject *args) {
     return Py_BuildValue("");
 }
 
+static PyObject *py_mmap(PyObject *self, PyObject* args) {
+    PyObject* file_capsule = NULL;
+    PyArg_ParseTuple(args, "O", &file_capsule);
+
+    segy_file* fp = get_FILE_pointer_from_capsule( file_capsule );
+    if (PyErr_Occurred()) { return NULL; }
+
+    int err = segy_mmap( fp );
+
+    if( err == SEGY_OK )
+        Py_RETURN_TRUE;
+
+    Py_RETURN_FALSE;
+}
 
 // ------------- ERROR Handling -------------
 struct error_args {
@@ -880,6 +894,7 @@ static PyMethodDef SegyMethods[] = {
         {"open",               (PyCFunction) py_FILE_open,          METH_VARARGS, "Opens a file."},
         {"close",              (PyCFunction) py_FILE_close,         METH_VARARGS, "Closes a file."},
         {"flush",              (PyCFunction) py_FILE_flush,         METH_VARARGS, "Flushes a file."},
+        {"mmap",               (PyCFunction) py_mmap,               METH_VARARGS, "Memory map a file."},
 
         {"binheader_size",     (PyCFunction) py_binheader_size,     METH_NOARGS,  "Return the size of the binary header."},
         {"textheader_size",    (PyCFunction) py_textheader_size,    METH_NOARGS,  "Return the size of the text header."},
diff --git a/python/segyio/segy.py b/python/segyio/segy.py
index 3b553ef..8a711b7 100644
--- a/python/segyio/segy.py
+++ b/python/segyio/segy.py
@@ -98,6 +98,34 @@ class SegyFile(object):
         """
         _segyio.close(self.xfd)
 
+    def mmap(self):
+        """Memory map the file
+        :rtype: bool
+
+        Memory map the file. This is an advanced feature for speed and
+        optimization; however, it is no silver bullet. If your file is smaller
+        than the memory available on your system this will likely result in
+        faster reads and writes, especially for line modes. However, if the
+        file is very large, or memory is very pressured, this optimization
+        might cause overall system slowdowns. However, if you're opening the
+        same file from many different instances of segyio then memory mapping
+        may significantly reduce the memory pressure.
+
+        If this call returns true, the file is memory mapped. If memory mapping
+        was build-time disabled or is not available for your platform this call
+        always return false. If the memory mapping is unsuccessful you can keep
+        using segyio - reading and writing falls back on non-memory mapped
+        features.
+
+        Examples:
+            Memory map::
+            >>> mapped = f.mmap()
+            >>> if mapped: print( "File is memory mapped!" )
+            >>> # keep using segyio as per usual
+            >>> print( f.trace[10] )
+        """
+        return _segyio.mmap(self.xfd)
+
     @property
     def sorting(self):
         """ :rtype: int """
diff --git a/tests/test_segyio_c.py b/tests/test_segyio_c.py
index 7bf006d..a3439b7 100644
--- a/tests/test_segyio_c.py
+++ b/tests/test_segyio_c.py
@@ -390,9 +390,11 @@ class _segyioTests(TestCase):
 
         _segyio.close(f)
 
-    def read_small(self):
+    def read_small(self, mmap = False):
         f = _segyio.open(self.filename, "r")
 
+        if mmap: _segyio.mmap(f)
+
         binary_header = _segyio.read_binaryheader(f)
         ilb = 189
         xlb = 193
@@ -437,6 +439,28 @@ class _segyioTests(TestCase):
 
         _segyio.close(f)
 
+    def test_read_line_mmap(self):
+        f, metrics, iline_idx, xline_idx = self.read_small(True)
+
+        tr0 = metrics['trace0']
+        bsz = metrics['trace_bsize']
+        samples = metrics['sample_count']
+        xline_stride = metrics['xline_stride']
+        iline_stride = metrics['iline_stride']
+
+        xline_trace0 = _segyio.fread_trace0(20, len(iline_idx), xline_stride, xline_idx, "crossline")
+        iline_trace0 = _segyio.fread_trace0(1, len(xline_idx), iline_stride, iline_idx, "inline")
+
+        buf = numpy.zeros((len(iline_idx), samples), dtype=numpy.single)
+
+        _segyio.read_line(f, xline_trace0, len(iline_idx), xline_stride, buf, tr0, bsz, 1, samples)
+        self.assertAlmostEqual(sum(sum(buf)), 800.061169624, places=6)
+
+        _segyio.read_line(f, iline_trace0, len(xline_idx), iline_stride, buf, tr0, bsz, 1, samples)
+        self.assertAlmostEqual(sum(sum(buf)), 305.061146736, places=6)
+
+        _segyio.close(f)
+
     def test_fread_trace0_for_depth(self):
         elements = list(range(25))
         indices = numpy.asarray(elements, dtype=numpy.uintc)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list