gpu-hello.cpp revision 11321
111308Santhony.gutierrez@amd.com/*
211308Santhony.gutierrez@amd.com * Copyright (c) 2015 Advanced Micro Devices, Inc.
311308Santhony.gutierrez@amd.com * All rights reserved.
411308Santhony.gutierrez@amd.com *
511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only
611308Santhony.gutierrez@amd.com *
711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without
811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met:
911308Santhony.gutierrez@amd.com *
1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice,
1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer.
1211308Santhony.gutierrez@amd.com *
1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice,
1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation
1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution.
1611308Santhony.gutierrez@amd.com *
1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors
1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software
1911308Santhony.gutierrez@amd.com * without specific prior written permission.
2011308Santhony.gutierrez@amd.com *
2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE.
3211308Santhony.gutierrez@amd.com *
3311308Santhony.gutierrez@amd.com * Author: Marc Orr, Brad Beckmann
3411308Santhony.gutierrez@amd.com */
3511308Santhony.gutierrez@amd.com
3611308Santhony.gutierrez@amd.com#include <CL/cl.h>
3711308Santhony.gutierrez@amd.com#include <malloc.h>
3811308Santhony.gutierrez@amd.com
3911308Santhony.gutierrez@amd.com#include <cstdio>
4011308Santhony.gutierrez@amd.com#include <cstring>
4111308Santhony.gutierrez@amd.com#include <fstream>
4211308Santhony.gutierrez@amd.com#include <string>
4311308Santhony.gutierrez@amd.com
4411308Santhony.gutierrez@amd.com#define SUCCESS 0
4511308Santhony.gutierrez@amd.com#define FAILURE 1
4611308Santhony.gutierrez@amd.com
4711308Santhony.gutierrez@amd.com// OpenCL datastructures
4811308Santhony.gutierrez@amd.comcl_context       context;
4911308Santhony.gutierrez@amd.comcl_device_id     *devices;
5011308Santhony.gutierrez@amd.comcl_command_queue commandQueue;
5111308Santhony.gutierrez@amd.comcl_program       program;
5211308Santhony.gutierrez@amd.comcl_kernel        readKernel;
5311308Santhony.gutierrez@amd.com
5411308Santhony.gutierrez@amd.com// Application datastructures
5511308Santhony.gutierrez@amd.comconst int CACHE_LINE_SIZE = 64;
5611308Santhony.gutierrez@amd.comsize_t grid_size = 512;
5711308Santhony.gutierrez@amd.comsize_t work_group_size = 256;
5811308Santhony.gutierrez@amd.com
5911308Santhony.gutierrez@amd.com// arguments
6011308Santhony.gutierrez@amd.comconst int code_size = 5;
6111308Santhony.gutierrez@amd.comconst char *code = "hello";
6211308Santhony.gutierrez@amd.comint *keys;
6311308Santhony.gutierrez@amd.comchar *msg;
6411308Santhony.gutierrez@amd.comint chars_decoded = 0;
6511308Santhony.gutierrez@amd.com
6611308Santhony.gutierrez@amd.com/*
6711308Santhony.gutierrez@amd.com    Setup data structures for application/algorithm
6811308Santhony.gutierrez@amd.com*/
6911308Santhony.gutierrez@amd.comint
7011308Santhony.gutierrez@amd.comsetupDataStructs()
7111308Santhony.gutierrez@amd.com{
7211308Santhony.gutierrez@amd.com    msg = (char *)memalign(CACHE_LINE_SIZE, (grid_size + 1) * sizeof(char));
7311321Ssteve.reinhardt@amd.com    if (msg == NULL) {
7411308Santhony.gutierrez@amd.com        printf("%s:%d: error: %s\n", __FILE__, __LINE__,
7511308Santhony.gutierrez@amd.com               "could not allocate host buffers\n");
7611308Santhony.gutierrez@amd.com       exit(-1);
7711308Santhony.gutierrez@amd.com    }
7811308Santhony.gutierrez@amd.com    msg[grid_size] = '\0';
7911308Santhony.gutierrez@amd.com
8011308Santhony.gutierrez@amd.com    keys = (int *)memalign(CACHE_LINE_SIZE, code_size * sizeof(int));
8111308Santhony.gutierrez@amd.com    keys[0] = 23;
8211308Santhony.gutierrez@amd.com    keys[1] = 0;
8311308Santhony.gutierrez@amd.com    keys[2] = 0;
8411308Santhony.gutierrez@amd.com    keys[3] = 0;
8511308Santhony.gutierrez@amd.com    keys[4] = 0;
8611308Santhony.gutierrez@amd.com
8711308Santhony.gutierrez@amd.com    return SUCCESS;
8811308Santhony.gutierrez@amd.com}
8911308Santhony.gutierrez@amd.com
9011308Santhony.gutierrez@amd.com/* Setup OpenCL data structures */
9111308Santhony.gutierrez@amd.comint
9211308Santhony.gutierrez@amd.comsetupOpenCL()
9311308Santhony.gutierrez@amd.com{
9411308Santhony.gutierrez@amd.com    cl_int status = 0;
9511308Santhony.gutierrez@amd.com    size_t deviceListSize;
9611308Santhony.gutierrez@amd.com
9711308Santhony.gutierrez@amd.com    // 1. Get platform
9811308Santhony.gutierrez@amd.com    cl_uint numPlatforms;
9911308Santhony.gutierrez@amd.com    cl_platform_id platform = NULL;
10011308Santhony.gutierrez@amd.com    status = clGetPlatformIDs(0, NULL, &numPlatforms);
10111308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
10211308Santhony.gutierrez@amd.com        printf("Error: Getting Platforms. (clGetPlatformsIDs)\n");
10311308Santhony.gutierrez@amd.com        return FAILURE;
10411308Santhony.gutierrez@amd.com    }
10511308Santhony.gutierrez@amd.com
10611308Santhony.gutierrez@amd.com    if (numPlatforms > 0) {
10711308Santhony.gutierrez@amd.com        cl_platform_id *platforms = new cl_platform_id[numPlatforms];
10811308Santhony.gutierrez@amd.com        status = clGetPlatformIDs(numPlatforms, platforms, NULL);
10911308Santhony.gutierrez@amd.com        if (status != CL_SUCCESS) {
11011308Santhony.gutierrez@amd.com            printf("Error: Getting Platform Ids. (clGetPlatformsIDs)\n");
11111308Santhony.gutierrez@amd.com            return FAILURE;
11211308Santhony.gutierrez@amd.com        }
11311308Santhony.gutierrez@amd.com        for (int i = 0; i < numPlatforms; ++i) {
11411308Santhony.gutierrez@amd.com            char pbuff[100];
11511308Santhony.gutierrez@amd.com            status = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR,
11611308Santhony.gutierrez@amd.com                                       sizeof(pbuff), pbuff, NULL);
11711308Santhony.gutierrez@amd.com            if (status != CL_SUCCESS) {
11811308Santhony.gutierrez@amd.com                printf("Error: Getting Platform Info.(clGetPlatformInfo)\n");
11911308Santhony.gutierrez@amd.com                return FAILURE;
12011308Santhony.gutierrez@amd.com            }
12111308Santhony.gutierrez@amd.com            platform = platforms[i];
12211308Santhony.gutierrez@amd.com            if (!strcmp(pbuff, "Advanced Micro Devices, Inc.")) {
12311308Santhony.gutierrez@amd.com                break;
12411308Santhony.gutierrez@amd.com            }
12511308Santhony.gutierrez@amd.com        }
12611308Santhony.gutierrez@amd.com        delete platforms;
12711308Santhony.gutierrez@amd.com    }
12811308Santhony.gutierrez@amd.com
12911321Ssteve.reinhardt@amd.com    if (NULL == platform) {
13011308Santhony.gutierrez@amd.com        printf("NULL platform found so Exiting Application.\n");
13111308Santhony.gutierrez@amd.com        return FAILURE;
13211308Santhony.gutierrez@amd.com    }
13311308Santhony.gutierrez@amd.com
13411308Santhony.gutierrez@amd.com    // 2. create context from platform
13511308Santhony.gutierrez@amd.com    cl_context_properties cps[3] =
13611308Santhony.gutierrez@amd.com        {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0};
13711308Santhony.gutierrez@amd.com    context = clCreateContextFromType(cps, CL_DEVICE_TYPE_GPU, NULL, NULL,
13811308Santhony.gutierrez@amd.com                                      &status);
13911308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
14011308Santhony.gutierrez@amd.com        printf("Error: Creating Context. (clCreateContextFromType)\n");
14111308Santhony.gutierrez@amd.com        return FAILURE;
14211308Santhony.gutierrez@amd.com    }
14311308Santhony.gutierrez@amd.com
14411308Santhony.gutierrez@amd.com    // 3. Get device info
14511308Santhony.gutierrez@amd.com    // 3a. Get # of devices
14611308Santhony.gutierrez@amd.com    status = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL,
14711308Santhony.gutierrez@amd.com                              &deviceListSize);
14811308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
14911308Santhony.gutierrez@amd.com        printf("Error: Getting Context Info (1st clGetContextInfo)\n");
15011308Santhony.gutierrez@amd.com        return FAILURE;
15111308Santhony.gutierrez@amd.com    }
15211308Santhony.gutierrez@amd.com
15311308Santhony.gutierrez@amd.com    // 3b. Get the device list data
15411308Santhony.gutierrez@amd.com    devices = (cl_device_id *)malloc(deviceListSize);
15511308Santhony.gutierrez@amd.com    if (devices == 0) {
15611308Santhony.gutierrez@amd.com        printf("Error: No devices found.\n");
15711308Santhony.gutierrez@amd.com        return FAILURE;
15811308Santhony.gutierrez@amd.com    }
15911308Santhony.gutierrez@amd.com    status = clGetContextInfo(context, CL_CONTEXT_DEVICES, deviceListSize,
16011308Santhony.gutierrez@amd.com                              devices, NULL);
16111308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
16211308Santhony.gutierrez@amd.com        printf("Error: Getting Context Info (2nd clGetContextInfo)\n");
16311308Santhony.gutierrez@amd.com        return FAILURE;
16411308Santhony.gutierrez@amd.com    }
16511308Santhony.gutierrez@amd.com
16611308Santhony.gutierrez@amd.com    // 4. Create command queue for device
16711308Santhony.gutierrez@amd.com    commandQueue = clCreateCommandQueue(context, devices[0], 0, &status);
16811308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
16911308Santhony.gutierrez@amd.com        printf("Creating Command Queue. (clCreateCommandQueue)\n");
17011308Santhony.gutierrez@amd.com        return FAILURE;
17111308Santhony.gutierrez@amd.com    }
17211308Santhony.gutierrez@amd.com
17311308Santhony.gutierrez@amd.com    const char *source = "dummy text";
17411308Santhony.gutierrez@amd.com
17511308Santhony.gutierrez@amd.com    size_t sourceSize[] = {strlen(source)};
17611308Santhony.gutierrez@amd.com
17711308Santhony.gutierrez@amd.com    // 5b. Register the kernel with the runtime
17811308Santhony.gutierrez@amd.com    program = clCreateProgramWithSource(context, 1, &source, sourceSize,
17911308Santhony.gutierrez@amd.com                                        &status);
18011308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
18111308Santhony.gutierrez@amd.com      printf("Error: Loading kernel (clCreateProgramWithSource)\n");
18211308Santhony.gutierrez@amd.com      return FAILURE;
18311308Santhony.gutierrez@amd.com    }
18411308Santhony.gutierrez@amd.com
18511308Santhony.gutierrez@amd.com    status = clBuildProgram(program, 1, devices, NULL, NULL, NULL);
18611308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
18711308Santhony.gutierrez@amd.com        printf("Error: Building kernel (clBuildProgram)\n");
18811308Santhony.gutierrez@amd.com        return FAILURE;
18911308Santhony.gutierrez@amd.com    }
19011308Santhony.gutierrez@amd.com
19111308Santhony.gutierrez@amd.com    readKernel = clCreateKernel(program, "read_kernel", &status);
19211308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
19311308Santhony.gutierrez@amd.com        printf("Error: Creating readKernel from program. (clCreateKernel)\n");
19411308Santhony.gutierrez@amd.com        return FAILURE;
19511308Santhony.gutierrez@amd.com    }
19611308Santhony.gutierrez@amd.com
19711308Santhony.gutierrez@amd.com    return SUCCESS;
19811308Santhony.gutierrez@amd.com}
19911308Santhony.gutierrez@amd.com
20011308Santhony.gutierrez@amd.com
20111308Santhony.gutierrez@amd.com/* Run kernels */
20211308Santhony.gutierrez@amd.comint
20311308Santhony.gutierrez@amd.comrunCLKernel(cl_kernel kernel)
20411308Santhony.gutierrez@amd.com{
20511308Santhony.gutierrez@amd.com    cl_int   status;
20611308Santhony.gutierrez@amd.com    cl_event event;
20711308Santhony.gutierrez@amd.com    size_t globalThreads[1] = {grid_size};
20811308Santhony.gutierrez@amd.com    size_t localThreads[1] = {work_group_size};
20911308Santhony.gutierrez@amd.com
21011308Santhony.gutierrez@amd.com    // 1. Set arguments
21111308Santhony.gutierrez@amd.com    // 1a. code size
21211308Santhony.gutierrez@amd.com    size_t code_size = strlen(code);
21311308Santhony.gutierrez@amd.com    status = clSetKernelArg(kernel, 0, sizeof(size_t), &code_size);
21411308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
21511308Santhony.gutierrez@amd.com        printf("Error: Setting kernel argument. (code_size)\n");
21611308Santhony.gutierrez@amd.com        return FAILURE;
21711308Santhony.gutierrez@amd.com    }
21811308Santhony.gutierrez@amd.com
21911308Santhony.gutierrez@amd.com    // 1b. code
22011308Santhony.gutierrez@amd.com    status = clSetKernelArg(kernel, 1, sizeof(char *), (void *)&code);
22111308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
22211308Santhony.gutierrez@amd.com        printf("Error: Setting kernel argument. (code_in)\n");
22311308Santhony.gutierrez@amd.com        return FAILURE;
22411308Santhony.gutierrez@amd.com    }
22511308Santhony.gutierrez@amd.com
22611308Santhony.gutierrez@amd.com    // 1c. keys
22711308Santhony.gutierrez@amd.com    printf("keys = %p, &keys = %p, keys[0] = %d\n", keys, &keys, keys[0]);
22811308Santhony.gutierrez@amd.com    status = clSetKernelArg(kernel, 2, sizeof(int *), (void *)&keys);
22911308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
23011308Santhony.gutierrez@amd.com        printf("Error: Setting kernel argument. (key_arr)\n");
23111308Santhony.gutierrez@amd.com        return FAILURE;
23211308Santhony.gutierrez@amd.com    }
23311308Santhony.gutierrez@amd.com
23411308Santhony.gutierrez@amd.com    // 1d. msg
23511308Santhony.gutierrez@amd.com    status = clSetKernelArg(kernel, 3, sizeof(char *), (void *)&msg);
23611308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
23711308Santhony.gutierrez@amd.com        printf("Error: Setting kernel argument. (memOut)\n");
23811308Santhony.gutierrez@amd.com        return FAILURE;
23911308Santhony.gutierrez@amd.com    }
24011308Santhony.gutierrez@amd.com
24111308Santhony.gutierrez@amd.com    // 1e. chars_decoded
24211308Santhony.gutierrez@amd.com    int *chars_decoded_ptr = &chars_decoded;
24311308Santhony.gutierrez@amd.com    status = clSetKernelArg(kernel, 4, sizeof(int *),
24411308Santhony.gutierrez@amd.com                            (void *)&chars_decoded_ptr);
24511308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
24611308Santhony.gutierrez@amd.com        printf("Error: Setting kernel argument. (memOut)\n");
24711308Santhony.gutierrez@amd.com        return FAILURE;
24811308Santhony.gutierrez@amd.com    }
24911308Santhony.gutierrez@amd.com
25011308Santhony.gutierrez@amd.com    // 2. Launch kernel
25111308Santhony.gutierrez@amd.com    status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL,
25211308Santhony.gutierrez@amd.com                                    globalThreads, localThreads, 0, NULL,
25311308Santhony.gutierrez@amd.com                                    &event);
25411308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
25511308Santhony.gutierrez@amd.com        printf("Error: Enqueue failed. (clEnqueueNDRangeKernel)\n");
25611308Santhony.gutierrez@amd.com        return FAILURE;
25711308Santhony.gutierrez@amd.com    }
25811308Santhony.gutierrez@amd.com
25911308Santhony.gutierrez@amd.com    // 3. Wait for the kernel
26011308Santhony.gutierrez@amd.com    status = clWaitForEvents(1, &event);
26111308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
26211308Santhony.gutierrez@amd.com        printf("Error: Waiting for kernel run to finish. (clWaitForEvents)\n");
26311308Santhony.gutierrez@amd.com        return FAILURE;
26411308Santhony.gutierrez@amd.com    }
26511308Santhony.gutierrez@amd.com
26611308Santhony.gutierrez@amd.com    // 4. Cleanup
26711308Santhony.gutierrez@amd.com    status = clReleaseEvent(event);
26811308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
26911308Santhony.gutierrez@amd.com        printf("Error: Release event object. (clReleaseEvent)\n");
27011308Santhony.gutierrez@amd.com        return FAILURE;
27111308Santhony.gutierrez@amd.com    }
27211308Santhony.gutierrez@amd.com
27311308Santhony.gutierrez@amd.com    return SUCCESS;
27411308Santhony.gutierrez@amd.com}
27511308Santhony.gutierrez@amd.com
27611308Santhony.gutierrez@amd.com
27711308Santhony.gutierrez@amd.com/* Release OpenCL resources (Context, Memory etc.) */
27811308Santhony.gutierrez@amd.comint
27911308Santhony.gutierrez@amd.comcleanupCL()
28011308Santhony.gutierrez@amd.com{
28111308Santhony.gutierrez@amd.com    cl_int status;
28211308Santhony.gutierrez@amd.com    status = clReleaseKernel(readKernel);
28311308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
28411308Santhony.gutierrez@amd.com        printf("Error: In clReleaseKernel \n");
28511308Santhony.gutierrez@amd.com        return FAILURE;
28611308Santhony.gutierrez@amd.com    }
28711308Santhony.gutierrez@amd.com    status = clReleaseProgram(program);
28811308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
28911308Santhony.gutierrez@amd.com        printf("Error: In clReleaseProgram\n");
29011308Santhony.gutierrez@amd.com        return FAILURE;
29111308Santhony.gutierrez@amd.com    }
29211308Santhony.gutierrez@amd.com    status = clReleaseCommandQueue(commandQueue);
29311308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
29411308Santhony.gutierrez@amd.com        printf("Error: In clReleaseCommandQueue\n");
29511308Santhony.gutierrez@amd.com        return FAILURE;
29611308Santhony.gutierrez@amd.com    }
29711308Santhony.gutierrez@amd.com    status = clReleaseContext(context);
29811308Santhony.gutierrez@amd.com    if (status != CL_SUCCESS) {
29911308Santhony.gutierrez@amd.com        printf("Error: In clReleaseContext\n");
30011308Santhony.gutierrez@amd.com        return FAILURE;
30111308Santhony.gutierrez@amd.com    }
30211308Santhony.gutierrez@amd.com
30311308Santhony.gutierrez@amd.com    return SUCCESS;
30411308Santhony.gutierrez@amd.com}
30511308Santhony.gutierrez@amd.com
30611308Santhony.gutierrez@amd.comint
30711308Santhony.gutierrez@amd.commain(int argc, char * argv[])
30811308Santhony.gutierrez@amd.com{
30911308Santhony.gutierrez@amd.com    // Initialize Host application
31011308Santhony.gutierrez@amd.com    if (setupDataStructs() != SUCCESS) {
31111308Santhony.gutierrez@amd.com        return FAILURE;
31211308Santhony.gutierrez@amd.com    }
31311308Santhony.gutierrez@amd.com
31411308Santhony.gutierrez@amd.com    // Initialize OpenCL resources
31511308Santhony.gutierrez@amd.com    if (setupOpenCL() != SUCCESS) {
31611308Santhony.gutierrez@amd.com        return FAILURE;
31711308Santhony.gutierrez@amd.com    }
31811308Santhony.gutierrez@amd.com
31911308Santhony.gutierrez@amd.com    // Run the CL program
32011308Santhony.gutierrez@amd.com    if (runCLKernel(readKernel) != SUCCESS) {
32111308Santhony.gutierrez@amd.com        return FAILURE;
32211308Santhony.gutierrez@amd.com    }
32311308Santhony.gutierrez@amd.com    printf("the gpu says:\n");
32411308Santhony.gutierrez@amd.com    printf("%s\n", msg);
32511308Santhony.gutierrez@amd.com
32611308Santhony.gutierrez@amd.com    // Releases OpenCL resources
32711308Santhony.gutierrez@amd.com    if (cleanupCL()!= SUCCESS) {
32811308Santhony.gutierrez@amd.com        return FAILURE;
32911308Santhony.gutierrez@amd.com    }
33011308Santhony.gutierrez@amd.com
33111308Santhony.gutierrez@amd.com    return SUCCESS;
33211308Santhony.gutierrez@amd.com}
333