Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > C/C++/С#


Ответ
 
Опции темы Опции просмотра
Старый 02.08.2010, 14:41   #1 (permalink)
Forester04
Новичок
 
Регистрация: 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);
}
Forester04 вне форума   Ответить с цитированием

Старый 02.08.2010, 14:41
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Не стоит торопить события, лучше пока обратить внимание на эти ссылки

Программа для ХР
Программа
Программа
Что за программа?
Использование fstream, OpenCL

Старый 02.08.2010, 15:01   #2 (permalink)
Long Cat
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
Long Cat вне форума   Ответить с цитированием
Старый 13.08.2010, 14:45   #3 (permalink)
Forester04
Новичок
 
Регистрация: 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.
Forester04 вне форума   Ответить с цитированием
Старый 20.09.2010, 15:11   #4 (permalink)
Forester04
Новичок
 
Регистрация: 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 выводит семизначное число. Наверняка, где-то косячу с выводом. дело не в самом кернеле, т.к. я пробовал его упрощать и результат получался такой же.
в остальном, вроде прога ошибок не выявляет, хотя не исключено, что напутал с буффером.
Forester04 вне форума   Ответить с цитированием
Старый 21.02.2011, 16:59   #5 (permalink)
daemvil
Новичок
 
Регистрация: 21.02.2011
Сообщений: 1
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

стучи в аську если что, у меня та же проблема, только нуль на выходе ( 481073926
daemvil вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Старый 22.02.2011, 00:36   #6 (permalink)
Long Cat
Banned
 
Регистрация: 01.09.2009
Сообщений: 4,396
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 2544
По умолчанию

Проблема та же, а код ваш где?
Long Cat вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 08:39.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.