حسین خسروی

وبلاگ دانشگاهی حسین خسروی، عضو هیات علمی دانشگاه صنعتی شاهرود

حسین خسروی

وبلاگ دانشگاهی حسین خسروی، عضو هیات علمی دانشگاه صنعتی شاهرود

حسین خسروی

باتوجه به محدودیتهای صفحه شخصی موجود در سایت دانشگاه، این بلاگ را راه اندازی کردم.
اطلاعیه های مربوط به دروسی که تدریس می کنم و تمرینها در این وبلاگ قرار خواهد گرفت.
برای آگاهی از مطالب مربوط به هر درس، در قاب زیر (طبقه بندی موضوعی) روی نام درس کلیک کنید.

پیوندهای روزانه
  • ۰
  • ۰

مثال شماره 2 درس چند پردازنده

این مثال و برخی از مثالهایی که در جلسات آینده طرح خواهد شد، از مثالهای شرکت AMD است که با تغییراتی در این درس طرح می شوند.

چاپ پیام Hello World از طریق کرنل - فایل CPP که در سمت میزبان اجرا می شود

/**********************************************************************
MultiCore Programming
Hossein Khosravi
Shahrood University of Technology
********************************************************************/

// For clarity,error checking has been omitted.

#include <CL/cl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <fstream>

#define SUCCESS 0
#define FAILURE 1

using namespace std;
 //برای دیدن کد کامل، ادامه مطلب را ببینید

 /* convert the kernel file into a string */ int convertToString(const char *filename, std::string& s) { size_t size; char* str; std::fstream f(filename, (std::fstream::in | std::fstream::binary)); if(f.is_open()) { size_t fileSize; f.seekg(0, std::fstream::end); size = fileSize = (size_t)f.tellg(); f.seekg(0, std::fstream::beg); str = new char[size+1]; if(!str) { f.close(); return 0; } f.read(str, fileSize); f.close(); str[size] = '\0'; s = str; delete[] str; return 0; } cout<<"Error: failed to open file\n:"<<filename<<endl; return FAILURE; } int main(int argc, char* argv[]) { /*Step1: Getting platforms and choose an available one.*/ cl_uint numPlatforms; //the NO. of platforms cl_platform_id platform = NULL; //the chosen platform cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); if (status != CL_SUCCESS) { cout << "Error: Getting platforms!" << endl; return FAILURE; } /*For clarity, choose the first available platform. */ if(numPlatforms > 0) { cl_platform_id* platforms = (cl_platform_id* )malloc(numPlatforms* sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); platform = platforms[0]; free(platforms); } /*Step 2:Query the platform and choose the first GPU device if has one.Otherwise use the CPU as device.*/ cl_uint numDevices = 0; cl_device_id *devices; status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); if (numDevices == 0) //no GPU available. { cout << "No GPU device available." << endl; cout << "Choose CPU as default device." << endl; status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &numDevices); devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id)); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, numDevices, devices, NULL); } else { devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id)); status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL); } /*char info[1024]; status = clGetDeviceInfo(devices[0], CL_DEVICE_EXTENSIONS, sizeof(info), info, 0); cout << info;*/ /*Step 3: Create context.*/ cl_context context = clCreateContext(NULL, 1, devices,NULL,NULL,NULL); /*Step 4: Creating command queue associate with the context.*/ cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL); /*Step 5: Create program object */ const char *filename = "HelloWorld_Kernel.cl"; string sourceStr; status = convertToString(filename, sourceStr); const char *source = sourceStr.c_str(); size_t sourceSize[] = {strlen(source)}; cl_program program = clCreateProgramWithSource(context, 1, &source, sourceSize, NULL); /*Step 6: Build program. */ status=clBuildProgram(program, 1, devices, NULL, NULL, NULL); if(status < 0) { size_t log_size = 0; clGetProgramBuildInfo(program, devices[0], CL_PROGRAM_BUILD_LOG, 0, 0, &log_size); char* log_str = (char*)malloc(log_size+1); clGetProgramBuildInfo(program, devices[0], CL_PROGRAM_BUILD_LOG, log_size+1, log_str, 0); printf("LOG FILE contains:\n%s", log_str); } /*Step 7: Initial input, output for the host and create memory objects for the kernel*/ const char* input = "GdkknVnqkc"; size_t strlength = strlen(input); cout << "input string:" << endl; cout << input << endl; char *output = (char*) malloc(strlength + 1); cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, (strlength + 1) * sizeof(char),(void *) input, NULL); cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY , (strlength + 1) * sizeof(char), NULL, NULL); /*Step 8: Create kernel object */ cl_kernel kernel = clCreateKernel(program,"helloworld", NULL); /*Step 9: Sets Kernel arguments.*/ status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&inputBuffer); status = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&outputBuffer); /*Step 10: Running the kernel.*/ size_t global_work_size[1] = {strlength}; status = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL); /*Step 11: Read the output back to host memory.*/ status = clEnqueueReadBuffer(commandQueue, outputBuffer, CL_TRUE, 0, strlength * sizeof(char), output, 0, NULL, NULL); output[strlength] = '\0'; //Add the terminal character to the end of output. cout << "\noutput string:" << endl; cout << output << endl; /*Step 12: Clean the resources.*/ status = clReleaseKernel(kernel); //Release kernel. status = clReleaseProgram(program); //Release the program object. status = clReleaseMemObject(inputBuffer); //Release mem object. status = clReleaseMemObject(outputBuffer); status = clReleaseCommandQueue(commandQueue); //Release Command queue. status = clReleaseContext(context); //Release context. if (output != NULL) { free(output); output = NULL; } if (devices != NULL) { free(devices); devices = NULL; } std::cout<<"Passed!\n"; return SUCCESS; }

فایل کرنل که در سمت پردازنده OpenCL (کارت گرافیک) اجرا می شود

// MultiCore Programming
// Hossein Khosravi
// Shahrood University of Technology
__kernel void helloworld(__global char* in, __global char* out)
{
	int num = get_global_id(0);
	out[num] = in[num] + 1;
	//out[num] = in[num] + 'A' - 'a';
}

برای دیدن خروجی، ادامه مطلب را ببینید:

خروجی

input string:

GdkknVnqkc


output string:

HelloWorld


Passed!

نظرات (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی