Esempio n. 1
0
/**
 * @internal
 *
 * @brief Tests creation, getting info from and destruction of
 * buffer wrapper objects.
 * */
static void create_info_destroy_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLBuffer * b = NULL;
    CCLErr * err = NULL;
    size_t buf_size = sizeof(cl_uint) * CCL_TEST_BUFFER_SIZE;

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Create regular buffer. */
    b = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Get some info and check if the return value is as expected. */
    cl_mem_object_type mot;
    mot = ccl_memobj_get_info_scalar(
        b, CL_MEM_TYPE, cl_mem_object_type, &err);
    g_assert_no_error(err);
    g_assert_cmphex(mot, ==, CL_MEM_OBJECT_BUFFER);

    cl_mem_flags flags;
    flags = ccl_memobj_get_info_scalar(
        b, CL_MEM_FLAGS, cl_mem_flags, &err);
    g_assert_no_error(err);
    g_assert_cmphex(flags, ==, CL_MEM_READ_WRITE);

    size_t mem_size;
    mem_size = ccl_memobj_get_info_scalar(b, CL_MEM_SIZE, size_t, &err);
    g_assert_no_error(err);
    g_assert_cmpuint(mem_size, ==, buf_size);

    void * host_ptr = NULL;
    host_ptr = ccl_memobj_get_info_scalar(
        b, CL_MEM_HOST_PTR, void*, &err);
    g_assert((err == NULL) || (err->code == CCL_ERROR_INFO_UNAVAILABLE_OCL));
    g_assert_cmphex(GPOINTER_TO_UINT(host_ptr), ==,
        GPOINTER_TO_UINT(NULL));
    g_clear_error(&err);

    cl_context context;
    context = ccl_memobj_get_info_scalar(
        b, CL_MEM_CONTEXT, cl_context, &err);
    g_assert_no_error(err);
    g_assert_cmphex(GPOINTER_TO_UINT(context), ==,
        GPOINTER_TO_UINT(ccl_context_unwrap(ctx)));

    /* Destroy stuff. */
    ccl_buffer_destroy(b);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 2
0
/**
 * @internal
 *
 * @brief Tests map/unmap operations in buffer objects.
 * */
static void map_unmap_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLDevice * d = NULL;
    CCLBuffer * b = NULL;
    CCLQueue * q;
    cl_uint h_in[CCL_TEST_BUFFER_SIZE];
    cl_uint * h_out;
    size_t buf_size = sizeof(cl_uint) * CCL_TEST_BUFFER_SIZE;
    CCLErr * err = NULL;

    /* Create a host array, put some stuff in it. */
    for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        h_in[i] = g_test_rand_int();

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Get first device in context. */
    d = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Create a command queue. */
    q = ccl_queue_new(ctx, d, 0, &err);
    g_assert_no_error(err);

    /* Create regular buffer and write data from the host buffer. */
    b = ccl_buffer_new(
        ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, buf_size, h_in, &err);
    g_assert_no_error(err);

    /* Map buffer onto host memory. */
    h_out = ccl_buffer_enqueue_map(
        b, q, CL_TRUE, CL_MAP_READ, 0, buf_size, NULL, NULL, &err);
    g_assert_no_error(err);

    /* Check data is OK. */
    for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        g_assert_cmpuint(h_in[i], ==, h_out[i]);

    /* Unmap buffer. */
    ccl_memobj_enqueue_unmap(
        (CCLMemObj *) b, q, h_out, NULL, &err);
    g_assert_no_error(err);

    /* Free stuff. */
    ccl_buffer_destroy(b);
    ccl_queue_destroy(q);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 3
0
/**
 * @internal
 *
 * @brief Tests buffer wrapper class reference counting.
 * */
static void ref_unref_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLBuffer * b = NULL;
    CCLErr * err = NULL;
    size_t buf_size = sizeof(cl_uint) * CCL_TEST_BUFFER_SIZE;

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Create regular buffer. */
    b = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Increase buffer reference count. */
    ccl_memobj_ref(b);

    /* Check that buffer ref count is 2. */
    g_assert_cmpuint(2, ==, ccl_wrapper_ref_count((CCLWrapper *) b));

    /* Increase buffer reference count again, this time using helper
     * macro. */
    ccl_buffer_ref(b);

    /* Check that buffer ref count is 3. */
    g_assert_cmpuint(3, ==, ccl_wrapper_ref_count((CCLWrapper *) b));

    /* Unref buffer, twice. */
    ccl_buffer_unref(b);
    ccl_buffer_unref(b);

    /* Check that buffer ref count is 1. */
    g_assert_cmpuint(1, ==, ccl_wrapper_ref_count((CCLWrapper *) b));

    /* Destroy stuff. */
    ccl_buffer_unref(b);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 4
0
/**
 * @internal
 *
 * @brief Test memory object destructor callbacks.
 * */
static void destructor_callback_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLBuffer * b = NULL;
    CCLErr * err = NULL;
    GTimer * timer = NULL;
    cl_bool test_var = CL_FALSE;

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Create a buffer. */
    b = ccl_buffer_new(
        ctx, CL_MEM_READ_WRITE, 128 * sizeof(cl_uint), NULL, &err);

    /* Add destructor callback. */
    ccl_memobj_set_destructor_callback(
        (CCLMemObj *) b, destructor_callback, &test_var, &err);
    g_assert_no_error(err);

    /* Destroy buffer. */
    ccl_buffer_destroy(b);

    /* Destroy context. */
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());

    /* Wait some more... */
    timer = g_timer_new();
    while (g_timer_elapsed(timer, NULL) < 2.0);
    g_timer_stop(timer);
    g_timer_destroy(timer);

    /* Confirm that test_var is CL_TRUE. */
    g_assert_cmpuint(test_var, ==, CL_TRUE);
}
Esempio n. 5
0
/**
 * @internal
 * Perform sort using device data.
 * */
static CCLEvent* clo_sort_gselect_sort_with_device_data(
	CloSort* sorter, CCLQueue* cq_exec, CCLQueue* cq_comm,
	CCLBuffer* data_in, CCLBuffer* data_out, size_t numel,
	size_t lws_max, GError** err) {

	/* Make sure err is NULL or it is not set. */
	g_return_val_if_fail(err == NULL || *err == NULL, NULL);

	/* Make sure cq_exec is not NULL. */
	g_return_val_if_fail(cq_exec != NULL, NULL);

	/* Worksizes. */
	size_t lws, gws;

	/* OpenCL object wrappers. */
	CCLContext* ctx = NULL;
	CCLDevice* dev = NULL;
	CCLKernel* krnl = NULL;
	CCLEvent* evt = NULL;

	/* Event wait list. */
	CCLEventWaitList ewl = NULL;

	/* Internal error reporting object. */
	GError* err_internal = NULL;

	/* Flag indicating if sorted data is to be copied back to original
	 * buffer, simulating an in-place sort. */
	cl_bool copy_back = CL_FALSE;

	/* If data transfer queue is NULL, use exec queue for data
	 * transfers. */
	if (cq_comm == NULL) cq_comm = cq_exec;

	/* Get device where sort will occurr. */
	dev = ccl_queue_get_device(cq_exec, &err_internal);
	g_if_err_propagate_goto(err, err_internal, error_handler);

	/* Get the kernel wrapper. */
	krnl = ccl_program_get_kernel(clo_sort_get_program(sorter),
		"gselect", &err_internal);
	g_if_err_propagate_goto(err, err_internal, error_handler);

	/* Determine worksizes. */
	gws = numel;
	lws = lws_max;
	ccl_kernel_suggest_worksizes(
		krnl, dev, 1, &gws, NULL, &lws, &err_internal);
	g_if_err_propagate_goto(err, err_internal, error_handler);

	/* Check if data_out is set. */
	if (data_out == NULL) {
		/* If not create it and set the copy back flag to TRUE. */

		/* Get context. */
		ctx = ccl_queue_get_context(cq_comm, &err_internal);
		g_if_err_propagate_goto(err, err_internal, error_handler);

		/* Set copy-back flag to true. */
		copy_back = CL_TRUE;

		/* Create output buffer. */
		data_out = ccl_buffer_new(ctx, CL_MEM_WRITE_ONLY,
			numel * clo_sort_get_element_size(sorter), NULL,
			&err_internal);
		g_if_err_propagate_goto(err, err_internal, error_handler);

	} else {

		/* Set copy back flag to FALSE. */
		copy_back = CL_FALSE;
	}

	/* Set kernel arguments. */
	cl_ulong numel_l = numel;
	ccl_kernel_set_args(
		krnl, data_in, data_out, ccl_arg_priv(numel_l, cl_ulong), NULL);

	/* Perform global memory selection sort. */
	evt = ccl_kernel_enqueue_ndrange(
		krnl, cq_exec, 1, NULL, &gws, &lws, NULL, &err_internal);
	g_if_err_propagate_goto(err, err_internal, error_handler);
	ccl_event_set_name(evt, "gselect_ndrange");

	/* If copy-back flag is set, copy sorted data back to original
	 * buffer. */
	if (copy_back) {
		ccl_event_wait_list_add(&ewl, evt, NULL);
		evt = ccl_buffer_enqueue_copy(data_out, data_in, cq_comm, 0, 0,
			numel * clo_sort_get_element_size(sorter), &ewl,
			&err_internal);
		g_if_err_propagate_goto(err, err_internal, error_handler);
		ccl_event_set_name(evt, "gselect_copy");
	}

	/* If we got here, everything is OK. */
	g_assert(err == NULL || *err == NULL);
	goto finish;

error_handler:
	/* If we got here there was an error, verify that it is so. */
	g_assert(err == NULL || *err != NULL);
	evt = NULL;

finish:

	/* Free data out buffer if copy-back flag is set. */
	if ((copy_back) && (data_out != NULL)) ccl_buffer_destroy(data_out);

	/* Return event wait list. */
	return evt;

}
Esempio n. 6
0
/**
 * Test RNG with GID-based device generated seeds.
 * */
