예제 #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());
}
예제 #2
0
/**
 * Tests creation (using "full" constructor), getting info from and
 * destruction of sampler wrapper objects.
 * */
static void create_full_info_destroy_test() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLSampler* s = NULL;
	const cl_sampler_properties sampler_properties[] = {
		CL_SAMPLER_NORMALIZED_COORDS, CL_FALSE,
		CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_CLAMP_TO_EDGE,
		CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST,
		0};

	GError* err = NULL;

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

	/* Create sampler using "full" constructor. */
	s = ccl_sampler_new_full(ctx, sampler_properties, &err);
	g_assert_no_error(err);

	/* Get some info and check if the return value is as expected. */
	cl_addressing_mode am;
	am = ccl_sampler_get_info_scalar(
		s, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode, &err);
	g_assert_no_error(err);
	g_assert_cmpuint(am, ==, CL_ADDRESS_CLAMP_TO_EDGE);

	cl_filter_mode fm;
	fm = ccl_sampler_get_info_scalar(
		s, CL_SAMPLER_FILTER_MODE, cl_filter_mode, &err);
	g_assert_no_error(err);
	g_assert_cmpuint(fm, ==, CL_FILTER_NEAREST);

	cl_bool nc;
	nc = ccl_sampler_get_info_scalar(
		s, CL_SAMPLER_NORMALIZED_COORDS, cl_bool, &err);
	g_assert_no_error(err);
	g_assert_cmpuint(nc, ==, CL_FALSE);

	cl_context context;
	context = ccl_sampler_get_info_scalar(
		s, CL_SAMPLER_CONTEXT, cl_context, &err);
	g_assert_no_error(err);
	g_assert_cmphex(GPOINTER_TO_UINT(context), ==,
		GPOINTER_TO_UINT(ccl_context_unwrap(ctx)));

	/* Destroy sampler. */
	ccl_sampler_destroy(s);
	ccl_context_destroy(ctx);

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

}
예제 #3
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());
}
예제 #4
0
/**
 * @internal
 *
 * @brief Tests buffer wrapping and unwrapping.
 * */
static void wrap_unwrap_test() {

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

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

    /* Create a buffer using OpenCL functions directly. */
    buffer = clCreateBuffer(
        ccl_context_unwrap(ctx), CL_MEM_READ_ONLY, buf_size, NULL, &status);
    g_assert_cmpint(status, ==, CL_SUCCESS);

    /* Wrap buffer. */
    b = ccl_buffer_new_wrap(buffer);

    /* If we now unwrap the wrapper, we must get the originally created
     * buffer. */
    g_assert(buffer == ccl_buffer_unwrap(b));

    /* If we again wrap the original buffer... */
    b_aux = ccl_buffer_new_wrap(buffer);

    /* ...we must get the same wrapper... */
    g_assert(b == b_aux);

    /* ... and the buffer wrapper ref count must be 2. */
    g_assert_cmpuint(2, ==, ccl_wrapper_ref_count((CCLWrapper *) b));

    /* Unref buffer, twice. */
    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_destroy(b);
    ccl_context_destroy(ctx);

    /* Confirm that memory allocated by wrappers has been properly
     * freed. */
    g_assert(ccl_wrapper_memcheck());
}
예제 #5
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());
}
예제 #6
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);
}
예제 #7
0
/**
 * Tests sampler wrapper class reference counting.
 * */
static void ref_unref_test() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLSampler* s = NULL;
	GError* err = NULL;

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

	/* Create sampler. */
	s = ccl_sampler_new(ctx, CL_TRUE, CL_ADDRESS_CLAMP,
		CL_FILTER_NEAREST, &err);
	g_assert_no_error(err);

	/* Increase sampler reference count. */
	ccl_sampler_ref(s);

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

	/* Unref sampler. */
	ccl_sampler_unref(s);

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

	/* Destroy stuff. */
	ccl_sampler_unref(s);
	ccl_context_destroy(ctx);

	/* Confirm that memory allocated by wrappers has been properly
	 * freed. */
	g_assert(ccl_wrapper_memcheck());
}
예제 #8
0
파일: test_rng.c 프로젝트: fakenmc/cl_ops
/**
 * 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());

}
예제 #9
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());
}
예제 #10
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());
}
예제 #11
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());
}
예제 #12
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());
}
예제 #13
0
/**
 * Kernel info main function.
 *
 * @param[in] argc Number of command line arguments.
 * @param[in] argv Command line arguments.
 * @return ::CCL_SUCCESS if program returns with no error, or another
 * ::CCLErrorCode value otherwise.
 * */
int main(int argc, char *argv[]) {

	/* ***************** */
	/* Program variables */
	/* ***************** */

	/* Function and program return status. */
	int status;
	/* Error management. */
	GError *err = NULL;
	/* Context wrapper. */
	CCLContext* ctx = NULL;
	/* Program wrapper. */
	CCLProgram* prg = NULL;
	/* Kernel wrapper. */
	CCLKernel* krnl = NULL;
	/* Device wrapper. */
	CCLDevice* dev = NULL;
	/* Device filters. */
	CCLDevSelFilters filters = NULL;
	/* Default device index. */
	cl_int dev_idx = -1;
	/* OpenCL version. */
	double ocl_ver;
	/* Kernel workgroup info variables. */
	size_t k_wg_size;
	size_t k_pref_wg_size_mult;
	size_t* k_compile_wg_size;
	cl_ulong k_loc_mem_size;
	cl_ulong k_priv_mem_size;

	/* ************************** */
	/* Parse command line options */
	/* ************************** */

	/* If version was requested, output version and exit. */
	if ((argc == 2) && (g_strcmp0("--version", argv[1]) == 0)) {
		ccl_common_version_print("ccl_kerninfo");
		exit(0);
	}

	ccl_if_err_create_goto(err, CCL_ERROR, (argc < 3) || (argc > 4),
		CCL_ERROR_ARGS, error_handler,
		"Usage: %s <program_file> <kernel_name> [device_index]\n",
		argv[0]);
	if (argc == 4) dev_idx = atoi(argv[3]);

	/* ********************************************* */
	/* Initialize OpenCL variables and build program */
	/* ********************************************* */

	/* Select a context/device. */
	ccl_devsel_add_dep_filter(
		&filters, ccl_devsel_dep_menu,
		(dev_idx == -1) ? NULL : (void*) &dev_idx);
	ctx = ccl_context_new_from_filters(&filters, &err);
	ccl_if_err_goto(err, error_handler);

	/* Get program which contains kernel. */
	prg = ccl_program_new_from_source_file(ctx, argv[1], &err);
	ccl_if_err_goto(err, error_handler);

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

	/* Get kernel */
	krnl = ccl_program_get_kernel(prg, argv[2], &err);
	ccl_if_err_goto(err, error_handler);

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

	/* Check platform  OpenCL version. */
	ocl_ver = ccl_kernel_get_opencl_version(krnl, &err);
	ccl_if_err_goto(err, error_handler);

	/* *************************** */
	/*  Get and print kernel info  */
	/* *************************** */

	g_printf("\n   ======================== Static Kernel Information =======================\n\n");

	k_wg_size = ccl_kernel_get_workgroup_info_scalar(
		krnl, dev, CL_KERNEL_WORK_GROUP_SIZE, size_t, &err);
	ccl_if_err_goto(err, error_handler);
	g_printf("     Maximum workgroup size                  : %lu\n",
		(unsigned long) k_wg_size);

	/* Only show info about CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
	 * if OpenCL version of the underlying platform is >= 1.1. */
	if (ocl_ver >= 110) {
		k_pref_wg_size_mult = ccl_kernel_get_workgroup_info_scalar(krnl,
			dev, CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_t, &err);
		ccl_if_err_goto(err, error_handler);
		g_printf("     Preferred multiple of workgroup size    : %lu\n",
			(unsigned long) k_pref_wg_size_mult);
	}

	k_compile_wg_size = ccl_kernel_get_workgroup_info_array(krnl, dev,
		CL_KERNEL_COMPILE_WORK_GROUP_SIZE, size_t*, &err);
	ccl_if_err_goto(err, error_handler);
	g_printf("     WG size in __attribute__ qualifier      : (%lu, %lu, %lu)\n",
		(unsigned long) k_compile_wg_size[0],
		(unsigned long) k_compile_wg_size[1],
		(unsigned long) k_compile_wg_size[2]);

	k_loc_mem_size = ccl_kernel_get_workgroup_info_scalar(krnl, dev,
		CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong, &err);
	ccl_if_err_goto(err, error_handler);
	g_printf("     Local memory used by kernel             : %lu bytes\n",
		(unsigned long) k_loc_mem_size);

	k_priv_mem_size = ccl_kernel_get_workgroup_info_scalar(krnl, dev,
		CL_KERNEL_PRIVATE_MEM_SIZE, cl_ulong, &err);
	ccl_if_err_goto(err, error_handler);
	g_printf("     Min. private mem. used by each workitem : %lu bytes\n",
		(unsigned long) k_priv_mem_size);

	g_printf("\n");

	/* ************** */
	/* Error handling */
	/* ************** */

	/* If we get here, no need for error checking, jump to cleanup. */
	g_assert(err == NULL);
	status = CCL_SUCCESS;
	goto cleanup;

error_handler:
	/* If we got here there was an error, verify that it is so. */
	g_assert(err != NULL);
	g_fprintf(stderr, "%s\n", err->message);
	status = (err->domain == CCL_ERROR) ? err->code : CCL_ERROR_OTHER;
	g_error_free(err);

cleanup:

	/* *********** */
	/* Free stuff! */
	/* *********** */

	if (prg != NULL) ccl_program_destroy(prg);
	if (ctx != NULL) ccl_context_destroy(ctx);

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

	/* Return status. */
	return status;

}
예제 #14
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());
}
예제 #15
0
파일: test_rng.c 프로젝트: fakenmc/cl_ops
/**
 * 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());

}
예제 #16
0
/**
 * Image filter main function.
 * */
