Alternating Error: "Invalid dimension for argument 0"
Alternating Error: "Invalid dimension for argument 0"
正在将下面的示例转换为 gfor 循环。我遇到了 "Invalid dimension for argument 0" 类型的错误,下面是完整的错误消息。但是,错误发生,然后函数运行,然后同样的错误。这种模式重复。我很困惑,想知道这个错误是否与系统有关。
完整的错误信息:
Error in random_shuffle(theta, 5, 1) :
ArrayFire Exception (Invalid input size:203):
In function af_err af_assign_seq(af_array *, const af_array, const unsigned int, const af_seq *, const af_array)
In file src/api/c/assign.cpp:168
Invalid dimension for argument 0
Expected: (outDims.ndims() >= inDims.ndims())
第二个问题,当使用 gfor 循环时,种子无法随输入参数改变。
#include "RcppArrayFire.h"
using namespace Rcpp;
using namespace RcppArrayFire;
// [[Rcpp::export]]
af::array random_shuffle(const RcppArrayFire::typed_array<f64> theta, int counts, int seed){
const int theta_size = theta.dims()[0];
af::array out(counts, theta_size, f64);
af::array seed_seq = af::seq(seed, seed+counts);
// for(int f = 0; f < counts; f++){
gfor ( af::seq f, counts-1 ){
af::randomEngine engine;
engine.setSeed(af::sum<double>(seed_seq(f)));
af::array index_shuffle(1, u16);
af::array temp_rand(1, f64);
af::array temp_end(1, f64);
af::array shuffled = theta;
// implementation of the Knuth-Fisher-Yates shuffle algo
for(int i = theta_size-1; i > 1; i --){
index_shuffle = af::round(af::randu(1, u16, engine)/(65536/(i+1)));
temp_rand = shuffled(index_shuffle);
temp_end = shuffled(i);
shuffled(index_shuffle) = temp_end;
shuffled(i) = temp_rand;
}
out(f, af::span) = shuffled;
}
return out;
}
/*** R
theta <- 10:20
random_shuffle(theta, 5, 1)
random_shuffle(theta, 5, 2)
*/
更新了 Ralf Stunber 的解决方案,但 'shuffled' 列 space 中的示例。
// [[Rcpp::export]]
af::array random_shuffle2(const RcppArrayFire::typed_array<f64> theta, int counts, int seed) {
int len = theta.dims(0);
af::setSeed(seed);
af::array tmp = af::randu(len, counts, 1);
af::array val, idx;
af::sort(val, idx, tmp, 1);
af::array shuffled = theta(idx);
return af::moddims(shuffled, len, counts);
}
/*** R
random_shuffle2(theta, 5, 1)
*/
这是输出图片,带替换采样:
在第二部分中,在 50 次重复中,样本朝着无反应的结果发展。
为什么要并行使用多个RNG引擎?真的没有这个必要。一般来说,只使用全局RNG引擎应该就足够了。只设置一次该引擎的种子也应该足够了。您可以使用 RcppArrayFire::arrayfire_set_seed
从 R 执行此操作。此外,gfor
循环中的随机数生成并不像人们预期的那样工作,c.f。 http://arrayfire.org/docs/page_gfor.htm.
无论如何,我不是编写高效 GPU 算法的专家,这就是为什么我喜欢使用 ArrayFire 等库中实现的方法。不幸的是,ArrayFire 没有洗牌算法,但相应的问题有一个 nice implementation,可以将其推广到你的情况下多次洗牌:
// [[Rcpp::depends(RcppArrayFire)]]
#include "RcppArrayFire.h"
// [[Rcpp::export]]
af::array random_shuffle(const RcppArrayFire::typed_array<f64> theta, int counts, int seed) {
int len = theta.dims(0);
af::setSeed(seed);
af::array tmp = af::randu(counts, len, 1);
af::array val, idx;
af::sort(val, idx, tmp, 1);
af::array shuffled = theta(idx);
return af::moddims(shuffled, counts, len);
}
顺便说一句,根据以后的使用情况,将不同的样本排列成列而不是行可能更有意义,因为 R 和 AF 都使用列主要布局。
正在将下面的示例转换为 gfor 循环。我遇到了 "Invalid dimension for argument 0" 类型的错误,下面是完整的错误消息。但是,错误发生,然后函数运行,然后同样的错误。这种模式重复。我很困惑,想知道这个错误是否与系统有关。
完整的错误信息:
Error in random_shuffle(theta, 5, 1) :
ArrayFire Exception (Invalid input size:203):
In function af_err af_assign_seq(af_array *, const af_array, const unsigned int, const af_seq *, const af_array)
In file src/api/c/assign.cpp:168
Invalid dimension for argument 0
Expected: (outDims.ndims() >= inDims.ndims())
第二个问题,当使用 gfor 循环时,种子无法随输入参数改变。
#include "RcppArrayFire.h"
using namespace Rcpp;
using namespace RcppArrayFire;
// [[Rcpp::export]]
af::array random_shuffle(const RcppArrayFire::typed_array<f64> theta, int counts, int seed){
const int theta_size = theta.dims()[0];
af::array out(counts, theta_size, f64);
af::array seed_seq = af::seq(seed, seed+counts);
// for(int f = 0; f < counts; f++){
gfor ( af::seq f, counts-1 ){
af::randomEngine engine;
engine.setSeed(af::sum<double>(seed_seq(f)));
af::array index_shuffle(1, u16);
af::array temp_rand(1, f64);
af::array temp_end(1, f64);
af::array shuffled = theta;
// implementation of the Knuth-Fisher-Yates shuffle algo
for(int i = theta_size-1; i > 1; i --){
index_shuffle = af::round(af::randu(1, u16, engine)/(65536/(i+1)));
temp_rand = shuffled(index_shuffle);
temp_end = shuffled(i);
shuffled(index_shuffle) = temp_end;
shuffled(i) = temp_rand;
}
out(f, af::span) = shuffled;
}
return out;
}
/*** R
theta <- 10:20
random_shuffle(theta, 5, 1)
random_shuffle(theta, 5, 2)
*/
更新了 Ralf Stunber 的解决方案,但 'shuffled' 列 space 中的示例。
// [[Rcpp::export]]
af::array random_shuffle2(const RcppArrayFire::typed_array<f64> theta, int counts, int seed) {
int len = theta.dims(0);
af::setSeed(seed);
af::array tmp = af::randu(len, counts, 1);
af::array val, idx;
af::sort(val, idx, tmp, 1);
af::array shuffled = theta(idx);
return af::moddims(shuffled, len, counts);
}
/*** R
random_shuffle2(theta, 5, 1)
*/
这是输出图片,带替换采样:
在第二部分中,在 50 次重复中,样本朝着无反应的结果发展。
为什么要并行使用多个RNG引擎?真的没有这个必要。一般来说,只使用全局RNG引擎应该就足够了。只设置一次该引擎的种子也应该足够了。您可以使用 RcppArrayFire::arrayfire_set_seed
从 R 执行此操作。此外,gfor
循环中的随机数生成并不像人们预期的那样工作,c.f。 http://arrayfire.org/docs/page_gfor.htm.
无论如何,我不是编写高效 GPU 算法的专家,这就是为什么我喜欢使用 ArrayFire 等库中实现的方法。不幸的是,ArrayFire 没有洗牌算法,但相应的问题有一个 nice implementation,可以将其推广到你的情况下多次洗牌:
// [[Rcpp::depends(RcppArrayFire)]]
#include "RcppArrayFire.h"
// [[Rcpp::export]]
af::array random_shuffle(const RcppArrayFire::typed_array<f64> theta, int counts, int seed) {
int len = theta.dims(0);
af::setSeed(seed);
af::array tmp = af::randu(counts, len, 1);
af::array val, idx;
af::sort(val, idx, tmp, 1);
af::array shuffled = theta(idx);
return af::moddims(shuffled, counts, len);
}
顺便说一句,根据以后的使用情况,将不同的样本排列成列而不是行可能更有意义,因为 R 和 AF 都使用列主要布局。