openCL (c++)中的二进制文件



假设我有一个openCL程序:

...
const unsigned char* binaries;
size_t binaries_size;
assign_binaries(&binaries, &binaries_size); // my assign function, assigns bin and bin_size
std::vector<std::vector<unsigned char>> Binaries;
cl::Program prog = cl::Program(context, device_list, Binaries, &binary_status, &err);
...

我该如何按

binaries

binaries_size

Binaries

?

在OpenCL文档中,它说:

Binaries: A vector of pairs of a pointer to a binary object and its length.

但是,这对我来说没有意义,因为存在明显的类型不匹配。

我该如何推送

binaries

binaries_size

Binaries

?

有很多方法可以做到这一点。

TL;博士:实现OPs意图的最简洁的代码可能是:

cl::Program prog
= cl::Program(context, device_list,
{ std::vector<unsigned char>(binaries, binaries + binaries_size) }, 
&binary_status, &err);

说来话长:

一个MCVE来演示两个:

#include <iomanip>
#include <iostream>
#include <vector>
// the OpenCL typedef
using Binaries = std::vector<std::vector<unsigned char>>;
void print(const Binaries& binaries)
{
std::cout << "Binaries: [" << binaries.size() << "]: {n";
for (const std::vector<unsigned char>& binary : binaries) {
std::cout << "  [" << binary.size() << "]: {" ;
const char* sep = " ";
for (const unsigned char value : binary) {
std::cout << sep << "0x"
<< std::hex << std::setw(2) << std::setfill('0') << (unsigned)value;
sep = ", ";
}
std::cout << " }n";
}
std::cout << "}n";
}
int main()
{
// sample data
const unsigned char data[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
};
// OPs initial exposure of data
const unsigned char *binaries = data;
const size_t binaries_size = std::size(data);
// filling a Binaries var.:
Binaries vecBinaries1;
vecBinaries1.push_back(
std::vector<unsigned char>(binaries, binaries + binaries_size));
print(vecBinaries1);
// or
const Binaries vecBinaries2(1, std::vector<unsigned char>(binaries, binaries + binaries_size));
print(vecBinaries2);
}

输出:

Binaries: [1]: {
[8]: { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
}
Binaries: [1]: {
[8]: { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
}

请注意,数据是在binaries中准备的,然后复制到std::vector的构造器std::vector<unsigned char>(binaries, binaries + binaries_size)中。

std::vector提供了多种构造函数。在本例中,使用具有firstlast迭代器的构造函数:

template< class InputIt >
vector( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );

(这是风味(5)在链接的文档。)

然而,这可能是一个不必要的复制步骤。从一开始就在std::vector<unsigned char>中提供数据可以用来摆脱这种情况。

push_back()可以与move语义一起使用(这可以防止2不必要的深度复制)。(链接的文档中是(2)口味。)如果内部向量的构造函数作为实参直接传递,则会产生一个RValue,该RValue将自动触发move语义。

如果存在内部向量的中间存储(例如在局部变量中),则仍然可以使用std::move()强制执行move语义:

std::vector<unsigned char> vecBinary3(binaries, binaries + binaries_size);
Binaries vecBinaries3;
vecBinaries3.push_back(std::move(vecBinary3));
print(vecBinaries3);

输出:

Binaries: [1]: {
[8]: { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
}

coliru Live Demo


我还添加了大括号初始化(在本例中是直接列表初始化)。

const Binaries vecBinaries4 {
std::vector<unsigned char>(binaries, binaries + binaries_size)
};
print(vecBinaries4);

输出:

Binaries: [1]: {
[8]: { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }
}

(我必须承认,我仍然考虑大括号init。有点吓人。因此,我很难提及它,但为了完整起见,我应该这样做。

在某些情况下,例如,如果你有一个积分向量,你必须小心区分大小为n和初始填充值的构造函数与初始化列表为两个值的构造函数。对于这两种方法,都必须提供两个整数值,但是括号的类型和数量决定了使用哪个构造函数。这很容易导致混淆。

的例子:

#include <iostream>
#include <vector>
void print(const std::vector<int>& values)
{
std::cout << '{';
const char* sep = " ";
for (const int value : values) {
std::cout << sep << value;
sep = ", ";
}
std::cout << " }n";
}
int main()
{
// sample 1:
print({ 1, 2 });
// sample 2:
print(std::vector<int>(1, 2));
// sample 3:
print(std::vector<int>{ 1, 2 });
// sample 4:
print(std::vector<int>({ 1, 2 }));
}
输出:

{ 1, 2 }
{ 2 }
{ 1, 2 }
{ 1, 2 }

coliru Live Demo

最新更新