enabled selecting between serial and OpenMP distance functions#529
enabled selecting between serial and OpenMP distance functions#529richardjgowers merged 3 commits intodevelopfrom
Conversation
|
Btw, I am very open for any comments on how to make this nicer, and I am also not very happy with the name mode for the keyword argument as used to determine if running in serial or OpenMP, e.g d = MDAnalysis.lib.distances.distance_array(g.positions, ow.positions, box=u.dimensions,
mode="OpenMP") |
|
@orbeckst instead of |
|
I agree with @kain88-de : |
package/MDAnalysis/lib/distances.py
Outdated
There was a problem hiding this comment.
Could we make this _select so people don't try and use directly?
There was a problem hiding this comment.
I changed it to _run().
|
Maybe backend instead of mode? |
|
—Reply to this email directly or view it on GitHub. |
|
On 11 Nov, 2015, at 09:54, Richard Gowers wrote:
Funnily enough, that's exactly what I just changed it to. It's a bit technical but the best description I can think of. parallel is not good because parallel="serial" sounds really strange. With backend we can also imagine backend="CUDA", backend="OpenCL", backend="SPIDAL" etc. |
|
I am +1 for backend if you have more than 2 choices. |
- all functions in lib.distances acquired the backend=<backend> keyword;
- "serial" selects the standard serial C/Cython code from lib._distances;
- "OpenMP" selects the OpenMP parallelized C/Cython code from
lib._distances_openmp
- on systems without an OpenMP capable compiler, this will likely just mean
that the OpenMP versions are actually serial (the OpenMP pragma should
get ignored) --- need to be confirmed/tested
- tests in test_distances were refactored so that both serial and OpenMP
versions are tested
- the current implementation is not very pretty (see lib.distances._run())
but will make it very easy to add additional acceleration schemes such as
CUDA or numba as long as the call signatures of the calc_* functions remain
the same.
- 'cimport c_numpy; c_numpy.import_array()' replaced with 'import numpy; cimport numpy' - replaced ndarray.dimensions --> ndarray.shape - re-ran cython to generate C files
9c147ca to
789acd9
Compare
|
Rebased to include
Also removed |
|
I am not sure why duplicate a lot of code here $ diff distances_openmp.pyx distances.pyx
19,20c19,20
< Parallel distance calculation library --- :mod:`MDAnalysis.lib._distances_openmp`
< =================================================================================
---
> Distance calculation library --- :mod:`MDAnalysis.lib._distances`
> =================================================================
22,23c22
<
< Contains OpenMP versions of the contents of "calc_distances.h"
---
> Serial versions of all distance calculations
25a25,28
> cimport cython
> cimport c_numpy
> c_numpy.import_array()
>
49a53
> void minimum_image(double *x, float *box, float *inverse_box)
83c87
< <double*>result.data)
---
> <double*>result.data)
255a260,307
>
>
> @cython.boundscheck(False)
> def contact_matrix_no_pbc(coord, sparse_contacts, cutoff):
> cdef int rows = len(coord)
> cdef double cutoff2 = cutoff ** 2
> cdef float[:, ::1] coord_view = coord
>
> cdef int i, j
> cdef double[3] rr;
> cdef double dist
> for i in range(rows):
> sparse_contacts[i, i] = True
> for j in range(i+1, rows):
> rr[0] = coord_view[i, 0] - coord_view[j, 0]
> rr[1] = coord_view[i, 1] - coord_view[j, 1]
> rr[2] = coord_view[i, 2] - coord_view[j, 2]
> dist = rr[0]*rr[0] + rr[1]*rr[1] + rr[2]*rr[2]
> if dist < cutoff2:
> sparse_contacts[i, j] = True
> sparse_contacts[j, i] = True
>
>
> @cython.boundscheck(False)
> def contact_matrix_pbc(coord, sparse_contacts, box, cutoff):
> cdef int rows = len(coord)
> cdef double cutoff2 = cutoff ** 2
> cdef float[:, ::1] coord_view = coord
> cdef float[::1] box_view = box
> cdef float[::1] box_inv = 1. / box
>
> cdef int i, j
> cdef double[3] rr;
> cdef double dist
> for i in range(rows):
> sparse_contacts[i, i] = True
> for j in range(i+1, rows):
> rr[0] = coord_view[i, 0] - coord_view[j, 0]
> rr[1] = coord_view[i, 1] - coord_view[j, 1]
> rr[2] = coord_view[i, 2] - coord_view[j, 2]
>
> minimum_image(rr, &box_view[0], &box_inv[0])
>
> dist = rr[0]*rr[0] + rr[1]*rr[1] + rr[2]*rr[2]
>
> if dist < cutoff2:
> sparse_contacts[i, j] = True
> sparse_contacts[j, i] = True |
package/MDAnalysis/lib/distances.py
Outdated
There was a problem hiding this comment.
This is pretty minor, but can we make the backend selection case insensitive? I think you could just call this 'openmp' and then call .lower() on whatever string is passed.
- backend is now case-insensitive (as requested by @richardjgowers) - missing/wrongly spelled backend now raises ValueError instead of RuntimeError - added tests for both
enabled selecting between serial and OpenMP distance functions
- the cython/prange-based/OpenMP versions of some of the distance calculations were slower and had fewer features than the C/OpenMP based ones that are now available with backend="OpenMP" as implemented in PR #529 so these ones (and there tests) are fully removed - closes issue #530 - The whole lib.parallel module was also removed because at the moment there is nothing in it; we can revisit the discussion about organization of lib (issue #287) when necessary.
- The cython/prange-based/OpenMP versions of some of the distance calculations were slower and had fewer features than the C/OpenMP based ones that are now available with backend="OpenMP" as implemented in PR #529 so these ones (and their tests) are fully removed. - removed test for deprecated core.parallel.distances - The whole lib.parallel module was also removed because at the moment there is nothing in it; we can revisit the discussion about organization of lib (issue #287) when necessary.
lib._distances_openmp
that the OpenMP versions are actually serial (the OpenMP pragma should
get ignored) --- need to be confirmed/tested
versions are tested
but will make it very easy to add additional acceleration schemes such as
CUDA or numba as long as the call signatures of the calc_* functions remain
the same.