Commit 9b79874b authored by Dr.李's avatar Dr.李

fixed linux bug

parent 7b72cb5a
...@@ -11,8 +11,8 @@ cimport numpy as np ...@@ -11,8 +11,8 @@ cimport numpy as np
cimport cython cimport cython
from libc.math cimport sqrt from libc.math cimport sqrt
from libc.math cimport fabs from libc.math cimport fabs
from libc.stdlib cimport calloc from cpython.mem cimport PyMem_Malloc
from libc.stdlib cimport free from cpython.mem cimport PyMem_Free
from numpy import array from numpy import array
from libcpp.vector cimport vector as cpp_vector from libcpp.vector cimport vector as cpp_vector
from libcpp.unordered_map cimport unordered_map as cpp_map from libcpp.unordered_map cimport unordered_map as cpp_map
...@@ -60,7 +60,7 @@ cpdef list groupby(long[:] groups): ...@@ -60,7 +60,7 @@ cpdef list groupby(long[:] groups):
@cython.wraparound(False) @cython.wraparound(False)
@cython.initializedcheck(False) @cython.initializedcheck(False)
cdef long* group_mapping(long* groups, size_t length, size_t* max_g): cdef long* group_mapping(long* groups, size_t length, size_t* max_g):
cdef long *res_ptr = <long*>calloc(length, sizeof(int)) cdef long *res_ptr = <long*>PyMem_Malloc(length*sizeof(long))
cdef cpp_map[long, long] current_hold cdef cpp_map[long, long] current_hold
cdef long curr_tag cdef long curr_tag
cdef long running_tag = -1 cdef long running_tag = -1
...@@ -85,14 +85,17 @@ cdef long* group_mapping(long* groups, size_t length, size_t* max_g): ...@@ -85,14 +85,17 @@ cdef long* group_mapping(long* groups, size_t length, size_t* max_g):
@cython.wraparound(False) @cython.wraparound(False)
@cython.cdivision(True) @cython.cdivision(True)
@cython.initializedcheck(False) @cython.initializedcheck(False)
cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_t width) nogil: cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>calloc((max_g+1)*width, sizeof(double)) cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double))
cdef size_t i cdef size_t i
cdef size_t j cdef size_t j
cdef size_t loop_idx1 cdef size_t loop_idx1
cdef size_t loop_idx2 cdef size_t loop_idx2
cdef long curr cdef long curr
for i in range((max_g+1)*width):
res_ptr[i] = 0.
for i in range(length): for i in range(length):
loop_idx1 = i*width loop_idx1 = i*width
loop_idx2 = groups[i]*width loop_idx2 = groups[i]*width
...@@ -105,14 +108,17 @@ cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -105,14 +108,17 @@ cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_
@cython.wraparound(False) @cython.wraparound(False)
@cython.cdivision(True) @cython.cdivision(True)
@cython.initializedcheck(False) @cython.initializedcheck(False)
cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, size_t width) nogil: cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>calloc((max_g+1)*width, sizeof(double)) cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double))
cdef size_t i cdef size_t i
cdef size_t j cdef size_t j
cdef size_t loop_idx1 cdef size_t loop_idx1
cdef size_t loop_idx2 cdef size_t loop_idx2
cdef long curr cdef long curr
for i in range((max_g+1)*width):
res_ptr[i] = 0.
for i in range(length): for i in range(length):
loop_idx1 = i*width loop_idx1 = i*width
loop_idx2 = groups[i]*width loop_idx2 = groups[i]*width
...@@ -125,15 +131,22 @@ cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, si ...@@ -125,15 +131,22 @@ cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, si
@cython.wraparound(False) @cython.wraparound(False)
@cython.cdivision(True) @cython.cdivision(True)
@cython.initializedcheck(False) @cython.initializedcheck(False)
cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size_t width) nogil: cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>calloc((max_g+1)*width, sizeof(double)) cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double))
cdef long* bin_count_ptr = <long*>calloc(max_g+1, sizeof(int)) cdef long* bin_count_ptr = <long*>PyMem_Malloc((max_g+1)*sizeof(long))
cdef size_t i cdef size_t i
cdef size_t j cdef size_t j
cdef size_t loop_idx1 cdef size_t loop_idx1
cdef size_t loop_idx2 cdef size_t loop_idx2
cdef long curr cdef long curr
try:
for i in range((max_g+1)*width):
res_ptr[i] = 0.
for i in range(max_g+1):
bin_count_ptr[i] = 0
for i in range(length): for i in range(length):
loop_idx1 = i*width loop_idx1 = i*width
loop_idx2 = groups[i]*width loop_idx2 = groups[i]*width
...@@ -147,8 +160,8 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size ...@@ -147,8 +160,8 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size
loop_idx1 = i*width loop_idx1 = i*width
for j in range(width): for j in range(width):
res_ptr[loop_idx1 + j] /= curr res_ptr[loop_idx1 + j] /= curr
finally:
free(bin_count_ptr) PyMem_Free(bin_count_ptr)
return res_ptr return res_ptr
...@@ -156,10 +169,10 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size ...@@ -156,10 +169,10 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size
@cython.wraparound(False) @cython.wraparound(False)
@cython.cdivision(True) @cython.cdivision(True)
@cython.initializedcheck(False) @cython.initializedcheck(False)
cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_t width, long ddof=1) nogil: cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_t width, long ddof=1):
cdef double* running_sum_square_ptr = <double*>calloc((max_g+1)*width, sizeof(double)) cdef double* running_sum_square_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double))
cdef double* running_sum_ptr = <double*>calloc((max_g+1)*width, sizeof(double)) cdef double* running_sum_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double))
cdef long* bin_count_ptr = <long*>calloc(max_g+1, sizeof(int)) cdef long* bin_count_ptr = <long*>PyMem_Malloc((max_g+1)*sizeof(long))
cdef size_t i cdef size_t i
cdef size_t j cdef size_t j
cdef size_t loop_idx1 cdef size_t loop_idx1
...@@ -167,6 +180,15 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -167,6 +180,15 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_
cdef long curr cdef long curr
cdef double raw_value cdef double raw_value
try:
for i in range((max_g+1)*width):
running_sum_square_ptr[i] = 0.
running_sum_ptr[i] = 0.
for i in range(max_g+1):
bin_count_ptr[i] = 0
for i in range(length): for i in range(length):
loop_idx1 = i * width loop_idx1 = i * width
loop_idx2 = groups[i] * width loop_idx2 = groups[i] * width
...@@ -184,9 +206,9 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -184,9 +206,9 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_
for j in range(width): for j in range(width):
loop_idx2 = loop_idx1 + j loop_idx2 = loop_idx1 + j
running_sum_square_ptr[loop_idx2] = sqrt((running_sum_square_ptr[loop_idx2] - running_sum_ptr[loop_idx2] * running_sum_ptr[loop_idx2] / curr) / (curr - ddof)) running_sum_square_ptr[loop_idx2] = sqrt((running_sum_square_ptr[loop_idx2] - running_sum_ptr[loop_idx2] * running_sum_ptr[loop_idx2] / curr) / (curr - ddof))
finally:
free(running_sum_ptr) PyMem_Free(running_sum_ptr)
free(bin_count_ptr) PyMem_Free(bin_count_ptr)
return running_sum_square_ptr return running_sum_square_ptr
...@@ -196,9 +218,9 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -196,9 +218,9 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_
cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str func): cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str func):
cdef size_t length = x.shape[0] cdef size_t length = x.shape[0]
cdef size_t width = x.shape[1] cdef size_t width = x.shape[1]
cdef size_t* max_g = <size_t*>calloc(1, sizeof(size_t)) cdef size_t* max_g = <size_t*>PyMem_Malloc(sizeof(size_t))
cdef long* mapped_groups = group_mapping(&groups[0], length, max_g) cdef long* mapped_groups = group_mapping(&groups[0], length, max_g)
cdef double* res_data_ptr = <double*>calloc(length*width, sizeof(double)) cdef double* res_data_ptr = <double*>PyMem_Malloc(length*width*sizeof(double))
cdef double* value_data_ptr cdef double* value_data_ptr
cdef np.ndarray[double, ndim=2] res cdef np.ndarray[double, ndim=2] res
cdef size_t i cdef size_t i
...@@ -206,7 +228,7 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -206,7 +228,7 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
cdef size_t loop_idx1 cdef size_t loop_idx1
cdef size_t loop_idx2 cdef size_t loop_idx2
try:
if func == 'mean': if func == 'mean':
value_data_ptr = agg_mean(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_mean(mapped_groups, max_g[0], &x[0, 0], length, width)
elif func == 'std': elif func == 'std':
...@@ -215,6 +237,8 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -215,6 +237,8 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
value_data_ptr = agg_sum(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_sum(mapped_groups, max_g[0], &x[0, 0], length, width)
elif func =='abssum': elif func =='abssum':
value_data_ptr = agg_abssum(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_abssum(mapped_groups, max_g[0], &x[0, 0], length, width)
else:
raise ValueError('({0}) is not recognized as valid functor'.format(func))
with nogil: with nogil:
for i in range(length): for i in range(length):
...@@ -222,9 +246,10 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -222,9 +246,10 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
loop_idx2 = mapped_groups[i] * width loop_idx2 = mapped_groups[i] * width
for j in range(width): for j in range(width):
res_data_ptr[loop_idx1 + j] = value_data_ptr[loop_idx2 + j] res_data_ptr[loop_idx1 + j] = value_data_ptr[loop_idx2 + j]
free(value_data_ptr) finally:
free(mapped_groups) PyMem_Free(value_data_ptr)
free(max_g) PyMem_Free(mapped_groups)
PyMem_Free(max_g)
res = np.PyArray_SimpleNewFromData(2, [length, width], np.NPY_FLOAT64, res_data_ptr) res = np.PyArray_SimpleNewFromData(2, [length, width], np.NPY_FLOAT64, res_data_ptr)
PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA) PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA)
return res return res
...@@ -236,11 +261,12 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -236,11 +261,12 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str func): cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str func):
cdef size_t length = x.shape[0] cdef size_t length = x.shape[0]
cdef size_t width = x.shape[1] cdef size_t width = x.shape[1]
cdef size_t* max_g = <size_t*>calloc(1, sizeof(size_t)) cdef size_t* max_g = <size_t*>PyMem_Malloc(sizeof(size_t))
cdef long* mapped_groups = group_mapping(&groups[0], length, max_g) cdef long* mapped_groups = group_mapping(&groups[0], length, max_g)
cdef np.ndarray[double, ndim=2] res cdef np.ndarray[double, ndim=2] res
cdef double* value_data_ptr cdef double* value_data_ptr
try:
if func == 'mean': if func == 'mean':
value_data_ptr = agg_mean(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_mean(mapped_groups, max_g[0], &x[0, 0], length, width)
elif func == 'std': elif func == 'std':
...@@ -249,9 +275,13 @@ cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str f ...@@ -249,9 +275,13 @@ cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str f
value_data_ptr = agg_sum(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_sum(mapped_groups, max_g[0], &x[0, 0], length, width)
elif func =='abssum': elif func =='abssum':
value_data_ptr = agg_abssum(mapped_groups, max_g[0], &x[0, 0], length, width) value_data_ptr = agg_abssum(mapped_groups, max_g[0], &x[0, 0], length, width)
else:
raise ValueError('({0}) is not recognized as valid functor'.format(func))
res = np.PyArray_SimpleNewFromData(2, [max_g[0]+1, width], np.NPY_FLOAT64, value_data_ptr) res = np.PyArray_SimpleNewFromData(2, [max_g[0]+1, width], np.NPY_FLOAT64, value_data_ptr)
PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA) PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA)
free(mapped_groups) finally:
free(max_g) PyMem_Free(mapped_groups)
PyMem_Free(max_g)
return res return res
\ No newline at end of file
...@@ -42,7 +42,8 @@ def generate_extensions(ext_modules, line_trace=False): ...@@ -42,7 +42,8 @@ def generate_extensions(ext_modules, line_trace=False):
for pyxfile in ext_modules: for pyxfile in ext_modules:
ext = Extension(name='.'.join(pyxfile.split('/'))[:-4], ext = Extension(name='.'.join(pyxfile.split('/'))[:-4],
sources=[pyxfile], sources=[pyxfile],
define_macros=define_macros) define_macros=define_macros,
extra_compile_args=['-std=c++11'])
extensions.append(ext) extensions.append(ext)
return extensions return extensions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment