1

我正在尝试通过在 GPU 的线程上实现 for 循环来优化我的代码。我正在尝试使用推力::transform 消除两个 for 循环。C++ 中的代码如下所示:

    ka_index = 0;
    for (int i = 0; i < N_gene; i++)
    {
        for (int j = 0; j < n_ka_d[i]; j++ )
        {
            co0 = get_coeff0(ka_vec_d[ka_index]);
            act[i] += (co0*ka_val_d[ka_index]); 
            ka_index++;
        }
        act[i] = pow(act[i],n); 
    }

我正在估计上述循环中常微分方程(ODE)的系数,并已使用推力将所有数据传输到设备上。考虑基因数量由 N_gene 表示的情况。第一个 for 循环必须运行 N_gene 次。第二个 for 循环受每个基因的激活因子(基因库中的其他友好基因)数量的限制。每个基因都有许多激活因子(友好的基因,其存在会增加基因 i 的浓度),由 n_ka 载体的元素表示。n_ka[i] 的值可以在 0 到 N_gene - 1 之间变化。ka_val 表示每个激活器 ka 的激活量度。ka_vec_d 具有激活基因 i 的基因索引。

我正在尝试使用迭代器来表示这些循环,但无法这样做。我熟悉将thrust::for_each(thrust::make_zip_iterator(thrust::make_tuple)) 用于单个for循环,但是很难想出一种使用counting_iterator或transform迭代器来实现两个for循环的方法。任何转换这两个 for 循环的指针或帮助将不胜感激。谢谢你的时间!

4

1 回答 1

1

这看起来像一个减少问题。我认为您可以使用thrust::transformzip 迭代器和thrust::reduce_by_key. 该解决方案的草图是:

// generate indices
std::vector< int > hindices;
for( size_t i=0 ; i<N_gene ; ++i )
    for( size_t j=0 ; j<n_ka_d[i] ; ++j )
     hindices.push_back( i );
thrust::device_vector< int > indices = hindices;

// generate tmp
// trafo1 implements get_coeff0( get< 0 >( t ) ) * get< 1 >( t);
thrust::device_vector< double > tmp( N );
thrust::transform(
    thrust::make_zip_iterator(
        thrust::make_tuple( ka_vec_d.begin() , ka_val_d.begin() ) ) ,
    thrust::make_zip_iterator(
        thrust::make_tuple( ka_vec_d.end() , ka_val_d.end() ) ) ,
    tmp.begin() , trafo1 );

// do the reduction for each ac[i]
thrust::device_vector< int > indices_out( N );
thrust::reduce_by_key( indices.begin() , indices.end() , tmp.begin() ,
    ac.begin() , indices_out.begin() );

// do the pow transformation
thrust::transform( ac.begin() , ac.end() , ac.begin() , pow_trafo );

我这也可以通过 transform_iterators 进行优化,以减少thrust::transformand的调用次数thrust::recuce_by_key

于 2013-04-06T11:38:01.567 回答