[yt-svn] commit/yt: atmyers: Merged in MatthewTurk/yt (pull request #2025)

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Mar 9 09:32:45 PST 2016


1 new commit in yt:

https://bitbucket.org/yt_analysis/yt/commits/14b7d1b6b906/
Changeset:   14b7d1b6b906
Branch:      yt
User:        atmyers
Date:        2016-03-09 17:32:34+00:00
Summary:     Merged in MatthewTurk/yt (pull request #2025)

Ghost zone optimization and experimentation
Affected #:  2 files

diff -r 7bc62a2db2deb15cade23e01644d40baff873d96 -r 14b7d1b6b9060f8364cff88cc0f006a8c1a7e9e6 yt/data_objects/construction_data_containers.py
--- a/yt/data_objects/construction_data_containers.py
+++ b/yt/data_objects/construction_data_containers.py
@@ -860,6 +860,7 @@
     """
     _type_name = "smoothed_covering_grid"
     filename = None
+    _min_level = None
     @wraps(YTCoveringGrid.__init__)
     def __init__(self, *args, **kwargs):
         ds = kwargs['ds']
@@ -886,12 +887,47 @@
         self._pdata_source.min_level = level_state.current_level
         self._pdata_source.max_level = level_state.current_level
 
+    def _compute_minimum_level(self):
+        # This attempts to determine the minimum level that we should be
+        # starting on for this box.  It does this by identifying the minimum
+        # level that could contribute to the minimum bounding box at that
+        # level; that means that all cells from coarser levels will be replaced.
+        if self._min_level is not None:
+            return self._min_level
+        ils = LevelState()
+        min_level = 0
+        for l in range(self.level, 0, -1):
+            dx = self._base_dx / self.ds.relative_refinement(0, l)
+            start_index, end_index, dims = self._minimal_box(dx)
+            ils.left_edge = start_index * dx + self.ds.domain_left_edge
+            ils.right_edge = ils.left_edge + dx * dims
+            ils.current_dx = dx
+            ils.current_level = l
+            self._setup_data_source(ils)
+            # Reset the max_level
+            ils.data_source.min_level = 0
+            ils.data_source.max_level = l
+            ils.data_source.loose_selection = False
+            min_level = self.level
+            for chunk in ils.data_source.chunks([], "io"):
+                # With our odd selection methods, we can sometimes get no-sized ires.
+                ir = chunk.ires
+                if ir.size == 0: continue
+                min_level = min(ir.min(), min_level)
+            if min_level >= l:
+                break
+        self._min_level = min_level
+        return min_level
 
     def _fill_fields(self, fields):
         fields = [f for f in fields if f not in self.field_data]
         if len(fields) == 0: return
         ls = self._initialize_level_state(fields)
+        min_level = self._compute_minimum_level()
         for level in range(self.level + 1):
+            if level < min_level:
+                self._update_level_state(ls)
+                continue
             domain_dims = self.ds.domain_dimensions.astype("int64") \
                         * self.ds.relative_refinement(0, ls.current_level)
             tot = ls.current_dims.prod()

diff -r 7bc62a2db2deb15cade23e01644d40baff873d96 -r 14b7d1b6b9060f8364cff88cc0f006a8c1a7e9e6 yt/geometry/selection_routines.pyx
--- a/yt/geometry/selection_routines.pyx
+++ b/yt/geometry/selection_routines.pyx
@@ -18,7 +18,7 @@
 cimport numpy as np
 cimport cython
 from libc.stdlib cimport malloc, free
-from yt.utilities.lib.fp_utils cimport fclip, iclip, fmax, fmin
+from yt.utilities.lib.fp_utils cimport fclip, iclip, fmax, fmin, imin, imax
 from .oct_container cimport OctreeContainer, OctAllocationContainer, Oct
 cimport oct_visitors
 from .oct_visitors cimport cind
@@ -806,6 +806,7 @@
     cdef np.float64_t right_edge[3]
     cdef np.float64_t right_edge_shift[3]
     cdef bint loose_selection
+    cdef bint check_period
 
     @cython.boundscheck(False)
     @cython.wraparound(False)
@@ -813,16 +814,17 @@
         cdef int i
         # We are modifying dobj.left_edge and dobj.right_edge , so here we will
         # do an in-place conversion of those arrays.
-        cdef np.ndarray[np.float64_t, ndim=1] RE = _ensure_code(dobj.right_edge)
-        cdef np.ndarray[np.float64_t, ndim=1] LE = _ensure_code(dobj.left_edge)
-        cdef np.ndarray[np.float64_t, ndim=1] DW = _ensure_code(dobj.ds.domain_width)
-        cdef np.ndarray[np.float64_t, ndim=1] DLE = _ensure_code(dobj.ds.domain_left_edge)
-        cdef np.ndarray[np.float64_t, ndim=1] DRE = _ensure_code(dobj.ds.domain_right_edge)
+        cdef np.float64_t[:] RE = _ensure_code(dobj.right_edge)
+        cdef np.float64_t[:] LE = _ensure_code(dobj.left_edge)
+        cdef np.float64_t[:] DW = _ensure_code(dobj.ds.domain_width)
+        cdef np.float64_t[:] DLE = _ensure_code(dobj.ds.domain_left_edge)
+        cdef np.float64_t[:] DRE = _ensure_code(dobj.ds.domain_right_edge)
         cdef np.float64_t region_width[3]
         cdef bint p[3]
         # This is for if we want to include zones that overlap and whose
         # centers are not strictly included.
         self.loose_selection = getattr(dobj, "loose_selection", False)
+        self.check_period = False
 
         for i in range(3):
             region_width[i] = RE[i] - LE[i]
@@ -836,6 +838,11 @@
         for i in range(3):
 
             if p[i]:
+                # First, we check if any criteria requires a period check,
+                # without any adjustments.  This is for short-circuiting the
+                # short-circuit of the loop down below in mask filling.
+                if LE[i] < DLE[i] or LE[i] > DRE[i] or RE[i] > DRE[i]:
+                    self.check_period = True
                 # shift so left_edge guaranteed in domain
                 if LE[i] < DLE[i]:
                     LE[i] += DW[i]
@@ -902,6 +909,52 @@
                 return 0
         return 1
 
+    @cython.boundscheck(False)
+    @cython.wraparound(False)
+    @cython.cdivision(True)
+    cdef int fill_mask_selector(self, np.float64_t left_edge[3],
+                                np.float64_t right_edge[3],
+                                np.float64_t dds[3], int dim[3],
+                                np.ndarray[np.uint8_t, ndim=3, cast=True] child_mask,
+                                np.ndarray[np.uint8_t, ndim=3] mask,
+                                int level):
+        cdef int i, j, k
+        cdef int total = 0, this_level = 0
+        cdef np.float64_t pos[3]
+        if level < self.min_level or level > self.max_level:
+            return 0
+        if level == self.max_level:
+            this_level = 1
+        cdef int si[3], ei[3]
+        #print self.left_edge[0], self.left_edge[1], self.left_edge[2],
+        #print self.right_edge[0], self.right_edge[1], self.right_edge[2],
+        #print self.right_edge_shift[0], self.right_edge_shift[1], self.right_edge_shift[2]
+        if not self.check_period:
+            for i in range(3):
+                si[i] = <int> ((self.left_edge[i] - left_edge[i])/dds[i])
+                ei[i] = <int> ((self.right_edge[i] - left_edge[i])/dds[i])
+                si[i] = iclip(si[i] - 1, 0, dim[i])
+                ei[i] = iclip(ei[i] + 1, 0, dim[i])
+        else:
+            for i in range(3):
+                si[i] = 0
+                ei[i] = dim[i]
+        with nogil:
+            pos[0] = left_edge[0] + (si[0] + 0.5) * dds[0]
+            for i in range(si[0], ei[0]):
+                pos[1] = left_edge[1] + (si[1] + 0.5) * dds[1]
+                for j in range(si[1], ei[1]):
+                    pos[2] = left_edge[2] + (si[2] + 0.5) * dds[2]
+                    for k in range(si[2], ei[2]):
+                        if child_mask[i, j, k] == 1 or this_level == 1:
+                            mask[i, j, k] = self.select_cell(pos, dds)
+                            total += mask[i, j, k]
+                        pos[2] += dds[2]
+                    pos[1] += dds[1]
+                pos[0] += dds[0]
+        return total
+
+
     def _hash_vals(self):
         return (("left_edge[0]", self.left_edge[0]),
                 ("left_edge[1]", self.left_edge[1]),

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the yt-svn mailing list