static void seed_dev_gid_test() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLDevice* dev = NULL;
	CCLQueue* cq = NULL;
	CCLProgram* prg = NULL;
	CCLKernel* krnl = NULL;
	CCLBuffer* seeds_dev = NULL;
	CCLBuffer* output_dev = NULL;
	GError* err = NULL;
	CloRng* rng = NULL;
	size_t lws = 0;
	size_t ws = CLO_RNG_TEST_NUM_SEEDS;
	gchar* src;

	/* Get context and device. */
	ctx = ccl_context_new_any(&err);
	g_assert_no_error(err);

	dev = ccl_context_get_device(ctx, 0, &err);
	g_assert_no_error(err);

	/* Create command queue. */
	cq = ccl_queue_new(ctx, dev, 0, &err);
	g_assert_no_error(err);

	/* Test all RNGs. */
	for (cl_uint i = 0; clo_rng_infos[i].name != NULL; ++i) {

		/* Create RNG object. */
		rng = clo_rng_new(clo_rng_infos[i].name, CLO_RNG_SEED_DEV_GID,
			NULL, CLO_RNG_TEST_NUM_SEEDS, CLO_RNG_TEST_INIT_SEED,
			CLO_RNG_TEST_HASH, ctx, cq, &err);
		g_assert_no_error(err);

		/* Get RNG seeds device buffer. */
		seeds_dev = clo_rng_get_device_seeds(rng);

		/* Get RNG kernels source. */
		src = g_strconcat(
			clo_rng_get_source(rng), CLO_RNG_TEST_SRC, NULL);

		/* Create and build program. */
		prg = ccl_program_new_from_source(ctx, src, &err);
		g_assert_no_error(err);

		ccl_program_build(prg, NULL, &err);
		g_assert_no_error(err);

		/* Create output buffer. */
		output_dev = ccl_buffer_new(ctx, CL_MEM_WRITE_ONLY,
			CLO_RNG_TEST_NUM_SEEDS * sizeof(cl_ulong), NULL, &err);
		g_assert_no_error(err);

		/* Get kernel from program. */
		krnl = ccl_program_get_kernel(prg, CLO_RNG_TEST_KERNEL, &err);
		g_assert_no_error(err);

		/* Get a "nice" local worksize. */
		ccl_kernel_suggest_worksizes(
			krnl, dev, 1, &ws, NULL, &lws, &err);
		g_assert_no_error(err);

		/* Execute kernel. */
		ccl_kernel_set_args_and_enqueue_ndrange(
			krnl, cq, 1, NULL, &ws, &lws, NULL, &err,
			seeds_dev, output_dev, NULL);
		g_assert_no_error(err);

		/* Release this iteration stuff. */
		g_free(src);
		ccl_buffer_destroy(output_dev);
		ccl_program_destroy(prg);
		clo_rng_destroy(rng);

	}

	/* Destroy queue and context. */
	ccl_queue_destroy(cq);
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly
	 * freed. */
	g_assert(ccl_wrapper_memcheck());

}
Esempio n. 7
0
/**
 * Test RNG with client generated seeds in device.
 * */
static void seed_ext_dev_test() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLDevice* dev = NULL;
	CCLQueue* cq = NULL;
	CCLProgram* prg = NULL;
	CCLKernel* krnl = NULL;
	CCLBuffer* seeds_dev = NULL;
	CCLBuffer* output_dev = NULL;
	GError* err = NULL;
	CloRng* rng = NULL;
	size_t lws = 0;
	size_t ws = CLO_RNG_TEST_NUM_SEEDS;
	gchar* src;
	cl_uchar* host_seeds;

	/* Get context and device. */
	ctx = ccl_context_new_any(&err);
	g_assert_no_error(err);

	dev = ccl_context_get_device(ctx, 0, &err);
	g_assert_no_error(err);

	/* Create command queue. */
	cq = ccl_queue_new(ctx, dev, 0, &err);
	g_assert_no_error(err);

	/* Test all RNGs. */
	for (cl_uint i = 0; clo_rng_infos[i].name != NULL; ++i) {

		/* Host seeds must account for the seed size of current RNG. */
		size_t seed_size =
			clo_rng_infos[i].seed_size * CLO_RNG_TEST_NUM_SEEDS;
		host_seeds = g_slice_alloc(seed_size);

		/* Initialize host seeds with any value. */
		for (cl_uint i = 0; i < seed_size; ++i)
			host_seeds[i] = (cl_uchar) (((i + 1) * 3) & 0xFF);

		/* Allocate memory for device seeds and copy host seeds. */
		seeds_dev = ccl_buffer_new(
			ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, seed_size,
			host_seeds, &err);
		g_assert_no_error(err);

		/* Create RNG object. */
		rng = clo_rng_new(clo_rng_infos[i].name, CLO_RNG_SEED_EXT_DEV,
			seeds_dev, CLO_RNG_TEST_NUM_SEEDS, CLO_RNG_TEST_INIT_SEED,
			NULL, ctx, cq, &err);
		g_assert_no_error(err);

		/* Get RNG kernels source. */
		src = g_strconcat(
			clo_rng_get_source(rng), CLO_RNG_TEST_SRC, NULL);

		/* Create and build program. */
		prg = ccl_program_new_from_source(ctx, src, &err);
		g_assert_no_error(err);

		ccl_program_build(prg, NULL, &err);
		g_assert_no_error(err);

		/* Create output buffer. */
		output_dev = ccl_buffer_new(ctx, CL_MEM_WRITE_ONLY,
			CLO_RNG_TEST_NUM_SEEDS * sizeof(cl_ulong), NULL, &err);
		g_assert_no_error(err);

		/* Get kernel from program. */
		krnl = ccl_program_get_kernel(prg, CLO_RNG_TEST_KERNEL, &err);
		g_assert_no_error(err);

		/* Get a "nice" local worksize. */
		ccl_kernel_suggest_worksizes(
			krnl, dev, 1, &ws, NULL, &lws, &err);
		g_assert_no_error(err);

		/* Execute kernel. */
		ccl_kernel_set_args_and_enqueue_ndrange(
			krnl, cq, 1, NULL, &ws, &lws, NULL, &err,
			seeds_dev, output_dev, NULL);
		g_assert_no_error(err);

		/* Release this iteration stuff. */
		g_slice_free1(seed_size, host_seeds);
		g_free(src);
		ccl_buffer_destroy(seeds_dev);
		ccl_buffer_destroy(output_dev);
		ccl_program_destroy(prg);
		clo_rng_destroy(rng);

	}

	/* Destroy queue and context. */
	ccl_queue_destroy(cq);
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly
	 * freed. */
	g_assert(ccl_wrapper_memcheck());

}
Esempio n. 8
0
/**
 * @internal
 *
 * @brief Tests memory object migration.
 * */
