# Path: pyresample/_multi_proc.py
# class Scheduler(object):
#     """Provide chunks of data to work on based on various 'schedule' algorithms."""
# 
#     def __init__(self, ndata, nprocs, chunk=None, schedule='guided'):
#         if schedule not in ['guided', 'dynamic', 'static']:
#             raise ValueError('unknown scheduling strategy')
#         self._ndata = mp.RawValue(ctypes.c_int, ndata)
#         self._start = mp.RawValue(ctypes.c_int, 0)
#         self._lock = mp.Lock()
#         self._schedule = schedule
#         self._nprocs = nprocs
#         if schedule == 'guided' or schedule == 'dynamic':
#             min_chunk = ndata // (10 * nprocs)
#             if chunk:
#                 min_chunk = chunk
#             min_chunk = max(min_chunk, 1)
#             self._chunk = min_chunk
#         elif schedule == 'static':
#             min_chunk = ndata // nprocs
#             if chunk:
#                 min_chunk = max(chunk, min_chunk)
#             min_chunk = max(min_chunk, 1)
#             self._chunk = min_chunk
# 
#     def __iter__(self):
#         """Iterate over individual chunks of data."""
#         while True:
#             self._lock.acquire()
#             ndata = self._ndata.value
#             nprocs = self._nprocs
#             start = self._start.value
#             if self._schedule == 'guided':
#                 _chunk = ndata // nprocs
#                 chunk = max(self._chunk, _chunk)
#             else:
#                 chunk = self._chunk
#             if ndata:
#                 if chunk > ndata:
#                     s0 = start
#                     s1 = start + ndata
#                     self._ndata.value = 0
#                 else:
#                     s0 = start
#                     s1 = start + chunk
#                     self._ndata.value = ndata - chunk
#                     self._start.value = start + chunk
#                 self._lock.release()
#                 yield slice(s0, s1)
#             else:
#                 self._lock.release()
#                 return
# 
# def shmem_as_ndarray(raw_array):
#     """Create numpy array from shared memory data."""
#     _ctypes_to_numpy = {
#         ctypes.c_char: np.int8,
#         ctypes.c_wchar: np.int16,
#         ctypes.c_byte: np.int8,
#         ctypes.c_ubyte: np.uint8,
#         ctypes.c_short: np.int16,
#         ctypes.c_ushort: np.uint16,
#         ctypes.c_int: np.int32,
#         ctypes.c_uint: np.int32,
#         ctypes.c_long: np.int32,
#         ctypes.c_ulong: np.int32,
#         ctypes.c_float: np.float32,
#         ctypes.c_double: np.float64
#     }
#     dtype = _ctypes_to_numpy[raw_array._type_]
# 
#     # The following works too, but occasionally raises
#     # RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
#     # and appears to be slower.
#     # return np.ctypeslib.as_array(raw_array)
# 
#     return np.frombuffer(raw_array, dtype=dtype)


import ctypes
import multiprocessing as mp
import numpy as np
import pyproj
    import numexpr as ne
        import scipy.spatial as sp
from ._multi_proc import Scheduler, shmem_as_ndarray
        self.shmem_data = mp.RawArray(ctypes.c_double, self.n * self.m)

        # View shared memory as ndarray, and copy over the data.
        # The RawArray objects have information about the dtype and
        # buffer size.
        _data = shmem_as_ndarray(self.shmem_data).reshape((self.n, self.m))
        _data[:, :] = data

        # Initialize parent, we must do this last because
        # cKDTree stores a reference to the data array. We pass in
        # the copy in shared memory rather than the origial data.
        self.leafsize = leafsize
        self._nprocs = nprocs
        self._chunk = chunk
        self._schedule = schedule

    def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
        """Query for points at index 'x' parallelized with multiple processes and shared memory."""
        # allocate shared memory for x and result
        nx = x.shape[0]
        shmem_x = mp.RawArray(ctypes.c_double, nx * self.m)
        shmem_d = mp.RawArray(ctypes.c_double, nx * k)
        shmem_i = mp.RawArray(ctypes.c_int, nx * k)

        # view shared memory as ndarrays
        _x = shmem_as_ndarray(shmem_x).reshape((nx, self.m))
        if k == 1:
            _d = shmem_as_ndarray(shmem_d)
            _i = shmem_as_ndarray(shmem_i)
        else:

