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
cimport cython
from libc.math cimport sqrt
from libc.math cimport fabs
from cpython.mem cimport PyMem_Malloc
from cpython.mem cimport PyMem_Free
from libc.stdlib cimport malloc
from libc.stdlib cimport free
from numpy import array
from libcpp.vector cimport vector as cpp_vector
from libcpp.unordered_map cimport unordered_map as cpp_map
......@@ -60,7 +60,7 @@ cpdef list groupby(long[:] groups):
@cython.wraparound(False)
@cython.initializedcheck(False)
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 long curr_tag
cdef long running_tag = -1
......@@ -86,7 +86,7 @@ cdef long* group_mapping(long* groups, size_t length, size_t* max_g):
@cython.cdivision(True)
@cython.initializedcheck(False)
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 j
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_
@cython.cdivision(True)
@cython.initializedcheck(False)
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 j
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
@cython.cdivision(True)
@cython.initializedcheck(False)
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 long* bin_count_ptr = <long*>PyMem_Malloc((max_g+1)*sizeof(long))
cdef double* res_ptr = <double*>malloc((max_g+1)*width*sizeof(double))
cdef long* bin_count_ptr = <long*>malloc((max_g+1)*sizeof(long))
cdef size_t i
cdef size_t j
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
for j in range(width):
res_ptr[loop_idx1 + j] /= curr
finally:
PyMem_Free(bin_count_ptr)
free(bin_count_ptr)
return res_ptr
......@@ -170,9 +170,9 @@ cdef double* agg_mean(long* groups, size_t max_g, double* x, size_t length, size
@cython.cdivision(True)
@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* running_sum_square_ptr = <double*>PyMem_Malloc((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*>PyMem_Malloc((max_g+1)*sizeof(long))
cdef double* running_sum_square_ptr = <double*>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*>malloc((max_g+1)*sizeof(long))
cdef size_t i
cdef size_t j
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_
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))
finally:
PyMem_Free(running_sum_ptr)
PyMem_Free(bin_count_ptr)
free(running_sum_ptr)
free(bin_count_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_
cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str func):
cdef size_t length = x.shape[0]
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 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 np.ndarray[double, ndim=2] res
cdef size_t i
......@@ -247,9 +247,9 @@ cpdef np.ndarray[double, ndim=2] transform(long[:] groups, double[:, :] x, str f
for j in range(width):
res_data_ptr[loop_idx1 + j] = value_data_ptr[loop_idx2 + j]
finally:
PyMem_Free(value_data_ptr)
PyMem_Free(mapped_groups)
PyMem_Free(max_g)
free(value_data_ptr)
free(mapped_groups)
free(max_g)
res = np.PyArray_SimpleNewFromData(2, [length, width], np.NPY_FLOAT64, res_data_ptr)
PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA)
return res
......@@ -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):
cdef size_t length = x.shape[0]
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 np.ndarray[double, ndim=2] res
cdef double* value_data_ptr
cdef np.ndarray[double, ndim=2] res
try:
if func == 'mean':
......@@ -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)
PyArray_ENABLEFLAGS(res, np.NPY_OWNDATA)
finally:
PyMem_Free(mapped_groups)
PyMem_Free(max_g)
free(mapped_groups)
free(max_g)
return res
\ No newline at end of file
......@@ -42,6 +42,6 @@ if __name__ == '__main__':
benchmark_simple_settle(3000, 10, 1000)
benchmark_simple_settle_with_group(3000, 10, 1000, 30)
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_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