int main(int argc, char * argv[]) {

    /* Wrappers for OpenCL objects. */
    CCLContext * ctx;
    CCLDevice * dev;
    CCLImage * img_in;
    CCLImage * img_out;
    CCLQueue * queue;
    CCLProgram * prg;
    CCLKernel * krnl;
    CCLSampler * smplr;

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

    /* Error handling object (must be initialized to NULL). */
    CCLErr * err = NULL;

    /* Does selected device support images? */
    cl_bool image_ok;

    /* Image data in host. */
    unsigned char * input_image;
    unsigned char * output_image;

    /* Image properties. */
    int width, height, n_channels;

    /* Image file write status. */
    int file_write_status;

    /* Image parameters. */
    cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT8 };

    /* Origin and region of complete image. */
    size_t origin[3] = { 0, 0, 0 };
    size_t region[3];

    /* Real worksize. */
    size_t real_ws[2];

    /* Global and local worksizes. */
    size_t gws[2];
    size_t lws[2];

    /* Check arguments. */
    if (argc < 2) {
        ERROR_MSG_AND_EXIT("Usage: image_filter <image_file> [device_index]");
    } else if (argc >= 3) {
        /* Check if a device was specified in the command line. */
        dev_idx = atoi(argv[2]);
    }

    /* Load image. */
    input_image = stbi_load(argv[1], &width, &height, &n_channels, 4);
    if (!input_image) ERROR_MSG_AND_EXIT(stbi_failure_reason());

    /* Real work size. */
    real_ws[0] = width; real_ws[1] = height;

    /* Set image region. */
    region[0] = width; region[1] = height; region[2] = 1;

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

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

    /* Ask device if it supports images. */
    image_ok = ccl_device_get_info_scalar(
        dev, CL_DEVICE_IMAGE_SUPPORT, cl_bool, &err);
    HANDLE_ERROR(err);
    if (!image_ok)
        ERROR_MSG_AND_EXIT("Selected device doesn't support images.");

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

    /* Create 2D input image using loaded image data. */
    img_in = ccl_image_new(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
        &image_format, input_image, &err,
        "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D,
        "image_width", (size_t) width,
        "image_height", (size_t) height,
        NULL);
    HANDLE_ERROR(err);

    /* Create 2D output image. */
    img_out = ccl_image_new(ctx, CL_MEM_WRITE_ONLY,
        &image_format, NULL, &err,
        "image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D,
        "image_width", (size_t) width,
        "image_height", (size_t) height,
        NULL);
    HANDLE_ERROR(err);

    /* Create program from kernel source and compile it. */
    prg = ccl_program_new_from_source(ctx, FILTER_KERNEL, &err);
    HANDLE_ERROR(err);

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

    /* Get kernel wrapper. */
    krnl = ccl_program_get_kernel(prg, "do_filter", &err);
    HANDLE_ERROR(err);

    /* Determine nice local and global worksizes. */
    ccl_kernel_suggest_worksizes(krnl, dev, 2, real_ws, gws, lws, &err);
    HANDLE_ERROR(err);

    /* Show information to user. */
    printf("\n * Image size: %d x %d, %d channels\n",
        width, height, n_channels);
    printf(" * Global work-size: (%d, %d)\n", (int) gws[0], (int) gws[1]);
    printf(" * Local work-size: (%d, %d)\n", (int) lws[0], (int) lws[1]);

    /* Create sampler (this could also be created in-kernel). */
    smplr = ccl_sampler_new(ctx, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE,
        CL_FILTER_NEAREST, &err);
    HANDLE_ERROR(err);

    /* Apply filter. */
    ccl_kernel_set_args_and_enqueue_ndrange(
        krnl, queue, 2, NULL, gws, lws, NULL, &err,
        img_in, img_out, smplr, NULL);
    HANDLE_ERROR(err);

    /* Allocate space for output image. */
    output_image = (unsigned char *)
        malloc(width * height * 4 * sizeof(unsigned char));

    /* Read image data back to host. */
    ccl_image_enqueue_read(img_out, queue, CL_TRUE, origin, region,
        0, 0, output_image, NULL, &err);
    HANDLE_ERROR(err);

    /* Write image to file. */
    file_write_status = stbi_write_png(IMAGE_FILE, width, height, 4,
        output_image, width * 4);

    /* Give feedback. */
    if (file_write_status) {
        fprintf(stdout, "\nImage saved in file '" IMAGE_FILE "'\n");
    } else {
        ERROR_MSG_AND_EXIT("Unable to save image in file.");
    }

    /* Release host images. */
    free(output_image);
    stbi_image_free(input_image);

    /* Release wrappers. */
    ccl_image_destroy(img_in);
    ccl_image_destroy(img_out);
    ccl_sampler_destroy(smplr);
    ccl_program_destroy(prg);
    ccl_queue_destroy(queue);
    ccl_context_destroy(ctx);

    /* Check all wrappers have been destroyed. */
    assert(ccl_wrapper_memcheck());

    /* Terminate. */
    return EXIT_SUCCESS;
}
예제 #17
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());

}
예제 #18
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());

}
예제 #19
0
/**
 * Tests devquery module helper functions.
 * */
