一种基于矩阵模型的多计算引擎的自动选择方法
技术领域
本发明涉及自动化调度领域,尤其涉及一种基于矩阵模型的多计算引擎的自动选择方法。
背景技术
矩阵是机器学习和数据挖掘中的重要模型,矩阵乘法、转置、分解等运算都是许多机器学习算法中必要的方法。在常用的数据分析计算的语言中,Matlab和R就是基于矩阵模型,它们在小规模矩阵运算执行速度很快。在大数据时代下,随着矩阵规模的扩大,单机计算存在规模上限,已经难以有效地存储和计算矩阵。随着MPI、Hadoop、Spark等分布式计算框架的出现,通过将矩阵数据划分存储到分布式系统中的各个机器上进行存储和计算,实现高效的大规模矩阵运算。然而,不同的分布式平台有着自己的优势,如MPI执行速度快,Hadoop适合批量运算,而Spark基于内存计算、容错性好。因此,矩阵运算在不同的计算平台上,随着数据规模的变化,执行的时间是互有优劣的。因此,在有多个计算平台的情形下,给定一系列的矩阵操作,如何将操作选择在不同的计算平台执行,使得总体运行时间最短,这就提出了自动化选择的挑战。
在自动选择中,需要对程序结构进行分析,数据流图是很重要的一种方法。DFG(DataFlowGraph,数据流图),是有向图,它通过图的形式来表达数据的流向。图中的每个节点都表示为对输入数据的某种操作,计算出来的数据又通过箭头流向下一个节点。通过数据流图,就可以分析出程序中包含哪些矩阵操作、矩阵的数据流向以及矩阵操作间的数据依赖。
以往的相关工作有基于CPU、GPU、FPGA三种平台的选择,它是对程序文件进行分析,文件中包含一系列的矩阵操作。通过对程序进行数据流图分析,根据矩阵操作在不同平台的执行时间以及数据在不同平台间的传输时间,将每个矩阵计算都映射到某个平台中计算,从而减少程序的总体执行时间。然而该工作仍是基于单机的,只能处理小规模的矩阵运算的选择。当矩阵规模很大时,单机都无法存储、计算,选择也就没有任何意义。
发明内容
发明目的:针对上述现有技术存在的问题和不足,本发明的目的是提供一种基于矩阵模型的多计算引擎的自动选择方法,解决了现有的矩阵计算平台单一、性能低、应对矩阵规模变化的能力不足的问题。
技术方案:为实现上述发明目的,本发明采用的技术方案为一种基于矩阵编程模型的多计算引擎的自动选择方法,包括以下步骤:
(1)采用矩阵作为编程模型,R作为编程语言,在R中去调用不同计算引擎的矩阵操作实现;
(2)通过对不同规模的矩阵,计算不同计算引擎下执行不同操作的时间,进行分析建模得到时间性能模型。同时对不同引擎间不同规模矩阵数据的传输时间建模,得到时间性能模型;
(3)对R程序进行语法分析,构建矩阵操作的数据流图,根据(2)得到的时间性能模型,根据总体执行时间最少的原则,将每个矩阵操作映射到某个计算引擎上;
(4)根据(3)中矩阵操作和计算引擎的映射,对R程序进行语法分析,将设置好的引擎信息添加到R语言程序中,得到最终的执行解决方案。
进一步地,所述步骤(1)中,采用标准的矩阵模型,在R中通过包的形式提供矩阵API,而这些API封装并可以调用不同计算引擎的矩阵操作的实现,通过选择计算引擎执行矩阵操作,使得执行时间在所述步骤(1)中性能最优。
进一步地,所述步骤(2)中,时间性能模型是通过标准的OLS(OrdinaryLeastSquare,普通最小二乘法)多元线性回归模型拟合得到,拟合的参数是矩阵的规模。
进一步地,所述步骤(3)中,通过R中parse函数分析程序得到语法树,并对语法树进行递归分析,针对矩阵操作构建数据流图,其中每个节点含有的信息包括矩阵的操作类型、矩阵规模、矩阵ID标识、父节点、子节点、不同引擎完成操作的时间。此外,矩阵的初始化时指定的行列数是参数形式,可以通过R语言中的eval函数对R语言程序在进行静态语法分析时计算值,从而得到矩阵的实际规模。
进一步地,所述步骤(3)中:根据矩阵操作时间模型和数据传输时间模型,对数据流图进行递归分析,每次计算一个节点,遍历所有计算引擎,得到计算矩阵操作时间以及需要的数据传输时间,当计算到最后一个节点时,计算得到最优的总体执行时间和对应的矩阵操作的执行引擎。此外,在递归过程中通过剪枝策略减少递归次数,如果当前节点前的总体时间大于已有的所有节点的执行时间,则不再递归下去。
进一步地,还包括步骤(4):对R程序进行语法分析,其中涉及矩阵操作的程序进行重写,每个矩阵操作单独作为一条语句,如果矩阵需要在不同计算引擎中计算,添加转换程序将转换后的矩阵作为新的变量在后面的程序中使用。
有益效果:本发明能够高效地执行矩阵操作,降低总体矩阵操作时间:第一,设计一个矩阵模型来存储数据,所有的计算和操作都是通过矩阵实现,暴露给用户使用的矩阵API封装了单机平台R、分布式平台MPI、Spark等矩阵操作的实现,实现了矩阵操作的可选择性;第二,设计了矩阵操作的执行时间与矩阵规模之间的模型。通过少量训练数据的矩阵运算时间的分析和拟合,得到了在不同计算平台下,不同的矩阵操作执行时间随着矩阵规模变化的模型,这样可以预测任意规模的矩阵完成操作的时间。同时也对不同计算平台下数据之间的传输时间与数据规模之间进行建模和预测;第三,通过对程序的语法分析,构建出矩阵运算的数据流图,估计每个数据流图节点的完成时间,并针对数据流图进行递归计算每个矩阵运算所执行的计算引擎,得到最优的执行时间。
附图说明
图1为本发明的方法总体框架示意图;
图2为本发明中矩阵操作时间随时间规模变化的最优的执行引擎示意图;
图3为本发明中针对LogisticRegression程序分析出的数据流图示意图。
具体实施方式
下面结合附图和具体实施例,进一步阐明本发明,应理解这些实施例仅用于说明本发明而不用于限制本发明的范围,在阅读了本发明之后,本领域技术人员对本发明的各种等价形式的修改均落于本申请所附权利要求所限定的范围。
如图1所示,本发明的完整流程包括设计矩阵模型、构建时间建模、构建矩阵操作的数据流图、最优化计算引擎分配和执行解决方案生成5个部分。具体的实施方式分别说明如下:
设计矩阵模型的具体实施方式为:矩阵模型是个抽象的矩阵类(基类),每个计算引擎类型(如R、Spark)都继承基类,并实现基类定义的方法,如矩阵转置、分解,这样就具有了动态绑定的好处,会根据子类去对应的计算引擎上执行方法,并且当多加一种计算引擎后,只要继承基类并实现方法,无需改动其它已写好的程序。而如矩阵乘法等涉及多个矩阵运算的操作时,可能会出现类型不一致的情形,如R的矩阵和Spark的矩阵相乘,这时通过定义一个优先级(如Spark>MPI>R),将低优先级的矩阵转换为高优先级的矩阵,这样同类型的矩阵就可以执行运算。当新加一种计算引擎时,只需要将该引擎类型添加到优先级中,而无需更改具体的实现程序。在R中实现该矩阵模型,提供成包的形式以供使用,暴露的API为基类的矩阵操作。
构建时间建模的具体实施方式为:对于矩阵操作时间的建模,采用的矩阵规模为(10,100,1000,100000,100000),行列值均为上述某个值。这里以矩阵乘法为例进行详细阐述:假定进行乘法的矩阵分别为A和B,对不同规模的A和B相乘并记录完成时间,得到(矩阵A行数,矩阵A列数,矩阵B列数,执行时间)这样形式的很多条记录,因为其它环境配置都未变,因此造成乘法完成时间不同是因为矩阵A行数、列数和矩阵B列数的变化,通过普通最小二乘法对因变量进行拟合,得到乘法的时间性能模型。值得注意的是,这里的因变量不一定只有矩阵A行列数和矩阵B列数,也有可能形如(矩阵A行数*矩阵A列数*矩阵B列数)这样因变量的组合,这里需要对每种引擎的实现去估计可能影响时间性能的因变量。而对矩阵数据在不同引擎之间的建模,因为矩阵之间的传递是通过分布式内存文件系统Tachyon实现的,因此只需建模不同引擎在Tachyon上读写不同规模矩阵的时间,而建模读写时间和建模矩阵操作时间类似。
图2是基于计算时间的设计空间图表(DesignSpaceChart),共有R、MPI、Spark三种计算引擎,纵向表示分析的矩阵操作共有矩阵标量乘、矩阵乘法、矩阵转置和矩阵apply四种操作,其中apply函数又分按所有元素、按行、按列三种形式。横向从10到10万,表示矩阵的规模(行列相同),横纵向的交汇表示在该规模下改种操作采用哪种引擎最优。从图示结果来看,不同的计算引擎都有着各自的优势。
构建矩阵操作的数据流图具体实施方式为:假定文件A是使用提供的矩阵API写出来的程序,通过R中的parse函数对A中程序进行语法分析,得到语法树(存储为嵌套列表)。对语法树的递归遍历,提取出矩阵操作作为节点(每个节点当作成一个矩阵),构建数据流图。在构建每个节点时,需要记录该矩阵操作类型、依赖的父节点、操作完成后矩阵的大小、矩阵的全局唯一ID标识(按计算的顺序递增)以及不同计算引擎完成该操作的时间。其中,识别变量是否为矩阵通过以下三点支持:1)只有通过初始化函数才能得到矩阵;2)对每个赋值语句中变量加入集合,以便判断该变量是否为矩阵;3)对矩阵操作的函数如转置、乘法等结果还是矩阵。在初始化矩阵时候,需要指定行列数,而行列数可能是变量而不是具体的数值。解决方法采用R中eval函数可以对先前该变量的定义进行计算并保存到环境中,而后在该环境取出该变量值,这样就在静态语法分析中实现变量值的计算。
最优化计算引擎分配的具体实施方式为:因为节点的ID标识是根据矩阵执行顺序依次递增的,保证了父节点的ID肯定小于子节点的ID,所以可以根据ID标识递归遍历数据流图。在处理每个节点时,需要知道的信息有执行到当前节点的总时间TimeA、暂时最优的数据流图总执行时间AllTime、每个节点所采用的计算引擎。依次遍历所有引擎类型,将TimeA加上当前节点在该计算引擎上完成时间,并且如果当前节点依赖的父节点的类型不是该引擎类型,则还需要加上类型转换的时间,如果加完后的时间小于AllTime,则递归计算下一个节点,否则遍历下一个引擎类型。通过上述递归加剪枝的策略,可以快速计算出最优的每个矩阵操作节点所对应的计算引擎类型。此外,数据转换是通过分布式文件系统Tachyon实现的,文件会被保存在内存中。而在转换时,可能会出现一个节点的矩阵被转换成其它类型矩阵多次的情形,为了减少多次转换的时间,在递归的时候添加了一个映射表,表明哪些节点被转换成哪些类型过。如果节点再次被转换成相同类型时就直接复用上次转换后的矩阵,这样减少了转换的时间;如果节点转换成不同的类型矩阵时则减少了数据存储的时间。
执行解决方案生成的具体实施方式为:通过对程序的再次语法分析,根据上述步骤中得到的矩阵操作(即数据流图节点)对应的计算引擎映射,在源程序基础上重新生成需要执行的程序。重新生成程序的规则如下:1)对有中间结果的矩阵操作将中间结果的矩阵操作重新写成一行程序;2)如果需要类型转换,则添加类型类型转换程序。比如对于程序A<-B%*%(C+D),其中%*%表示矩阵乘法,假设B是Spark类型矩阵,C、D是R类型矩阵,结果A是Spark类型矩阵。则改程序被翻译成“tmp<-C+D;tmp_Spark<-AsOctMatrix(tmp,“Spark”);A<-B%*%tmp_Spark;”三句。第一句是将C+D这个中间结果赋值给变量,对应规则1);第二个将R类型的tmp矩阵转换成Spark类型的矩阵,对应规则2);第三句正确调用转换后Spark类型的矩阵。为了实现上述功能,需要增加一个节点ID到节点变量名的映射表,这样就可以根据ID去正确调用变量名。对于中间结果,如tmp节点,命名是自动生成的,后面以节点ID标识结尾保证变量名不重复。同时为了实现转换过矩阵转换成相同类型时不再转换的功能,还需添加一个映射表,记录节点ID和对应转换成某种类型的变量名,如tmp节点的转换成Spark类型矩阵的变量名为tmp_Spark,命名自动生成并防止重复性。
本发明基于已有的一些开源软件实现了一个原型系统。其中底层数据存储使用HDFS,不同计算引擎中数据转换采用Tachyon,计算引擎的矩阵实现均采用开源实现(如R使用自带矩阵操作,Spark使用Marlin)。上述软件不属于本发明的内容。
通过对LogisticRegression(逻辑斯蒂回归,简称LR)程序对本发明实现的原型系统进行测试,图3是原型系统对逻辑斯蒂代码构建的数据流图(每个节点上数据分别表示节点ID、节点操作类型、节点矩阵规模、计算引擎完成操作的时间)。表1是对数据流图节点的R和Spark计算引擎的真实时间和预测时间的对比。从表格中可以看出,大部分的预测和实际值误差是可接受的,而对于Spark而言因为其延时计算的性质和阶段的划分,会导致一些节点的计算时间出现偏差(如ID6和8),然而这些因素无法避免。从最后一行的时间可以看出,逻辑斯蒂回归总体执行时间的预测在两个计算引擎上都可以接受。从图3可以看出,最终执行时,LR程序在Spark计算引擎上执行时间最优,其中不涉及到矩阵在不同平台间的选择执行,这点从表1中也可间接验证。