Skip to content

Commit c1d8c4a

Browse files
Merge pull request #39 from NumPower/feat/update_package_1
Convolve2D SciPy porting and color pallete support for GD images
2 parents 6510671 + 9fa45cf commit c1d8c4a

File tree

13 files changed

+692
-516
lines changed

13 files changed

+692
-516
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
21+
SOFTWARE.

Makefile.frag

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,11 @@ install-cuda:
8080
$(CC) -I. -I $(CXX) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/arithmetics.c -shared -fPIC -o .libs/arithmetics.o
8181
$(NVCC) -I. -I $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/double_math.c -shared -Xcompiler -fPIC -o .libs/double_math.o
8282
$(CC) -I. -I $(CXX) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/linalg.c -shared -fPIC -o .libs/linalg.o
83+
$(CC) -I. -I $(CXX) $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/signal.c -shared -fPIC -o .libs/signal.o
8384
$(NVCC) -I. -I $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/gpu_alloc.c -shared -Xcompiler -fPIC -o .libs/gpu_alloc.o
8485
$(NVCC) -I. -I $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/cuda/cuda_math.cu -shared -Xcompiler -fPIC -o .libs/cuda_math.o
8586
$(NVCC) -I. -I $(COMMON_FLAGS) $(CFLAGS_CLEAN) $(EXTRA_CFLAGS) $(ALL_CCFLAGS) $(GENCODE_FLAGS) -c $(builddir)./src/ndmath/statistics.c -shared -Xcompiler -fPIC -o .libs/statistics.o
86-
$(NVCC) -shared .libs/numpower.o .libs/initializers.o .libs/double_math.o .libs/ndarray.o .libs/debug.o .libs/statistics.o .libs/buffer.o .libs/logic.o .libs/gpu_alloc.o .libs/linalg.o .libs/manipulation.o .libs/iterators.o .libs/indexing.o .libs/arithmetics.o .libs/types.o .libs/cuda_math.o -lcublas -lcusolver -lcudart -llapack -llapacke -lopenblas -lpthread -lcuda -o .libs/ndarray.so
87+
$(NVCC) -shared .libs/numpower.o .libs/signal.o .libs/initializers.o .libs/double_math.o .libs/ndarray.o .libs/debug.o .libs/statistics.o .libs/buffer.o .libs/logic.o .libs/gpu_alloc.o .libs/linalg.o .libs/manipulation.o .libs/iterators.o .libs/indexing.o .libs/arithmetics.o .libs/types.o .libs/cuda_math.o -lcublas -lcusolver -lcudart -llapack -llapacke -lopenblas -lpthread -lcuda -o .libs/ndarray.so
8788
cp ./.libs/ndarray.so $(phplibdir)/ndarray.so
8889
cp ./.libs/ndarray.so $(EXTENSION_DIR)/ndarray.so
8990

config.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ if test "$PHP_NDARRAY" != "no"; then
115115
src/indexing.c \
116116
src/ndmath/arithmetics.c \
117117
src/ndmath/statistics.c \
118+
src/ndmath/signal.c \
118119
src/types.c,
119120
$ext_shared)
120121
fi

numpower.c

Lines changed: 120 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "src/types.h"
2424
#include "src/indexing.h"
2525
#include "src/ndmath/statistics.h"
26+
#include "src/ndmath/signal.h"
2627

2728
#ifdef HAVE_CUBLAS
2829
#include <cuda_runtime.h>
@@ -71,7 +72,7 @@ NDArray* ZVAL_TO_NDARRAY(zval* obj) {
7172
#ifdef HAVE_GD
7273
/* Check if the zend_object class name is "GdImage" */
7374
if (strcmp(ZSTR_VAL(class_name), "GdImage") == 0) {
74-
return NDArray_FromGD(obj);
75+
return NDArray_FromGD(obj, false);
7576
}
7677
#endif
7778
}
@@ -819,17 +820,17 @@ PHP_METHOD(NDArray, normal) {
819820
}
820821

