02.08.2010, 14:41 | #1 (permalink) |
Новичок
Регистрация: 02.08.2010
Сообщений: 3
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Программа в OpenCL
В общем, делал-делал и пришёл я к тупику на данном этапе... не знаю, что и делать. Изначально программа должна была высчитывать с помощью ЦПУ корень из числа. На выходе получается большое отрицательное число. Помогите пожалуйста исправить ошибки. ↓↓↓ #include <stdafx.h> #include <CL/cl.h> const char* OpenCLSource[] = {"__kernel void kor (__global float* X, __global float* SM,__global float* rez)" "{" "X = 10000;" "if (X > 1) SM = X / 2; else SM = 1;" "for(; (SM != 0); SM /= 2) if ((rez * rez) > X) rez -= SM; else rez += SM;" "return(rez);" "}" }; int main(int argc, char **argv) { float X; float SM; float rez; //Инициализация устройства cl_context cxGPUContext = clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU, NULL, NULL, NULL); cl_int cdDevice = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_CPU, NULL, NULL, NULL); //Очерёдность выполнения cl_command_queue cqCommandQue = clCreateCommandQueue(cl_context (cxGPUContext), NULL, 0, NULL); //Memory Objects cl_mem Xq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, 100, &X, NULL); cl_mem SMq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, 100, &SM, NULL); cl_mem rezq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_READ_ONLY, 100, &rez, NULL); cl_program OpenCLProgram = clCreateProgramWithSource(cl_context (cxGPUContext), 1, OpenCLSource , NULL, NULL); clBuildProgram(OpenCLProgram, 0, NULL, NULL, NULL, NULL); cl_kernel kor = clCreateKernel(cl_program (OpenCLProgram), "kor2.cl", NULL); clSetKernelArg(kor, 0, sizeof(cl_mem), (void*)&Xq); clSetKernelArg(kor, 1, sizeof(cl_mem), (void*)&SMq); clSetKernelArg(kor, 2, sizeof(cl_mem), (void*)&rezq); cl_int clEnqueueNDRangeKernel(cl_command_queue (cqCommandQue)); clEnqueueReadBuffer(cqCommandQue, rezq, CL_TRUE, 0, sizeof(cl_float), rezq, 0, NULL, NULL); printf("Hello %f\n", rez); } |
02.08.2010, 14:41 | |
Helpmaster
Member
Регистрация: 08.03.2016
Сообщений: 0
|
Не стоит торопить события, лучше пока обратить внимание на эти ссылки Программа для ХР Программа Программа Что за программа? Использование fstream, OpenCL |
02.08.2010, 15:01 | #2 (permalink) |
Banned
Регистрация: 01.09.2009
Сообщений: 4,396
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 2544
|
Во-первых, ваша программа неверно оформлена - используйте тег [code].
Во-вторых, ваша переменная rez не инициализируется перед входом в цикл, из-за этого все чудеса. В-третьих, ваш метод половинного деления реализован неверно - он не сходится. Вот пример правильной реализации: Код:
double isqrt(double k) { if(k==1) { return(1); } double a=0; double b=k; while(true) { const double mid=((b-a)/2.0)+a; if(b-a<=0.0001) { return(mid); } const double fc=mid-k/mid; if(fc==0) { return(mid); } if(fc>0) { b=mid; } else { a=mid; } } } Последний раз редактировалось Long Cat; 02.08.2010 в 19:11 |
13.08.2010, 14:45 | #3 (permalink) |
Новичок
Регистрация: 02.08.2010
Сообщений: 3
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Код:
#include <stdafx.h> #include <CL/cl.h> const char* OpenCLSource[] = {"__kernel void kor (__global float* X, __global float* SM,__global float* rez)" "{" "X = 10000;" "rez = 0;" "if (X > 1) SM = X / 2; else SM = 1;" "for(; (SM != 0); SM /= 2) if ((rez * rez) > X) rez -= SM; else rez += SM;" "return(rez);" "}" }; int main(int argc, char **argv) { float X; float SM; float rez; //Инициализация устройства cl_context cxGPUContext = clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU, NULL, NULL, NULL); cl_int cdDevice = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_CPU, NULL, NULL, NULL); //Очерёдность выполнения cl_command_queue cqCommandQue = clCreateCommandQueue(cl_context (cxGPUContext), NULL, 0, NULL); //Memory Objects cl_mem Xq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, 100, &X, NULL); cl_mem SMq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, 100, &SM, NULL); cl_mem rezq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_READ_ONLY, 100, &rez, NULL); cl_program OpenCLProgram = clCreateProgramWithSource(cl_context (cxGPUContext), 1, OpenCLSource , NULL, NULL); clBuildProgram(OpenCLProgram, 0, NULL, NULL, NULL, NULL); cl_kernel kor = clCreateKernel(cl_program (OpenCLProgram), "kor.cl", NULL); clSetKernelArg(kor, 0, sizeof(cl_mem), (void*)&Xq); clSetKernelArg(kor, 1, sizeof(cl_mem), (void*)&SMq); clSetKernelArg(kor, 2, sizeof(cl_mem), (void*)&rezq); clEnqueueWriteBuffer(cqCommandQue, Xq, CL_TRUE, 0, sizeof(cl_float), Xq, 0, NULL, NULL); clEnqueueWriteBuffer(cqCommandQue, SMq, CL_TRUE, 0, sizeof(cl_float), SMq, 0, NULL, NULL); cl_int clEnqueueNDRangeKernel(cl_command_queue (cqCommandQue)); clEnqueueReadBuffer(cqCommandQue, rezq, CL_TRUE, 0, sizeof(cl_float), rezq, 0, NULL, NULL); printf("Hello %f\n", rezq); } последний вариант. на выходе стабильно 0. |
20.09.2010, 15:11 | #4 (permalink) |
Новичок
Регистрация: 02.08.2010
Сообщений: 3
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
Друзья, вариант программы последний такой:
Код:
#include <stdafx.h> #include <stdio.h> #include <stdlib.h> #include <CL/cl.h> #include "kor.hpp" const char* OpenCLSource[] = {"__kernel void kor(__global int* X, __global int* SM, __global int* rez, int iNumElements)" "{" "int iGID = get_global_id(0);" "if (iGID >= iNumElements)" "{" "return;" "}" "if (X[iGID] > 1) SM[iGID] = X[iGID] / 2; else SM[iGID] = 1;" "for(; (SM[iGID] != 0); SM[iGID] /= 2) if ((rez[iGID] * rez[iGID]) > X[iGID]) rez[iGID] -= SM[iGID]; else rez[iGID] += SM[iGID];" "return(rez[iGID]);" "}" }; void main(int argc, char **argv) { width = 200; input = NULL; output = NULL; cl_int status = 0; cl_uint numPlatforms; cl_platform_id platform = NULL; cl_device_type dType; dType = CL_DEVICE_TYPE_CPU; size_t deviceListSize; int iNumElements; #define SIZE 200 //Инициализация устройства /**/ status = clGetPlatformIDs(0, NULL, &numPlatforms); if(status != CL_SUCCESS) { printf("Error: Getting Platforms. (clGetPlatformsIDs)\n"); return; } else { printf("Get Platform ID Done! :)\n"); } if(numPlatforms > 0) { cl_platform_id* platforms = (cl_platform_id *)malloc(numPlatforms*sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); if(status != CL_SUCCESS) { printf("Error: Getting Platform Ids. (clGetPlatformsIDs)\n"); return; } for(unsigned int i=0; i < numPlatforms; ++i) { char pbuff[100]; status = clGetPlatformInfo( platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL); if(status != CL_SUCCESS) { printf("Error: Getting Platform Info. (clGetPlatformInfo)\n"); return; } platform = platforms[i]; if(!strcmp(pbuff, "Advanced Micro Devices, Inc.")) { break; } } delete platforms; } if(NULL == platform) { std::cout << "NULL platform found so Exiting Application." << std::endl; return; } /* * If we could find our platform, use it. Otherwise use just available platform. */ cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; ///////////////////////////////////////////////////////////////// // Create an OpenCL context ///////////////////////////////////////////////////////////////// cl_context cxGPUContext = clCreateContextFromType(cps, CL_DEVICE_TYPE_CPU, NULL, NULL, &status); if(status != CL_SUCCESS) { printf("Error: Creating Context. (clCreateContextFromType)\n"); return; } else { printf("Creating Context Done! :)\n"); } status = clGetContextInfo(cxGPUContext, CL_CONTEXT_DEVICES, 0, NULL, &deviceListSize); if(status != CL_SUCCESS) { printf( "Error: Getting First Context Info \ (device list size, clGetContextInfo)\n"); return; } devices = (cl_device_id *)malloc(deviceListSize); if(devices == 0) { printf("Error: No devices found.\n"); return; } status = clGetContextInfo(cxGPUContext, CL_CONTEXT_DEVICES, deviceListSize, devices, &deviceListSize); if(status != CL_SUCCESS) { printf( "Error: Getting Context Info \ (device list size, clGetContextInfo)\n"); } //Очерёдность выполнения cl_command_queue cqCommandQue = clCreateCommandQueue(cxGPUContext, devices[0], 0, &status); if(status != CL_SUCCESS) { printf("Error: create ComandQue. (clCreateCommandQueue)\n"); } else { printf("Create ComandQue Done! :)\n"); } //Memory Objects cl_mem Xq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, sizeof(cl_uint) * width, NULL, &status); if(status != CL_SUCCESS) { printf("Error: Create Memory Buffer. (clCreateBuffer)\n"); } else { printf("Create Memory Buffer Done! :)\n"); } cl_mem SMq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_WRITE_ONLY, sizeof(cl_uint) * width, NULL, &status); if(status != CL_SUCCESS) { printf("Error: Create Memory Buffer. (clCreateBuffer)\n"); } else { printf("Create Memory Buffer Done! :)\n"); } cl_mem rezq = clCreateBuffer(cl_context (cxGPUContext), CL_MEM_READ_ONLY, sizeof(cl_uint) * width, NULL, &status); if(status != CL_SUCCESS) { printf("Error: Create Memory Buffer. (clCreateBuffer)\n"); } else { printf("Create Memory Buffer Done! :)\n"); } //Create Programm cl_program OpenCLProgram = clCreateProgramWithSource(cxGPUContext, 1, OpenCLSource , NULL, &status); if(status != CL_SUCCESS) { printf("Error: Create OpenCLrogram. (clCreateProgramWithSource)\n"); } else { printf("Create OpenCLrogram Done! :)\n"); } status = clBuildProgram(OpenCLProgram, 1, devices, NULL, NULL, NULL); if(status != CL_SUCCESS) { printf("Error: Build OpenCL Program. (clBuildProgram)\n"); } else { printf("Build OpenCL Program Done! :)\n"); } //////////// CREATING KERNEL ! cl_kernel kor = clCreateKernel(OpenCLProgram, "kor", &status); if(status != CL_SUCCESS) { printf("Error: Create Kernel. (clCreateKernel)\n"); } else { printf("Create Kernel Done! :)\n"); } status = clSetKernelArg(kor, 0, sizeof(cl_mem), (void*)&Xq); if(status != CL_SUCCESS) { printf("Error: Setting Kernel Argument 1. (clSetKernelArg)\n"); } else { printf("Setting Kernel Argument 1 Done! :)\n"); } status = clSetKernelArg(kor, 1, sizeof(cl_mem), (void*)&SMq); if(status != CL_SUCCESS) { printf("Error: Setting Kernel Argument 2. (clSetKernelArg)\n"); } else { printf("Setting Kernel Argument 2 Done! :)\n"); } status = clSetKernelArg(kor, 2, sizeof(cl_mem), (void*)&rezq); if(status != CL_SUCCESS) { printf("Error: Setting Kernel Argument 3. (clSetKernelArg)\n"); } else { printf("Setting Kernel Argument 3 Done! :)\n"); } status = clSetKernelArg(kor, 3, sizeof(cl_int), (void*)&iNumElements); if(status != CL_SUCCESS) { printf("Error: Setting Kernel Argument 4. (clSetKernelArg)\n"); } else { printf("Setting Kernel Argument 4 Done! :)\n"); } status = clEnqueueWriteBuffer(cqCommandQue, Xq, CL_TRUE, 100, sizeof(cl_float), Xq, 0, NULL, NULL); if(status != CL_SUCCESS) { printf("Error: Write Buffer 1. (clEnqueueWriteBuffer)\n"); } else { printf("Write Buffer 1 Done! :)\n"); } status = clEnqueueWriteBuffer(cqCommandQue, SMq, CL_TRUE, 100, sizeof(cl_float), SMq, 0, NULL, NULL); if(status != CL_SUCCESS) { printf("Error: Write Buffer 2. (clEnqueueWriteBuffer)\n"); } else { printf("Write Buffer 2 Done! :)\n"); } // RANGE KERNEL !!!!!!!!!!)))))))))*********** //************* //^^^^^^^^^^^^^^^^^^^^^^^^^ cl_event events[2]; size_t globalThreads[1]; size_t localThreads[1]; globalThreads[0] = width; localThreads[0] = 1; status = clEnqueueNDRangeKernel(cqCommandQue, kor, 1, NULL, globalThreads, NULL, 0, NULL, &events[0]); if(status != CL_SUCCESS) { printf("Error: EnqueueNDRangeKernel. (clEnqueueNDRangeKernel)%d\n", status); } else { printf("EnqueueNDRangeKernel Done! :)\n"); } status = clWaitForEvents(1, &events[0]); if(status != CL_SUCCESS) { printf( "Error: Waiting for kernel run to finish. \ (clWaitForEvents)\n"); return; } status = clReleaseEvent(events[0]); if(status != CL_SUCCESS) { printf("Error: clReleaseEvent. (events[0])\n"); return; } int vivod [SIZE]; status = clEnqueueReadBuffer(cqCommandQue, rezq, CL_TRUE, 0, sizeof(cl_uint)*width, vivod, 0, NULL, &events[1]); if(status != CL_SUCCESS) { printf( "Error: clEnqueueReadBuffer failed. \ (clEnqueueReadBuffer)\n"); } else { printf("clEnqueueReadBuffer Done! :)\n"); } /* Wait for the read buffer to finish execution */ status = clWaitForEvents(1, &events[1]); if(status != CL_SUCCESS) { printf( "Error: Waiting for read buffer call to finish. \ (clWaitForEvents)\n"); return; } status = clReleaseEvent(events[1]); if(status != CL_SUCCESS) { printf("Error: clReleaseEvent. (events[1])\n"); return; } printf("\n\n\n\n"); printf("Hello %d\n", vivod); } printf выводит семизначное число. Наверняка, где-то косячу с выводом. дело не в самом кернеле, т.к. я пробовал его упрощать и результат получался такой же. в остальном, вроде прога ошибок не выявляет, хотя не исключено, что напутал с буффером. |
21.02.2011, 16:59 | #5 (permalink) |
Новичок
Регистрация: 21.02.2011
Сообщений: 1
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
|
стучи в аську если что, у меня та же проблема, только нуль на выходе ( 481073926
|
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
22.02.2011, 00:36 | #6 (permalink) |
Banned
Регистрация: 01.09.2009
Сообщений: 4,396
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 2544
|
Проблема та же, а код ваш где?
|
Ads | |
Member
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
|
|
|