APP下载

面向计算机视觉的领域特定语言

2020-05-12郑启龙

小型微型计算机系统 2020年3期
关键词:算子代码语法

姜 靖,郑启龙,2

1(中国科学技术大学 计算机科学与技术学院,合肥 230026)

2(中国科学技术大学 国家高性能计算中心,合肥 230026)

E-mail:jjdl@mail.ustc.edu.cn

1 引 言

计算机视觉(Computer Vision,CV)是指使用计算机及相关设备对生物视觉的一种模拟,最终目标是使计算机能够像人类一样通过视觉观察进而理解世界,具有自主适应环境的能力[1].近些年来,计算机视觉得到了飞速发展,大量高效、实用的AI算子被设计了出来.传统CV算子库也得到了更新和完善.更多基于计算机视觉的软件和系统已被广泛使用.

领域特定语言(Domain Specific Language,DSL)是领域工程技术之一,它是针对某一特定领域具有受限制表达性的一种计算机程序设计语言[2].不同于普通的编程语言,领域特定语言抽象层次更高.针对特定领域,领域特定语言能更简洁、清晰、系统地描述某部分的意图,提高开发效率,使开发过程更加轻松.随着需求和技术的不断更新,领域特定语言的种类也越来越多.以下是一些比较常见的领域特定语言:用于描述Web页面的HTML,用于构造软件系统的Ant、RAKE、MAKE,用于表达语法的 BNF 范式,语法分析器生成语言 YACC、Bison、ANTLR,用于数据库结构化查询的SQL,用于描述样式表的CSS,专用的排版系统LaTex等[3].近些年随着人工智能的快速发展,一些面向机器学习、深度学习的领域特定语言也相继面世,例如OptiML、DeepDSL等.

在工业生产和科研工作中,有时需使用大量计算机视觉算子,例如OpenCV算子[4,5]、Halcon算子[6,7]以及其它商业算子,同时也在越来越多的使用基于机器学习和深度学习的AI算子[8].这些算子间的组合调用较为困难,难以集成.例如在完成某商品包装的缺陷检测时,比较好的方式是先做A滤波再做亚像素的边缘提取,A滤波算子只有OpenCV提供,而亚像素的边缘提取只有某商业算子库提供,所以需要跨算子库调用两种算子.虽然大部分算子库均提供C++接口,用C++可以完成这些任务,但编码过于繁琐,而且一些计算机视觉开发人员并非计算机背景出身,因此他们更愿意使用一种更抽象、简单的语言.在开发过程中,领域专家和编码人员的沟通也存在很大的问题.故本文设计实现了一种DSL,其基本思想是为现有的常用计算机视觉算子库和AI算子提供简单、一致的语法,从而整合使用这些算子,以提供统一的开发平台.这样一种DSL减少了编码时间和编码量,能让领域工作者将更多的时间和精力放在算法设计上.具有开发经验的用户也可以修改添加平台内的元模型,从而实现对平台的扩展.此处将面向计算机视觉的领域特定语言命名为CVDSL.

图1 CVDSL整体设计图

本文采用模型驱动开发的方式对CVDSL进行建模、设计与实现,主要进行了以下几个方面的工作:1)构建CV领域元模型;2)定义CVDSL语法规则;3)定制CVDSL语法检查器;4)定制将CVDSL转换为C++的代码自动生成器.CVDSL的整体设计方案如图1所示.

2 CVDSL的设计与实现

本文首先确定了构建CV领域元模型的方法及工具,并通过分析领域中的共性和变性、所需要的原始数据类型、必须的原始数据规模等一系列领域相关因素,确定了元模型的组成内容,在此基础上建立了CV领域元模型.

本文在CV领域元模型的映射和持久化的基础上,定义了CVDSL语法规则体系.同时通过自定义语法规则库,定制了模型语法检查器.语法检查的目的是为了防止开发人员在使用领域特定语言编码时产生语法错误,从而影响生成代码的正确性.

本文通过研究基于模板映射语言的、符合特定标准的应用模型代码自动生成技术,设计了将CVDSL代码转换成对应的C++代码的代码自动生成器,实现领域特定语言向通用语言的自动转换.

2.1 构建CV领域元模型

