Exemplo n.º 1
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());
}
Exemplo n.º 2
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());
}
Exemplo n.º 3
0
/**
 * @internal
 *
 * @brief Tests basic read/write operations from/to buffer objects.
 * */
static void read_write_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[CCL_TEST_BUFFER_SIZE];
    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);

    /* 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());
}
Exemplo n.º 4
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());
}
Exemplo n.º 5
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;
}