-
Notifications
You must be signed in to change notification settings - Fork 114
How to use ir::For::Make in Compute? #892
Comments
嗨,首先回答issue的问题,从原理上,CINN的算子是由CINN形成,所以如你所说,直接用C++语言的for循环是无法形成IR For的,需要使用你问的ir::For 但是对于实现Argmin/max,这个操作和ReduceMin/Max很像,在一个范围内返回一个Min/Max,只是ReduceMin/Max返回的是最小/最大值,而Argmin/max返回的是最小/最大值对应的位置。 因此你可以跟踪ReduceMin/ReduceMax在ir::Expr层别的实现,相应从最小/最大值改为位置,然后在Compute中调用即可。 我所阐述的ReduceMin/Max代码位置在 Line 93 in 0431271
|
我在 ReduceMax中发现使用了 lang::ReduceMax,通过进一步查找发现调用的是ir::Reduce::Make,所以我应该直接修改ir::Reduce的实现,我这样理解是对的吗。 例如按我是否应该按如下方式修改,并相应修改其他的部分 struct Reduce : public ExprNode<Reduce> {
enum ReduceType {
kSum = 0,
kSub,
kMul,
kDiv,
kMax,
kMin,
kArgMax,
kArgMin
};
...
};
|
我认为可以,LGTM! |
我找到的最核心的实现部分是在tensor.cc中 Line 326 in 0431271
auto *reduce_node = body().As<ir::Reduce>();
if (reduce_node) {
final_body = reduce_node->body;
switch (reduce_node->reduce_type) {
case ir::Reduce::kSum:
final_body = Tensor(this)(g_axis) + final_body;
break;
case ir::Reduce::kMul:
final_body = Tensor(this)(g_axis) * final_body;
break;
case ir::Reduce::kMax:
final_body = Max::Make(Tensor(this)(g_axis), final_body);
break;
case ir::Reduce::kMin:
final_body = Min::Make(Tensor(this)(g_axis), final_body);
break;
case ir::Reduce::kArgmax:
auto cur_value = Tensor(this)(g_axis)
auto max_value = ...;
auto update = ir::GT::Make(cur_value, max_value);
final_body = ir::Select::Make(update, ..., final_body);
break;
default:
CINN_NOT_IMPLEMENTED
}
} 我参考其他的实现,直接使用了ir::Max::Make 等方法,但是其更加底层的实现我只找到了cuda的实现,但是对其如何联系起来的并不明确。 |
我在开发argmin算子时。参考了min等同类算子的实现方法后,发现这些全部都涉及到了更底层的开发,
需要改动的地方非常多,似乎不是本次任务所希望的实现方法。
开发中遇到的问题核心就是不知道在Compute中如何正确的使用与具体尺寸相关的循环,
若直接使用普通的for循环,对
shape
取值得到的是Expr(n)
,而使用for(Expr i = Expr(0); i< shape[aixs]; i++)
不能正确编译程序,于是考虑使用 ir::For,但是对其的原理不理解,不知道其 Expr类型的返回值的含义,编写如下代码仍然无法获得理想的结果。
我在对已经实现的所有compute中均未发现类似的可以参考的用法,多数都采用Reduce方法,但是Reduce只支持max/min/sum/mul等,如果要扩展需要修改较多底层的实现,似乎不是本次任务所希望的实现方法,
因此希望可以得到一个在compute中使用与具体尺寸相关的循环的例子参考,或者有一些其他方向上的指导。
The text was updated successfully, but these errors were encountered: