我正在Halide中实现径向基函数,虽然我已经成功运行但它很慢。对于每个像素,我计算距离,然后采用该距离的加权和来产生输出。要循环权重,我使用RDom(如下所示)。在此实现中,每个像素计算都需要重新加载所有(3000+)个权重,因此速度很慢。
我的问题是如何在此实例中利用Halide的调度功能。我的愿望是加载一些权重,计算像素子集的部分加权和,加载下一组权重,然后继续完成。这样可以保持每个较小的权重组的位置,而这种情况正是Halide所构建的。不幸的是,我找不到任何针对这个特定问题的东西。 RDom似乎处于比调度原语更低的抽象层次,因此不清楚如何安排这个。
欢迎任何有关Halide加权和实施的替代建议。不需要使用RDom,我只是不知道任何其他方式。
Func rbf_ctrl_pts("rbf_ctrl_pts");
// Initialization with all zero
rbf_ctrl_pts(x,y,c) = cast<float>(0);
// Index to iterate with
RDom idx(0,num_ctrl_pts);
// Loop code
// Subtract the vectors
Expr red_sub = (*in_func)(x,y,0) - (*ctrl_pts_h)(0,idx);
Expr green_sub = (*in_func)(x,y,1) - (*ctrl_pts_h)(1,idx);
Expr blue_sub = (*in_func)(x,y,2) - (*ctrl_pts_h)(2,idx);
// Take the L2 norm to get the distance
Expr dist = sqrt( red_sub*red_sub +
green_sub*green_sub +
blue_sub*blue_sub );
// Update persistant loop variables
rbf_ctrl_pts(x,y,c) = select( c == 0, rbf_ctrl_pts(x,y,c) +
( (*weights_h)(0,idx) * dist),
c == 1, rbf_ctrl_pts(x,y,c) +
( (*weights_h)(1,idx) * dist),
rbf_ctrl_pts(x,y,c) +
( (*weights_h)(2,idx) * dist));
答案 0 :(得分:1)
您可以在rbf_ctrl_pts的idx维度中使用split或tile和rfactor来计算和计划缩减操作。通过这些机制可以实现权重的局部性。我并非100%确定关联证明者将处理选择,因此可能需要按频道展开或移动到跨频道使用元组,尽管在上面的代码中,我不确定选择与传递c相比,它正在做任何事情。