首页> 中国专利> 算子注册方法和相关产品

算子注册方法和相关产品

摘要

本申请实施例公开了一种算子注册方法和相关产品,该方法包括:编译注册配置文件,得到目标算子对应的类;将所述目标算子对应的类和推断函数添加到注册表;所述推断函数用于推断所述目标算子的输出的形状。本申请实施例中,编译注册配置文件就能得到目标算子对应的类,不需要为算子定义一个类,能够提高向计算库中添加算子的效率、操作简单。

著录项

  • 公开/公告号CN112558942A

    专利类型发明专利

  • 公开/公告日2021-03-26

    原文格式PDF

  • 申请/专利权人 上海商汤智能科技有限公司;

    申请/专利号CN202011525682.X

  • 发明设计人 王志宏;李慧星;肖波;

    申请日2020-12-22

  • 分类号G06F8/20(20180101);G06F8/41(20180101);G06F8/71(20180101);

  • 代理机构44202 广州三环专利商标代理有限公司;

  • 代理人熊永强;董文俊

  • 地址 200233 上海市徐汇区桂平路391号3号楼1605A室

  • 入库时间 2023-06-19 10:24:22

说明书

技术领域

本申请涉及计算机领域,尤其涉及一种算子注册方法和相关产品。

背景技术

计算库中算子的数量是衡量其计算能力的重要指标之一。目前,向一个计算库中添加一个算子的效率较低。因此需要研究效率更高的向计算库中添加算子的方案。

发明内容

本申请实施例公开了一种算子注册方法和相关产品,能够解决向计算库中添加算子的效率较低的技术问题。

第一方面,本申请实施例提供了一种算子的注册方法,该方法包括:编译注册配置文件,得到目标算子对应的类;将所述目标算子对应的类和推断函数添加到注册表;所述推断函数用于推断所述目标算子的输出的形状。

当前采用的向计算库中添加算子的方案如下:1、为算子定义一个类,该类用于向不同的计算后端进行派遣;2、将1中为算子定义的类加入到注册表中;3、为算子添加对应的测试。也就是说,用户需要定义算子的类。本申请中,通过编译注册配置文件就能得到目标算子对应的类,即自动生成算子的类,不需要为算子定义一个类,操作简单。

本申请实施例中,编译注册配置文件就能得到目标算子对应的类,不需要为算子定义一个类,能够提高向计算库中添加算子的效率、操作简单。

在一个可能的实现方式中,所述编译注册配置文件,得到目标算子对应的类包括:解析所述注册配置文件以得到注册配置信息;所述注册配置信息包括所述目标算子的名称、所述目标算子的输入参数、所述目标算子的输出参数以及所述目标算子对应的核函数;基于所述注册配置信息,生成所述目标算子对应的类;所述目标算子对应的类用于调用所述目标算子对应的核函数做处理得到所述目标算子的输出。

在该实现方式中,利用解析注册配置文件得到的注册配置信息,生成目标算子对应的类;可以自动快速地生成目标算子对应的类。

在一个可能的实现方式中,所述注册配置信息还包括第一配置信息,所述第一配置信息指示所述目标算子对应的至少一个核函数调用参数的顺序。

在该实现方式中,第一配置信息指示目标算子对应的至少一个核函数调用参数的顺序,可以快速、准确地生成相应的核函数。

在一个可能的实现方式中,所述注册配置信息还包括所述推断函数的名称;在解析所述注册配置文件以得到注册配置信息之后,所述方法还包括:基于所述推断函数的名称以及所述目标算子的名称,生成注册代码;所述注册代码用于关联所述目标算子对应的类和所述推断函数。

在该实现方式中,可以快速、准确地将目标算子对应的类和所述推断函数做关联。

在一个可能的实现方式中,所述注册配置信息还包括第二配置信息;在所述解析所述注册配置文件以得到注册配置信息之后,所述方法还包括;基于所述第二配置信息,生成所述推断函数;关联所述推断函数和所述目标算子对应的类。

在该实现方式中,可以根据第二配置信息,生成所需的推断函数;

在一个可能的实现方式中,所述推断函数包括第二代码,所述基于所述第二配置信息,生成所述推断函数包括:基于所述第二配置信息中的第一代码,生成所述第二代码;所述第一代码与所述第二代码存在至少部分相同的代码,所述第二代码为用于推断所述目标算子的输出的形状的代码。

在该实现方式中,基于第二配置信息,生成推断函数;使得用户能够按照自己的需求生成所需的推断函数,可满足不同的用户需求。

在一个可能的实现方式中,所述推断函数包括第四代码,所述基于所述第二配置信息,生成所述推断函数包括:基于所述第二配置信息中的第三代码,生成所述第四代码;所述第四代码用于在调用时检查所述第三代码指示的待检查的参数。

在该实现方式中,基于第二配置信息中的第三代码,生成第四代码;使得生成的推断函数在被调用时可检查待检测的参数。

在一个可能的实现方式中,在所述编译注册配置文件,得到目标算子对应的类之前,所述方法还包括:根据用户的第一操作,生成所述注册配置文件;所述第一操作为在原始注册配置文件中添加一个或多个参数的操作,所述一个或多个参数基于所述目标算子区别于其他算子的部分,经抽象处理得到。

在该实现方式中,根据用户的第一操作,在原始注册配置文件添加一个或多个参数,就能生成注册配置文件,不需要编写整个注册配置文件,可以快速地生成注册配置文件,能够解决算子添加中重复代码过多的问题。

在一个可能的实现方式中,所述方法还包括:使用第一框架解析测试配置文件,得到测试数据并保存;所述测试数据包含测试目标函数所需的数据,所述目标函数为所述目标算子中的第一函数;使用所述第一框架利用所述测试数据对所述目标函数做测试,得到第一测试结果并保存;使用第二框架读取并利用所述测试数据对所述目标函数做测试,得到第二测试结果;所述第二框架和所述第一框架不同;基于所述第一测试结果和所述第二测试结果,得到目标测试结果;所述目标测试结果为指示所述目标函数通过或未通过测试。所述目标函数为所述目标算子中的任意函数。

在该实现方式中,可实现自动化测试,测试效率高。

在一个可能的实现方式中,所述测试配置文件包括生成规则;所述使用第一框架解析测试配置文件,得到测试数据并保存包括:使用所述第一框架按照所述生成规则,生成所述测试数据并保存。

在该实现方式中,按照生成规则,生成测试数据;能够快速地生成不同的测试样例。

在一个可能的实现方式中,所述测试配置文件还包括测试程序执行逻辑配置信息,所述测试程序执行逻辑配置信息用于生成测试所述目标函数的测试程序的执行逻辑;所述使用第一框架解析测试配置文件,得到测试数据并保存包括:使用所述第一框架按照所述生成规则以及所述测试程序执行逻辑配置信息,生成所述测试数据并保存;所述测试数据包含测试所述目标函数的测试程序的执行逻辑。

在该实现方式中,按照配置的生成规则和测试程序的执行逻辑进行自动化测试,可以提高测试效率。

在一个可能的实现方式中,所述测试配置文件中的以字符串的形式定义的函数指示所述生成规则。

在该实现方式中,允许用户在定义张量(tensor)的生成规则和测试程序执行逻辑的时候插入python代码。用户可以在测试配置文件中以字符串的形式定义函数来指定生成规则,以确保测试的边界情况。

在一个可能的实现方式中,在所述使用第一框架解析测试配置文件,得到测试数据并保存之前,所述方法还包括:根据用户的第二操作,生成所述测试配置文件;所述第二操作用于在原始测试配置文件中添加所述测试数据的格式和生成规则的操作,所述生成规则用于生成所述测试数据。

在该实现方式中,在原始测试配置文件中添加测试数据的格式和生成规则的操作,能够按照需求快速地生成能够生成所需测试数据的测试配置文件。

在一个可能的实现方式中,所述第一框架为pytorch框架,所述第二框架为parrots框架;或者,所述第一框架为parrots框架,所述第二框架为pytorch框架。

第二方面,本申请实施例提供了一种算子注册装置,包括:第一处理单元,用于编译注册配置文件,得到目标算子对应的类;第二处理单元,用于将所述目标算子对应的类和推断函数添加到注册表;所述推断函数用于推断所述目标算子的输出的形状。

在一个可能的实现方式中,所述第一处理单元,具体用于解析所述注册配置文件以得到注册配置信息;所述注册配置信息包括所述目标算子的名称、所述目标算子的输入参数、所述目标算子的输出参数以及所述目标算子对应的核函数;基于所述注册配置信息,生成所述目标算子对应的类;所述目标算子对应的类用于调用所述目标算子对应的核函数做处理得到所述目标算子的输出。

在一个可能的实现方式中,所述注册配置信息还包括第一配置信息,所述第一配置信息指示所述目标算子对应的至少一个核函数调用参数的顺序。

在一个可能的实现方式中,所述注册配置信息还包括所述推断函数的名称;所述第一处理单元,还用于基于所述推断函数的名称以及所述目标算子的名称,生成注册代码;所述注册代码用于关联所述目标算子对应的类和所述推断函数。

在一个可能的实现方式中,所述注册配置信息还包括第二配置信息;所述第一处理单元,还用于基于所述第二配置信息,生成所述推断函数;关联所述推断函数和所述目标算子对应的类。

在一个可能的实现方式中,所述推断函数包括第二代码,所述第一处理单元,具体用于基于所述第二配置信息中的第一代码,生成所述第二代码;所述第一代码与所述第二代码存在至少部分相同的代码,所述第二代码为用于推断所述目标算子的输出的形状的代码。

在一个可能的实现方式中,所述推断函数包括第四代码,所述第一处理单元,具体用于基于所述第二配置信息中的第三代码,生成所述第四代码;所述第四代码用于在调用时检查所述第三代码指示的待检查的参数。

在一个可能的实现方式中,所述第一处理单元,还用于根据用户的第一操作,生成所述注册配置文件;所述第一操作为在原始注册配置文件中添加一个或多个参数的操作,所述一个或多个参数基于所述目标算子区别于其他算子的部分,经抽象处理得到。

在一个可能的实现方式中,所述第一处理单元,还用于使用第一框架解析测试配置文件,得到测试数据并保存;所述测试数据包含测试目标函数所需的数据,所述目标函数为所述目标算子中的第一函数;使用所述第一框架利用所述测试数据对所述目标函数做测试,得到第一测试结果并保存;使用第二框架读取并利用所述测试数据对所述目标函数做测试,得到第二测试结果;所述第二框架和所述第一框架不同;基于所述第一测试结果和所述第二测试结果,得到目标测试结果;所述目标测试结果为指示所述目标函数通过或未通过测试。所述目标函数为所述目标算子中的任意函数。

在一个可能的实现方式中,所述测试配置文件包括生成规则;所述第一处理单元,具体用于使用所述第一框架按照所述生成规则,生成所述测试数据并保存。

在一个可能的实现方式中,所述测试配置文件还包括测试程序执行逻辑配置信息,所述测试程序执行逻辑配置信息用于生成测试所述目标函数的测试程序的执行逻辑;所述第一处理单元,具体用于使用所述第一框架按照所述生成规则以及所述测试程序执行逻辑配置信息,生成所述测试数据并保存;所述测试数据包含测试所述目标函数的测试程序的执行逻辑。

