Опитвам се да науча основите на OpenCL.
Мислех, че този код в ядрото:
out[ 1 & ((a+b)==(b+a)) ] = (char)1;
Ще генерира същите резултати като:
out[ 1 ] = (char)1;
Може ли някой да ми каже защо генерира различен резултат?
Ето пълния изходен код за моето ядро:
#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
__kernel void hello(__global char * out)
{
size_t tid = get_global_id(0);
int a = tid & 0xff;
int b = (tid >> 8) & 0xff;
out[ 1 & ((a+b)==(b+a)) ] = (char)1;
}
Ако заменя последния израз с "out[1]=(char)1;" тогава "out[0]" няма да бъде изписано. Но ядрото по-горе ще напише "1" на out[0].
РЕДАКТИРАНЕ: Това е моят C++ код:
#include <utility>
#define __NO_STD_VECTOR // Use cl::vector instead of STL version
#include <CL/cl.hpp>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
#include <iterator>
inline void checkErr(cl_int err, const char * name)
{
if (err != CL_SUCCESS) {
std::cerr << "ERROR: " << name
<< " (" << err << ")" << std::endl;
std::exit(EXIT_FAILURE);
}
}
int main()
{
cl_int err;
cl::vector< cl::Platform > platformList;
cl::Platform::get(&platformList);
checkErr(platformList.size()!=0 ? CL_SUCCESS : -1, "cl::Platform::get");
std::cerr << "Platform number is: " << platformList.size() << std::endl;
std::string platformVendor;
platformList[0].getInfo((cl_platform_info)CL_PLATFORM_VENDOR, &platformVendor);
std::cerr << "Platform is by: " << platformVendor << "\n";
cl_context_properties cprops[3] =
{CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0};
cl::Context context(
CL_DEVICE_TYPE_GPU,
cprops,
NULL,
NULL,
&err);
checkErr(err, "Conext::Context()");
unsigned char outH[2] = {0};
cl::Buffer outCL(
context,
CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
sizeof(outH),
outH,
&err);
checkErr(err, "Buffer::Buffer()");
cl::vector<cl::Device> devices;
devices = context.getInfo<CL_CONTEXT_DEVICES>();
checkErr(
devices.size() > 0 ? CL_SUCCESS : -1, "devices.size() > 0");
std::ifstream file("condition1.cl");
checkErr(file.is_open() ? CL_SUCCESS:-1, "condition1.cl");
const std::string prog(std::istreambuf_iterator<char>(file), (std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length()+1));
cl::Program program(context, source);
err = program.build(devices,"");
checkErr(err, "Program::build()");
cl::Kernel kernel(program, "hello", &err);
checkErr(err, "Kernel::Kernel()");
err = kernel.setArg(0, outCL);
checkErr(err, "Kernel::setArg()");
cl::CommandQueue queue(context, devices[0], 0, &err);
checkErr(err, "CommandQueue::CommandQueue()");
cl::Event event;
err = queue.enqueueNDRangeKernel(
kernel,
cl::NullRange,
cl::NDRange(65536),
cl::NDRange(1, 1),
NULL,
&event);
checkErr(err, "ComamndQueue::enqueueNDRangeKernel()");
event.wait();
err = queue.enqueueReadBuffer(
outCL,
CL_TRUE,
0,
sizeof(outH),
outH);
checkErr(err, "ComamndQueue::enqueueReadBuffer()");
for (int i = 0; i < sizeof(outH); i++)
std::cout << (int)outH[i] << " ";
std::string str;
std::getline(std::cin, str);
return EXIT_SUCCESS;
}
РЕДАКТИРАНЕ 2:
Поне не е причинено от „недефинирано поведение“. Получавам странни резултати и за този код на ядрото:
char result = 0;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
if ((a+b) != (b+a))
result |= (1 << (a+2*b));
}
}
Очаквам, че "резултат" ще получи стойност 0. Но получава стойност 6. Ако променя != на ==, тогава резултатът получава стойност 9. Така че в този код, когато "а" не е равно на "b", тогава (a+b) не е равно на (b+a).
Ако променя кода и задам известна стойност за "a" или "b", тогава резултатът ще бъде 0, както очаквам. Например:
char result = 0;
int a = 1;
/*for (int a = 0; a < 2; a++)*/ {
for (int b = 0; b < 2; b++) {
if ((a+b) != (b+a))
result |= (1 << (a+2*b));
}
}
enqueueNDRangeKernel
? - person Fabien R   schedule 12.01.2013Замяната на
getModel
изглежда причинява проблеми с останалата част от програмата. Така или иначе не е задължително за това, което се опитвате да постигнете.Лично аз не бих се занимавал с персонализираната таблица, вие не добавяте никаква нова функционалност към класа, която не може да се управлява директно през модела, където така или иначе трябва да се извършва управлението
Също така бих се тревожил за прекомерната употреба на
- person Tom Fenech   schedule 06.11.2013static
, тъй като това вероятно ще ви причини някои проблеми, когато програмата стане по-голяма