Beispiel #1
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());
}
Beispiel #2
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;

}
Beispiel #3
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());

}