static void helpers_test() {

	CCLPlatforms* platfs = NULL;
	CCLPlatform* p = NULL;
	CCLDevice* d = NULL;
	GError* err = NULL;
	guint num_devs;
	guint num_platfs;
	CCLWrapperInfo* info;
	gchar param_value_str[CCL_TEST_DEVQUERY_MAXINFOLEN];

	/* Get platforms. */
	platfs = ccl_platforms_new(&err);
	if (err == NULL) {

		/* Number of platforms. */
		num_platfs = ccl_platforms_count(platfs);
		g_debug("* Found %d OpenCL platforms", num_platfs);

		/* Cycle through platforms. */
		for (guint i = 0; i < num_platfs; i++) {

			/* Get current platform. */
			p = ccl_platforms_get(platfs, i);
			g_debug(">> Platform %d:", i);

			/* Get number of devices. */
			num_devs = ccl_platform_get_num_devices(p, &err);

			/* Only test for device information if device count was
			 * successfully obtained. */
			if (err != NULL) {
				g_test_message("Error obtaining number of devices for platform %d (%s).",
					i, err->message);
				g_clear_error(&err);
			} else {

				g_debug("==== # Devs  : %d", num_devs);

				/* Cycle through devices in platform. */
				for (guint j = 0; j < num_devs; j++) {

					/* Get current device. */
					d = ccl_platform_get_device(p, j, &err);
					g_assert_no_error(err);
					g_debug("====== Device #%d", j);

					for (gint k = 0; k < ccl_devquery_info_map_size; k++) {
						info = ccl_device_get_info(d, ccl_devquery_info_map[k].device_info, &err);
						if (err == NULL) {
							g_debug("\t%s : %s",
								ccl_devquery_info_map[k].param_name,
								ccl_devquery_info_map[k].format(
									info, param_value_str,
									CCL_TEST_DEVQUERY_MAXINFOLEN,
									ccl_devquery_info_map[k].units));
						} else {
							g_clear_error(&err);
							g_debug("\t%s : %s",
								ccl_devquery_info_map[k].param_name, "N/A");

						}
					}

				}
			}
		}

		/* Destroy list of platforms. */
		ccl_platforms_destroy(platfs);

	} else {

		/* Unable to get any OpenCL platforms, test can't pass. */
		g_test_message("Test failed due to following error: %s",
			err->message);
		g_test_fail();
	}

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

}
예제 #20
0
파일: ca_mt.c 프로젝트: flysurfer28/cf4ocl
/**
 * Cellular automata sample main function.
 * */