在一个可能的实现方式中,所述测试配置文件中的以字符串的形式定义的函数指示所述生成规则。

在一个可能的实现方式中,所述第一处理单元,还用于根据用户的第二操作,生成所述测试配置文件;所述第二操作为在原始测试配置文件中添加所述测试数据的格式和生成规则的操作,所述生成规则用于生成所述测试数据。

在一个可能的实现方式中,所述第一框架为pytorch框架,所述第二框架为parrots框架;或者,所述第一框架为parrots框架,所述第二框架为pytorch框架。

关于第二方面或各种可选的实施方式所带来的技术效果,可参考对于第一方面或相应的实现方式的技术效果的介绍。

第三方面,本申请实施例提供了一种电子设备,该电子设备包括:处理器和存储器,其中,所述存储器用于存储指令,所述处理器用于执行所述存储器存储的指令,使得所述处理器执行如上述第一方面以及任一种可能的实现方式的方法。

第四方面,本申请实施例提供了一种芯片,该芯片包括数据接口和处理器,其中,所述处理器用于执行第一方面或第一方面的任意可能的实现方式中的方法。

第五方面,本申请实施例提供了一种计算机可读存储介质,该计算机存储介质存储有计算机程序,该计算机程序包括程序指令,该程序指令当被处理器执行时使该处理器执行上述第一方面以及上述第一方面任一种可选的实现方式的方法。

第六方面,本申请实施例提供了一种计算机程序产品,该计算机程序产品包括程序指令,所述程序指令当被处理器执行时使所述处理器执行上述第一方面以及任一种可选的实现方式的方法。

附图说明

为了更清楚地说明本申请实施例或背景技术中的技术方案,下面将对本申请实施例或背景技术中所需要使用的附图进行说明。

图1为本申请实施例提供的一种算子注册方法流程图;

图2为本申请实施例提供的另一种算子注册方法流程图;

图3为本申请实施例提供的另一种算子注册方法流程图;

图4为本申请实施例提供的一种测试方法流程图;

图5为本申请实施例提供的一种自动化测试过程示意图;

图6为本申请实施例提供的一种算子注册装置的结构示意图;

图7为本申请实施例提供的一种终端设备的结构示意图。

具体实施方式

本申请的说明书实施例和权利要求书及附图中的术语“第一”、“第二”、和“第三”等是用于区别类似的对象,而不必用于描述特定的顺序或先后次序。此外,术语“包括”和“具有”以及他们的任何变形,意图在于覆盖不排他的包含,例如,包含了一系列步骤或单元。方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。

目前,向计算库中添加一个算子通常需要以下三个步骤:1)、为算子定义一个类,该类用于向不同的计算后端进行派遣;2)、将为算子定义的类加入到注册表中;3)、为算子添加对应的测试。通常情况下,编写测试文件的时候会首先使用pytorch框架生成测试数据,然后将测试数据和使用pytorch框架做测试得到的测试结果保存在硬盘上,在测试的时候使用parrots框架读取数据并测试,最后和pytorch的测试结果进行对比。pytorch框架是一个基于python语言的深度学习框架,基本上,它所有的程序都是用python写的,这就使得它的源码看上去比较简洁,在机器学习领域中有广泛的应用。python是一种跨平台的计算机程序设计语言,也是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。parrots框架是一种有python的接口的深度学习框架。

在为算子定义类的时候,不同的算子存在着大量重复的代码,当相关框架发生改变的时候,就要将所有已经定义好的类做出相应的改变。每个算子的类都要进行注册,当修改算子的名称的时候,需要在注册处做出对应的修改。除此之外,测试的时候需要开发者手动地去编写测试文件并生成测试样例,其步骤非常繁琐,而且测试样例生成后不再改变,造成测试样例不完全。测试样例生成后不再改变(即不能增加新的测试样例),利用已生成的测试样例可能无法完全所有的测试工作,这样就会造成测试样例不完全。

由于问题,算子添加的效率非常低,开发者和代码审阅者都需要花费大量的时间来确保代码的正确性。因此需要研究算子添加效率更高的方案。本申请提供了算子添加效率更高的算子注册方法。下面分别对申请实施例提供的算子注册方法适用的场景进行简单的介绍。

算子注册场景:算子注册装置使用自动化注册框架将算子开发过程中任意算子区别于其他算子的部分抽象成注册配置文件中的参数;使用自动化注册框架编译注册配置文件,自动地生成相应的算子类(即算子对应的类),并完成该算子的注册;通过python配置文件定义出一套测试方案,然后使用python代码解析配置文件,并且使用pytorch框架执行一次测试项,将测试数据和测试结果存储到硬盘中;然后再使用parrots框架根据各个测试样例读取测试数据,执行测试项,并将parrots框架的测试结果和pytorch框架的测试结果做对比。

采用本申请提供的算子注册方法,可以大幅度降低算子开发的代码量,减轻代码审阅的负担,提高算子开发的效率。

下面结合附图来介绍本申请实施例提供的算子注册方法。

请参见图1,图1为本申请实施例提供的一种算子注册方法流程图。如图1所示,该方法可包括:

101、算子注册装置编译注册配置文件,得到目标算子对应的类。

算子注册装置可以是台式电脑、笔记本电脑以及其他具备数据处理能力的终端设备。在一些实施例中,研发人员(或者用户)将算子开发过程中目标算子(任一算子或是指定的一个算子)区别于其他算子的部分抽象成注册配置文件中的参数,得到注册配置文件。在一些实施例中,注册配置文件是一种yaml文件(即使用yaml写的配置文件),算子注册装置使用自动化注册框架编译注册配置文件,得到目标算子对应的类。YAML(即yaml)是专门用来写配置文件的语言,非常简洁和强大。

