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

fixed memory bug when PyMem_Malloc work with PyArray_SimpleNewFromData (I...

fixed memory bug when PyMem_Malloc work with PyArray_SimpleNewFromData (I don't know why they just don't work)
parent 9b79874b
...@@ -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 cpython.mem cimport PyMem_Malloc from libc.stdlib cimport malloc
from cpython.mem cimport PyMem_Free from libc.stdlib cimport 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*>PyMem_Malloc(length*sizeof(long)) cdef long *res_ptr = <long*>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
...@@ -86,7 +86,7 @@ cdef long* group_mapping(long* groups, size_t length, size_t* max_g): ...@@ -86,7 +86,7 @@ cdef long* group_mapping(long* groups, size_t length, size_t* max_g):
@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): cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double)) cdef double* res_ptr = <double*>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
...@@ -109,7 +109,7 @@ cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -109,7 +109,7 @@ cdef double* agg_sum(long* groups, size_t max_g, double* x, size_t length, size_
@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): cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double)) cdef double* res_ptr = <double*>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
...@@ -132,8 +132,8 @@ cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, si ...@@ -132,8 +132,8 @@ cdef double* agg_abssum(long* groups, size_t max_g, double* x, size_t length, si
@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): cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size_t width):
cdef double* res_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double)) cdef double* res_ptr = <double*>malloc((max_g+1)*width*sizeof(double))
cdef long* bin_count_ptr = <long*>PyMem_Malloc((max_g+1)*sizeof(long)) cdef long* bin_count_ptr = <long*>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
...@@ -161,7 +161,7 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size ...@@ -161,7 +161,7 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size
for j in range(width): for j in range(width):
res_ptr[loop_idx1 + j] /= curr res_ptr[loop_idx1 + j] /= curr
finally: finally:
PyMem_Free(bin_count_ptr) free(bin_count_ptr)
return res_ptr return res_ptr
...@@ -170,9 +170,9 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size ...@@ -170,9 +170,9 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size
@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): 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*>PyMem_Malloc((max_g+1)*width*sizeof(double)) cdef double* running_sum_square_ptr = <double*>malloc((max_g+1)*width*sizeof(double))
cdef double* running_sum_ptr = <double*>PyMem_Malloc((max_g+1)*width*sizeof(double)) cdef double* running_sum_ptr = <double*>malloc((max_g+1)*width*sizeof(double))
cdef long* bin_count_ptr = <long*>PyMem_Malloc((max_g+1)*sizeof(long)) cdef long* bin_count_ptr = <long*>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
...@@ -207,8 +207,8 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -207,8 +207,8 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_
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: finally:
PyMem_Free(running_sum_ptr) free(running_sum_ptr)
PyMem_Free(bin_count_ptr) free(bin_count_ptr)
return running_sum_square_ptr return running_sum_square_ptr
...@@ -218,9 +218,9 @@ cdef double* agg_std(long* groups, size_t max_g, double* x, size_t length, size_ ...@@ -218,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*>PyMem_Malloc(sizeof(size_t)) cdef size_t* max_g = <size_t*>malloc(1*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*>PyMem_Malloc(length*width*sizeof(double)) cdef double* res_data_ptr = <double*>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
...@@ -247,9 +247,9 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -247,9 +247,9 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
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]
finally: finally:
PyMem_Free(value_data_ptr) free(value_data_ptr)
PyMem_Free(mapped_groups) free(mapped_groups)
PyMem_Free(max_g) 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
...@@ -261,10 +261,10 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f ...@@ -261,10 +261,10 @@ 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*>PyMem_Malloc(sizeof(size_t)) cdef size_t* max_g = <size_t*>malloc(1*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 double* value_data_ptr cdef double* value_data_ptr
cdef np.ndarray[double, ndim=2] res
try: try:
if func == 'mean': if func == 'mean':
...@@ -281,7 +281,7 @@ cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str f ...@@ -281,7 +281,7 @@ cpdef np.ndarray[double, ndim=2] aggregate(long[:] groups, double[:, :] x, str f
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)
finally: finally:
PyMem_Free(mapped_groups) free(mapped_groups)
PyMem_Free(max_g) free(max_g)
return res return res
\ No newline at end of file
...@@ -42,6 +42,6 @@ if __name__ == '__main__': ...@@ -42,6 +42,6 @@ if __name__ == '__main__':
benchmark_simple_settle(3000, 10, 1000) benchmark_simple_settle(3000, 10, 1000)
benchmark_simple_settle_with_group(3000, 10, 1000, 30) benchmark_simple_settle_with_group(3000, 10, 1000, 30)
benchmark_simple_settle(30, 10, 50000) benchmark_simple_settle(30, 10, 50000)
benchmark_simple_settle_with_group(30, 10, 5000, 5) benchmark_simple_settle_with_group(30, 10, 50000, 5)
benchmark_simple_settle(50000, 50, 20) benchmark_simple_settle(50000, 50, 20)
benchmark_simple_settle_with_group(50000, 50, 20, 50) benchmark_simple_settle_with_group(50000, 50, 20, 50)
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