发明内容
本公开至少一个实施例提供一种代码检查方法,包括:对代码文件进行解析以获得多条指令以及与所述多条指令对应的领域知识,其中,所述领域知识指示所述多条指令的操作内容以及关联参数;执行所述多条指令中的至少一条指令以得到执行结果;基于所述领域知识,判断所述执行结果是否满足预设条件;响应于所述执行结果满足所述预设条件,继续执行所述多条指令中所述至少一条指令的后续指令。
例如,在本公开一实施例提供的方法中,采用功能模拟软件执行所述代码检查方法。
例如,在本公开一实施例提供的方法中,所述执行结果包括至少一个寄存器值,基于所述领域知识,判断所述执行结果是否满足所述预设条件,包括:将所述至少一个寄存器值与所述领域知识进行比较,判断所述至少一个寄存器值与所述领域知识的差值是否满足所述预设条件。
例如,在本公开一实施例提供的方法中,所述预设条件包括:所述差值小于预设阈值。
例如,在本公开一实施例提供的方法中,所述执行结果包括至少一个寄存器值,基于所述领域知识,判断所述执行结果是否满足所述预设条件,包括:将所述至少一个寄存器值与所述领域知识进行比较,判断所述至少一个寄存器值的属性是否满足所述预设条件。
例如,在本公开一实施例提供的方法中,所述预设条件包括:所述至少一个寄存器值的属性与所述领域知识的属性一致。
例如,在本公开一实施例提供的方法中,所述领域知识以注释的形式标注在所述代码文件中,所述领域知识在所述代码文件中的位置与对应的指令在所述代码文件中的位置相邻。
例如,在本公开一实施例提供的方法中,在执行所述至少一条指令之前,所述方法还包括:基于所述领域知识,对解析获得的所述多条指令进行检查。
例如,在本公开一实施例提供的方法中,基于所述领域知识,对解析获得的所述多条指令进行检查,包括:根据语义规则,结合所述领域知识,对解析获得的所述多条指令进行检查。
例如,本公开一实施例提供的方法还包括:对调度执行单元的状态进行检查,以确定是否出现死锁状况;其中,所述调度执行单元包括多个线程,所述多个线程至少之一用于执行所述至少一条指令。
例如,在本公开一实施例提供的方法中,对所述调度执行单元的状态进行检查,以确定是否出现所述死锁状况,包括:周期性检查所述调度执行单元的状态;响应于所有未结束的调度执行单元均处于等待状态,确定出现所述死锁状况;响应于确定出现所述死锁状况,生成死锁提示信息,并且停止指令执行。
例如,本公开一实施例提供的方法还包括:响应于所述执行结果不满足所述预设条件,根据所述执行结果的规律性确定对所述至少一条指令的处理方式。
例如,在本公开一实施例提供的方法中,根据所述执行结果的规律性确定对所述至少一条指令的处理方式,包括:判断所述执行结果的规律性是否满足目标条件;响应于所述执行结果的规律性不满足所述目标条件,切换精度并再次执行所述至少一条指令,其中,再次执行所采用的精度高于上一次执行所采用的精度;响应于所述执行结果的规律性满足所述目标条件,生成规律提示信息,并且停止指令执行。
例如,在本公开一实施例提供的方法中,所述方法用于通用图形处理器中神经网络算法模拟仿真的代码检查。
例如,在本公开一实施例提供的方法中,所述多条指令包括汇编指令。
本公开至少一个实施例还提供一种代码编写方法,包括:将指令以及与所述指令对应的领域知识均编写在代码文件中;其中,所述领域知识指示所述指令的操作内容以及关联参数。
例如,在本公开一实施例提供的方法中,所述领域知识以注释的形式标注在所述代码文件中,所述领域知识在所述代码文件中的位置与对应的指令在所述代码文件中的位置相邻。
本公开至少一个实施例还提供一种代码检查装置,包括:解析单元,配置为对代码文件进行解析以获得多条指令以及与所述多条指令对应的领域知识,其中,所述领域知识指示所述多条指令的操作内容以及关联参数;执行单元,配置为执行所述多条指令中的至少一条指令以得到执行结果;第一检查单元,配置为基于所述领域知识,判断所述执行结果是否满足预设条件;其中,所述执行单元还配置为响应于所述执行结果满足所述预设条件,继续执行所述多条指令中所述至少一条指令的后续指令。
例如,在本公开一实施例提供的装置还包括:第二检查单元,配置为在执行所述至少一条指令之前,基于所述领域知识,对解析获得的所述多条指令进行检查;死锁检查单元,配置为对调度执行单元的状态进行检查,以确定是否出现死锁状况,其中,所述调度执行单元包括多个线程,所述多个线程至少之一用于执行所述至少一条指令。
本公开至少一个实施例还提供一种电子设备,包括本公开任一实施例提供的代码检查装置。
本公开至少一个实施例还提供一种电子设备,包括:处理器;存储器,包括一个或多个计算机程序模块;其中,所述一个或多个计算机程序模块被存储在所述存储器中并被配置为由所述处理器执行,所述一个或多个计算机程序模块包括用于实现本公开任一实施例提供的代码检查方法。
具体实施方式
为使本公开实施例的目的、技术方案和优点更加清楚,下面将结合本公开实施例的附图,对本公开实施例的技术方案进行清楚、完整地描述。显然,所描述的实施例是本公开的一部分实施例,而不是全部的实施例。基于所描述的本公开的实施例,本领域普通技术人员在无需创造性劳动的前提下所获得的所有其他实施例,都属于本公开保护的范围。
除非另外定义,本公开使用的技术术语或者科学术语应当为本公开所属领域内具有一般技能的人士所理解的通常意义。本公开中使用的“第一”、“第二”以及类似的词语并不表示任何顺序、数量或者重要性,而只是用来区分不同的组成部分。同样,“一个”、“一”或者“该”等类似词语也不表示数量限制,而是表示存在至少一个。“包括”或者“包含”等类似的词语意指出现该词前面的元件或者物件涵盖出现在该词后面列举的元件或者物件及其等同,而不排除其他元件或者物件。“连接”或者“相连”等类似的词语并非限定于物理的或者机械的连接,而是可以包括电性的连接,不管是直接的还是间接的。“上”、“下”、“左”、“右”等仅用于表示相对位置关系,当被描述对象的绝对位置改变后,则该相对位置关系也可能相应地改变。
在针对图形处理器(Graphics Processing Unit,GPU)和/或通用图形处理器(General-purpose Computing on Graphics Processing Unit,GPGPU)进行设计开发时,通常会根据GPU/GPGPU芯片设计方案编写功能模拟软件(或者称为芯片功能模拟软件)以模拟芯片硬件的行为。例如,常用的功能模拟软件为CModel。在GPU/GPGPU上进行大型神经网络的训练推理时,需要将神经网络转换为高性能的汇编级指令,而检查指令逻辑的正确性十分复杂,这涉及大量的属性与同步。
图1为一种采用功能模拟软件执行指令的示意图。如图1所示,利用编译器对程序进行编译后可以得到二进制文件,该二进制文件可以直接被执行。将二进制文件以及所需要的数据输入功能模拟软件(例如CModel),以使功能模拟软件运行该二进制文件。在软件运行结束后,可以对输出的结果进行比较和判断,从而检查指令逻辑的正确性。如果结果存在错误,则需要基于软件代码针对执行的指令进行调试。
一方面,由于功能模拟软件的输入为编译后的二进制指令,这会丢失大量领域知识,只能对指令本身的语法正确性进行验证,难以获得指令运行时领域的上下文环境,无法判断指令相关属性设置是否合理,只能在最后比较结果后才能判断对错,这将导致问题显现的滞后,极大增加调试的难度。
另一方面,由于功能模拟软件完全按照硬件的行为实现,而深度学习对精度要求不太高,中间计算过程可能会引入数值精度误差。当仿真输出结果与理论结果存在偏差时,难以判断是数值精度问题引起的误差还是汇编逻辑问题引起的错误。而且,由于功能模拟软件的复杂性,难以及时确定并行指令间的同步是否出现死锁,且死锁位置确定困难。
本公开至少一个实施例提供一种代码检查方法、代码编写方法、代码检查装置、电子设备。该代码检查方法可以及时自动地发现汇编指令中存在的逻辑问题,能够在指令执行过程中及时进行检查,极大地降低逻辑问题的定位难度,降低调试的难度。
下面,将参考附图详细地说明本公开的实施例。应当注意的是,不同的附图中相同的附图标记将用于指代已描述的相同的元件。
本公开至少一个实施例提供一种代码检查方法。该代码检查方法包括:对代码文件进行解析以获得多条指令以及与多条指令对应的领域知识,领域知识指示多条指令的操作内容以及关联参数;执行多条指令中的至少一条指令以得到执行结果;基于领域知识,判断执行结果是否满足预设条件;响应于执行结果满足预设条件,继续执行多条指令中至少一条指令的后续指令。
图2为本公开一些实施例提供的一种代码检查方法的流程示意图。如图2所示,在一些实施例中,该代码检查方法包括如下操作。
步骤S11:对代码文件进行解析以获得多条指令以及与多条指令对应的领域知识,其中,领域知识指示多条指令的操作内容以及关联参数;
步骤S12:执行多条指令中的至少一条指令以得到执行结果;
步骤S13:基于领域知识,判断执行结果是否满足预设条件;
步骤S14:响应于执行结果满足预设条件,继续执行多条指令中至少一条指令的后续指令。
例如,该代码检查方法可以用于图形处理器(GPU)和/或通用图形处理器(GPGPU)中神经网络算法模拟仿真的代码检查。由于涉及神经网络算法的代码通常规模较大,代码逻辑较为复杂,可能会存在错误,因此需要对指令(例如汇编指令)的正确性进行检查。如果在整个代码对应的指令运行完之后再检查,会导致问题显现的滞后,不便于及时发现和定位问题。由于神经网络算法涉及大量领域知识,因此,本公开实施例提供的代码检查方法在执行指令的过程中根据领域知识进行检查,可以及时自动地发现汇编指令中存在的逻辑问题。需要说明的是,本公开的实施例中,该代码检查方法不限于应用在GPU/GPGPU中神经网络算法模拟仿真的代码检查,还可以应用在其他需要进行代码检查的场景中,本公开的实施例对此不作限制。
例如,在步骤S11中,可以利用功能模拟软件对代码文件进行解析,从而可以获得多条指令以及与多条指令对应的领域知识,也即是,在解析指令的同时解析与指令相关的领域知识。该指令可以被功能模拟软件执行。例如,上述代码文件可以是汇编文件。例如,这些指令可以是汇编指令或者其他可以被执行的硬件指令。例如,在解析获得的所有指令中,至少部分指令具有对应的领域知识。
例如,领域知识可以指示指令的操作内容以及关联参数。也即是,领域知识可以是对神经网络算法进行辅助性说明的内容,例如是神经网络算法中涉及的上下文知识,或者是对具体运算方式、运算参数、属性的描述,还可以是其他适用的内容,本公开的实施例对此不作限制。这里,关联参数可以指神经网络算法中涉及的任意参数。
图3为本公开一些实施例提供的代码检查方法中领域知识的示意图。例如,在一些示例中,如图3所示,针对卷积运算,其领域知识涵盖了卷积运算的参数、卷积运算的实现方式等内容。例如,“Layer Info”描述了下一段代码是做一个卷积运算,该卷积运算中activation尺寸为2*64*56*56,weight尺寸为256*64*1*1,stride为1,dilation为1,padding的x和y均为0,数据类型为bf16。“Subtensor info”描述了该部分代码仅完成其中一部分的计算,即只完成56*32(行*列)部分的卷积运算。“Layer loops”描述了代码的循环顺序,以该循环顺序实现该部分的卷积计算过程。
例如,领域知识以注释的形式标注在代码文件中,领域知识在代码文件中的位置与对应的指令在代码文件中的位置相邻。这里,代码文件可以是指汇编文件。例如,可以将与神经网络计算相关的领域知识以指定格式的注释标识在指令之前或之后,具体的标注格式和标注位置可以根据实际需求而定。
图4为本公开一些实施例提供的代码检查方法中领域知识的标注方式示意图。如图4所示,在一些示例中,虚线框内的内容是领域知识,实线框内的内容是对应的指令,该领域知识以注释的形式标注在对应的指令之前。当然,本公开的实施例不限于此,在其他示例中,领域知识也可以采用注释的形式标注在对应的指令之后。
在图4的示例中,仍然以卷积计算为例,“Loop”描述了该指令是对卷积核中的一块与输入样本中的一块进行卷积运算,也即,将weight中的一块与input中的一块进行卷积运算。其中,卷积核中的这一块的参数为oc:128~192,ic:0~64;输入样本中的这一块的参数为sample:0~1,ic:0~64,行:8~16,列:24~32。同时,相应的指令是调度执行单元中的第21条指令。
需要说明的是,上述关于领域知识的内容和标注方式的说明仅是示例性的,而非限制性的,领域知识可以是对神经网络算法进行辅助性说明的任意内容,其可以采用任意适用的格式进行标注,本公开的实施例对此不作限制。
返回至图2,在步骤S12中,执行解析得到的多条指令中的至少一条指令,从而得到执行结果。例如,可以执行一条指令,然后在后续步骤中对执行结果进行判断;也可以一次执行多条指令,然后在后续步骤中在信息充分的情况下对执行结果进行判断。例如,本公开实施例提供的代码检查方法采用功能模拟软件执行,因此可以利用功能模拟软件执行指令以得到执行结果。例如,功能模拟软件可以为任意适用的用于进行模拟仿真的软件,本公开的实施例对此不作限制。例如,在一些示例中,可以将代码文件输入功能模拟软件,并且将需要使用的数据输入功能模拟软件,从而使功能模拟软件解析代码文件以得到指令以及相应的领域知识,且运行指令并得到该指令对应的执行结果。
例如,在步骤S13中,基于领域知识,判断执行结果是否满足预设条件。该步骤用于进行动态检查,也即是,在执行指令的过程中对各个指令的执行结果进行检查。
例如,在一些示例中,执行结果包括至少一个寄存器值,也即是,通过执行指令可以得到一个或多个寄存器值。上述步骤S13可以进一步包括:将至少一个寄存器值与领域知识进行比较,判断至少一个寄存器值与领域知识的差值是否满足预设条件。例如,预设条件包括:差值小于预设阈值。也即是,可以将执行指令所得到的寄存器值与领域知识进行比较,以判断寄存器值与领域知识之间的差值是否小于预设阈值,若小于预设阈值,则确定执行结果满足预设条件。例如,预设阈值的具体数值大小可以根据实际需求而定,本公开的实施例对此不作限制。
例如,在图4的示例中,寄存器值只有在动态运行时才能确定,在执行卷积计算时(也即在动态仿真的过程中),根据相应指令的卷积计算区域,可以检查各个寄存器值(例如寄存器中的坐标值)是否与领域知识中包含的相应的理论值匹配,从而判断执行结果是否符合预期。例如,如图4所示,可以检查oc坐标是否为128,ic坐标是否为0等;又例如,图4中的指令表示行(row)的值是在上一条指令运行时值的基础上增加一个步长,如果该指令运行时寄存器中行(row)的值为8,则为正确,否则为错误。需要注意的是,若对执行结果具有一定的容错性,则可以判断寄存器值与领域知识是否较为接近(也即差值是否小于预设阈值),若两者较为接近,则可以确定执行结果满足预设条件。
例如,在另一些示例中,执行结果包括至少一个寄存器值。也即是,通过执行指令可以得到一个或多个寄存器值。上述步骤S13可以进一步包括:将至少一个寄存器值与领域知识进行比较,判断至少一个寄存器值的属性是否满足预设条件。例如,预设条件包括:至少一个寄存器值的属性与领域知识的属性一致。也即是,可以将执行指令所得到的寄存器值与领域知识进行比较,以判断寄存器值的属性与领域知识的属性是否相同。例如,寄存器值的属性可以为数据类型、参数类型等,因此可以判断寄存器值的属性是否与领域知识中包含的相应理论值的属性相同,从而确定执行结果是否满足预设条件。
需要说明的是,上述示例分别以判断寄存器值的大小、判断寄存器值的属性为例对判断执行结果是否满足预设条件进行了示例性说明,但这并不构成对本公开实施例的限制。由于领域知识可以包括任意的对神经网络算法进行辅助性说明的内容,因此在判断执行结果是否满足预设条件时,可以根据领域知识的内容和特性来确定如何判断执行结果,这可以根据实际需求而定,本公开的实施例对此不作限制。
例如,在步骤S14中,若执行结果满足预设条件,则继续执行多条指令中至少一条指令的后续指令。也即是,通过上述步骤S13判断出执行结果符合预期,则表示指令逻辑不存在问题,因此继续执行当前指令的后续指令。
通过上述方式,可以在运行仿真的过程中基于领域知识对每一条指令的合理性、合法性进行验证。由此,可以在动态仿真的过程中及时检查各个指令是否正确执行,可以及时自动地发现汇编指令中存在的逻辑问题,而无需等到全部指令执行完毕后再检查,从而可以极大地降低逻辑问题的定位难度,降低调试的难度。
图5为本公开一些实施例提供的另一种代码检查方法的流程示意图。例如,在一些实施例中,如图5所示,除了包括步骤S11-S14,该代码检查方法还可以进一步包括步骤S15-S17。该实施例中的步骤S11-S14与图2所示的代码检查方法中的步骤S11-S14基本相同,此处不再赘述。
步骤S15:基于领域知识,对解析获得的多条指令进行检查;
步骤S16:对调度执行单元的状态进行检查,以确定是否出现死锁状况;
步骤S17:响应于执行结果不满足预设条件,根据执行结果的规律性确定对至少一条指令的处理方式。
例如,在步骤S15中,可以根据领域知识对解析获得的多条指令进行检查,该步骤用于进行静态检查,例如在步骤S12之前执行。也即是,当解析获得多条指令及领域知识后,首先根据领域知识对解析获得的多条指令进行静态检查,完成静态检查之后,再执行多条指令中的至少一条指令并且根据执行结果和领域知识进行动态检查。
例如,步骤S15可以包括:根据语义规则,结合领域知识,对解析获得的多条指令进行检查。例如,根据语义规则,可以对指令进行合法性检查,并且,结合领域知识,可以对指令进行合理性检查。例如,如图6A所示,在该示例中,指令中的字符串“wt”为写出时使用的属性,而此处用在了读取的指令中,因此该指令是不合法的。又例如,如图6B所示,在该示例中,指令中的字符串“last”为最后一次读取时使用的属性,但是根据领域知识可知该指令的后续指令还会读取该部分数据,因此,此处使用“last”是不合理的。
通过进行静态检查,可以在执行指令之前尽早发现可能存在的问题,从而避免执行指令的过程中出现较多错误,降低动态检查的报错率,提高代码检查的效率。
例如,在步骤S16中,对调度执行单元的状态进行检查,从而确定是否出现死锁状况。例如,调度执行单元包括多个线程,多个线程至少之一用于执行至少一条指令。由于功能模拟软件较为复杂,功能模拟软件中的调度执行单元执行指令时可能会出现并行指令间的同步死锁,因此通过该步骤对死锁状况进行监测,从而及时发现死锁问题。
例如,在一些示例中,如图7所示,上述步骤S16可以进一步包括如下操作。
步骤S161:周期性检查调度执行单元的状态;
步骤S162:响应于所有未结束的调度执行单元均处于等待状态,确定出现死锁状况;
步骤S163:响应于确定出现死锁状况,生成死锁提示信息,并且停止指令执行。
例如,在步骤S161中,可以周期性地检查各个调度执行单元的状态。例如,可以每间隔一定时长检查一次,从而可以及时发现死锁状况。关于相邻两次检查所间隔的时间,可以根据实际需求而定,本公开的实施例对此不作限制。例如,在一些示例中,在多次检查中,每相邻两次检查的间隔时长可以相同,从而可以简化控制方式。例如,在另一些示例中,在多次检查中,每相邻两次检查的间隔时长可以不同,从而可以根据指令执行情况对容易出现死锁的阶段进行有针对性的检查,以便于及时发现死锁状况。
例如,在步骤S162中,若所有未结束的调度执行单元均处于等待状态,则确定出现死锁状况,这表明同步策略存在错误。
例如,在步骤S163中,若确定出现死锁状况,则生成死锁提示信息,并且停止指令执行。此时,可以在屏幕中显示死锁提示信息,也可以发出死锁提示信息的声音,或者采用其他方式传达死锁提示信息,这可以根据实际需求而定,本公开的实施例对此不作限制,只要能够使用户知道发生死锁状况即可。由于出现死锁状况,无法继续执行指令,因此停止指令执行。
通过上述方式,可以在指令运行过程中对并行运行指令的状态进行周期性检查,可以及时发现、反馈同步死锁问题,降低死锁问题的定位难度,同时测试同步策略的正确性。
返回至图5,在步骤S17中,在判断执行结果是否满足预设条件后,若执行结果不满足预设条件,则根据执行结果的规律性确定对至少一条指令的处理方式。也即是,当执行结果不满足预设条件时,则表示执行结果不符合预期,因此可能存在逻辑错误,此时,需要根据执行结果的规律性确定下一步操作。
例如,在一些示例中,如图8所示,上述步骤S17可以进一步包括如下操作。
步骤S171:判断执行结果的规律性是否满足目标条件;
步骤S172:响应于执行结果的规律性不满足目标条件,切换精度并再次执行至少一条指令,其中,再次执行所采用的精度高于上一次执行所采用的精度;
步骤S173:响应于执行结果的规律性满足目标条件,生成规律提示信息,并且停止指令执行。
例如,在步骤S171中,判断执行结果的规律性是否满足目标条件,也即是,对执行结果的规律性进行判断,以确定执行结果的规律性是否符合预期的规律程度。例如,目标条件可以是预期的规律程度,或者是指呈现出一定的规律性。
例如,在步骤S172中,若执行结果的规律性不满足目标条件,则切换精度并再次执行至少一条指令。例如,再次执行所采用的精度高于上一次执行所采用的精度。也即是,若执行结果的规律性不符合预期的规律程度,或者执行结果没有呈现出一定规律性,则表明执行结果的偏差可能不是由于逻辑错误造成的,可能是由于运算精度造成的,因此切换为高精度再次执行,以进一步确定是否存在逻辑错误。由此,可以快速协助判定是否是由于精度问题而引起的偏差,从而保证代码逻辑的正确性。例如,在一些示例中,可以将精度从bf16切换为fp32,或者切换为其他更高精度以再次运行。
例如,在一些示例中,可以在所有指令执行完之后再次以高精度重新执行所有指令,也即,采用高精度重新模拟仿真。例如,在另一些示例中,也可以在当前的指令执行完之后再次以高精度重新执行当前的指令。本公开的实施例对以高精度再次执行指令的方式不作限制,这可以根据实际需求而定。
例如,在步骤S173中,若执行结果的规律性满足目标条件,则生成规律提示信息,并且停止指令执行。也即是,若执行结果的规律性符合预期的规律程度,或者执行结果呈现出一定规律性,则表明可能是由于逻辑错误造成的,因此生成规律提示信息,并且停止指令执行,由此向用户报告可能存在逻辑错误,由用户分析错误,以便于用户进行检查和调试。
图9为本公开一些实施例提供的一种代码检查方法的工作流程图。下面结合图9对本公开实施例提供的代码检查方法的工作流程进行示例性说明。
如图9所示,首先将代码文件和所需要使用的数据输入功能模拟软件。接着,利用功能模拟软件对代码文件进行解析,以得到指令以及相应的领域知识。该指令可以直接被功能模拟软件执行。
得到指令以及领域知识之后,在执行指令之前,对指令进行静态检查。例如,可以根据语义规则并结合领域知识,对解析获得的指令进行合法性、合理性检查。由于此时还未执行指令,因此可以快速完成静态检查。
接着,开始执行指令,并在执行指令的过程中进行动态检查。例如,可以计算指令运行时的状态及数据,并基于该条指令的上下文领域知识,判断该指令运行时属性的合理性、合法性。例如,针对每个指令或某些指令,可以根据相应的领域知识对其执行结果进行检查,判断执行结果是否满足预设条件,也即,执行结果与领域知识是否匹配。如果执行结果满足预设条件,则表示该条指令不存在问题,则继续执行后续指令。
如果执行结果不满足预设条件,则表示该条指令可能存在逻辑错误,需要进行进一步判断。此时,需要进一步判断执行结果的规律性是否满足目标条件。
如果执行结果的规律性不满足目标条件,也即,执行结果的规律性不符合预期的规律程度,或者执行结果没有规律性,则表明执行结果的偏差可能不是由于逻辑错误造成的,可能是由于运算精度造成的,因此切换为高精度再次执行,以进一步确定是否存在逻辑错误。如果执行结果的规律性满足目标条件,也即,执行结果的规律性符合预期的规律程度,或者执行结果呈现出一定规律性,则表明可能是由于逻辑错误造成的,因此生成规律提示信息并且停止指令执行,由此向用户报告可能存在逻辑错误,由用户分析错误,以便于用户进行检查和调试。例如,在切换为高精度执行的情形中,可以在所有指令执行完之后再次以高精度重新执行所有指令,也可以在当前的指令执行完之后再次以高精度重新执行当前的指令。
在执行指令的过程中,除了进行动态检查,还对调度执行单元的状态进行周期性检查,以确定是否出现死锁状况。如果所有未结束的调度执行单元均处于等待状态,则确定出现死锁状况,此时生成死锁提示信息并且停止指令执行。如果所有未结束的调度执行单元并没有均处于等待状态,则确定没有出现死锁状况,则间隔一定周期后再次检查。
通过上述方式,在执行指令之前进行静态检查,在执行指令的过程中进行动态检查以及死锁检查,最后输出全部指令的最终执行结果,从而完成代码文件的模拟仿真。最终执行结果可以继续与参照数据进行比较,以判断最终执行结果是否正确。
需要说明的是,本公开实施例提供的代码检查方法不限于上文描述的步骤和顺序,还可以包括更多或更少的步骤,各个步骤的执行顺序可以根据实际需求而定,本公开的实施例对此不作限制。
本公开至少一个实施例还提供一种代码编写方法。该代码编写方法所编写的代码在被执行时,可以及时自动地发现汇编指令中存在的逻辑问题,能够在指令执行过程中及时进行检查,极大地降低逻辑问题的定位难度,降低调试的难度。
图10为本公开一些实施例提供的一种代码编写方法的流程示意图。在一些实施例中,如图10所示,该代码编写方法包括如下操作。
步骤S20:将指令以及与指令对应的领域知识均编写在代码文件中,其中,领域知识指示指令的操作内容以及关联参数。
例如,该代码编写方法所编写的代码可以是在图形处理器(GPU)和/或通用图形处理器(GPGPU)中运行的神经网络算法,该代码编写方法所编写的代码经功能模拟软件解析之后,可以在功能模拟软件中执行,以实现模拟仿真。需要说明的是,本公开的实施例中,该代码编写方法所编写的代码不限于为GPU/GPGPU中运行的神经网络算法,还可以是应用在其他需要进行代码检查的场景中的算法或程序,本公开的实施例对此不作限制。
例如,在步骤S20中,将指令(例如汇编指令)编写在代码文件中,并且将与指令对应的领域知识也编写在代码文件中。例如,在代码文件所包含的所有指令中,至少部分指令具有对应的领域知识。
例如,领域知识可以指示指令的操作内容以及关联参数。也即是,领域知识可以是对神经网络算法进行辅助性说明的内容,例如是神经网络算法中涉及的上下文知识,或者是对具体运算方式、运算参数、属性的描述,还可以是其他适用的内容,本公开的实施例对此不作限制。这里,关联参数可以指神经网络算法中涉及的任意参数。
例如,领域知识以注释的形式标注在代码文件中,领域知识在代码文件中的位置与对应的指令在代码文件中的位置相邻。例如,可以采用如图4所示的方式将领域知识以注释的形式标注在对应的指令之前。当然,本公开的实施例不限于此,在其他示例中,领域知识也可以采用注释的形式标注在对应的指令之后。
该代码编写方法所编写的代码在被功能模拟软件解析之后可以在功能模拟软件中执行,以实现模拟仿真。在采用功能模拟软件执行时,可以采用前述的代码检查方法进行代码检查,包括静态检查、动态检查、死锁检查等,从而可以及时自动地发现汇编指令中存在的逻辑问题,能够在指令执行过程中及时进行检查,极大地降低逻辑问题的定位难度,降低调试的难度。
需要说明的是,本公开实施例提供的代码编写方法不限于上文描述的步骤和顺序,还可以包括更多或更少的步骤,各个步骤的执行顺序可以根据实际需求而定,本公开的实施例对此不作限制。
本公开至少一个实施例还提供一种代码检查装置。该代码检查装置可以及时自动地发现汇编指令中存在的逻辑问题,能够在指令执行过程中及时进行检查,极大地降低逻辑问题的定位难度,降低调试的难度。
图11为本公开一些实施例提供的一种代码检查装置的示意框图。如图11所示,该代码检查装置100包括解析单元110、执行单元120、第一检查单元130。
解析单元110配置为对代码文件进行解析以获得多条指令以及与多条指令对应的领域知识。例如,领域知识指示多条指令的操作内容以及关联参数。例如,解析单元110可以执行图2所示的代码检查方法中的步骤S11。执行单元120配置为执行多条指令中的至少一条指令以得到执行结果。第一检查单元130配置为基于领域知识,判断执行结果是否满足预设条件。执行单元120还配置为响应于执行结果满足预设条件,继续执行多条指令中至少一条指令的后续指令。例如,执行单元120可以执行图2所示的代码检查方法中的步骤S12、S14,第一检查单元130可以执行图2所示的代码检查方法中的步骤S13。
图12为本公开一些实施例提供的另一种代码检查装置的示意框图。如图12所示,在一些示例中,该代码检查装置100还可以进一步包括第二检查单元140和死锁检查单元150。该代码检查装置100中的解析单元110、执行单元120、第一检查单元130与图11中所示的解析单元110、执行单元120、第一检查单元130基本相同,此处不再赘述。
第二检查单元140配置为在执行至少一条指令之前,基于领域知识,对解析获得的多条指令进行检查。例如,第二检查单元140可以执行图5所示的代码检查方法中的步骤S15。死锁检查单元150配置为对调度执行单元的状态进行检查,以确定是否出现死锁状况。调度执行单元包括多个线程,多个线程至少之一用于执行至少一条指令。例如,死锁检查单元150可以执行图5所示的代码检查方法中的步骤S16。
例如,解析单元110、执行单元120、第一检查单元130、第二检查单元140和死锁检查单元150可以为硬件、软件、固件以及它们的任意可行的组合。例如,解析单元110、执行单元120、第一检查单元130、第二检查单元140和死锁检查单元150可以为专用或通用的电路、芯片或装置等,也可以为处理器和存储器的结合。关于解析单元110、执行单元120、第一检查单元130、第二检查单元140和死锁检查单元150的具体实现形式,本公开的实施例对此不作限制。
需要说明的是,本公开的实施例中,代码检查装置100的各个单元与前述的代码检查方法的各个步骤对应,关于该代码检查装置100的具体功能可以参考上文中关于代码检查方法的相关描述,此处不再赘述。图11和图12所示的代码检查装置100的组件和结构只是示例性的,而非限制性的,根据需要,该代码检查装置100还可以包括其他组件和结构。
本公开至少一个实施例还提供一种电子设备。该电子设备可以及时自动地发现汇编指令中存在的逻辑问题,能够在指令执行过程中及时进行检查,极大地降低逻辑问题的定位难度,降低调试的难度。
图13为本公开一些实施例提供的一种电子设备的示意框图。如图13所示,电子设备200包括代码检查装置210,代码检查装置210可以为前述的代码检查装置100。例如,该电子设备200可以为能够运行功能模拟软件的计算机、服务器等,或者为其他任意的能够运行功能模拟软件的电子设备,以便于利用功能模拟软件进行模拟仿真,并在模拟仿真的过程中进行代码检查。关于该电子设备200的相关说明可参考上文中关于代码检查装置100的描述,此处不再赘述。
图14为本公开一些实施例提供的另一种电子设备的示意框图。如图14所示,该电子设备300包括处理器310和存储器320。存储器320用于存储非暂时性计算机可读指令(例如一个或多个计算机程序模块)。处理器310用于运行非暂时性计算机可读指令,非暂时性计算机可读指令被处理器310运行时可以执行上文所述的代码检查方法中的一个或多个步骤。存储器320和处理器310可以通过总线系统和/或其它形式的连接机构(未示出)互连。
例如,处理器310可以是中央处理单元(CPU)、图形处理单元(GPU)、数字信号处理器(DSP)或者具有数据处理能力和/或程序执行能力的其它形式的处理单元,例如现场可编程门阵列(FPGA)等;例如,中央处理单元(CPU)可以为X86或ARM架构等。处理器310可以为通用处理器或专用处理器,可以控制电子设备300中的其它组件以执行期望的功能。
例如,存储器320可以包括一个或多个计算机程序产品的任意组合,计算机程序产品可以包括各种形式的计算机可读存储介质,例如易失性存储器和/或非易失性存储器。易失性存储器例如可以包括随机存取存储器(RAM)和/或高速缓冲存储器(cache)等。非易失性存储器例如可以包括只读存储器(ROM)、硬盘、可擦除可编程只读存储器(EPROM)、便携式紧致盘只读存储器(CD-ROM)、USB存储器、闪存等。在计算机可读存储介质上可以存储一个或多个计算机程序模块,处理器310可以运行一个或多个计算机程序模块,以实现电子设备300的各种功能。在计算机可读存储介质中还可以存储各种应用程序和各种数据以及应用程序使用和/或产生的各种数据等。
需要说明的是,本公开的实施例中,电子设备300的具体功能和技术效果可以参考上文中关于代码检查方法的描述,此处不再赘述。
有以下几点需要说明:
(1)本公开实施例附图只涉及到本公开实施例涉及到的结构,其他结构可参考通常设计。
(2)在不冲突的情况下,本公开的实施例及实施例中的特征可以相互组合以得到新的实施例。
以上所述,仅为本公开的具体实施方式,但本公开的保护范围并不局限于此,本公开的保护范围应以所述权利要求的保护范围为准。