-
Notifications
You must be signed in to change notification settings - Fork 277
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
add code reading about "PHI kernel registration" #794
Conversation
可以发现,主要是存了一下传入的`fn`和`variadic_fn`,因为`variadic_fn`不为空,所以`kernel_registered_type_`赋值为`KernelRegisteredType::FUNCTION`(看到这里涉及`structure`和`function`,猜测这块可能是兼容老的op体系用的?老的fluid体系为结构体算子,新的phi体系算子为函数式算子) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个猜测是对的
arg_type); | ||
``` | ||
|
||
从这里其实就可以知道,我们在算子注册的时候,输入变量的类型为什么必须严格带`const`,而且常常需要`DenseTensor`的指针了把。因为要在这里对上,才能顺利地把参数类型信息存到`args_def`中去。 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
错别字,了把 -> 了吧
|
||
所以在`args_def_fn(kernel_key, &kernel);`的时候,在这之前,由于注册时指定了`CPU`,所以`kernel_key`的backend是cpu,所以之前存入的参数`x`的backend就是cpu。现在就是”逆天改命“,把`x`的backend变成`ALL_BACKEND`;第二个也同理,注册的backend为gpu,也是在这时候改成`ALL_BACKEND`。 | ||
|
||
(思考:对一个输入tensor而言,他的backend(或者说,处在这个位置的参数的backend意味着什么?)这是否意味着,在调用算子进行计算的时候,框架自动对其backend进行检测?有的也对输出的dtype进行修改,可能这里会调整kernel允许输出的类别?譬如什么都不加,就是输入`T`输出`T`,加入类似于`kernel->OutputAt(0).SetDataType(phi::DataType::BOOL);`这种就是输入`T`,输出`bool`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为默认情况下我们认为所有输入和输出信息比如dtype或者backend这种一般是一致的,但并不是所有算子都是这样,有的存在这些信息不一致的情况,所以这里可以对其进行修改,修改后框架会对Tensor做相应的变换以满足处理条件
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
因为默认情况下我们认为所有输入和输出信息比如dtype或者backend这种一般是一致的,但并不是所有算子都是这样,有的存在这些信息不一致的情况,所以这里可以对其进行修改,修改后框架会对Tensor做相应的变换以满足处理条件
谢谢~,我在这里还有一个小疑问。就是在这里修改输入输出的datatype、backend、layout之后,然后注册到kernel_factory
中,会产生什么影响呢?
我暂时还没有仔细梳理调度流程,不过猜测在调用这个kernel的时候,会对传入的参数先进行检查嘛?例如在注册的时候:
kernel->InputAt(0).SetDataType(phi::DataType::BOOL);
kernel->OutputAt(0).SetDataType(phi::DataType::BOOL);
这样修改了第0个输入的Tensor和第0个输出的Tensor,是不是意味着调度的时候会预先检查输入和输出的dtype呢?
如果是的话,想问如果注册的时候限定了layout是如何做限制的呢?毕竟我们调用的时候就是传入一个paddle.to_tensor([1,2,3])
这样的tensor,看上去不带什么layout的信息。
还有,如果是修改了输出的SetDataType
,那么在kernel中,我们通过dev_ctx.template Alloc<T>(out);
的方法来为输出申请内存,这里的T
是会受到什么限制吗?
(我之前在写一个kernel的时候,没有特意设置输出的SetDataType
,所以应该是默认的情况,也就是注册的时候,输入输出的dtype是相同的。但是似乎我只要在dev_ctx.template Alloc<T>(out);
为输出申请内存的时候,把T
改成其他cpp type(例如T
为int32,然后把申请输出空间的时候 Alloc<T>
改成 Alloc<float32>
),就可以实现“接收int32
输入,计算输出"float32""这样的操作。这样看来,虽然我是默认的DataType,但是似乎没有限制我的输出必须和输入相同,所以对”注册时,对输入输出dtype、backend、layout的作用比较疑惑“)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你可以理解成是一种检查,但实际情况比较复杂,需要根据这里的信息判断是否要做transform,具体需要熟悉了调度流程才会明白,layout的话其实我们现在一般都是用的ALL_LAYOUT,也就是默认情况,只有一些sparse kernel会对其进行修改,设置成SPARSE_COO等格式,以满足sparse kernel的执行条件
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你可以理解成是一种检查,但实际情况比较复杂,需要根据这里的信息判断是否要做transform,具体需要熟悉了调度流程才会明白,layout的话其实我们现在一般都是用的ALL_LAYOUT,也就是默认情况,只有一些sparse kernel会对其进行修改,设置成SPARSE_COO等格式,以满足sparse kernel的执行条件
ok明白了~
#define PD_EXPAND(x) x | ||
``` | ||
|
||
看样子它直接返回了输入?具体为什么加这个,还不太清楚。它包了一层`_PD_REGISTER_2TA_KERNEL` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里加这个主要是由于嵌套宏有时候无法正常展开,比如带有##连接的时候,多使用一个额外的宏包裹一下,比如这里的PD_EXPAND,可以让嵌套宏能够正常展开
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以举个具体例子嘛?
PD_EXPAND(PD_KERNEL_REGISTRAR_INIT( \
reg_type, \
kernel_name, \
backend, \
context, \
layout, \
&__PD_KERNEL_args_def_FN_##kernel_name##_##backend##_##layout, \
meta_kernel_fn, \
arg_parse_functor_macro, \
kernel_unfold_macro, \
variadic_kernel_unfold_marco, \
__VA_ARGS__)); \
我看这部分连接的__PD_KERNEL_args_def_FN_##kernel_name##_##backend##_##layout
,但是kernel_name
,backend
,layout
应该是实打实的参数,不是#define kernel_name xxx
这样需要展开的吧。
不太清楚为什么需要EXPAND一层
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
嵌套宏展开比较复杂,不同平台不同编译器的处理情况可能不一样,PD_EXPAND这里虽然并不是我设计的,但是我这边理解应该就是这个作用,你可以提交一个pr把所有PD_EXPAND删了,看看ci上会不会有什么问题
Add "PHI kernel registration" in
./pfcc/paddle-code-reading
.