int main(int argc, char* argv[]) {

	/* Wrappers for OpenCL objects. */
	CCLContext* ctx;
	CCLDevice* dev;
	CCLImage* img1;
	CCLImage* img2;
	CCLProgram* prg;
	CCLKernel* krnl;
	CCLEvent* evt1;
	CCLEvent* evt2;
	/* Other variables. */
	CCLEventWaitList ewl = NULL;
	/* Profiler object. */
	CCLProf* prof;
	/* Output images filename. */
	char* filename;
	/* Selected device, may be given in command line. */
	int dev_idx = -1;
	/* Error handling object (must be NULL). */
	GError* err = NULL;
	/* Does selected device support images? */
	cl_bool image_ok;
	/* Initial sim state. */
	cl_uchar4* input_image;
	/* Simulation states. */
	cl_uchar4** output_images;
	/* RNG seed, may be given in command line. */
	unsigned int seed;
	/* Image file write status. */
	int file_write_status;
	/* Image format. */
	cl_image_format image_format = { CL_RGBA, CL_UNSIGNED_INT8 };
	/* Thread data. */
	struct thread_data td;

	/* Global and local worksizes. */
	size_t gws[2];
	size_t lws[2];
	/* Threads. */
	GThread* comm_thread;
	GThread* exec_thread;

	/* Check arguments. */
	if (argc >= 2) {
		/* Check if a device was specified in the command line. */
		dev_idx = atoi(argv[1]);
	}
	if (argc >= 3) {
		/* Check if a RNG seed was specified. */
		seed = atoi(argv[2]);
	} else {
		seed = (unsigned int) time(NULL);
	}

	/* Initialize RNG. */
	srand(seed);

	/* Create random initial state. */
	input_image = (cl_uchar4*)
		malloc(CA_WIDTH * CA_HEIGHT * sizeof(cl_uchar4));
	for (cl_uint i = 0; i < CA_WIDTH * CA_HEIGHT; ++i) {
		cl_uchar state = (rand() & 0x3) ? 0xFF : 0x00;
		input_image[i] = (cl_uchar4) {{ state, state, state, 0xFF }};
	}

	/* Allocate space for simulation results. */
	output_images = (cl_uchar4**)
		malloc((CA_ITERS + 1) * sizeof(cl_uchar4*));
	for (cl_uint i = 0; i < CA_ITERS + 1; ++i)
		output_images[i] = (cl_uchar4*)
			malloc(CA_WIDTH * CA_HEIGHT * sizeof(cl_uchar4));

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

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

	/* Ask device if it supports images. */
	image_ok = ccl_device_get_info_scalar(
		dev, CL_DEVICE_IMAGE_SUPPORT, cl_bool, &err);
	HANDLE_ERROR(err);
	if (!image_ok)
		ERROR_MSG_AND_EXIT("Selected device doesn't support images.");

	/* Create command queues. */
	queue_exec = ccl_queue_new(ctx, dev, CL_QUEUE_PROFILING_ENABLE, &err);
	HANDLE_ERROR(err);
	queue_comm = ccl_queue_new(ctx, dev, CL_QUEUE_PROFILING_ENABLE, &err);
	HANDLE_ERROR(err);

	/* Create 2D image for initial state. */
	img1 = ccl_image_new(ctx, CL_MEM_READ_WRITE,
		&image_format, NULL, &err,
		"image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D,
		"image_width", (size_t) CA_WIDTH,
		"image_height", (size_t) CA_HEIGHT,
		NULL);
	HANDLE_ERROR(err);

	/* Create another 2D image for double buffering. */
	img2 = ccl_image_new(ctx, CL_MEM_READ_WRITE,
		&image_format, NULL, &err,
		"image_type", (cl_mem_object_type) CL_MEM_OBJECT_IMAGE2D,
		"image_width", (size_t) CA_WIDTH,
		"image_height", (size_t) CA_HEIGHT,
		NULL);
	HANDLE_ERROR(err);

	/* Create program from kernel source and compile it. */
	prg = ccl_program_new_from_source(ctx, CA_KERNEL, &err);
	HANDLE_ERROR(err);

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

	/* Get kernel wrapper. */
	krnl = ccl_program_get_kernel(prg, "ca", &err);
	HANDLE_ERROR(err);

	/* Determine nice local and global worksizes. */
	ccl_kernel_suggest_worksizes(krnl, dev, 2, real_ws, gws, lws, &err);
	HANDLE_ERROR(err);

	printf("\n * Global work-size: (%d, %d)\n", (int) gws[0], (int) gws[1]);
	printf(" * Local work-size: (%d, %d)\n", (int) lws[0], (int) lws[1]);

	/* Create thread communication queues. */
	comm_thread_queue = g_async_queue_new();
	exec_thread_queue = g_async_queue_new();
	host_thread_queue = g_async_queue_new();

	/* Setup thread data. */
	td.krnl = krnl;
	td.img1 = img1;
	td.img2 = img2;
	td.gws = gws;
	td.lws = lws;
	td.output_images = output_images;

	/* Create threads. */
	exec_thread = g_thread_new("exec_thread", exec_func, &td);
	comm_thread = g_thread_new("comm_thread", comm_func, &td);

	/* Start profiling. */
	prof = ccl_prof_new();
	ccl_prof_start(prof);

	/* Write initial state. */
	ccl_image_enqueue_write(img1, queue_comm, CL_TRUE,
		origin, region, 0, 0, input_image, NULL, &err);
	HANDLE_ERROR(err);

	/* Run CA_ITERS iterations of the CA. */
	for (cl_uint i = 0; i < CA_ITERS; ++i) {

		/* Send message to comms thread. */
		g_async_queue_push(comm_thread_queue, &go_msg);

		/* Send message to exec thread. */
		g_async_queue_push(exec_thread_queue, &go_msg);

		/* Get event wrappers from both threads. */
		evt1 = (CCLEvent*) g_async_queue_pop(host_thread_queue);
		evt2 = (CCLEvent*) g_async_queue_pop(host_thread_queue);

		/* Can't continue until this iteration is over. */
		ccl_event_wait_list_add(&ewl, evt1, evt2, NULL);

		/* Wait for events. */
		ccl_event_wait(&ewl, &err);
		HANDLE_ERROR(err);

	}

	/* Send message to comms thread to read last result. */
	g_async_queue_push(comm_thread_queue, &go_msg);

	/* Send stop messages to both threads. */
	g_async_queue_push(comm_thread_queue, &stop_msg);
	g_async_queue_push(exec_thread_queue, &stop_msg);

	/* Get event wrapper from comms thread. */
	evt1 = (CCLEvent*) g_async_queue_pop(host_thread_queue);

	/* Can't continue until final read is over. */
	ccl_event_wait_list_add(&ewl, evt1, NULL);
	ccl_event_wait(&ewl, &err);
	HANDLE_ERROR(err);

	/* Make sure both queues are finished. */
	ccl_queue_finish(queue_comm, &err);
	HANDLE_ERROR(err);
	ccl_queue_finish(queue_exec, &err);
	HANDLE_ERROR(err);

	/* Stop profiling timer and add queues for analysis. */
	ccl_prof_stop(prof);
	ccl_prof_add_queue(prof, "Comms", queue_comm);
	ccl_prof_add_queue(prof, "Exec", queue_exec);

	/* Allocate space for base filename. */
	filename = (char*) malloc(
		(strlen(IMAGE_FILE_PREFIX ".png") + IMAGE_FILE_NUM_DIGITS + 1) * sizeof(char));

	/* Write results to image files. */
	for (cl_uint i = 0; i < CA_ITERS; ++i) {

		/* Determine next filename. */
		sprintf(filename, "%s%0" G_STRINGIFY(IMAGE_FILE_NUM_DIGITS) "d.png", IMAGE_FILE_PREFIX, i);

		/* Save next image. */
		file_write_status = stbi_write_png(filename, CA_WIDTH, CA_HEIGHT, 4,
			output_images[i], CA_WIDTH * sizeof(cl_uchar4));

		/* Give feedback if unable to save image. */
		if (!file_write_status) {
			ERROR_MSG_AND_EXIT("Unable to save image in file.");
		}
	}

	/* Process profiling info. */
	ccl_prof_calc(prof, &err);
	HANDLE_ERROR(err);

	/* Print profiling info. */
	ccl_prof_print_summary(prof);

	/* Save profiling info. */
	ccl_prof_export_info_file(prof, "prof.tsv", &err);
	HANDLE_ERROR(err);

	/* Destroy threads. */
	g_thread_join(exec_thread);
	g_thread_join(comm_thread);

	/* Destroy thread communication queues. */
	g_async_queue_unref(comm_thread_queue);
	g_async_queue_unref(exec_thread_queue);
	g_async_queue_unref(host_thread_queue);

	/* Release host buffers. */
	free(filename);
	free(input_image);
	for (cl_uint i = 0; i < CA_ITERS + 1; ++i)
		free(output_images[i]);
	free(output_images);

	/* Release wrappers. */
	ccl_image_destroy(img1);
	ccl_image_destroy(img2);
	ccl_program_destroy(prg);
	ccl_queue_destroy(queue_comm);
	ccl_queue_destroy(queue_exec);
	ccl_context_destroy(ctx);

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

	/* Check all wrappers have been destroyed. */
	g_assert(ccl_wrapper_memcheck());

	/* Terminate. */
	return 0;

}
예제 #21
0
/**
 * Tests creation (using "simple" constructor), getting info from and
 * destruction of sampler wrapper objects.
 * */