在一些实施例中,步骤101一种可能的实现方式如下:解析注册配置文件以得到注册配置信息,注册配置信息包括目标算子的名称、目标算子的输入参数、目标算子的输出参数以及目标算子对应的核函数;基于注册配置信息,生成目标算子对应的类;目标算子对应的类可调用目标算子对应的核函数做处理得到目标算子的输出。在一些实施例中,注册配置信息还包括第一配置信息,第一配置信息指示目标算子对应的至少一个核函数调用参数的顺序。在一些实施例中,注册配置信息还包括推断函数的名称;算子注册装置在解析注册配置文件以得到注册配置信息之后,可执行如下操作:基于推断函数的名称以及目标算子的名称,生成注册代码;注册代码用于关联目标算子对应的类和推断函数。关联目标算子对应的类和推断函数可理解为将用于推断目标算子的输出的形状的推断函数与该目标算子对应的类关联起来。算子注册装置在关联目标算子对应的类和推断函数之后,可将该目标算子对应的类和推断函数添加到注册表,即完成目标算子的注册。

在一些实施例中,注册配置信息还包括第二配置信息;算子注册装置在解析注册配置文件以得到注册配置信息之后,可执行如下操作:基于第二配置信息,生成推断函数;关联推断函数和目标算子对应的类。在一些实施例中,推断函数包括第二代码,基于第二配置信息,生成推断函数包括:基于第二配置信息中的第一代码,生成第二代码;第一代码与第二代码存在至少部分相同的代码,第二代码为用于推断目标算子的输出的形状的代码。举例来说,第二配置信息中的第一代码为calculate:outSpecs[0]=DArraySpec::scalar(inSpecs[0].elemType());推断函数包括第二代码为outSpecs[0]=DArraySpec::scalar(inSpecs[0].elemType())。在一些实施例中,推断函数包括第四代码,基于第二配置信息,生成推断函数包括:基于第二配置信息中的第三代码,生成第四代码;第四代码用于在调用时检查第三代码指示的待检查的参数。举例来说,第三代码用于指示推断函数中待检查的参数,第四代码通过PARROTS_CHECKARGS这一宏定义检测该第三代码指示的待检查的参数。后续结合示例再详述步骤101的实现方式,这里先不对步骤101的实现方式作进一步详述。

102、算子注册装置将目标算子对应的类和推断函数添加到注册表。

推断函数用于推断目标算子的输出的形状。步骤101和步骤102可理解为:算子注册装置将目标算子添加至算子库的实现方式。

在一些实施例中,算子注册装置在执行步骤101之后,还可执行如下步骤:使用第一框架解析测试配置文件,得到测试数据并保存,测试数据包含测试目标函数所需的数据,目标函数为目标算子中的任一函数或是指定的一个函数;使用第一框架利用测试数据对目标函数做测试,得到第一测试结果并保存;使用第二框架读取并利用测试数据对目标函数做测试,得到第二测试结果;第二框架和第一框架不同;基于第一测试结果和第二测试结果,得到目标测试结果;目标测试结果为指示目标函数通过或未通过测试。对目标函数做测试可以理解为对目标算子做测试,即对目标算子对应的函数接口做测试。在一些实施例中,目标函数为目标算子对应的核函数。其中,第一框架与第二框架不同。

测试配置文件可以是python配置文件。在一些实施例中,测试配置文件包括生成规则;使用第一框架解析测试配置文件,得到测试数据并保存可以是:使用第一框架按照生成规则,生成测试数据并保存。在一些实施例中,测试配置文件还包括测试程序执行逻辑配置信息,测试程序执行逻辑配置信息用于生成测试目标函数的测试程序的执行逻辑;使用第一框架解析测试配置文件,得到测试数据并保存可以是:使用第一框架按照生成规则以及测试程序执行逻辑配置信息,生成测试数据并保存;测试数据包含测试目标函数的测试程序的执行逻辑。算子注册装置可按照测试目标函数的测试程序的执行逻辑进行测试。第一框架可以是pytorch框架,第二框架可以是parrots框架。在一些实施例中,算子注册装置使用自动化测试框架对parrots的接口进行测试,即对目标算子中的函数进行测试。在一些实施例中,算子注册装置的测试方案是通过python配置文件(即测试配置文件)定义出一套测试方案,一种可能的测试过程如下:使用python代码解析测试配置文件,并且使用pytorch框架(对应于第一框架)执行一次测试项,并将测试数据和测试结果存储到硬盘或者临时文件中;使用parrots框架(对应于第二框架)根据各个测试样例(对应于函数接口)读取测试数据,执行测试项并将parrots框架的测试结果和pytorch框架的测试结果做对比。

本申请实施例中,算子注册装置编译注册配置文件就能得到目标算子对应的类,不需要为算子定义一个类,能够提高向计算库中添加算子的效率、操作简单。

图2为本申请实施例提供的另一种算子注册方法流程图。图2中的方法流程是对图1中的方法流程的细化和完善。如图2所示,该方法包括:

201、算子注册装置解析注册配置文件以得到注册配置信息。

注册配置信息包含抽象出的目标算子(任一算子或是指定的一个算子)区别于其他算子的参数。也就是说,注册配置信息包含算子注册装置生成目标算子所需的全部参数和/或信息。

