From b2e4fd6f32630aadf51d1004e34abf49f67aea0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Fri, 31 Aug 2012 23:46:23 +0200 Subject: [PATCH] Add parallel execution support --- skimage/_shared/interpolation.pxd | 16 ++++++++-------- skimage/_shared/interpolation.pyx | 16 ++++++++-------- skimage/transform/_warps_cy.pyx | 16 ++++++++++------ skimage/transform/setup.py | 4 +++- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/skimage/_shared/interpolation.pxd b/skimage/_shared/interpolation.pxd index ef880109..6038a853 100644 --- a/skimage/_shared/interpolation.pxd +++ b/skimage/_shared/interpolation.pxd @@ -2,23 +2,23 @@ cdef inline double nearest_neighbour_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval) + double cval) nogil cdef inline double bilinear_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval) + double cval) nogil -cdef inline double quadratic_interpolation(double x, double[3] f) +cdef inline double quadratic_interpolation(double x, double[3] f) nogil cdef inline double biquadratic_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval) + double cval) nogil -cdef inline double cubic_interpolation(double x, double[4] f) +cdef inline double cubic_interpolation(double x, double[4] f) nogil cdef inline double bicubic_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval) + double cval) nogil cdef inline double get_pixel(double* image, int rows, int cols, int r, int c, - char mode, double cval) + char mode, double cval) nogil -cdef inline int coord_map(int dim, int coord, char mode) +cdef inline int coord_map(int dim, int coord, char mode) nogil diff --git a/skimage/_shared/interpolation.pyx b/skimage/_shared/interpolation.pyx index 3150f41b..231ca045 100644 --- a/skimage/_shared/interpolation.pyx +++ b/skimage/_shared/interpolation.pyx @@ -8,7 +8,7 @@ from libc.math cimport ceil, floor, round cdef inline double nearest_neighbour_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval): + double cval) nogil: """Nearest neighbour interpolation at a given position in the image. Parameters @@ -37,7 +37,7 @@ cdef inline double nearest_neighbour_interpolation(double* image, int rows, cdef inline double bilinear_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval): + double cval) nogil: """Bilinear interpolation at a given position in the image. Parameters @@ -75,7 +75,7 @@ cdef inline double bilinear_interpolation(double* image, int rows, int cols, return (1 - dr) * top + dr * bottom -cdef inline double quadratic_interpolation(double x, double[3] f): +cdef inline double quadratic_interpolation(double x, double[3] f) nogil: """Quadratic interpolation. Parameters @@ -96,7 +96,7 @@ cdef inline double quadratic_interpolation(double x, double[3] f): cdef inline double biquadratic_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval): + double cval) nogil: """Biquadratic interpolation at a given position in the image. Parameters @@ -147,7 +147,7 @@ cdef inline double biquadratic_interpolation(double* image, int rows, int cols, return quadratic_interpolation(xr, fr) -cdef inline double cubic_interpolation(double x, double[4] f): +cdef inline double cubic_interpolation(double x, double[4] f) nogil: """Cubic interpolation. Parameters @@ -172,7 +172,7 @@ cdef inline double cubic_interpolation(double x, double[4] f): cdef inline double bicubic_interpolation(double* image, int rows, int cols, double r, double c, char mode, - double cval): + double cval) nogil: """Bicubic interpolation at a given position in the image. Parameters @@ -220,7 +220,7 @@ cdef inline double bicubic_interpolation(double* image, int rows, int cols, cdef inline double get_pixel(double* image, int rows, int cols, int r, int c, - char mode, double cval): + char mode, double cval) nogil: """Get a pixel from the image, taking wrapping mode into consideration. Parameters @@ -251,7 +251,7 @@ cdef inline double get_pixel(double* image, int rows, int cols, int r, int c, return image[coord_map(rows, r, mode) * cols + coord_map(cols, c, mode)] -cdef inline int coord_map(int dim, int coord, char mode): +cdef inline int coord_map(int dim, int coord, char mode) nogil: """ Wrap a coordinate, according to a given mode. diff --git a/skimage/transform/_warps_cy.pyx b/skimage/transform/_warps_cy.pyx index ce400ed6..9d3dca70 100644 --- a/skimage/transform/_warps_cy.pyx +++ b/skimage/transform/_warps_cy.pyx @@ -5,6 +5,7 @@ cimport numpy as np import numpy as np +from cython.parallel import prange from skimage._shared.interpolation cimport (nearest_neighbour_interpolation, bilinear_interpolation, biquadratic_interpolation, @@ -12,7 +13,7 @@ from skimage._shared.interpolation cimport (nearest_neighbour_interpolation, cdef inline void _matrix_transform(double x, double y, double* H, double *x_, - double *y_): + double *y_) nogil: """Apply a homography to a coordinate. Parameters @@ -101,8 +102,9 @@ def _warp_fast(np.ndarray image, np.ndarray H, output_shape=None, int order=1, out_r = output_shape[0] out_c = output_shape[1] - cdef np.ndarray[dtype=np.double_t, ndim=2] out = \ + cdef np.ndarray[dtype=np.double_t, ndim=2, mode="c"] out = \ np.zeros((out_r, out_c), dtype=np.double) + cdef double* out_data = out.data cdef int tfr, tfc cdef double r, c @@ -110,7 +112,7 @@ def _warp_fast(np.ndarray image, np.ndarray H, output_shape=None, int order=1, cdef int cols = img.shape[1] cdef double (*interp_func)(double*, int, int, double, double, - char, double) + char, double) nogil if order == 0: interp_func = nearest_neighbour_interpolation elif order == 1: @@ -120,10 +122,12 @@ def _warp_fast(np.ndarray image, np.ndarray H, output_shape=None, int order=1, elif order == 3: interp_func = bicubic_interpolation - for tfr in range(out_r): + for tfr in prange(out_r, nogil=True): + # make r, c thread local variables + r = c = 0 for tfc in range(out_c): _matrix_transform(tfc, tfr, M.data, &c, &r) - out[tfr, tfc] = interp_func(img.data, rows, cols, r, c, - mode_c, cval) + out_data[tfr * out_r + tfc] = interp_func(img.data, rows, + cols, r, c, mode_c, cval) return out diff --git a/skimage/transform/setup.py b/skimage/transform/setup.py index 0e415bad..cd2a0f8a 100644 --- a/skimage/transform/setup.py +++ b/skimage/transform/setup.py @@ -20,7 +20,9 @@ def configuration(parent_package='', top_path=None): include_dirs=[get_numpy_include_dirs()]) config.add_extension('_warps_cy', sources=['_warps_cy.c'], - include_dirs=[get_numpy_include_dirs(), '../_shared']) + include_dirs=[get_numpy_include_dirs(), '../_shared'], + extra_compile_args=['-fopenmp'], + extra_link_args=['-fopenmp']) return config