将数据从 arrayfire 数组传输到犰狳结构
Transfer data from arrayfire arrays to armadillo structures
我想用 ArrayFire
替换以前用 armadillo
编写的一些计算,以便使用一些 GPU 功能。我不想替换所有内容,只是时间紧迫的地方。因此,我需要将 armadillo
-结构转换为 arrayfire
-结构并返回。第一步很简单:
arma::colvec A_arma(5, arma::fill::ones);
af::array A_array(5, A_arma.memptr());//Done
回去更难。如何将数据从 arrayfire
-结构获取到 armadillo
-结构?我可以遍历所有元素并将它们写入 armadillo
结构,但这会花费很多时间。有没有更简单的方法?
您可以使用 host 成员函数从 af::array
中复制数据。例如,您可以将数据从 ArrayFire 数组复制到 std::vector
,如下所示:
af::array gpu_data = af::randu(10, 10);
vector<float> cpu_data(gpu_data.elements());
gpu_data.host<float>(cpu_data.data());
这会将列主顺序中的数据复制到 cpu_data
向量。
我不太熟悉犰狳的数据结构,但我相信你可以将 memptr
返回的指针传递给宿主函数,数据将被复制到其中。
您可以使用 ArrayFire 数组的 host
指针直接转换为犰狳结构。
size_t nrows = 10;
size_t ncols = 10;
af::array af = af::constant(0, nrows, ncols); // defaults to dtype=f32
float* host_ptr = af.host<double>();
arma::fmat arma(host_ptr, nrows, ncols);
请注意类型和大小需要匹配。在上述情况下,使用了单精度浮点类型。对于双精度,您必须更改为以下内容。
af::array af = af::constant(0, nrows, ncols, f64); // specify dtype=f64
double* host_ptr = af.host<double>();
arma::mat arma(host_ptr, nrows, ncols);
对于复杂的向量,它有点复杂。 Armadillo 使用 std::complex
而 ArrayFire 在底层使用不同的数据结构。这些应该兼容(针对您的系统进行验证),因此使用 reinterpret_cast
应该可以解决问题。
af::cfloat* host_ptr = img_af.host<af::cfloat>(); // Assuming dtype=c32
arma::cx_fmat arma(reinterpret_cast<std::complex<float>*>(host_ptr), nrows, ncols);
最后但同样重要的是,一定要释放主机指针,否则会发生内存泄漏!
af::freeHost(host_ptr);
我想用 ArrayFire
替换以前用 armadillo
编写的一些计算,以便使用一些 GPU 功能。我不想替换所有内容,只是时间紧迫的地方。因此,我需要将 armadillo
-结构转换为 arrayfire
-结构并返回。第一步很简单:
arma::colvec A_arma(5, arma::fill::ones);
af::array A_array(5, A_arma.memptr());//Done
回去更难。如何将数据从 arrayfire
-结构获取到 armadillo
-结构?我可以遍历所有元素并将它们写入 armadillo
结构,但这会花费很多时间。有没有更简单的方法?
您可以使用 host 成员函数从 af::array
中复制数据。例如,您可以将数据从 ArrayFire 数组复制到 std::vector
,如下所示:
af::array gpu_data = af::randu(10, 10);
vector<float> cpu_data(gpu_data.elements());
gpu_data.host<float>(cpu_data.data());
这会将列主顺序中的数据复制到 cpu_data
向量。
我不太熟悉犰狳的数据结构,但我相信你可以将 memptr
返回的指针传递给宿主函数,数据将被复制到其中。
您可以使用 ArrayFire 数组的 host
指针直接转换为犰狳结构。
size_t nrows = 10;
size_t ncols = 10;
af::array af = af::constant(0, nrows, ncols); // defaults to dtype=f32
float* host_ptr = af.host<double>();
arma::fmat arma(host_ptr, nrows, ncols);
请注意类型和大小需要匹配。在上述情况下,使用了单精度浮点类型。对于双精度,您必须更改为以下内容。
af::array af = af::constant(0, nrows, ncols, f64); // specify dtype=f64
double* host_ptr = af.host<double>();
arma::mat arma(host_ptr, nrows, ncols);
对于复杂的向量,它有点复杂。 Armadillo 使用 std::complex
而 ArrayFire 在底层使用不同的数据结构。这些应该兼容(针对您的系统进行验证),因此使用 reinterpret_cast
应该可以解决问题。
af::cfloat* host_ptr = img_af.host<af::cfloat>(); // Assuming dtype=c32
arma::cx_fmat arma(reinterpret_cast<std::complex<float>*>(host_ptr), nrows, ncols);
最后但同样重要的是,一定要释放主机指针,否则会发生内存泄漏!
af::freeHost(host_ptr);