static void create_info_destroy_test() {

	/* Test variables. */
	CCLContext* ctx = NULL;
	CCLSampler* s = NULL;
	cl_sampler sampler = NULL;
	GError* err = NULL;
	cl_int ocl_status;
	const cl_sampler_properties sampler_properties[] = {
		CL_SAMPLER_NORMALIZED_COORDS, CL_TRUE,
		CL_SAMPLER_ADDRESSING_MODE, CL_ADDRESS_NONE,
		CL_SAMPLER_FILTER_MODE, CL_FILTER_NEAREST,
		0};

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

	/* Test three ways to create a sampler. */
	for (cl_uint i = 0; i < 3; ++i) {

		/* Create sampler wrapper. */
		switch (i) {
			case 0:
				/* Create sampler using "simple" constructor. */
				s = ccl_sampler_new(ctx, CL_TRUE, CL_ADDRESS_NONE,
					CL_FILTER_NEAREST, &err);
				g_assert_no_error(err);
				break;
			case 1:
				/* Using the "full" constructor. */
				s = ccl_sampler_new_full(ctx, sampler_properties, &err);
				g_assert_no_error(err);
				break;
			case 2:
				/* Using the "wrap" constructor. */
				CCL_BEGIN_IGNORE_DEPRECATIONS
				sampler = clCreateSampler(ccl_context_unwrap(ctx),
					CL_TRUE, CL_ADDRESS_NONE, CL_FILTER_NEAREST,
					&ocl_status);
				g_assert_cmpint(ocl_status, ==, CL_SUCCESS);
				CCL_END_IGNORE_DEPRECATIONS
				s = ccl_sampler_new_wrap(sampler);
				g_assert_cmphex(GPOINTER_TO_UINT(sampler), ==,
					GPOINTER_TO_UINT(ccl_sampler_unwrap(s)));
				break;
		}

		/* Get some info and check if the return value is as expected. */
		cl_addressing_mode am;
		am = ccl_sampler_get_info_scalar(
			s, CL_SAMPLER_ADDRESSING_MODE, cl_addressing_mode, &err);
		g_assert_no_error(err);
		g_assert_cmpuint(am, ==, CL_ADDRESS_NONE);

		cl_filter_mode fm;
		fm = ccl_sampler_get_info_scalar(
			s, CL_SAMPLER_FILTER_MODE, cl_filter_mode, &err);
		g_assert_no_error(err);
		g_assert_cmpuint(fm, ==, CL_FILTER_NEAREST);

		cl_bool nc;
		nc = ccl_sampler_get_info_scalar(
			s, CL_SAMPLER_NORMALIZED_COORDS, cl_bool, &err);
		g_assert_no_error(err);
		g_assert_cmpuint(nc, ==, CL_TRUE);

		cl_context context;
		context = ccl_sampler_get_info_scalar(
			s, CL_SAMPLER_CONTEXT, cl_context, &err);
		g_assert_no_error(err);
		g_assert_cmphex(GPOINTER_TO_UINT(context), ==,
			GPOINTER_TO_UINT(ccl_context_unwrap(ctx)));

		/* Destroy sampler. */
		ccl_sampler_destroy(s);
	}

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

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

}
예제 #22
0
파일: ccl_devinfo.c 프로젝트: LaSEEB/cf4ocl
/**
 * Device info main program function.
 *
 * @param[in] argc Number of command line arguments.
 * @param[in] argv Vector of command line arguments.
 * @return ::CCL_SUCCESS if program returns with no error, or another
 * ::CCLErrorCode value otherwise.
 */
