我想将两个String传递给OpenCL kernet,并直接从中打印文本。
到目前为止,我有这个:
int main(void) {
Context(CL_DEVICE_TYPE_GPU);
static const unsigned elements = 1000;
vector<string> dataA;
for (int i = 0; i < elements; i++) {
dataA.push_back("a");
}
vector<string> dataB;
for (int i = 0; i < elements; i++) {
dataB.push_back("b");
}
Buffer a(begin(dataA), end(dataA), true, false);
Buffer b(begin(dataB), end(dataB), true, false);
Program addProg(R"d(
kernel
void add(string a, string b) {
unsigned idx = get_global_id(0);
c[idx] = 2.0;
}
)d", true);
auto add = make_kernel<Buffer, Buffer>(addProg, "add");
add(EnqueueArgs(elements), a, b);
system("pause");
}
此代码在运行时崩溃,没有任何解释。
我如何调试它,是否可以从内核打印文本并将其显示在屏幕上?
答案 0 :(得分:2)
好的,所以听起来你想将一个数组/字符串向量传递给内核,并让内核中的每个工作项处理一个不同的字符串。你无法用STL向量和字符串类来实现这一点,因为这些在OpenCL内核中不起作用,所以最简单的方法是使用扁平的C字符数组(所有字符串都在一个数组中) )。
我已修改下面的程序来执行此操作。基本上,我们在charsPerString
变量中设置任何字符串所需的最大字符数(假设您知道这是什么)。然后我们分配一个带有elements*charsPerString
个字符的数组,并用你正在做的单个字符初始化字符串。第i个字符串从索引i*charsPerString
开始。然后我们可以将它作为单个缓冲区传递给内核。
然后内核让每个工作项打印出使用printf
传递的两个字符串中的每个字符串中的第一个字符,以与上面相同的方式计算字符串的开头。
我还添加了典型的带有异常的C ++错误检查方法,它将显示可能发生的任何OpenCL错误。我已经在自己的笔记本电脑上测试了它,它可以正常打印出来:
0 has characters a and b
1 has characters a and b
2 has characters a and b
3 has characters a and b
4 has characters a and b
(这是我们所期望的)。
希望您能够将此扩展到您自己的用例。
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <iostream>
using namespace cl;
using namespace std;
int main(void) {
try {
Context(CL_DEVICE_TYPE_GPU);
static const unsigned elements = 1000;
static const unsigned charsPerString = 16;
char *dataA = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataA[i*charsPerString] = 'a';
}
char *dataB = new char[elements*charsPerString];
for (int i = 0; i < elements; i++) {
dataB[i*charsPerString] = 'b';
}
Buffer a(dataA, dataA+elements*charsPerString, true, false);
Buffer b(dataB, dataB+elements*charsPerString, true, false);
Program addProg(R"d(
constant unsigned charsPerString = 16;
kernel
void add(global char *a, global char *b) {
unsigned idx = get_global_id(0);
printf("%d has characters %c and %c\n",
idx, a[idx*charsPerString], b[idx*charsPerString]);
}
)d");
try {
addProg.build();
}
catch (Error err) {
if (err.err() == CL_BUILD_PROGRAM_FAILURE) {
cout << "OpenCL build failure:" << endl;
cout << addProg.getBuildInfo<CL_PROGRAM_BUILD_LOG>(Device::getDefault());
}
throw err;
}
addProg.build();
auto add = make_kernel<Buffer, Buffer>(addProg, "add");
add(EnqueueArgs(elements), a, b);
CommandQueue::getDefault().finish();
delete[] dataA;
delete[] dataB;
}
catch (Error err) {
cerr << "ERROR: " << err.what() << " (" << err.err() << ")" << endl;
}
system("pause");
}