在一些实施例中,算子注册装置在执行步骤201之前,可执行如下操作:该算子注册装置根据用户的第一操作,生成注册配置文件;第一操作为在原始注册配置文件中添加一个或多个参数的操作,一个或多个参数基于目标算子区别于其他算子的部分,经抽象处理得到。原始注册配置文件可预先配置有一些基本的配置信息(例如生成任意算子都必不可少的配置信息),用户在原始注册配置文件中添加一个或多个参数的操作可理解为将该原始注册配置文件调整为编译得到目标算子对应的类的注册配置文件。在实际应用中,开发人员将算子开发过程中每个算子区别于其他算子的部分抽象成注册配置文件中的参数。在编译的时候,算子注册装置可以根据注册配置文件,自动地生成相应的算子类(即算子对应的类),并完成该算子的注册。

算子(operator)的输出通常为它所对应的核函数(kernel function)的输出。当算子注册装置需要生成一个算子的时候,需要提供该算子对应的推断(infer)函数和核函数。简单来说,推断函数用来为核函数的输出做一个早期的内存空间开辟,这样当核函数计算结束它的输出就能直接利用这片内存。下面以addc这个算子的生成为例,介绍如何实现将算子添加至计算库。

(1)下面是算子注册装置自动生成addc这个算子需要的注册配置信息的示例:

1.addc: #(1)算子的名称

2.ins:in #(2)算子的输入中属于张量类型的部分,可能有多个

3.outs:out #(3)算子的输出中属于张量类型的部分,可能有多个

4.attr:c #(4)算子的输入中的属于其他类型的部分,可能有多个

5.inferfunc:inferUnaryOp #(5)算子对应的推断函数名称,用于推断函数输出的规格,可以没有

6.dispatch: #(6)算子对应的核函数,可能有多个

7.native:addc(ctx,c,in,out)#(7)native后端表示这是一个计算库本身的核函数

可以看到,在注册配置文件中写入的addc这一名称,算子注册装置将通过帕斯卡命名方式转换为AddcOp,注册配置文件中的ins和outs分别是类型为张量的输入和输出的打包列表。此例中ins实际上包含了in这个唯一的输入,而outs包含了out这个唯一的输出。在一些实施例中,算子注册装置在生成的代码中将输入和输出解包,这样就拿到了类型为张量的输入和输出。应理解,ins表示算子接口(即算子对应的核函数)中需要用到的输入张量(tensor)名称,不同张量用','隔开;outs表示算子接口中需要用到的输出张量名称;attr表示算子接口中需要用到的超参数和标量;infer表示得到输出数组(DArray)的形状(shape),并做一些类型检查。一些简单的推断函数可以直接通过简单的规则来生成,复杂的推断函数则需要直接写推断函数,并指定函数名称。attr是算子在调用过程中,传入的除张量(tensor)以外的参数,可以被赋予默认值,而且在向后端转换的时候,还会进行相应的类型转换。例如,double(int)eps=1e-05,表示这个attr的类型是double,名字叫eps,默认值是1e-05,在调用后端函数时会被转换为整数类型(int)。

在一些实施例中,算子注册装置可以由ins,outs和attrs得到所有后端函数调用的统一接口,例如void layer_norm(constDArray&input,constDArray&weight,constDArray&bias,DArray&output,vectornormalized_shape,double eps,bool cudnn_enable)。

大部分算子除了张量这一种输入还会有不定数目的其他类型的输入,此例中只有c(实际上,默认地有个backend输入),它是标量(scalar)类型,在配置中通常将这些不定输入打包到attr中,然后在生成的代码中解包将其逐个拿到,如(1)第4行和(2)第11行所示,这样就拿到了非张量类型的输入和输出。

算子注册装置从注册配置信息可拿到生成目标算子所需的全部的参数之后,可以调用核函数进行计算了。但是一个算子可使用的核函数可能会有多个,算子注册装置需要确定到底使用哪一个,并且该算子注册装置需要知道核函数调用的参数顺序,这就是(1)第7行这个配置的必要性:它指出算子注册装置生成算子(例如目标算子)对应的类需要的是native后端中addc这个核函数,并且指出了参数的顺序,ctx是所有的native核函数的第一个参数,由于共性在此不做赘述。native后端表示这是算子注册装置的计算库本身。在一些实施例中,注册配置信息还包括第一配置信息,第一配置信息指示目标算子对应的至少一个核函数调用参数的顺序。也就是说,注册配置信息中的第一配置信息可目标算子对应的至少一个核函数调用参数的顺序,算子注册装置按照第一配置信息生成目标算子对应的核函数。

202、算子注册装置基于注册配置信息,生成目标算子对应的类。

目标算子对应的类用于调用目标算子对应的核函数做处理得到目标算子的输出。在一些实施例中,注册配置信息还包括第一配置信息,第一配置信息指示目标算子对应的至少一个核函数调用参数的顺序。

203、算子注册装置基于从注册配置信息中获得的推断函数的名称以及目标算子的名称,生成注册代码。

注册代码用于关联目标算子对应的类和推断函数。前面已提到,算子注册装置生成一个完整的算子不仅仅需要核函数进行计算,还需要推断函数进行输出的推断。算子注册装置还需要将生成的算子代码(即算子对应的类)和相应的推断函数关联起来:利用(1)第5行的信息以及算子对应的类,算子注册装置可生成注册代码,注册代码用于关联目标算子对应的类和推断函数。算子注册装置在生成注册代码之后,就可关联目标算子对应的类和推断函数。

(2)以下是算子注册装置生成的注册代码,它将推断函数和算子对应的类关联了起来,并且将这个算子的名称起为"addc"。

1.OperatorRegistry::add("addc",

2.OpCreateWithArchByOutput(),

3.inferUnaryOp,

4.ComputeOpTypeInfer());