821822
/**
822-
* NDArray::random_binominal
823+
* NDArray::random_binomial
823824
*
824825
* @param execute_data
825826
* @param return_value
826827
*/
827-
ZEND_BEGIN_ARG_INFO_EX(arginfo_ndarray_binominal, 0, 0, 3)
828+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ndarray_binomial, 0, 0, 3)
828829
ZEND_ARG_INFO(0, shape)
829830
ZEND_ARG_INFO(0, p)
830831
ZEND_ARG_INFO(0, n)
831832
ZEND_END_ARG_INFO()
832-
PHP_METHOD(NDArray, random_binominal) {
833+
PHP_METHOD(NDArray, random_binomial) {
833834
NDArray *rtn = NULL;
834835
int *ishape;
835836
zval* shape;
@@ -845,7 +846,7 @@ PHP_METHOD(NDArray, random_binominal) {
845846
for (int i = 0; i < NDArray_NUMELEMENTS(nda); i++) {
846847
ishape[i] = (int) NDArray_FDATA(nda)[i];
847848
}
848-
rtn = NDArray_Binominal(ishape, NDArray_NUMELEMENTS(nda), (int)n, p);
849+
rtn = NDArray_Binomial(ishape, NDArray_NUMELEMENTS(nda), (int)n, p);
849850
NDArray_FREE(nda);
850851
RETURN_NDARRAY(rtn, return_value);
851852
}
@@ -1846,6 +1847,29 @@ PHP_METHOD(NDArray, arccosh) {
18461847
RETURN_NDARRAY(rtn, return_value);
18471848
}
18481849

1850+
/**
1851+
* NDArray::fromImage
1852+
*
1853+
* @param execute_data
1854+
* @param return_value
1855+
*/
1856+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ndarray_fromimage, 0, 0, 1)
1857+
ZEND_ARG_INFO(0, image)
1858+
ZEND_ARG_INFO(0, channelLast)
1859+
ZEND_END_ARG_INFO()
1860+
PHP_METHOD(NDArray, fromImage) {
1861+
NDArray *rtn = NULL;
1862+
zval *image;
1863+
bool channelLast = true;
1864+
ZEND_PARSE_PARAMETERS_START(1, 2)
1865+
Z_PARAM_ZVAL(image)
1866+
Z_PARAM_OPTIONAL
1867+
Z_PARAM_BOOL(channelLast)
1868+
ZEND_PARSE_PARAMETERS_END();
1869+
rtn = NDArray_FromGD(image, channelLast);
1870+
RETURN_NDARRAY(rtn, return_value);
1871+
}
1872+
18491873
/**
18501874
* NDArray::arctanh
18511875
*
@@ -3476,7 +3500,7 @@ PHP_METHOD(NDArray, matrix_rank) {
34763500
/**
34773501
* NDArray::convolve2d
34783502
*/
3479-
ZEND_BEGIN_ARG_INFO(arginfo_ndarray_convolve2d, 0)
3503+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ndarray_convolve2d, 4, 0, 1)
34803504
ZEND_ARG_INFO(0, a)
34813505
ZEND_ARG_INFO(0, b)
34823506
ZEND_ARG_INFO(0, mode)
@@ -3489,6 +3513,7 @@ PHP_METHOD(NDArray, convolve2d) {
34893513
char *mode, *boundary;
34903514
double fill_value = 0.0f;
34913515
size_t size = 1;
3516+
int imode = 0, iboundary = 0;
34923517
ZEND_PARSE_PARAMETERS_START(4, 5)
34933518
Z_PARAM_ZVAL(a)
34943519
Z_PARAM_ZVAL(b)
@@ -3502,7 +3527,90 @@ PHP_METHOD(NDArray, convolve2d) {
35023527
if (nda == NULL || ndb == NULL) {
35033528
return;
35043529
}
3505-
rtn = NDArray_Convolve2D(nda, ndb, mode[0], boundary[0], (float)fill_value);
3530+
switch(mode[0]) {
3531+
case 'v':
3532+
imode = VALID;
3533+
break;
3534+
case 's':
3535+
imode = SAME;
3536+
break;
3537+
case 'f':
3538+
imode = FULL;
3539+
break;
3540+
}
3541+
switch(boundary[0]) {
3542+
case 'f':
3543+
iboundary = PAD;
3544+
break;
3545+
case 'w':
3546+
iboundary = CIRCULAR;
3547+
break;
3548+
case 's':
3549+
iboundary = REFLECT;
3550+
break;
3551+
}
3552+
rtn = NDArray_Correlate2D(nda, ndb, imode, iboundary, NULL, 1);
3553+
if (rtn == NULL) {
3554+
return;
3555+
}
3556+
CHECK_INPUT_AND_FREE(a, nda);
3557+
CHECK_INPUT_AND_FREE(b, ndb);
3558+
RETURN_NDARRAY(rtn, return_value);
3559+
}
3560+
3561+
/**
3562+
* NDArray::correlate2d
3563+
*/
3564+
ZEND_BEGIN_ARG_INFO_EX(arginfo_ndarray_correlate2d, 4, 0, 1)
3565+
ZEND_ARG_INFO(0, a)
3566+
ZEND_ARG_INFO(0, b)
3567+
ZEND_ARG_INFO(0, mode)
3568+
ZEND_ARG_INFO(0, boundary)
3569+
ZEND_ARG_INFO(0, fill_value)
3570+
ZEND_END_ARG_INFO()
3571+
PHP_METHOD(NDArray, correlate2d) {
3572+
NDArray *rtn;
3573+
zval *a, *b;
3574+
char *mode, *boundary;
3575+
double fill_value = 0.0f;
3576+
size_t size = 1;
3577+
int imode = 0, iboundary = 0;
3578+
ZEND_PARSE_PARAMETERS_START(4, 5)
3579+
Z_PARAM_ZVAL(a)
3580+
Z_PARAM_ZVAL(b)
3581+
Z_PARAM_STRING(mode, size)
3582+
Z_PARAM_STRING(boundary, size)
3583+
Z_PARAM_OPTIONAL
3584+
Z_PARAM_DOUBLE(fill_value)
3585+
ZEND_PARSE_PARAMETERS_END();
3586+
NDArray *nda = ZVAL_TO_NDARRAY(a);
3587+
NDArray *ndb = ZVAL_TO_NDARRAY(b);
3588+
if (nda == NULL || ndb == NULL) {
3589+
return;
3590+
}
3591+
switch(mode[0]) {
3592+
case 'v':
3593+
imode = VALID;
3594+
break;
3595+
case 's':
3596+
imode = SAME;
3597+
break;
3598+
case 'f':
3599+
imode = FULL;
3600+
break;
3601+
}
3602+
switch(boundary[0]) {
3603+
case 'f':
3604+
iboundary = PAD;
3605+
break;
3606+
case 'w':
3607+
iboundary = CIRCULAR;
3608+
break;
3609+
case 's':
3610+
iboundary = REFLECT;
3611+
break;
3612+
}
3613+
rtn = NDArray_Correlate2D(nda, ndb, imode, iboundary, NULL, 0);
35063614
if (rtn == NULL) {
35073615
return;
35083616
}
@@ -4089,13 +4197,14 @@ static const zend_function_entry class_NDArray_methods[] = {
40894197
ZEND_ME(NDArray, full, arginfo_ndarray_full, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40904198
ZEND_ME(NDArray, fill, arginfo_fill, ZEND_ACC_PUBLIC)
40914199
ZEND_ME(NDArray, array, arginfo_ndarray_array, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
4200+
ZEND_ME(NDArray, fromImage, arginfo_ndarray_fromimage, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40924201

40934202
// RANDOM
40944203
ZEND_ME(NDArray, normal, arginfo_ndarray_normal, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40954204
ZEND_ME(NDArray, standard_normal, arginfo_ndarray_standard_normal, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40964205
ZEND_ME(NDArray, poisson, arginfo_ndarray_poisson, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40974206
ZEND_ME(NDArray, uniform, arginfo_ndarray_uniform, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
4098-
ZEND_ME(NDArray, random_binominal, arginfo_ndarray_binominal, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
4207+
ZEND_ME(NDArray, random_binomial, arginfo_ndarray_binomial, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
40994208

41004209
// LINALG
41014210
ZEND_ME(NDArray, matmul, arginfo_ndarray_matmul, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
@@ -4116,6 +4225,7 @@ static const zend_function_entry class_NDArray_methods[] = {
41164225
ZEND_ME(NDArray, lu, arginfo_ndarray_lu, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
41174226
ZEND_ME(NDArray, matrix_rank, arginfo_ndarray_matrix_rank, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
41184227
ZEND_ME(NDArray, convolve2d, arginfo_ndarray_convolve2d, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
4228+
ZEND_ME(NDArray, correlate2d, arginfo_ndarray_correlate2d, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
41194229

41204230
// LOGIC
41214231
ZEND_ME(NDArray, all, arginfo_ndarray_all, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
@@ -4246,9 +4356,9 @@ PHP_MSHUTDOWN_FUNCTION(ndarray) {
42464356
}
42474357

42484358
PHP_RSHUTDOWN_FUNCTION(ndarray) {
4249-
char *envvar = "NDARRAY_FREEBUFFER";
4359+
char *envvar = "NDARRAY_BUFFERLEAK";
42504360
char *envvar_vcheck = "NDARRAY_VCHECK";
4251-
if(getenv(envvar)) {
4361+
if(!getenv(envvar)) {
42524362
buffer_free();
42534363
}
42544364
#ifdef HAVE_CUBLAS

src/buffer.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ void buffer_ndarray_free(int uuid) {
7070
MAIN_MEM_STACK.buffer[uuid] = NULL;
7171
MAIN_MEM_STACK.totalFreed++;
7272
}
73+
if (MAIN_MEM_STACK.numElements - 1 == 0) {
74+
buffer_free();
75+
}
7376
}
7477
}
7578

@@ -88,6 +91,9 @@ NDArray* buffer_get(int uuid) {
8891
* @param size size_t Size of CArray in bytes
8992
*/
9093
void add_to_buffer(NDArray* ndarray, size_t size) {
94+
if (MAIN_MEM_STACK.buffer == NULL) {
95+
buffer_init(1);
96+
}
9197
if (MAIN_MEM_STACK.lastFreed > -1) {
9298
ndarray->uuid = MAIN_MEM_STACK.lastFreed;
9399
MAIN_MEM_STACK.buffer[MAIN_MEM_STACK.lastFreed] = ndarray;

src/initializers.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ NDArray_Arange(double start, double stop, double step) {
791791
}
792792

793793
NDArray*
794-
NDArray_Binominal(int *shape, int ndim, int n, float p) {
794+
NDArray_Binomial(int *shape, int ndim, int n, float p) {
795795
// Calculate the total number of elements in the output array
796796
int total_elements = 1;
797797
for (int i = 0; i < ndim; i++) {
@@ -812,4 +812,58 @@ NDArray_Binominal(int *shape, int ndim, int n, float p) {
812812
NDArray_FDATA(rtn)[i] = (float)successes;
813813
}
814814
return rtn;
815+
}
816+
817+
/**
818+
* Create NDArray from pre-allocated data.
819+
*
820+
* @param data
821+
* @param ndim
822+
* @param shape
823+
* @param device
824+
* @param type
825+
* @return
826+
*/
827+
NDArray*
828+
NDArray_Create(char *data, int ndim, int *shape, int device, const char* type) {
829+
NDArray *rtn;
830+
831+
int *strides = emalloc(sizeof(int) * ndim);
832+
int num_elements = 1;
833+
for (int i = 0; i < ndim; i++) {
834+
num_elements = num_elements * shape[i];
835+
strides[i] = shape[i] * sizeof(float);
836+
}
837+
838+
if (device == NDARRAY_DEVICE_GPU) {
839+
#ifdef HAVE_CUBLAS
840+
rtn = emalloc(sizeof(NDArray));
841+
rtn->dimensions = shape;
842+
rtn->strides = strides;
843+
rtn->device = NDARRAY_DEVICE_GPU;
844+
rtn->refcount = 1;
845+
rtn->flags = 0;
846+
rtn->base = NULL;
847+
rtn->ndim = ndim;
848+
rtn->data = data;
849+
rtn->descriptor = Create_Descriptor(num_elements, sizeof(float), type);
850+
NDArrayIterator_INIT(rtn);
851+
return rtn;
852+
#else
853+
return NULL;
854+
#endif
855+
} else {
856+
rtn = emalloc(sizeof(NDArray));
857+
rtn->dimensions = shape;
858+
rtn->strides = strides;
859+
rtn->device = NDARRAY_DEVICE_CPU;
860+
rtn->refcount = 1;
861+
rtn->flags = 0;
862+
rtn->ndim = ndim;
863+
rtn->base = NULL;
864+
rtn->data = data;
865+
rtn->descriptor = Create_Descriptor(num_elements, sizeof(float), type);
866+
NDArrayIterator_INIT(rtn);
867+
return rtn;
868+
}
815869
}

src/initializers.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ int* Generate_Strides(int* dimensions, int dimensions_size, int elsize);
2323
NDArray* NDArray_CreateFromFloatScalar(float scalar);
2424
NDArray* NDArray_Empty(int *shape, int ndim, const char *type, int device);
2525
NDArray* NDArray_Arange(double start, double stop, double step);
26-
NDArray* NDArray_Binominal(int *shape, int ndim, int n, float p);
26+
NDArray* NDArray_Binomial(int *shape, int ndim, int n, float p);
2727
NDArray* NDArray_EmptyLike(NDArray *a);
28+
NDArray* NDArray_Create(char *data, int ndim, int *shape, int device, const char* type);
2829
#ifdef __cplusplus
2930
extern "C" {
3031
#endif

0 commit comments

Comments
 (0)