# Path: pyresample/_multi_proc.py
# class Scheduler(object):
#     """Provide chunks of data to work on based on various 'schedule' algorithms."""
# 
#     def __init__(self, ndata, nprocs, chunk=None, schedule='guided'):
#         if schedule not in ['guided', 'dynamic', 'static']:
#             raise ValueError('unknown scheduling strategy')
#         self._ndata = mp.RawValue(ctypes.c_int, ndata)
#         self._start = mp.RawValue(ctypes.c_int, 0)
#         self._lock = mp.Lock()
#         self._schedule = schedule
#         self._nprocs = nprocs
#         if schedule == 'guided' or schedule == 'dynamic':
#             min_chunk = ndata // (10 * nprocs)
#             if chunk:
#                 min_chunk = chunk
#             min_chunk = max(min_chunk, 1)
#             self._chunk = min_chunk
#         elif schedule == 'static':
#             min_chunk = ndata // nprocs
#             if chunk:
#                 min_chunk = max(chunk, min_chunk)
#             min_chunk = max(min_chunk, 1)
#             self._chunk = min_chunk
# 
#     def __iter__(self):
#         """Iterate over individual chunks of data."""
#         while True:
#             self._lock.acquire()
#             ndata = self._ndata.value
#             nprocs = self._nprocs
#             start = self._start.value
#             if self._schedule == 'guided':
#                 _chunk = ndata // nprocs
#                 chunk = max(self._chunk, _chunk)
#             else:
#                 chunk = self._chunk
#             if ndata:
#                 if chunk > ndata:
#                     s0 = start
#                     s1 = start + ndata
#                     self._ndata.value = 0
#                 else:
#                     s0 = start
#                     s1 = start + chunk
#                     self._ndata.value = ndata - chunk
#                     self._start.value = start + chunk
#                 self._lock.release()
#                 yield slice(s0, s1)
#             else:
#                 self._lock.release()
#                 return
# 
# def shmem_as_ndarray(raw_array):
#     """Create numpy array from shared memory data."""
#     _ctypes_to_numpy = {
#         ctypes.c_char: np.int8,
#         ctypes.c_wchar: np.int16,
#         ctypes.c_byte: np.int8,
#         ctypes.c_ubyte: np.uint8,
#         ctypes.c_short: np.int16,
#         ctypes.c_ushort: np.uint16,
#         ctypes.c_int: np.int32,
#         ctypes.c_uint: np.int32,
#         ctypes.c_long: np.int32,
#         ctypes.c_ulong: np.int32,
#         ctypes.c_float: np.float32,
#         ctypes.c_double: np.float64
#     }
#     dtype = _ctypes_to_numpy[raw_array._type_]
# 
#     # The following works too, but occasionally raises
#     # RuntimeWarning: Item size computed from the PEP 3118 buffer format string does not match the actual item size.
#     # and appears to be slower.
#     # return np.ctypeslib.as_array(raw_array)
# 
#     return np.frombuffer(raw_array, dtype=dtype)


# Path: pyresample/_spatial_mp.py
import ctypes
import multiprocessing as mp
import numpy as np
import pyproj
    import numexpr as ne
        import scipy.spatial as sp
from ._multi_proc import Scheduler, shmem_as_ndarray

        self.shmem_data = mp.RawArray(ctypes.c_double, self.n * self.m)

        # View shared memory as ndarray, and copy over the data.
        # The RawArray objects have information about the dtype and
        # buffer size.
        _data = shmem_as_ndarray(self.shmem_data).reshape((self.n, self.m))
        _data[:, :] = data

        # Initialize parent, we must do this last because
        # cKDTree stores a reference to the data array. We pass in
        # the copy in shared memory rather than the origial data.
        self.leafsize = leafsize
        self._nprocs = nprocs
        self._chunk = chunk
        self._schedule = schedule

    def query(self, x, k=1, eps=0, p=2, distance_upper_bound=np.inf):
        """Query for points at index 'x' parallelized with multiple processes and shared memory."""
        # allocate shared memory for x and result
        nx = x.shape[0]
        shmem_x = mp.RawArray(ctypes.c_double, nx * self.m)
        shmem_d = mp.RawArray(ctypes.c_double, nx * k)
        shmem_i = mp.RawArray(ctypes.c_int, nx * k)

        # view shared memory as ndarrays
        _x = shmem_as_ndarray(shmem_x).reshape((nx, self.m))
        if k == 1:
            _d = shmem_as_ndarray(shmem_d)
            _i = shmem_as_ndarray(shmem_i)
        else:

            _d = shmem_as_ndarray(shmem_d).reshape((nx, k))