thrust::gather可以用"in-place"吗?
Can thrust::gather be used "in-place"?
考虑以下代码:
#include <time.h> // --- time
#include <stdlib.h> // --- srand, rand
#include<fstream>
#include <thrust\host_vector.h>
#include <thrust\device_vector.h>
#include <thrust\sort.h>
#include <thrust\iterator\zip_iterator.h>
#include "TimingGPU.cuh"
/********/
/* MAIN */
/********/
int main() {
const int N = 16384;
std::ifstream h_indices_File, h_x_File;
h_indices_File.open("h_indices.txt");
h_x_File.open("h_x.txt");
std::ofstream h_x_result_File;
h_x_result_File.open("h_x_result.txt");
thrust::host_vector<int> h_indices(N);
thrust::host_vector<double> h_x(N);
thrust::host_vector<double> h_sorted(N);
for (int k = 0; k < N; k++) {
h_indices_File >> h_indices[k];
h_x_File >> h_x[k];
}
thrust::device_vector<int> d_indices(h_indices);
thrust::device_vector<double> d_x(h_x);
thrust::gather(d_indices.begin(), d_indices.end(), d_x.begin(), d_x.begin());
h_x = d_x;
for (int k = 0; k < N; k++) h_x_result_File << h_x[k] << "\n";
//thrust::device_vector<double> d_x_sorted(N);
//thrust::gather(d_indices.begin(), d_indices.end(), d_x.begin(), d_x_sorted.begin());
//h_x = d_x_sorted;
//for (int k = 0; k < N; k++) h_x_result_File << h_x[k] << "\n";
}
代码从文件加载一个索引数组 h_indices.txt
和一个 double
数组 h_x.txt
。然后,它将这些数组传输到 GPU 到 d_indices
和 d_x
并使用 thrust::gather
来实现 Matlab 的等效
d_x(d_indices)
这两个txt文件可以从h_indices.txt and h_x.txt下载。该代码创建一个输出结果文件 h_x_result.txt
。
如果我使用 thrust::gather
的 "in-place" 版本(代码最后未注释的三行),那么我得到的结果与 d_x(d_indices)
不同,而如果我使用not "in-place"版本(最后注释三行代码),则结果正确。
在 Matlab 中,我使用
load h_indices.txt; load h_x.txt; load h_x_result.txt
plot(h_x(h_indices + 1)); hold on; plot(h_x_result, 'r'); hold off
"in-place"案例returns下面比较
另一方面,"in-place"案例returns
我正在使用 Windows 10,CUDA 8.0,Visual Studio 2013,在发布模式下编译,运行 在 NVIDIA GTX 960 cc 上。 5.2.
推力gather
不能原地使用。
但我什至会建议 "naïve" 收集操作不能就地安全执行,并且您提供的 Matlab 片段是就地(大概是 d_x = d_x(d_indices)
) 根本不是就地操作。
考虑以下代码:
#include <time.h> // --- time
#include <stdlib.h> // --- srand, rand
#include<fstream>
#include <thrust\host_vector.h>
#include <thrust\device_vector.h>
#include <thrust\sort.h>
#include <thrust\iterator\zip_iterator.h>
#include "TimingGPU.cuh"
/********/
/* MAIN */
/********/
int main() {
const int N = 16384;
std::ifstream h_indices_File, h_x_File;
h_indices_File.open("h_indices.txt");
h_x_File.open("h_x.txt");
std::ofstream h_x_result_File;
h_x_result_File.open("h_x_result.txt");
thrust::host_vector<int> h_indices(N);
thrust::host_vector<double> h_x(N);
thrust::host_vector<double> h_sorted(N);
for (int k = 0; k < N; k++) {
h_indices_File >> h_indices[k];
h_x_File >> h_x[k];
}
thrust::device_vector<int> d_indices(h_indices);
thrust::device_vector<double> d_x(h_x);
thrust::gather(d_indices.begin(), d_indices.end(), d_x.begin(), d_x.begin());
h_x = d_x;
for (int k = 0; k < N; k++) h_x_result_File << h_x[k] << "\n";
//thrust::device_vector<double> d_x_sorted(N);
//thrust::gather(d_indices.begin(), d_indices.end(), d_x.begin(), d_x_sorted.begin());
//h_x = d_x_sorted;
//for (int k = 0; k < N; k++) h_x_result_File << h_x[k] << "\n";
}
代码从文件加载一个索引数组 h_indices.txt
和一个 double
数组 h_x.txt
。然后,它将这些数组传输到 GPU 到 d_indices
和 d_x
并使用 thrust::gather
来实现 Matlab 的等效
d_x(d_indices)
这两个txt文件可以从h_indices.txt and h_x.txt下载。该代码创建一个输出结果文件 h_x_result.txt
。
如果我使用 thrust::gather
的 "in-place" 版本(代码最后未注释的三行),那么我得到的结果与 d_x(d_indices)
不同,而如果我使用not "in-place"版本(最后注释三行代码),则结果正确。
在 Matlab 中,我使用
load h_indices.txt; load h_x.txt; load h_x_result.txt
plot(h_x(h_indices + 1)); hold on; plot(h_x_result, 'r'); hold off
"in-place"案例returns下面比较
另一方面,"in-place"案例returns
我正在使用 Windows 10,CUDA 8.0,Visual Studio 2013,在发布模式下编译,运行 在 NVIDIA GTX 960 cc 上。 5.2.
推力gather
不能原地使用。
但我什至会建议 "naïve" 收集操作不能就地安全执行,并且您提供的 Matlab 片段是就地(大概是 d_x = d_x(d_indices)
) 根本不是就地操作。