元模型的构建依据元对象机制(MOF,Meta Object Facility).MOF也被称为MOF标准,其特点是具有易扩展性,高开放性及良好的互操作性.MOF方法的核心是一种具有易扩展性的元模型数据管理方法,其实现的方式是对元数据分层.它的特点是提供了一种四层建模结构,支持各种元数据的框架.在需要添加新元模型数据的时候,就可以方便地加入新的类型[9].

MOF的层次分别为M0、M1、M2和M3,且M3∈M2∈M1∈M0.

1)M3层,元元模型层.为领域元模型的提取或搭建,而定义的模型.一般这些模型包括属性、数据类型、关联关系等,是元模型搭建的基础.CVDSL的元元模型包括独立的算子(如读取图片的算子)、单个的语法规则(如赋值语句)等.

2)M2层,元模型层.由上一层模型搭建而来,它的元素包括各个元元模型之间的关系、元元模型的类型等.这一层输出的结果是领域元模型,它是定制领域特定语言语义模型和语法规范的基础.

3)M1层,模型层.这一层的模型由用户使用上一层的模型搭建而来.所以,这一层的模型是元模型层的实例,即用户使用CVDSL编写出来的应用模型.语法检查将基于这一层的输出结果进行.

4)M0层,对象和数据.这一层的结果是现实世界中的事物对象,由上一层的结果通过自动生成的方式得到,比如文档和代码等.

元模型的构建,需要去符合以下两个条件:

1)分析领域模型内部特征的相似性,对相似特征进行合并;

2)对于合并之后的领域模型内部特征,需要在对应的元模型上体现.

元模型的构建过程如图2所示.

图2 元模型的构建流程

本文采用EMF(Eclipse Modeling Framework)作为构建元模型的工具.用EMF搭建的元模型即Ecore模型.Ecore模型是一种简化的UML模型.与UML类似,EMF也可以进行图形化的模型搭建,框架自带了Existing Elements、Classifier、Feature、Relation、Dynamic、Package六大类型,包括Class、Datatype、Attribute、SuperType、Reference等实用基本模型[10].对于开发人员来说可以很方便地通过拖拽的方式搭建CV领域的元模型.

另一方面,由于EMF的模型实例是由EMF框架提供的模型搭建的,如果当模型实例需要修改或者添加的时候,就可以轻易地通过 EMF提供的各种模型对模型实例进行修改或者额外添加一个新的模型实例.EMF中集成的 Class、Datatype、Attribute、SuperType、Reference 等模型即相当于CV领域中的元元模型,用 EMF 搭建出来的模型实例,就相当于CV领域中的元模型,而在设计好的开发平台里用EMF搭建的模型实例再次搭建的模型,就相当于是CV领域的模型实例了.将CV领域的模型实例通过代码自动生成最终将得到模型的目标代码实现.这样MOF的四层结构就很清晰了.

通过对CV领域的分析,确定CV领域元模型的两个主要组成部分如下:

1)基础语法部分.CV领域的实际应用模型中,是需要循环、分支、跳转等基础语法结构的,因此在元模型中,需要有常见的基础语法建模.

2)算子库部分.CV领域应用模型的核心是各种算子的组合调用.本文将所涉及的算子分为两大类:ImageOperators和BasicOperators.其中ImageOperators中包含与图像处理相关的算子,依据算子的功能划分成File、Filter、Matching等23类.其中每一类又依据更具体的功能划分成若干细分类,例如File中的算子被划分成Images、XLD_file、Text、Misc、Region和Tuple六类.每一细分类中则包含具体的算子模型,例如Images中包含用于进行图片读取的算子ReadImage(string path,stringname,string color).BasicOperators中则包含字符串操作、位操作、元组操作、数学函数以及异常处理等相关的算子.

图3 CV领域元模型部分结构图

图3为CV领域元模型部分结构图,其中”a-> b”表示a包含b,”0..*”表示一个a包含0个或多个b,”0..1”表示一个a包含0个或1个b.整个元模型为树形结构,DomainModel为树的根节点.元模型的树形结构是下文建立语法规则树的基础,也是代码自动生成器中,关键字查询匹配的基础.

元模型中不同类型的元元模型的具体构建如表1所示.

2.2 CVDSL语法规则定义

CVDSL的语法规则定义分为以下两步:

2.2.1 元模型的映射

