numpy数组的并行就地排序

Max*_*aev 9 sorting numpy numexpr

我经常需要对大型numpy数组(几十亿个元素)进行排序,这成了我代码的瓶颈.我正在寻找一种并行化的方法.

ndarray.sort()功能是否有任何并行实现?Numexpr模块为numpy数组上的大多数数学运算提供并行实现,但缺乏排序功能.

也许,有可能围绕C++并行排序实现一个简单的包装,并通过Cython使用它?

Max*_*aev 7

我最终包装了GCC并行排序.这是代码:

parallelSort.pyx

# cython: wraparound = False
# cython: boundscheck = False
import numpy as np
cimport numpy as np
import cython
cimport cython 

ctypedef fused real:
    cython.char
    cython.uchar
    cython.short
    cython.ushort
    cython.int
    cython.uint
    cython.long
    cython.ulong
    cython.longlong
    cython.ulonglong
    cython.float
    cython.double

cdef extern from "<parallel/algorithm>" namespace "__gnu_parallel":
    cdef void sort[T](T first, T last) nogil 

def numpyParallelSort(real[:] a):
    "In-place parallel sort for numpy types"
    sort(&a[0], &a[a.shape[0]])
Run Code Online (Sandbox Code Playgroud)

额外的编译器args:-fopenmp(compile)和-lgomp(链接)

这个makefile会这样做:

all:
    cython --cplus parallelSort.pyx  
    g++  -g -march=native -Ofast -fpic -c    parallelSort.cpp -o parallelSort.o -fopenmp `python-config --includes`
    g++  -g -march=native -Ofast -shared  -o parallelSort.so parallelSort.o `python-config --libs` -lgomp 

clean:
    rm -f parallelSort.cpp *.o *.so
Run Code Online (Sandbox Code Playgroud)

这表明它有效:

from parallelSort import numpyParallelSort
import numpy as np 
a = np.random.random(100000000)

numpyParallelSort(a) 
print a[:10]
Run Code Online (Sandbox Code Playgroud)

编辑:修复了下面评论中注意到的bug

  • 很好的答案,并运作良好(在两分钟内排序32亿浮动!!!)然而,有一个有趣的错误.如果你看一下列表'a [-10:0]`的末尾,你会看到原始的最后一个元素没有排序.我不得不将`&a [a.shape [0] -1]`更改为`a [a.shape [0]]`以获得正确的排序. (2认同)