-
Notifications
You must be signed in to change notification settings - Fork 263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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
.