在CV领域中,元模型本身会映射为领域特定语言中的语法框架,每个元元模型会映射为领域特定语言的每条基础语法规则以及算子定义,元元模型的参数会映射成领域特定语言中各条语法规则定义的形参定义.

2.2.2 规则添加

为了领域特定语言语法的正确性与美观,语法规范中除了元模型对应的代码之外,往往还需要加入其它的代码.比如一个分支语句的开始结束要有关键字给予明显的提示;在代码中是否要明确体现每一个模块之间的关联关系等.

表1 不同类型的元元模型示例

本文选择Xtext框架作为CVDSL语法规则定义的工具,因为其支持Ecore元模型的导入.Xtext是一种基于Eclipse的开源框架,配套语言为Xtend,其主要用于DSL的设计与实现.

语法模型映射活动图如图4所示.

图4 语法模型映射

Xtext需要提取元模型语法的关键字与结构,组合它们,产生抽象语法树.在本文中,Xtext的XModelSet()方法会访问EMF项目中的 Model文件夹,捕获所有类名称、属性、相互之间的逻辑关系等[11].

作为DSL来说,本身即是一种不完备的语言,故在定制语法模型的时候一方面不能让基于语法模型生成的代码,在进行语法检查时遇到特征属性缺失等问题.另一方面,要使领域开发人员能够简便地捕捉到DSL代码中的相关信息,从而方便定制代码生成的模板.

CVDSL部分语法规则的Xtend语言形式化描述如下:

DomainModel:(elements+=AbstractElement)*;

AbstractElement:BasicGrammar | Operators;

BasicGrammar:ControlFlow | Assignment |

Import |Arithmetic |Comparison |VariableDeclaration;

Operators:ImageOperatos | BasicOperatos;

ImageOperatos:File |_1D_Measurling | XLD | _3D_Matching |_3D_Reconstruction | Classification | Calibration | Filter | Indentification | Graphics | Image | Inspection | Matirx | Matching | Object | OCR | Morphology | Regions | Segmentation | System | Transformations | Tools | _Tuple;

BasicOperatos:BitOp | StringOp | TupleOp | BooleanOp | TrigonometricFunctions | ExponentialFunctions | NumericalFunctions | ExceptionHandling;

File:Images | XLD_file | Text | Misc | Region | TupleFile;

Images:ReadImage | WriteImage | ListImageFiles | ParseFilename;

ReadImage:′ReadImage′′(′ path=CharacterType‘,’ name=CharacterType(‘,’color=CharcterType)?′)′;

由此可知CVDSL的语法规则框架是继承于元模型的树形结构的.

表2为算子部分和基础语法部分的语法规则定义的Xtend语言形式化描述示例.

表2 算子和基础语法定义示例

因为Xtend的内置数据类型有限,而在CV领域会涉及到丰富的数据类型,如RealType、Tuple、

Matrix等,因此需要在元模型映射的基础上扩展新

的数据类型.具体示例如下:

1)扩展数据类型语法定义示例:

terminalDOUBLE:((′0′..′9′)*(′.′)(′0′..′9′)*);

terminalBOOL:′true′ | ′false′;

terminalTUPLE:′[′(STRING | ID | INT | DOUBLE)*′]′;

terminalMATRIX_TYPE:′[′(TUPLE)*′]′;

2)复合数据类型语法定义示例:

CharacterType:STRING | ID;

RealType:INT | DOUBLE;

其中STRING、ID、INT为Xtend语言内置数据类型,DOUBLE为扩展数据类型.CharterType和RealType为复合数据类型.

2.3 定制语法检查器

CV领域应用模型检查是依据语法规则库,检查在之前步骤中建立的CV领域应用模型,判断这些已经建立的应用模型的语法是否正确[12].

语法检查应以领域特定语言的语法模型为基础,定制模型语法检查器[13].模型语法检查器通过用户对模型的选择,找到其对应的对象根节点,然后找到应用模型对应的CV领域元模型.此时找到领域特定语言相应元模型对应的语法规则,验证用户搭建的应用模型的正确性,与通用语言相同,这种验证应该是一种即时性的验证.同时,在语法检查器中还应该包括警告验证.警告,不一定会导致程序错误,但是可能会提高出错的风险,或者影响用户阅读体验.比如模块名称是由不恰当的字符组成,或者将不同类型的数据进行比较等.无论是错误还是提醒,语法检查器都应该进行快速定位,并将语法检查的结果直观体现在用户界面上.语法检查的流程如图5所示.

