gpt4 book ai didi

c++ - 使用 VexCL 的 Gram 矩阵

转载 作者:行者123 更新时间:2023-11-28 07:06:37 31 4
gpt4 key购买 nike

我有一个非常大的数据(不适合 GPU 内存),其中包含许多 vector ,其中每个 vector 有几个 MB。我想使用多个 GPU 设备计算使用高斯内核的 Gram 矩阵。

换句话说,对于每对 vector x,y,我需要计算 x-y 的范数。所以如果我有 N 个 vector ,我就有 (N^2+N)/2 个这样的对。我不在乎利用对称性来节省空间或时间,它可以完成整个 N^2。

我怎样才能用 VexCL 做到这一点? ?我知道它是唯一支持多个 GPU 的库,我用普通的 OpenCL 做了很多有效的工作,但到目前为止没有成功。

请注意,数据集甚至无法容纳机器的 RAM,我正在从内存映射文件中读取 vector block 。

非常感谢!!

最佳答案

您显然需要将您的 vector 分成多个组,例如 m,将这些组一个接一个(或者更确切地说,两个接两个)加载到您的 GPU 上并进行计算。这是一个完整的程序,它为两个当前加载的 block 进行计算(据我所知):

#include <vexcl/vexcl.hpp>

int main() {
const size_t n = 1024; // Each vector size.
const size_t m = 4; // Number of vectors in a chunk.

vex::Context ctx( vex::Filter::Count(1) );

// The input vectors...
vex::vector<double> chunk1(ctx, m * n);
vex::vector<double> chunk2(ctx, m * n);

// ... with some data.
chunk1 = vex::element_index();
chunk2 = vex::element_index();

vex::vector<double> gram(ctx, m * m); // The current chunk of Gram matrix to fill.

/*
* chunk1 and chunk2 both have dimensions [m][n].
* We want to take each of chunk2 m rows, subtract those from each of
* chunk1 rows, and reduce the result along the dimension n.
*
* In order to do this, we create two virtual 3D matrices (x and y below,
* those are just expressions and are never instantiated) sized [m][m][n],
* where
*
* x[i][j][k] = chunk1[i][k] for each j, and
* y[i][j][k] = chunk2[j][k] for each i.
*
* Then what we need to compute is
*
* gram[i][j] = sum_k( (x[i][j][k] - y[i][j][k])^2 );
*
* Here it goes:
*/
using vex::extents;

auto x = vex::reshape(chunk1, extents[m][m][n], extents[0][2]);
auto y = vex::reshape(chunk2, extents[m][m][n], extents[1][2]);

// The single OpenCL kernel is generated and launched here:
gram = vex::reduce<vex::SUM>(
extents[m][m][n], // The dimensions of the expression to reduce.
pow(x - y, 2.0), // The expression to reduce.
2 // The dimension to reduce along.
);

// Copy the result to host, spread it across your complete gram matrix.
// I am lazy though, so let's just dump it to std::cout:
std::cout << gram << std::endl;
}

我建议您加载一次chunk1,然后依次加载所有chunk2 变体并进行计算,然后加载下一个chunk1,依此类推。等。请注意,切片、 reshape 和多维缩减操作仅支持其中包含单个计算设备的上下文。所以剩下的就是如何将计算分散到所有计算设备上。最简单的方法可能是创建单个 VexCL 上下文来获取所有可用的 GPU,然后从中创建命令队列 vector :

vex::Context ctx( vex::Filter::Any );

std::vector<std::vector<vex::command_queue>> q;
for(size_t d = 0; d < ctx.size(); ++d)
q.push_back({ctx.queue(d)});


//...

// In a std::thread perhaps:
chunk1(q[d], m * n);
chunk2(q[d], m * n);
// ...

我希望这足以让您入门。

关于c++ - 使用 VexCL 的 Gram 矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21682012/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com