算子注册装置可利用(1)第5行的信息以及算子对应的类,生成(2)中所示的注册代码;(2)中所示的注册代码可关联推断函数和算子对应的类。这样,生成一个完整的算子所需要的两部分就全部完成了。

204、算子注册装置将目标算子对应的类和推断函数添加到注册表。

推断函数用于推断目标算子的输出的形状。本申请实施例中,算子注册装置可使用自动化注册框架基于注册配置文件生成目标算子对应的类。算子注册装置还可生成一个推断函数,该推断函数用于推断目标算子的输出的形状。最后,算子注册装置将该目标算子对应的类和推断函数添加到注册表中。算子注册装置将目标算子对应的类和推断函数添加到注册表可理解为算子注册装置将目标算子添加至计算库。

本申请实施例中,算子注册装置生成目标算子对应的类,再将目标算子对应的类和推断函数关联起来,最后将目标算子对应的类和推断函数添加到注册表;可实现算子的自动注册,算子注册效率高。

图3为本申请实施例提供的另一种算子注册方法流程图。图3中的方法流程是对图1中的方法流程的细化和完善。如图3所示,该方法包括:

301、算子注册装置解析注册配置文件以得到注册配置信息。

302、算子注册装置基于注册配置信息,生成目标算子对应的类。

目标算子对应的类为调用目标算子对应的核函数做处理得到目标算子的输出的代码。

303、算子注册装置基于注册配置信息中的第二配置信息,生成推断函数。

在一个可能的实现方式中,推断函数包括第二代码;算子注册装置基于注册配置信息中的第二配置信息,生成推断函数可以包括:基于第二配置信息中的第一代码,生成第二代码;第一代码与第二代码存在至少部分相同的代码,第二代码为用于推断目标算子的输出的形状的代码。

在一个可能的实现方式中,推断函数包括第四代码,算子注册装置基于注册配置信息中的第二配置信息,生成推断函数可以包括:基于第二配置信息中的第三代码,生成第四代码;第四代码用于在调用时检查第三代码指示的待检查的参数。

当算子注册装置需要生成一个算子的时候,需要提供该算子对应的推断函数和核函数。如果算子注册装置能够生成算子对应的核函数,那么算子注册装置唯一要做的就是生成算子对应的推断函数了。下面以trace这个算子为例,着重说明一下推断函数的生成。

(3)生成trace算子的推断函数需要的配置(对应于第二配置信息)

1-trace:

2 ins:input

3 outs:out

4 infer:

5 check:inSpecs[0].ndims()==2

6 requirements:inSpecs[0]

7 calculate:outSpecs[0]=DArraySpec::scalar(inSpecs[0].elemType());

8 dispatch:

9 aten:Tensor trace(input);

(4)以下是自动生成的trace算子的推断函数:

1.bool inferTraceOp(const SSElement&attrs,

2.

3.PARROTS_CHECKARGS(inSpecs.size()==1);

4.PARROTS_CHECKARGS(outSpecs.size()==1);

5.if(inSpecs[0].isNone()){

6.

7.}

8.

9.PARROTS_CHECKARGS(inSpecs[0].ndims()==2);

10.outSpecs[0]=DArraySpec::scalar(inSpecs[0].elemType());

11.return true;

12.}

可以看到,(3)中第4行到第7行的配置信息(对应于第一代码)生成了对应的推断函数,对于必须要有的参数可使用requirements来配置。对于需要检查的参数(对应于第三代码),无论是attr中的还是ins/outs中的,算子注册装置统一使用了PARROTS_CHECKARGS这一宏定义来进行检查。推断函数最重要的目的是为了给这一算子的输出做一个规格化,这就是(3)第7行的必要性,它指示算子注册装置生成了(4)的第10行,指明了我们这个算子的输出是一个数据类型和输入相同的标量对象。

trace使用的是aten后端的核函数,如(3)第9行所示,而对于如何联系推断函数和算子已经在上个例子中详细介绍,在此不再赘述。

304、算子注册装置关联推断函数和目标算子对应的类。

在一些实施例中,算子注册装置可通过类似前面(2)中的注册代码,将推断函数和目标算子对应的类做关联。

305、算子注册装置将目标算子对应的类和推断函数添加到注册表。

本申请实施例中,基于第二配置信息,生成推断函数;使得用户能够按照自己的需求生成所需的推断函数,可满足不同的用户需求。

前述实施例描述了将目标算子对应的类和推断函数添加到注册表的实现方式。算子注册装置在将算子添加至计算库之后,还需要对算子进行测试。下面介绍如何实现算子的自动化测试的方式。

图4为本申请实施例提供的一种测试方法流程图。如图4所示,该方法包括:

401、算子注册装置使用第一框架解析测试配置文件,得到测试数据并保存。

测试数据包含测试目标函数所需的数据,目标函数为目标算子中的任一函数,例如核函数。测试配置文件可以是使用python编写的配置文件。第一框架可以为pytorch框架或者python框架。

在一些实施例中,算子注册装置在执行步骤401之前,可执行如下操作:算子注册装置根据用户的第二操作,生成测试配置文件。第二操作为在原始测试配置文件中添加测试数据的格式和生成规则的操作。生成规则用于生成测试数据。原始测试配置文件可预先配置有一些基本的配置信息(例如生成任意测试数据都必不可少的配置信息),用户在原始测试配置文件中添加测试数据的格式和生成规则的操作可理解为将该原始测试配置文件调整为可解析得到所需测试数据的测试配置文件。在实际应用中,开发人员将测试数据的格式以及测试数据的生成规则添加至原始测试配置文件,以便算子注册装置生成测试配置文件。

