numpy数组的并行就地排序

时间:2014-12-18 16:32:16

标签: sorting numpy numexpr

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

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

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

2 个答案:

答案 0 :(得分:6)

我最终包装了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]])

额外编译器args:-fopenmp(编译)和-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

这表明它有效:

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

numpyParallelSort(a) 
print a[:10]

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

答案 1 :(得分:2)

Mergesort非常自然地并行化。让每个工作者对任意块进行预排序,然后对其运行单个合并传递。最后的合并应该只需要O(N)操作,而且在numba或者某些事情中编写函数是很简单的。

Wikipedia agrees