图5 语法检查流程

语法检查器的开发同样基于Xtext.Xtext验证机制中提供两个文件:CVDSLValidator.Xtend和CVDSLQuickfixProvider.Xtend.这两个文件,前者主要是添加检查规则,对出现错误的代码进行标注说明,后者主要是针对不同的代码错误提供快速修正的方法.具体实现过程如下:

1)由编辑器中的监视器通知CVDSLValidator.Xtend,用户修改了模型.

2)由typeof()接口,确定模型的类型.

3)再次调用typeof()接口确定检查的属性,或者调用方法的名称.

4)判断相关属性类型,属性值等数据是否符合规范标准.

5)如果符合标准,该次检查结束.如果不符合标准,定位不符合标准的代码位置,执行6).

6)根据具体标准的不同,使用error()或者warning()接口.这两个接口都需要提供代码的定位以便标注,同时为了用户修改的方便,还需要提供相应的提示文字.如果该类错误可控性较高,则将该错误用一串字符串作为特征,调用CVDSLQuickfixProvider.Xtend相应快速修复方法.

7)CVDSLQuickfixProvider.Xtend中的相应方法会得到错误的关键信息,在提示框里对用户提供快速修复按钮.

8)用户点击快速修复后,模型会发生相应变化,故将再次激活步骤1).

算法1描述了在CVDSLValidator.Xtend文件中检查算子首字母是否大写的过程.

算法1.检查算子首字母是否大写:

输入:算子类型参数

输出:在编程界面上提示算子首字母是否大写

1.通过代码生成器中的过滤器获取每一个operator,将其作为参数传入2.中函数

2.defcheckOpetationNameStartsWithCapital:

ifoperator.name.charAt(0).lowerCase==true

warning("Operator′s name should start with a capital",CVDSLPackage.eINSTANCE.operation_Name,INVALID_NAME,operator.name);

算法2描述了在CVDSLQuickfixProvider.Xtend文件中快速修正首字母为大写的过程.

算法2.快速修正算子首字母为大写:

输入:Issue类对象,IssueResolutionAcceptor对象

输出:在编程界面上呈现出将算子首字母修正为大写的提示,双击即可修正

1.将输入中的系统类的对象传入2.中函数

2.defvoidcapitalizeOperationNameFirstLetterWithModel

acceptor.accept( issue,"Capitalize first letter","Capitalize first letter of ′" + issue.data.get( 0)+ "′","upcase.gif",[element,context|(element as Operation).

name=issue.data.get(0).toFirstUpper])

表3 语法检查器运行示例

表3为检查算子首字母是否大写及快速修正的运行示例.

2.4 定制代码自动生成器

领域特定语言虽然在领域相关环境或者人员中具有其独特的优势和作用,但是基于通用性、安全性等的考量,领域特定语言的代码必须能够转换成通用语言代码.

由于计算机视觉领域软件有规模庞大、功能复杂、迭代更新快等因素,再加上人工代码的书写习惯差异及良莠不齐的不确定性,希望人工通过领域语言代码,编写通用代码是不现实的.所以选择代码自动生成是必然结果[14].

代码生成技术可以提高代码质量,增强代码的一致性,也可以突出设计决策或者便于系统的迁移实现.应用模型代码生成技术使设计师拥有更多的设计时间,使得程序员将更多的时间花在系统架构设计上,从而可以提高系统健壮性、可扩展性、以及可维护性.

所以,CV领域软件的非领域代码生成器,应当建立在已经研究的领域语言规则标准及非领域语言规则标准之上,然后将开发过程中各个阶段的模型集成,从而形成统一且符合规则标准的持久化模型文件,然后将这些模型文件通过代码生成器生成出符合已有标准的通用代码.

代码自动生成器的开发同样基于Xtext框架,因为其可满足代码自动生成器对于良好扩展性的需求.代码自动生成器主要由元模型分析数据、应用模型分析数据、生成通用代码的模板以及环境配置工具组成,其设计的核心思想是制定CVDSL与C++间的映射关系,确定每一条合法的CVDSL语句将对应的C++代码块.当代码生成器获取到CVDSL的应用模型后,会依据上文中建立的语法树,检索每一行代码,确定它所对应的元元模型类型和语法规则,然后依据该语句与C++代码块的映射规则,进行代码生成.图6为代码自动生成活动图.

