gpu-hello.cpp revision 11308
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)); 7311308Santhony.gutierrez@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 12911308Santhony.gutierrez@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