402、使用第一框架利用测试数据对目标函数做测试,得到第一测试结果并保存。

在一些实施例中,算子注册装置使用python代码解析测试配置文件,并且使用pytorch框架执行一次测试项,并将生成的测试数据和执行测试得到测试结果(对应于第一测试结果)存储到硬盘中。测试范围:测试主要包含对torch接口的测试、对tensor接口的测试、对函数式(functional)接口的测试以及对module接口的测试。functional接口可理解为一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。module接口可理解为专门为神经网络设计的模块化接口,可以包含网络各层的定义,以及前向传递(forward)方法。因为torch接口和tensor接口基本一致,因此将两个接口的规则定义在同一个配置文件中,其他functional接口和module接口则分别定义在各自的配置文件中。每个接口可理解为一个函数,对接口进行测试就是测试一个函数。

定义规则:规则包括按照用户的需求(形状,数据类型,生成规则)去生成测试数据,超参数的选择范围,以及函数的调用和测试结果的检验。为了使规则更加简洁和灵活,允许用户在定义tensor的生成规则和测试程序的执行逻辑的时候插入python代码。用户可以在测试配置文件中以字符串的形式定义函数来指定生成规则,以确保测试的边界情况。为了避免对极个别情况的处理而引入大量的额外参数,算子注册装置对一些参数预定义了一些可能的情况,并且设置了默认值。用户可以使用别名选取一种预定义的情况,如果用户忽略了这一属性,则将自动赋予默认值。

数据的生成和存储:在生成测试数据时,用户可以自由地指定由规则(生成规则)去随机生成,还是赋予特定的值。当若干个tensor满足同一套规则的时候,可以将这些tensor写在同一行,按tensor是否需要求导以分号分开,然后定义这一行的tensor生成规则。数据按照测试样例(case)存储在硬盘中,只存储pytorch生成的测试数据和测试结果,即使用pytorch按照测试样例进行测试输入的测试数据以及得到的测试结果。parrots按照每个测试样例进行测试的时候读取该测试样例对应的测试数据进行测试,并将测试得到的测试结果和已存储的该测试样例的测试结果(即pytorch生成的测试结果)做对比。可以理解,若使用pytorch按照某个测试样例进行测试得到的测试结果和使用parrots按照该测试样例进行测试得到的测试结果相同,则表明该测试样例测试成功。

403、使用第二框架读取并利用测试数据对目标函数做测试,得到第二测试结果。

第二框架和第一框架不同。第二框架可以是parrots框架或pytorch框架。在一些实施例中,第一框架为parrots框架,第二框架为pytorch框架。在一些实施例中,第一框架为pytorch框架,第二框架为parrots框架。步骤402和步骤403被算子注册装置执行的先后顺序不作限定。算子注册装置可先执行步骤402,再执行步骤403;也可以先执行步骤403,再执行步骤402;也可以并行执行(即同时执行)步骤402和步骤403。应理解,步骤402和步骤403之间无依赖关系,图4仅为一种示例。

在一些实施例中,算子注册装置可构建算子的自动测试框架,测试开发人员可利用该自动化测试框架将测试数据的格式和生成规则写在测试配置文件中,在每次测试的时候,都会首先使用pytorch生成对应的测试数据和测试结果保存在一个临时文件下,然后使用parrots读取数据,进行测试并对比pytorch的测试结果。图5为本申请实施例提供的一种自动化测试过程示意图。如图5所示,用户可编辑测试配置文件,即利用自动化测试框架将测试数据的格式和生成规则写在测试配置文件中;算子注册装置可通过自动化测试框架先使用pytorch(对应于第一框架)生成对应的测试数据,并将测试数据和测试结果保存在一个临时文件下,然后再使用parrots(对应于第二框架)读取测试数据,进行测试并对比pytorch的测试结果。图5中,每个case对应于一个测试样例,case的个数不作限定。例如case1表示一个测试样例的测试数据以及使用pytorch测试该测试样例的测试结果,case6表示另一个测试样例的测试数据以及使用parrots测试该测试样例的测试结果。

404、基于第一测试结果和第二测试结果,得到目标测试结果。

目标测试结果为指示目标函数通过或未通过测试。在一些实施例中,在第一测试结果和第二测试结果相同的情况下,确定目标函数通过测试(对应于目标测试结果);在第一测试结果和第二测试结果不同的情况下,确定目标函数未通过测试(对应于目标测试结果)

算子注册装置在对算子进行测试的时候,通过在测试配置文件中添加相应的测试参数,即可在执行测试的时候对该算子进行对应的测试。

本申请实施例中,将测试数据的格式和生成规则写在测试配置文件,可以按照需求生成所需的测试数据,可以解决算子测试中代码量大以及测试数据固定的问题,降低测试开发的成本。另外,算子注册装置在对算子测试时,生成测试数据,并将测试数据和测试结果存储在临时文件下,只是临时存储测试数据和测试结果,可以解决测试数据保存在git仓库会占用大量的空间的问题。也就是说,算子注册装置仅需存储测试配置文件,在测试的时候,才会生成测试数据以及测试结果。

图6为本申请实施例提供的一种算子注册装置的结构示意图,如图6所示,该装置包括:

第一处理单元601,用于编译注册配置文件,得到目标算子对应的类;

第二处理单元602,用于将目标算子对应的类和推断函数添加到注册表;推断函数用于推断目标算子的输出的形状。

在一个可能的实现方式中,第一处理单元601,具体用于解析注册配置文件以得到注册配置信息;注册配置信息包括目标算子的名称、目标算子的输入参数、目标算子的输出参数以及目标算子对应的核函数;基于注册配置信息,生成目标算子对应的类;目标算子对应的类用于调用目标算子对应的核函数做处理得到目标算子的输出。

