コード例 #1
0
ファイル: ca_mt.c プロジェクト: flysurfer28/cf4ocl
/* Kernel execution function thread. */
static gpointer exec_func(gpointer data) {

	/* Get data. */
	struct thread_data* td = (struct thread_data*) data;
	CCLImage* img1 = td->img1;
	CCLImage* img2 = td->img2;
	CCLImage* img_aux;

	/* Execution event. */
	CCLEvent* evt_exec;

	/* Error reporting. */
	GError* err = NULL;

	/* Keep thread alive until host thread says otherwise. */
	while(*((int*) g_async_queue_pop(exec_thread_queue)) == go_msg) {

		/* Execute kernel. */
		evt_exec = ccl_kernel_set_args_and_enqueue_ndrange(
			td->krnl, queue_exec, 2, NULL, td->gws, td->lws, NULL, &err,
			img1, img2, NULL);
		HANDLE_ERROR(err);

		/* Send event to host thread. */
		g_async_queue_push(host_thread_queue, evt_exec);

		/* Swap buffers. */
		img_aux = img1;
		img1 = img2;
		img2 = img_aux;

	}

	/* Quit thread/function. */
	return NULL;
}
コード例 #2
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());

}
コード例 #3
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());

}
コード例 #4
0
ファイル: image_filter.c プロジェクト: fakenmc/cf4ocl
/**
 * 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;
}