Permalink
Browse files

Implement cl_build_program().

  • Loading branch information...
1 parent 21812ad commit 8e9e9afa5efc2e8481528deba0cd45246a63b963 @rsky committed Sep 1, 2012
Showing with 120 additions and 6 deletions.
  1. +1 −1 context.c
  2. +2 −0 examples/mandelbrot.php
  3. +19 −2 opencl.c
  4. +6 −2 php_opencl.h
  5. +91 −1 program.c
  6. +1 −0 program.h
View
@@ -168,7 +168,7 @@ PHP_FUNCTION(cl_create_context)
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
- "z/|z!/z/z/z", &zdevices, &zproperties,
+ "z|z!/z/z/z", &zdevices, &zproperties,
&zcallback, &zdata, &zerrcode) == FAILURE) {
return;
}
@@ -14,3 +14,5 @@
$source = __DIR__ . '/mandelbrot.cl';
$program = cl_create_program_with_source($context, $source, $err);
var_dump($program, $err);
+//cl_build_program($program, $devices[0]);
+cl_build_program($program);
View
@@ -77,7 +77,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_get_context_info, ZEND_SEND_BY_VAL, ZEND_RETURN_V
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_create_context, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
- ZEND_ARG_INFO(0, device)
+ ZEND_ARG_INFO(0, devices)
ZEND_ARG_ARRAY_INFO(0, properties, 1)
ZEND_ARG_INFO(0, callback)
ZEND_ARG_INFO(0, userdata)
@@ -120,6 +120,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_create_program_with_source, ZEND_SEND_BY_VAL, ZEN
ZEND_ARG_INFO(1, errcode)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_build_program, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
+ ZEND_ARG_INFO(0, program)
+ ZEND_ARG_INFO(0, devices)
+ ZEND_ARG_INFO(0, options)
+ ZEND_ARG_INFO(0, callback)
+ ZEND_ARG_INFO(0, userdata)
+ZEND_END_ARG_INFO()
+
/* kernel */
ZEND_BEGIN_ARG_INFO_EX(arginfo_get_kernel_info, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
ZEND_ARG_INFO(0, kernel)
@@ -160,6 +168,7 @@ static zend_function_entry phpcl_functions[] = {
/* program */
PHP_FE(cl_get_program_info, arginfo_get_program_info)
PHP_FE(cl_create_program_with_source, arginfo_create_program_with_source)
+ PHP_FE(cl_build_program, arginfo_build_program)
/* kernel */
PHP_FE(cl_get_kernel_info, arginfo_get_kernel_info)
/* event */
@@ -796,7 +805,15 @@ static void _destroy_mem(zend_rsrc_list_entry *rsrc TSRMLS_DC)
static void _destroy_program(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
- clReleaseProgram((cl_program)rsrc->ptr);
+ phpcl_program_t *prg = (phpcl_program_t *)rsrc->ptr;
+ clReleaseProgram(prg->program);
+ if (prg->callback) {
+ zval_ptr_dtor(&prg->callback);
+ }
+ if (prg->data) {
+ zval_ptr_dtor(&prg->data);
+ }
+ efree(prg);
}
static void _destroy_kernel(zend_rsrc_list_entry *rsrc TSRMLS_DC)
View
@@ -29,10 +29,14 @@ typedef struct {
cl_context context;
zval *callback;
zval *data;
- zend_fcall_info fci;
- zend_fcall_info_cache fcc;
} phpcl_context_t;
+typedef struct {
+ cl_program program;
+ zval *callback;
+ zval *data;
+} phpcl_program_t;
+
typedef enum {
INFO_TYPE_BITFIELD = 0,
INFO_TYPE_BOOL,
View
@@ -12,6 +12,11 @@
#define get_info ((phpcl_get_info_func_t)_get_program_info)
#define get_info_ex NULL
+/* {{{ type definitions */
+
+typedef void (*build_program_callback_func_t)(cl_program, void *);
+
+/* }}} */
/* {{{ globals */
static const phpcl_info_param_t program_info_params[] = {
@@ -147,8 +152,93 @@ PHP_FUNCTION(cl_create_program_with_source)
}
if (program) {
- ZEND_REGISTER_RESOURCE(return_value, program, phpcl_le_program());
+ phpcl_program_t *prg = emalloc(sizeof(phpcl_program_t));
+ prg->program = program;
+ prg->callback = NULL;
+ prg->data = NULL;
+ ZEND_REGISTER_RESOURCE(return_value, prg, phpcl_le_program());
+ }
+}
+
+/* }}} */
+/* {{{ void cl_build_program(resource cl_program program[, mixed devices[, string options[, callback callback[, ]]]]) */
+
+PHP_FUNCTION(cl_build_program)
+{
+ cl_int errcode = CL_SUCCESS;
+ zval *zprogram = NULL;
+ phpcl_program_t *prg = NULL;
+ zval *zdevices = NULL;
+ cl_device_id *devices = NULL;
+ cl_uint num_devices = 0;
+ cl_device_id device = NULL;
+ char *options = NULL;
+ int options_len = 0;
+ zval *zcallback = NULL;
+ build_program_callback_func_t notify_func = NULL;
+ zval *zdata = NULL;
+ void *userdata = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "r|z!/s!z/z/", &zprogram, &zdevices,
+ &options, &options_len, &zcallback, &zdata) == FAILURE) {
+ return;
}
+
+ ZEND_FETCH_RESOURCE(prg, phpcl_program_t *, &zprogram, -1,
+ "cl_program", phpcl_le_program());
+
+ if (!zdevices) {
+ cl_context context = NULL;
+ errcode = clGetProgramInfo(prg->program, CL_PROGRAM_CONTEXT,
+ sizeof(cl_context), &context, NULL);
+ if (errcode != CL_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "%s", phpcl_errstr(errcode));
+ return;
+ }
+ devices = phpcl_context_get_devices(context, &num_devices, &errcode);
+ if (!devices) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "%s", phpcl_errstr(errcode));
+ return;
+ }
+ } else if (Z_TYPE_P(zdevices) == IS_RESOURCE) {
+ ZEND_FETCH_RESOURCE(device, cl_device_id, &zdevices, -1,
+ "cl_device", phpcl_le_device());
+ devices = emalloc(sizeof(cl_device_id));
+ devices[0] = device;
+ num_devices = 1;
+ } else {
+ /* TODO: support multiple devices */
+ php_error(E_WARNING,
+ "%s() expects parameter 2 to be a valid resource",
+ get_active_function_name(TSRMLS_C));
+ return;
+ }
+
+ if (zcallback) {
+ if (!zend_is_callable(zcallback, 0, NULL TSRMLS_CC)) {
+ efree(devices);
+ php_error(E_WARNING,
+ "%s() expects parameter 4 to be a valid callback",
+ get_active_function_name(TSRMLS_C));
+ return;
+ }
+ }
+
+ if (zcallback) {
+ prg->callback = zcallback;
+ Z_ADDREF_P(zcallback);
+ if (zdata) {
+ prg->data = zdata;
+ Z_ADDREF_P(zdata);
+ }
+ }
+
+ clBuildProgram(prg->program, num_devices, devices,
+ options, notify_func, prg);
+ efree(devices);
}
/* }}} */
View
@@ -14,6 +14,7 @@
PHP_FUNCTION(cl_get_program_info);
PHP_FUNCTION(cl_create_program_with_source);
+PHP_FUNCTION(cl_build_program);
#endif

0 comments on commit 8e9e9af

Please sign in to comment.