在一个可能的实现方式中,注册配置信息还包括第一配置信息,第一配置信息指示目标算子对应的至少一个核函数调用参数的顺序。

在一个可能的实现方式中,注册配置信息还包括推断函数的名称;

第一处理单元601,还用于基于推断函数的名称以及目标算子的名称,生成注册代码;注册代码用于关联目标算子对应的类和推断函数。

在一个可能的实现方式中,注册配置信息还包括第二配置信息;

第一处理单元601,还用于基于第二配置信息,生成推断函数;关联推断函数和目标算子对应的类。

在一个可能的实现方式中,推断函数包括第二代码;

第一处理单元601,具体用于基于第二配置信息中的第一代码,生成第二代码;第一代码与第二代码存在至少部分相同的代码,第二代码为用于推断目标算子的输出的形状的代码。

在一个可能的实现方式中,推断函数包括第四代码;

第一处理单元601,具体用于基于第二配置信息中的第三代码,生成第四代码;第四代码用于在调用时检查第三代码指示的待检查的参数。

在一个可能的实现方式中,第一处理单元601,还用于根据用户的第一操作,生成注册配置文件;第一操作为在原始注册配置文件中添加一个或多个参数的操作,一个或多个参数基于目标算子区别于其他算子的部分,经抽象处理得到。

在一个可能的实现方式中,第一处理单元601,还用于使用第一框架解析测试配置文件,得到测试数据并保存;测试数据包含测试目标函数所需的数据,目标函数为目标算子中的第一函数;使用第一框架利用测试数据对目标函数做测试,得到第一测试结果并保存;使用第二框架读取并利用测试数据对目标函数做测试,得到第二测试结果;第二框架和第一框架不同;基于第一测试结果和第二测试结果,得到目标测试结果;目标测试结果为指示目标函数通过或未通过测试。目标函数为目标算子中的任意函数。

在一个可能的实现方式中,测试配置文件包括生成规则;

第一处理单元601,具体用于使用第一框架按照生成规则,生成测试数据并保存。

在一个可能的实现方式中,测试配置文件还包括测试程序执行逻辑配置信息,测试程序执行逻辑配置信息用于生成测试目标函数的测试程序的执行逻辑;

第一处理单元601,具体用于使用第一框架按照生成规则以及测试程序执行逻辑配置信息,生成测试数据并保存;测试数据包含测试目标函数的测试程序的执行逻辑。

在一个可能的实现方式中,测试配置文件中的以字符串的形式定义的函数指示生成规则。

在一个可能的实现方式中,第一处理单元601,还用于根据用户的第二操作,生成测试配置文件;第二操作为在原始测试配置文件中添加测试数据的格式和生成规则的操作,生成规则用于生成测试数据。

在一个可能的实现方式中,第一框架为pytorch框架,第二框架为parrots框架;或者,第一框架为parrots框架,第二框架为pytorch框架。

在一个可能的实现方式中,算子注册装置还包括:输出单元603,用于输出目标测试结果。举例来说,算子注册装置为台式电脑,显示器为输出单元603的硬件设备,通过显示器来显示目标测试结果。

应理解以上算子注册装置的各个单元的划分仅仅是一种逻辑功能的划分,实际实现时可以全部或部分集成到一个物理实体上,也可以物理上分开。例如,以上各个单元可以为单独设立的处理元件,也可以集成同一个芯片中实现,此外,也可以以程序代码的形式存储于控制器的存储元件中,由处理器的某一个处理元件调用并执行以上各个单元的功能。此外各个单元可以集成在一起,也可以独立实现。这里的处理元件可以是一种集成电路芯片,具有信号的处理能力。在实现过程中,方法的各步骤或以上各个单元可以通过处理器元件中的硬件的集成逻辑电路或者软件形式的指令完成。该处理元件可以是通用处理器,例如中央处理器(central processing unit,CPU),还可以是被配置成实施以上方法的一个或多个集成电路,例如:一个或多个特定集成电路(application-specific integratedcircuit,ASIC),或,一个或多个微处理器(digital signal processor,DSP),或,一个或者多个现场可编程门阵列(field-programmable gate array,FPGA)等。

图7为本申请实施例提供的一种终端设备的结构示意图。如图7所示,该终端设备70包括处理器701、存储器702和通信接口703;该处理器701、存储器702和通信接口703通过总线相互连接。图7中的终端设备可以为前述实施例中的算子注册装置。

存储器702包括但不限于是随机存储记忆体(random access memory,RAM)、只读存储器(read-only memory,ROM)、可擦除可编程只读存储器(erasable programmablereadonly memory,EPROM)、或便携式只读存储器(compact disc read-only memory,CDROM),该存储器702用于相关指令及数据。通信接口703用于接收和发送数据。

处理器701可以是一个或多个CPU,在处理器701是一个CPU的情况下,该CPU可以是单核CPU,也可以是多核CPU。前述实施例中由算子注册装置所执行的步骤可以基于该图7所示的终端设备的结构。具体的,处理器701可实现图6中各单元的功能。

在本申请的实施例中提供一种计算机可读存储介质,该计算机可读存储介质存储有计算机程序,该计算机程序被处理器执行时实现前述实施例所提供的算子注册方法。

本申请实施例提供了一种包含指令的计算机程序产品,当其在计算机上运行时,使得该计算机执行前述实施例所提供的算子注册方法。

以上所述,仅为本申请的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本申请揭露的技术范围内,可轻易想到各种等效的修改或替换,这些修改或替换都应涵盖在本申请的保护范围之内。因此,本申请的保护范围应以权利要求的保护范围为准。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号