图6 代码自动生成活动图

算法3描述了CVDSL代码自动转换为C++代码的过程.

算法3.CVDSL代码自动转换C++代码模板

输入:Resource类对象,IFileSystemAccess类对象,IGeneratorContext类对象

输出:生成的C++代码文件

1.对classCVDSLGeneratoreXtendsAbstractGenerator中的函数doGenerate进行重写

2.在函数overridevoiddoGenerate(Resource resource,IFileSystemAccess2 fsa,IGeneratorContext context)中,对CVDSL中的每一个元元模型进行遍历,然后调用相应的映射模板进行代码生成

for(e:resource.allContents.toIterable.filter(AbstractElement)):

/*调用自定义的映射模板中的函数,获取每一行CVDSL代码所对应的C++代码块,并进行存储*/

fsa.generateFile(/*这里包含两个参数:①所生成的文件名②上文中已获取的所需生成文件的内容*/)

算法4描述了ReadImage算子的代码生成过程.

算法4.ReadImage算子代码生成模板

输入:CVDSL中的ReadImage类型变量

输出:ReadImage对应的C++代码

1.将ReadImage变量作为参数传递给compile函数,在complie函数中,解析ReadImage的参数,并用content记录对应的C++代码

varcontent=′′′′′′

content+=′′′Mat ′′′

content+=readImage.name.compile

content+=′′′=imread(′′′

content+=readImage.path.compile

content+=′′′,′′′

if(readImage.color==null)

content+="IMREAD_COLOR"

else

content+=readImage.color.compile

content+=′′′)′′′

2.返回content

returncontent

3 实验及评估

3.1 实 验

3.1.1 实验过程

本实验邀请了四位领域工作者,并提前对他们进行了两种语言的培训.而后将他们分为两组,分别使用CVDSL和C++来开发猫眼识别、人脸识别和人脸定位三个CV应用模型,并对开发时间以及代码量进行了对比.

3.1.2 实验结果及评估

实验结果如表4、表5所示.从表4可知,采用CVDSL的开发效率约为采用C++的3倍.从表5可知,采用CVDSL开发的代码量约为采用C++的0.5倍.由此可得到初步结论:在CV领域,使用CVDSL编程比C++编程效率更高,所编写的代码量更少,更加面向领域工作者,凸显出了CVDSL的易用性和高效性.

表4 CVDSL与C++开发时间对比

表5 CVDSL与C++代码量对比

表6为猫眼识别应用模型示例,对比CVDSL源码和所生成的C++代码,可知CVDSL具有以下优点:

1)语法规则严格统一;从表6可知,使用C++调用不同底层算子库中的算子时,在语法上是存在差异的.CVDSL在语法规则定义上,统一了所有算子的语法风格,通过代码生成器中制定的映射规则将这些差异透明化,从而可以极大降低领域工作者的编码难度.

2)相关头文件及代码自动补全;在表6中,生成的C++代码中编号为0的行,是依据函数体中使用的相关算子自动补全的,既减少了领域工作者的编码量,又降低了bug的出现率.

3)算子合并;在构建CV应用模型时,很多时候某些算子间有着严格的调用次序,那么在构建元模型和定制语法规则时,可将这些算子进行合并.例如本例中CVDSL代码中编号6的代码行,在通过代码生成后得到了对应C++代码中编号为6的两行代码.通过算子合并的方式可以极大降低领域工作者的编码难度和编码量.

4)保证算子性能较优;通过前期的充分调研,以及与多位CV领域专家、工程师的充分沟通,本文对实现不同功能的算子的性能进行了评估.例如Halcon中与域处理相关的算子的性能要优于其他算子库中的相应算子,因此在进行代码生成时,以Region为前缀的算子,在生成的C++代码中,默认调用Halcon中的相应算子.这样领域工作者在进行编码时,仅需考虑算子的功能,而无需考虑算子的性能优劣,这在很大程度上提高了其编码效率.

5)隐藏不同算子库中变量的声明;不同算子库中的某些变量,在C++代码中有着不同的变量类型.例如OpenCV用Mat来表示图像类型,而Halcon中用Himage来表示图像类型.CVDSL通过在代码自动生成器中判别不同算子所属的算子库以及算子的参数类型,生成相应变量声明的C++代码.同时CVDSL对不同类型变量的转换进行了封装.这一过程对于领域工作者是透明的,从而降低了其编码难度.

3.2 基于FQAD对CVDSL的评估

FQAD是基于ISO/IEC 25010:2011标准的用于DSL定性评估的框架[15].该框架定义了一套评估DSL质量的特性,包括:功能适用性,可用性,可靠性,可扩展性,可集成性,可维护性,生产力,兼容性,表达性和可重用性.本文基于以上特性,对CVDSL作出了如下评估:

1)功能适用性是指DSL完全开发的程度,即判断DSL是否包括所有必要的功能且不包括域中不存在的功能.CVDSL拥有完整的面向于域的语法定义,且其底层有多个计算机视觉算子库的支持,并支持算子库的扩展,因此可以满足大部分计算机视觉应用模型开发的需求.且其语法规则不具有普适性,仅面向计算机视觉领域.综上可知CVDSL拥有良好的功能适用性.

2)可用性是指用户可以使用DSL来实现指定目标的难易程度.为分析CVDSL的可用性,本文邀请多位CV领域专家和CV领域工程师对CVDSL进行了评估,得出的结论是:CVDSL简单且具有表现力,相对容易学习.与通用编程语言C++相比,CVDSL降低了构建CV应用模型的复杂性,并提高了可理解性和可维护性.综上可知CVDSL的可用性极高,未来可通过完善用户使用手册来进一步提高CVDSL的可用性.

3)可靠性是指生成可靠程序语言的属性.CVDSL语法规则的定义较为完善,并且本文针对CVDSL的语法规则及CV领域C++代码风格定制了语法检查器,大幅度减少了在编码过程中可能产生的语法错误.同时本文设计实现了基于模板映射的的代码自动生成器,使得每一行CVDSL代码能够转换成对应的C++代码块,确保了C++代码风格的统一.以上都是CVDSL可靠性的保证,未来可通过在CVDSL级定制调试器来进一步提高CVDSL的可靠性.

4)可扩展性是指DSL添加新功能的难易程度.本文是采用模型驱动开发的方式对CVDSL进行建模、设计与实现的,因此可方便的通过扩展元模型来实现对CVDSL功能的扩展,可见CVDSL拥有很好的扩展性.

表6 猫眼识别应用模型示例

5)可集成性是指DSL与其他语言和建模工具集成的难易程度.CVDSL的开发是基于EMF工具和Xtext框架的,两者均属于Eclipse框架中的插件.Eclipse平台允许开发人员通过插件扩展Eclipse IDE等Eclipse应用程序以及其他功能,故未来可将CVDSL语言框架开发为Eclipse框架中的插件,然后使用Eclipse IDE和整个OSGI组件模型来完成CVDSL和其他语言的集成.

6)可维护性是指DSL易于维护的程度.可维护性与可扩展性相关,上文中已说明CVDSL具有很好的可扩展性,并且CVDSL的构建是基于元模型的,故易于修改和完善.由此可知CVDSL是具有良好的可维护性的.

7)生产力是指DSL提高编程效率的程度.CVDSL仅面向计算机视觉领域,因此与通用编程语言相比,在领域概念的描述上有着明显的优势,便于领域工作者的建模.从上文的实验中可知使用CVDSL开发CV应用模型的效率约为C++的3倍,大大提高了领域工作者的开发效率.

8)兼容性是指DSL与域和开发过程的兼容程度.CVDSL是基于CV领域元模型的,因此与CV领域有很好的兼容性.同时CV领域元模型的构建与CV应用模型的开发过程密切相关,这使得CVDSL与开发过程也有着良好的兼容性.

9)可重用性是指DSL的语言结构在其他语言中的使用程度.CVDSL本身的语言结构是唯一的,但为CVDSL所定制的基于模板映射的代码自动生成器是可重用的,通过修改映射规则,CVDSL可以转换成任意一种通用编程语言.同时CVDSL底层的算子库也是可重用的,凡有相应算子库接口的语言均可调用.

10)表达性是指问题解决策略映射为程序的难易程度.CVDSL的语法规则是针对CV领域而定制的,因此其对于任何CV应用模型都有很好的表达性.与C++相比,CVDSL封装了很多与问题解决策略无关的编程细节,如类型转换等.通过使用CVDSL,领域工作者可以轻松的将问题解决策略映射为程序.在CV领域,CVDSL有着强大的表达性.