int main(int argc, char* argv[]) {

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

	/* List of platform wrapper objects. */
	CCLPlatforms* platforms = NULL;

	/* List of device wrapper objects. */
	CCLDevSelDevices devices = NULL;

	/* Current platform and device. */
	CCLPlatform* p;
	CCLDevice* d;

	/* Number of devices in platform. */
	guint num_devs;

	/* Device information value object. */
	CCLWrapperInfo* info_value = NULL;

	/* Device name. */
	gchar* dev_name;

	/* Program return status. */
	gint status;

	/* Parse command line options. */
	ccl_devinfo_args_parse(argc, argv, &err);
	ccl_if_err_goto(err, error_handler);

	/* If version was requested, output version and exit. */
	if (version) {
		ccl_common_version_print("ccl_devinfo");
		exit(0);
	}

	/* Check if user requested a list of known information parameters. */
	if (opt_list) {

		/*Yes, user requested list, present it. */

		g_fprintf(CCL_DEVINFO_OUT, "\nKnown information parameters:\n\n");
		for (gint i = 0; i < ccl_devquery_info_map_size; i++) {
			if (opt_verb) {
				g_fprintf(CCL_DEVINFO_OUT,
					"\t%s\n\t\t%s.\n\n",
					ccl_devquery_info_map[i].param_name,
					ccl_devquery_info_map[i].description);
			} else {
				g_fprintf(CCL_DEVINFO_OUT,
					"\t%s\n",
					ccl_devquery_info_map[i].param_name);
			}
		}
		g_fprintf(CCL_DEVINFO_OUT, "\n");

	} else {

		/* User didn't request list, proceed as normal query. */

		/* Ignore platforms and focus only on number of devices in system? */
		if (no_platf) {

			/* Ignore platform, continue device-wise. */

			/* Get all devices in the system. */
			devices = ccl_devsel_devices_new(&err);
			ccl_if_err_goto(err, error_handler);

			/* Cycle through devices. */
			for (guint j = 0; j < devices->len; j++) {

				/* Get out if this device is not to be queried. */
				if ((opt_dev != G_MAXUINT) && (j != opt_dev))
					continue;

				/* Get current device. */
				d = (CCLDevice*) devices->pdata[j];

				/* Get device name. */
				info_value = ccl_device_get_info(d, CL_DEVICE_NAME, &err);
				ccl_if_err_goto(err, error_handler);

				dev_name = (gchar*) info_value->value;

				/* Show device information. */
				g_fprintf(CCL_DEVINFO_OUT,
					"\n    [ Device #%d: %s ]\n\n",
					j, dev_name);
				ccl_devinfo_show_device_info(d);

			}
			g_fprintf(CCL_DEVINFO_OUT, "\n");

		} else {

			/* Do not ignore platforms, continue platform-wise. */

			/* Get list of platform wrapper objects. */
			platforms = ccl_platforms_new(&err);
			ccl_if_err_goto(err, error_handler);

			/* Cycle through platforms. */
			for (guint i = 0; i < ccl_platforms_count(platforms); i++) {

				/* Get out if this platform is not to be queried. */
				if ((opt_platf != G_MAXUINT) && (i != opt_platf))
					continue;

				/* Get current platform. */
				p = ccl_platforms_get(platforms, i);

				/* Show platform information. */
				ccl_devinfo_show_platform_info(p, i);

				/* Get number of devices. */
				num_devs = ccl_platform_get_num_devices(p, &err);

				/* Is this a platform without devices? */
				if ((err) && (err->domain == CCL_OCL_ERROR) &&
						(err->code == CL_DEVICE_NOT_FOUND)) {

					/* Clear "device not found" error. */
					g_clear_error(&err);

					/* Inform about non-existing devices. */
					g_fprintf(CCL_DEVINFO_OUT,
						"\n    [ No devices found ]\n\n");

					/* Skip this platform. */
					continue;
				}
				ccl_if_err_goto(err, error_handler);

				/* Cycle through devices. */
				for (guint j = 0; j < num_devs; j++) {

					/* Get out if this device is not to be queried. */
					if ((opt_dev != G_MAXUINT) && (j != opt_dev))
						continue;

					/* Get current device. */
					d = ccl_platform_get_device(p, j, &err);
					ccl_if_err_goto(err, error_handler);

					/* Get device name. */
					info_value = ccl_device_get_info(d, CL_DEVICE_NAME, &err);
					ccl_if_err_goto(err, error_handler);

					dev_name = (gchar*) info_value->value;

					/* Show device information. */
					g_fprintf(CCL_DEVINFO_OUT,
						"\n    [ Device #%d: %s ]\n\n",
						j, dev_name);
					ccl_devinfo_show_device_info(d);

				}
				g_fprintf(CCL_DEVINFO_OUT, "\n");
			}
		}
	}

	/* If we got here, everything is OK. */
	g_assert(err == NULL);
	status = CCL_SUCCESS;
	goto cleanup;

error_handler:

	/* If we got here there was an error, verify that it is so. */
	g_assert(err != NULL);
	g_fprintf(stderr, "%s\n", err->message);
	status = (err->domain == CCL_ERROR) ? err->code : CCL_ERROR_OTHER;
	g_error_free(err);

cleanup:

	/* Free stuff! */
	if (platforms) ccl_platforms_destroy(platforms);
	if (devices) ccl_devsel_devices_destroy(devices);
	g_strfreev(opt_custom);

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

	/* Return status. */
	return status;

}
예제 #23
0
파일: canon.c 프로젝트: LaSEEB/cf4ocl
/**
 * 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;
}