static void migrate_test() {

    /* Test variables. */
    CCLPlatforms * ps;
    CCLPlatform * p;
    CCLContext * ctx = NULL;
    CCLDevice * d = NULL;
    CCLBuffer * b = NULL;
    CCLQueue * q;
    size_t buf_size = sizeof(cl_char8) * CCL_TEST_BUFFER_SIZE;
    CCLErr * err = NULL;

    /* Get a context which supports OpenCL 1.2 if possible. */
    ps = ccl_platforms_new(&err);
    g_assert_no_error(err);
    for (guint i = 0; i < ccl_platforms_count(ps); ++i) {
        p = ccl_platforms_get(ps, i);
        cl_uint ocl_ver = ccl_platform_get_opencl_version(p, &err);
        if (ocl_ver >= 120) {
            ctx = ccl_context_new_from_devices(
                ccl_platform_get_num_devices(p, NULL),
                ccl_platform_get_all_devices(p, NULL),
                &err);
            g_assert_no_error(err);
            break;
        }
    }

    /* If not possible to find a 1.2 or better context, finish this
     * test. */
    if (ctx == NULL) {
        g_test_message("'%s' test not performed because no platform " \
            "with OpenCL 1.2 support was found", CCL_STRD);
        ccl_platforms_destroy(ps);
        return;
    }

    /* Get first device in context. */
    d = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Create a command queue associated with first device in
     * context. */
    q = ccl_queue_new(ctx, d, 0, &err);
    g_assert_no_error(err);

    /* Create regular buffer. */
    b = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Assign buffer to first device in context (via the command
     * queue). */
    ccl_memobj_enqueue_migrate((CCLMemObj **) &b, 1, q, 0, NULL, &err);
    g_assert_no_error(err);

    /* Migrate buffer to host. */
    ccl_memobj_enqueue_migrate(
        (CCLMemObj **) &b, 1, q, CL_MIGRATE_MEM_OBJECT_HOST, NULL, &err);
    g_assert_no_error(err);

    /* Wait for queue to finish... */
    ccl_queue_finish(q, &err);
    g_assert_no_error(err);

    /* Free stuff. */
    ccl_buffer_destroy(b);
    ccl_queue_destroy(q);
    ccl_context_destroy(ctx);
    ccl_platforms_destroy(ps);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 9
0
/**
 * @internal
 *
 * @brief Tests buffer fill.
 * */
static void fill_test() {

    /* Test variables. */
    CCLPlatforms * ps;
    CCLPlatform * p;
    CCLContext * ctx = NULL;
    CCLDevice * d = NULL;
    CCLBuffer * b = NULL;
    CCLQueue * q;
    cl_char8 h[CCL_TEST_BUFFER_SIZE];
    cl_char8 pattern = {{ 1, -1, 5, 4, -12, 3, 7, -20 }};
    size_t buf_size = sizeof(cl_char8) * CCL_TEST_BUFFER_SIZE;
    CCLErr * err = NULL;

    /* Get a context which supports OpenCL 1.2, if possible. */
    ps = ccl_platforms_new(&err);
    g_assert_no_error(err);
    for (guint i = 0; i < ccl_platforms_count(ps); ++i) {
        p = ccl_platforms_get(ps, i);
        cl_uint ocl_ver = ccl_platform_get_opencl_version(p, &err);
        if (ocl_ver >= 120) {
            ctx = ccl_context_new_from_devices(
                ccl_platform_get_num_devices(p, NULL),
                ccl_platform_get_all_devices(p, NULL),
                &err);
            g_assert_no_error(err);
            break;
        }
    }

    /* If not possible to find a 1.2 or better context, finish this
     * test. */
    if (ctx == NULL) {
        g_test_message("'%s' test not performed because no platform " \
            "with OpenCL 1.2 support was found", CCL_STRD);
        ccl_platforms_destroy(ps);
        return;
    }

    /* Get first device in context. */
    d = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Create a command queue. */
    q = ccl_queue_new(ctx, d, 0, &err);
    g_assert_no_error(err);

    /* Create regular buffer. */
    b = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Fill buffer with pattern. */
    ccl_buffer_enqueue_fill(
        b, q, &pattern, sizeof(cl_char8), 0, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Read data back to host. */
    ccl_buffer_enqueue_read(b, q, CL_TRUE, 0, buf_size, h, NULL, &err);
    g_assert_no_error(err);

    /* Check data is OK. */
    for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        for (guint j = 0; j < 8; ++j)
            g_assert_cmpuint(h[i].s[j], ==, pattern.s[j]);

    /* Free stuff. */
    ccl_buffer_destroy(b);
    ccl_queue_destroy(q);
    ccl_context_destroy(ctx);
    ccl_platforms_destroy(ps);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 10
0
/**
 * @internal
 *
 * @brief Tests the ccl_buffer_new_from_region() function.
 * */
static void create_from_region_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLDevice * dev = NULL;
    CCLQueue * cq = NULL;
    CCLBuffer * buf = NULL;
    CCLBuffer * subbuf = NULL;
    CCLEvent * evt = NULL;
    CCLEventWaitList ewl = NULL;
    CCLErr * err = NULL;
    cl_ulong * hbuf;
    cl_ulong * hsubbuf;
    cl_uint min_align;
    size_t siz_buf;
    size_t siz_subbuf;

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Get first device in context. */
    dev = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Get minimum alignment for sub-buffer in bits. */
    min_align = ccl_device_get_info_scalar(
        dev, CL_DEVICE_MEM_BASE_ADDR_ALIGN, cl_uint, &err);
    g_assert_no_error(err);

    /* Determine buffer and sub-buffer sizes (divide by 64 because its
     * the number of bits in cl_ulong). */
    siz_subbuf = sizeof(cl_ulong) * min_align / 64;
    siz_buf = 4 * siz_subbuf;

    /* Allocate memory for host buffer and host sub-buffer. */
    hbuf = g_slice_alloc(siz_buf);
    hsubbuf = g_slice_alloc(siz_subbuf);

    /* Initialize initial host buffer. */
    for (cl_uint i = 0; i < siz_buf / sizeof(cl_ulong); ++i)
        hbuf[i] = g_test_rand_int();

    /* Create a command queue. */
    cq = ccl_queue_new(ctx, dev, 0, &err);
    g_assert_no_error(err);

    /* Create a regular buffer, put some data in it. */
    buf = ccl_buffer_new(
        ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, siz_buf, hbuf, &err);
    g_assert_no_error(err);

    /* Create sub-buffer from indexes 16 to 31 (16 positions) of
     * original buffer. */
    subbuf = ccl_buffer_new_from_region(
        buf, 0, siz_subbuf, siz_subbuf, &err);
    g_assert_no_error(err);

    /* Get data in sub-buffer to a new host buffer. */
    evt = ccl_buffer_enqueue_read(
        subbuf, cq, CL_FALSE, 0, siz_subbuf, hsubbuf, NULL, &err);
    g_assert_no_error(err);

    /* Wait for read to be complete. */
    ccl_event_wait(ccl_ewl(&ewl, evt, NULL), &err);
    g_assert_no_error(err);

    /* Check that expected values were successfully read. */
    for (cl_uint i = 0; i < siz_subbuf / sizeof(cl_ulong); ++i)
        g_assert_cmpuint(
            hsubbuf[i], ==, hbuf[i + siz_subbuf / sizeof(cl_ulong)]);

    /* Destroy stuff. */
    ccl_buffer_destroy(buf);
    ccl_buffer_destroy(subbuf);
    ccl_queue_destroy(cq);
    ccl_context_destroy(ctx);
    g_slice_free1(siz_buf, hbuf);
    g_slice_free1(siz_subbuf, hsubbuf);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 11
0
/**
 * @internal
 *
 * @brief Tests rect buffer operations.
 * */
static void rect_read_write_copy_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLDevice * d = NULL;
    CCLBuffer * b1 = NULL;
    CCLBuffer * b2 = NULL;
    CCLQueue * cq;
    cl_uchar h1[CCL_TEST_BUFFER_SIZE * CCL_TEST_BUFFER_SIZE];
    cl_uchar h2[CCL_TEST_BUFFER_SIZE * CCL_TEST_BUFFER_SIZE];
    size_t buf_size = sizeof(cl_uchar) * sizeof(cl_uchar)
        * CCL_TEST_BUFFER_SIZE * CCL_TEST_BUFFER_SIZE;
    CCLErr * err = NULL;
    const size_t origin[] = {0, 0, 0};
    const size_t region[] = {CCL_TEST_BUFFER_SIZE * sizeof(cl_uchar),
        CCL_TEST_BUFFER_SIZE * sizeof(cl_uchar), 1};

    /* Create a "2D" host array, put some stuff in it. */
    for (cl_uint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        for (cl_uint j = 0; j < CCL_TEST_BUFFER_SIZE; ++j)
            h1[i * CCL_TEST_BUFFER_SIZE + j] =
                (cl_uchar) (g_test_rand_int() % 0xFF);

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Get first device in context. */
    d = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Create a command queue. */
    cq = ccl_queue_new(ctx, d, 0, &err);
    g_assert_no_error(err);

    /* Create device buffers. */
    b1 = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);
    b2 = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Write "rect" data to first buffer in device. */
    ccl_buffer_enqueue_write_rect(
        b1, cq, CL_TRUE, origin, origin, region, 0, 0, 0, 0, h1, NULL, &err);
    g_assert_no_error(err);

    /* Copy "rect" data from first buffer to second buffer. */
    ccl_buffer_enqueue_copy_rect(
        b1, b2, cq, origin, origin, region, 0, 0, 0, 0, NULL, &err);
    g_assert_no_error(err);

    /* Read data "rect" back to host from the second buffer. */
    ccl_buffer_enqueue_read_rect(
        b2, cq, CL_TRUE, origin, origin, region, 0, 0, 0, 0, h2, NULL, &err);
    g_assert_no_error(err);

    /* Check data is OK doing a flat comparison. */
    for (cl_uint i = 0; i < CCL_TEST_BUFFER_SIZE * CCL_TEST_BUFFER_SIZE; ++i)
        g_assert_cmpuint(h1[i], ==, h2[i]);

    /* Free stuff. */
    ccl_buffer_destroy(b1);
    ccl_buffer_destroy(b2);
    ccl_queue_destroy(cq);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 12
0
/**
 * @internal
 *
 * @brief Tests copy operations from one buffer to another.
 * */
static void copy_test() {

    /* Test variables. */
    CCLContext * ctx = NULL;
    CCLDevice * d = NULL;
    CCLBuffer * b1 = NULL;
    CCLBuffer * b2 = NULL;
    CCLQueue * q;
    cl_long h1[CCL_TEST_BUFFER_SIZE];
    cl_long h2[CCL_TEST_BUFFER_SIZE];
    size_t buf_size = sizeof(cl_long) * CCL_TEST_BUFFER_SIZE;
    CCLErr * err = NULL;

    /* Create a host array, put some stuff in it. */
    for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        h1[i] = g_test_rand_int();

    /* Get the test context with the pre-defined device. */
    ctx = ccl_test_context_new(&err);
    g_assert_no_error(err);

    /* Get first device in context. */
    d = ccl_context_get_device(ctx, 0, &err);
    g_assert_no_error(err);

    /* Create a command queue. */
    q = ccl_queue_new(ctx, d, 0, &err);
    g_assert_no_error(err);

    /* Create regular buffer and write data from the host buffer. */
    b1 = ccl_buffer_new(
        ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, buf_size, h1, &err);
    g_assert_no_error(err);

    /* Create another buffer, double the size. */
    b2 = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, 2 * buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Copy data from first buffer to second buffer, using an offset on
     * the second buffer. */
    ccl_buffer_enqueue_copy(
        b1, b2, q, 0, buf_size / 2, buf_size, NULL, &err);
    g_assert_no_error(err);

    /* Read data back to host from the second buffer. */
    ccl_buffer_enqueue_read(
        b2, q, CL_TRUE, buf_size / 2, buf_size, h2, NULL, &err);
    g_assert_no_error(err);

    /* Check data is OK. */
    for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
        g_assert_cmpuint(h1[i], ==, h2[i]);

    /* Free stuff. */
    ccl_buffer_destroy(b1);
    ccl_buffer_destroy(b2);
    ccl_queue_destroy(q);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
Esempio n. 13
0
/**
 * Tests basic read/write operations from/to buffer objects.
 * */
static void buffer_read_write() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLDevice* d = NULL;
	CCLBuffer* b = NULL;
	CCLQueue* q;
	cl_uint h_in[CCL_TEST_BUFFER_SIZE];
	cl_uint h_out[CCL_TEST_BUFFER_SIZE];
	size_t buf_size = sizeof(cl_uint) * CCL_TEST_BUFFER_SIZE;
	GError* err = NULL;

	/* Create a host array, put some stuff in it. */
	for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
		h_in[i] = g_test_rand_int();

	/* Get a context with any device. */
	ctx = ccl_context_new_any(&err);
	g_assert_no_error(err);

	/* Get first device in context. */
	d = ccl_context_get_device(ctx, 0, &err);
	g_assert_no_error(err);

	/* Create a command queue. */
	q = ccl_queue_new(ctx, d, 0, &err);
	g_assert_no_error(err);

	/* Create regular buffer and write data from the host buffer. */
	b = ccl_buffer_new(ctx, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR,
		buf_size, h_in, &err);
	g_assert_no_error(err);

	/* Read data back to host. */
	ccl_buffer_enqueue_read(b, q, CL_TRUE, 0, buf_size, (void*) h_out,
		NULL, &err);
	g_assert_no_error(err);

	/* Check data is OK. */
	for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
		g_assert_cmpuint(h_in[i], ==, h_out[i]);

	/* Set some other data in host array. */
	for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
		h_in[i] = g_test_rand_int();

	/* Write it explicitly to buffer. */
	ccl_buffer_enqueue_write(b, q, CL_TRUE, 0, buf_size, (void*) h_in,
		NULL, &err);
	g_assert_no_error(err);

	/* Read new data to host. */
	ccl_buffer_enqueue_read(b, q, CL_TRUE, 0, buf_size, (void*) h_out,
		NULL, &err);
	g_assert_no_error(err);

	/* Check data is OK. */
	for (guint i = 0; i < CCL_TEST_BUFFER_SIZE; ++i)
		g_assert_cmpuint(h_in[i], ==, h_out[i]);

	/* Free stuff. */
	ccl_buffer_destroy(b);
	ccl_queue_destroy(q);
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly
	 * freed. */
	g_assert(ccl_wrapper_memcheck());

}
Esempio n. 14
0
/**
 * Tests creation, getting info from and destruction of
 * profiler objects, and their relationship with context, device and
 * queue wrapper objects.
 * */
static void create_add_destroy_test() {

	/* Test variables. */
	CCLErr* err = NULL;
	CCLBuffer* buf1 = NULL;
	CCLBuffer* buf2 = NULL;
	CCLProf* prof = NULL;
	CCLContext* ctx = NULL;
	CCLDevice* d = NULL;
	CCLQueue* cq1 = NULL;
	CCLQueue* cq2 = NULL;
	CCLEvent* evt = NULL;
	CCLEventWaitList ewl = NULL;
	size_t buf_size = 8 * sizeof(cl_short);
	cl_short hbuf[8] = {1, 2, 3, 4, 5, 6, 7, 8};
	cl_ulong duration, eff_duration;
	double time_elapsed;

	/* Create a new profile object. */
	prof = ccl_prof_new();

	/* Get a context and a device. */
	ctx = ccl_test_context_new(&err);
	g_assert_no_error(err);

	d = ccl_context_get_device(ctx, 0, &err);
	g_assert_no_error(err);

	/* Create two command queue wrappers. */
	cq1 = ccl_queue_new(ctx, d, CL_QUEUE_PROFILING_ENABLE, &err);
	g_assert_no_error(err);

	cq2 = ccl_queue_new(ctx, d, CL_QUEUE_PROFILING_ENABLE, &err);
	g_assert_no_error(err);

	/* Create device buffers. */
	buf1 = ccl_buffer_new(ctx, CL_MEM_READ_ONLY, buf_size, NULL, &err);
	g_assert_no_error(err);
	buf2 = ccl_buffer_new(ctx, CL_MEM_READ_WRITE, buf_size, NULL, &err);
	g_assert_no_error(err);

	/* Start profile object timer. */
	ccl_prof_start(prof);

	/* Transfer data to buffer. */
	evt = ccl_buffer_enqueue_write(
		buf1, cq1, CL_FALSE, 0, buf_size, hbuf, NULL, &err);
	g_assert_no_error(err);

	/* Transfer data from one buffer to another. */
	evt = ccl_buffer_enqueue_copy(buf1, buf2, cq2, 0, 0, buf_size,
		ccl_ewl(&ewl, evt, NULL), &err);
	g_assert_no_error(err);

	/* Wait for copy. */
	ccl_event_wait(ccl_ewl(&ewl, evt, NULL), &err);
	g_assert_no_error(err);

	/* Stop profile object timer. */
	ccl_prof_stop(prof);

	/* Add both queues to profile object. */
	ccl_prof_add_queue(prof, "A Queue", cq1);
	ccl_prof_add_queue(prof, "Another Queue", cq2);

	/* Process queues. */
	ccl_prof_calc(prof, &err);
	g_assert_no_error(err);

	/* Request some profiling information. */
	time_elapsed = ccl_prof_time_elapsed(prof);
	duration = ccl_prof_get_duration(prof);
	eff_duration = ccl_prof_get_eff_duration(prof);

	g_debug("Profiling time elapsed: %lf", time_elapsed);
	g_debug("Profiling duration: %d", (cl_int) duration);
	g_debug("Profiling eff. duration: %d", (cl_int) eff_duration);

	/* Destroy buffers. */
	ccl_buffer_destroy(buf1);
	ccl_buffer_destroy(buf2);

	/* Unref cq1, which should not be destroyed because it is held
	 * by the profile object. */
	ccl_queue_destroy(cq1);

	/* Destroy the profile object, which will also destroy cq1. cq2
	 * will me merely unrefed and must still be explicitly destroyed. */
	ccl_prof_destroy(prof);

	/* Destroy cq2. */
	ccl_queue_destroy(cq2);

	/* Destroy the context. */
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly
	 * freed. */
	g_assert(ccl_wrapper_memcheck());

}
Esempio n. 15
0
/**
 * Canonical example main function.
 * */
int main(int argc, char** argv) {

	/* Number of elements in buffer. */
	size_t buf_n = DEF_BUF_N;

	/* Device selected specified in the command line. */
	int dev_idx = -1;

	/* Program return value. */
	int ret_val;

	/* Check if a device was specified in the command line. */
	if (argc >= 2) {
		dev_idx = atoi(argv[1]);
	}

	/* Check if a new buffer size was specified in the command line. */
	if (argc >= 3) {
		buf_n = atoi(argv[2]);
	}

	/* Wrappers. */
	CCLContext* ctx = NULL;
	CCLProgram* prg = NULL;
	CCLDevice* dev = NULL;
	CCLQueue* queue = NULL;
	CCLKernel* krnl = NULL;
	CCLBuffer* a_dev;
	CCLBuffer* b_dev;
	CCLBuffer* c_dev;
	CCLEvent* evt_write1;
	CCLEvent* evt_write2;
	CCLEvent* evt_exec;
	CCLEventWaitList ewl = NULL;

	/* Profiler. */
	CCLProf* prof;

	/* Global and local worksizes. */
	size_t gws = 0;
	size_t lws = 0;

	/* Host buffers. */
	cl_uint* a_host = NULL;
	cl_uint* b_host = NULL;
	cl_uint* c_host = NULL;
	cl_uint d_host;

	/* Error reporting object. */
	CCLErr* err = NULL;

	/* Check results flag. */
	cl_bool check_result;

	/* Create a context with device selected from menu. */
	ctx = ccl_context_new_from_menu_full(&dev_idx, &err);
	HANDLE_ERROR(err);

	/* Get the selected device. */
	dev = ccl_context_get_device(ctx, 0, &err);
	HANDLE_ERROR(err);

	/* Create a new program from kernel source. */
	prg = ccl_program_new_from_source(ctx, KERNEL_SRC, &err);
	HANDLE_ERROR(err);

	/* Build program. */
	ccl_program_build(prg, NULL, &err);
	HANDLE_ERROR(err);

	/* Create a command queue. */
	queue = ccl_queue_new(ctx, dev, CL_QUEUE_PROFILING_ENABLE, &err);
	HANDLE_ERROR(err);

	/* Get kernel object. */
	krnl = ccl_program_get_kernel(prg, KERNEL_NAME, &err);
	HANDLE_ERROR(err);

	/* Get worksizes. */
	lws = ccl_kernel_suggest_worksizes(krnl, dev, 1, &buf_n, &gws, &lws, &err);
	HANDLE_ERROR(err);

	/* Show worksizes. */
	printf("\n");
	printf(" * Global worksize: %d\n", (int) gws);
	printf(" * Local worksize : %d\n", (int) lws);

	/* Initialize host buffers. */
	a_host = (cl_uint*) malloc(sizeof(cl_uint) * buf_n);
	b_host = (cl_uint*) malloc(sizeof(cl_uint) * buf_n);
	c_host = (cl_uint*) malloc(sizeof(cl_uint) * buf_n);

	/* Fill host buffers. */
	for (cl_uint i = 0; i < buf_n; ++i) {
		a_host[i] = i;
		b_host[i] = buf_n - i;
	}
	d_host = buf_n / 4;

	/* Create device buffers. */
	a_dev = ccl_buffer_new(ctx, CL_MEM_READ_ONLY,
		buf_n * sizeof(cl_uint), NULL, &err);
	HANDLE_ERROR(err);
	b_dev = ccl_buffer_new(ctx, CL_MEM_READ_ONLY,
		buf_n * sizeof(cl_uint), NULL, &err);
	HANDLE_ERROR(err);
	c_dev = ccl_buffer_new(ctx, CL_MEM_WRITE_ONLY,
		buf_n * sizeof(cl_uint), NULL, &err);
	HANDLE_ERROR(err);

	/* Copy host data to device buffers without waiting for transfer
	 * to terminate before continuing host program. */
	evt_write1 = ccl_buffer_enqueue_write(a_dev, queue, CL_FALSE, 0,
		buf_n * sizeof(cl_uint), a_host, NULL, &err);
	HANDLE_ERROR(err);
	evt_write2 = ccl_buffer_enqueue_write(b_dev, queue, CL_FALSE, 0,
		buf_n * sizeof(cl_uint), b_host, NULL, &err);
	HANDLE_ERROR(err);

	/* Initialize event wait list and add the two transfer events. */
	ccl_event_wait_list_add(&ewl, evt_write1, evt_write2, NULL);

	/* Execute program kernel, waiting for the two transfer events
	 * to terminate (this will empty the event wait list). */
	evt_exec = ccl_program_enqueue_kernel(prg, KERNEL_NAME, queue, 1,
		NULL, &gws, &lws, &ewl, &err,
		/* Kernel arguments. */
		a_dev, b_dev, c_dev,
		ccl_arg_priv(d_host, cl_uint), ccl_arg_priv(buf_n, cl_uint),
		NULL);
	HANDLE_ERROR(err);

	/* Add the kernel termination event to the wait list. */
	ccl_event_wait_list_add(&ewl, evt_exec, NULL);

	/* Sync. queue for events in wait list (just the execute event in
	 * this case) to terminate before going forward... */
	ccl_enqueue_barrier(queue, &ewl, &err);
	HANDLE_ERROR(err);

	/* Read back results from host waiting for transfer to terminate
	 * before continuing host program. */
	ccl_buffer_enqueue_read(c_dev, queue, CL_TRUE, 0,
		buf_n * sizeof(cl_uint), c_host, NULL, &err);
	HANDLE_ERROR(err);

	/* Check results are as expected (not available with OpenCL stub). */
	check_result = CL_TRUE;
	for (cl_uint i = 0; i < buf_n; ++i) {
		if(c_host[i] != a_host[i] + b_host[i] + d_host) {
			check_result = CL_FALSE;
			break;
		}
	}

	if (check_result) {
		fprintf(stdout, " * Kernel execution produced the expected results.\n");
		ret_val = EXIT_SUCCESS;
	} else {
		fprintf(stderr,
			" * Kernel execution failed to produce the expected results.\n");
		ret_val = EXIT_FAILURE;
	}

	/* Perform profiling. */
	prof = ccl_prof_new();
	ccl_prof_add_queue(prof, "queue1", queue);
	ccl_prof_calc(prof, &err);
	HANDLE_ERROR(err);
	/* Show profiling info. */
	ccl_prof_print_summary(prof);
	/* Export profiling info. */
	ccl_prof_export_info_file(prof, "out.tsv", &err);
	HANDLE_ERROR(err);

	/* Destroy profiler object. */
	ccl_prof_destroy(prof);

	/* Destroy host buffers. */
	free(a_host);
	free(b_host);
	free(c_host);

	/* Destroy wrappers. */
	ccl_buffer_destroy(a_dev);
	ccl_buffer_destroy(b_dev);
	ccl_buffer_destroy(c_dev);
	ccl_queue_destroy(queue);
	ccl_program_destroy(prg);
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly freed. */
	assert(ccl_wrapper_memcheck());

	/* Bye. */
	return ret_val;
}