3.3 CVDSL与Halide的性能比较

Halide是面向图像处理的著名领域特定语言,比起传统编程语言,用Halide编写的程序不仅更容易阅读、编写和修改,而且由于Halide能够自动优化代码,因此程序运行速度也显著提高[16].Halide语言将算法描述、算法中数据存储与计算执行等调度方便的内容解耦合,从而算法的描述和性能的优化可以分开进行,可在不改动算法的情况下对算法进行调优[17].

下面基于FQAD中定义的特性,对CVDSL与Halide进行性能比较:

1)功能适用性:Halide和CVDSL均只面向计算机视觉领域,在语法上均不具有普适性,且均能满足大部分计算机视觉应用模型的开发,因此都具有很好的功能适用性.但在对代码性能要求更高的情况下,Halide要优于CVDSL.

2)可用性:Halide不是独立的编程语言,而是嵌入在C++中的.在语法上,相比较于CVDSL,要复杂一些,CVDSL更易于学习和使用.可用性上CVDSL要优于Halide.

3)可靠性:Halide是非常成熟的商用编程语言,有独立的编译器,能在多种操作系统上运行,且其能自动优化代码.而CVDSL目前没有独立的编译器,仅提供从CVDSL到C++的代码自动生成器.因此在可靠性上比Halide稍差一些.

4)可扩展性:Halide是成熟的商用编程语言,普通用户很难在功能上进行扩展.而具有开发经验的用户可通过扩展元模型,方便的对CVDSL进行功能扩展.Halide提供C++API,甚至可以将Halide中功能强大的算子扩展到CVDSL中,因此CVDSL有着更优的可扩展性.

5)可集成性:CVDSL是一门独立的语言,因此很难做到和其他语言集成,但后期可将CVDSL开发成Eclipse的插件,因此可将其与其它建模工具进行集成.Halide在某种意义上可看做一个函数库,因此它可与其它提供接口的通用编程语言进行集成.由此可见在不同层面上,CVDSL和Halide都有较好的集成性.

6)可维护性:CVDSL的构建是基于元模型的,具有良好的维护性.Halide作为一门著名的编程语言,同样具有很好的维护性.

7)生产力:CVDSL语法更简洁,底层算子库更庞大.但Halide对于代码的优化更好,因此两者都可以大大提高领域工作者的开发效率.对于不同的开发需求,两者所能带来的效率提升则不同.

8)兼容性:CVDSL和Halide都是仅面向计算机视觉的编程语言,因此两者与域及开发过程必然具有很好的兼容性.

9)可重用性:CVDSL的可重用性体现在基于模板映射的代码生成器.而Halide有着独立的编译器,其语言结构很难在其他语言中重用,因此CVDSL相比较于Halide,有着更好的可重用性.

10)表达性:CVDSL与Halide对于任何CV领域的问题,都可以方便的将解决策略映射为程序,因此两者都具有很好的表达性.

综上可知,CVDSL与Halide各有优劣,选择哪门开发语言完全依赖于开发需求.

4 总 结

本文基于CV领域元模型,采用模型驱动开发的方式,设计实现了一种面向计算机视觉的领域特定语言——CVDSL.本文首先分析了CV领域元模型的结构及构建方法,然后在领域元模型的基础上,定义了CVDSL的语法规则,并依据语法规则定制了语法检查器,以减少在使用CVDSL编码过程中出现的语法错误.最后本文基于模板映射规则,设计实现了将CVDSL转换为C++的代码自动生成器,保证了其通用性和安全性.

本文通过实验和FQAD框架,对CVDSL做了详细评估,分析了CVDSL所具有的优势和特性,并依据FQAD对CVDSL和Halide进行了比较.在未来的工作中,可通过定制CVDSL级调试器来提升其可靠性,并可通过将CVDSL语言框架封装成Eclipse插件的方式来提升其可集成性.

猜你喜欢

算子代码语法
有界线性算子及其函数的(R)性质
Domestication or Foreignization:A Cultural Choice
跟踪导练(二)4
QK空间上的叠加算子
参考答案
神秘的代码
一周机构净增(减)仓股前20名
一行代码玩完19亿元卫星
近期连续上涨7天以上的股