用于在Jacinto™7处理器上进行异构计算的OpenVX框架
让我们通过一个简单的OpenVX“Hello world”程序来说明OpenVX编程模型。在OpenVX中,执行发生在所谓的OpenVX上下文中。首先,我们创建一个OpenVX上下文。在这个上下文中,可以创建和执行多个OpenVX图形。
接下来,我们创建将在上下文中使用的数据对象。在这种情况下,我们有一个输入图像和一个输出图像。在创建数据对象之后,我们创建将在其中使用这些数据对象的图表。在本例中,我们需要处理节点之间的中间图像。
为了利用中间对象的优化,我们可以创建一个虚拟映像,它是在图的上下文中创建的。然后,建立图形、数据对象和处理节点之间的关系,处理节点由OpenVX节点api指定。
下一个调用是针对节点F1的节点API的,该节点将我们创建的输入图像作为输入,并将中间图像作为输出。该节点属于前面创建的图。类似地,我们创建节点F2,它将中间图像作为输入,将输出图像作为输出。
创建此图之后,我们调用OpenVX提供的验证图API。除了验证图的参数之外,这个API还允许实现根据底层图的特征来优化图。例如,在本例中,一个实现可以完全消除F1和F2之间的中间数据对象,因为它可以通过内部内存或某种类型的小缓冲区(而不是完整的图像大小)将数据从F1流到F2。
由于Verify Graph调用具有完整的图信息和特征,因此可以执行许多此类优化,具体取决于实现是否启用了这些优化。一旦验证了图形,用户调用vxProcessGraph来执行图形。用户可以根据需要多次调用它。
这展示了一个非常简单的OpenVX API示例。现在创建并执行图形、数据对象和节点。我们简单的OpenVX API示例到此结束。
如果您想了解更多关于如何使用OpenVX进行编程的信息,可以参考Khronos提供的YouTube系列,提供关于如何使用OpenVX 1.1标准的教程。上面显示了这个系列的链接。本模块的下一个视频将比较OpenVX和其他流行的计算框架。
TI的OpenVX框架的源代码包含在处理器SDK Automotive中。
你好。欢迎来到这个关于OpenVX框架的演讲。在上一个视频中,我们查看了一个简单的OpenVX示例,以理解OpenVX编程模型。在本视频中,我们将把OpenVX框架与其他流行的计算框架进行比较,看看OpenVX框架所提供的价值。
为了进一步介绍OpenVX的优点,现在让我们将OpenVX框架与其他流行的计算框架OpenCL和OpenCV进行比较。与OpenVX类似,OpenCL是由Khronos Group创建和维护的,两者都是开放api。这些规范的供应商都在他们的设备上实现了这个API,以获得最佳性能。另一方面,OpenCV是由英特尔创建的,并拥有BSD许可。
OpenCL编程模型由一个运行时控制框架组成,该框架允许并行计算。这通常用于跨CPU和GPU的优化并行计算。尽管在某些情况下,这也可以用于带有DSP的并行计算,如果供应商启用了这一点的话。
OpenCV本质上是一个庞大的计算机视觉功能库,用于cpu或gpu上。这些视觉功能在性能上是不可移植的,可能需要针对特定平台进行优化。OpenVX由一个基于图的编程模型组成,该模型允许跨异构核进行分布式计算。OpenVX标准由一组最小的vision函数组成,同时提供了一个简单的接口来扩展这个函数列表。
供应商可以基于系统中可能包含的特定硬件实现定制功能。与open OpenCL和OpenCV不同,OpenVX除了提供更传统的内核外,还可以提供到定制硬件的接口,比如异构架构中的gpu和dsp。
这张幻灯片演示了OpenVX与OpenCV的关系。首先,OpenCV是一个开源库,设计用于在CPU上处理一些GPU加速。相反,具有不透明内存模型的OpenVX更适合使用硬件加速器进行计算。
接下来,有许多OpenCV测试可以用来验证功能,但不能保证整个API在给定的设备上可用。OpenVX更好地保证了所有承诺的功能都是可用的,因为所有实现都必须通过一个定义好的一致性测试套件。其次,虽然OpenCV是一个巨大的库,通常有重叠的定义,是专门为桌面开发的,但OpenVX要小得多,强调嵌入式视觉,并提供了一个简单的接口,用于用内核扩展列表。
接下来,在OpenCV中,函数通过主系统内存进行通信,而在OpenVX中,图形和不透明内存模型提供了更多的优化机会。最后,虽然OpenCV有利于快速构建原型和探索,但OpenVX通常是在移动和嵌入式设备上部署优化实现的更好解决方案。
考虑到OpenCV和OpenVX的不同优势,开发人员可能希望在他们的应用程序中结合使用这些api。这里有两种不同的方法可以实现这一点。第一种方法是在OpenVX图形和单独的OpenCV函数之间共享缓冲区。
OpenVX提供数据对象作为OpenVX图形的输入和输出参数。每个数据对象都有一个关联的map和unmap API,用于传输与该对象对应的数据缓冲区的访问。这个数据缓冲区可以与OpenCV函数共享,在CPU或GPU上执行计算。
OpenCV与OpenVX结合使用的另一种方式是将OpenCV API调用封装在一个自定义用户节点中。OpenVX提供了一个简单的API,用于扩展OpenVX图中可用的节点列表。因此,可以创建一个调用OpenCV的新的OpenVX自定义节点。这个节点可以在CPU上运行OpenCV api。
类似地,开发人员可能需要同时使用OpenCL和OpenVX集成应用程序,以利用每种编程模型的各种优势。与OpenCV类似,可以创建一个运行OpenCL的专用用户节点,并将其添加到OpenVX节点列表中。然后可以在OpenVX图中实例化这个节点。OpenCL节点可用于利用OpenCL提供的优势,它允许CPU和远程核心(如GPU或DSP)之间频繁协作。这种编程模型允许开发人员利用OpenVX提供的优势,它允许开发人员访问所有专用加速器和远程片上内核,并利用OpenCL的优势。
本视频结束了介绍OpenVX的模块。在下一个模块中,我们将概述TI的OpenVX实现。TI OpenVX的源代码包含在处理器SDK Automotive中
讨论TI支持的官方OpenVX规范和扩展。
TI符合由Khronos组定义的OpenVX 1.1规范。为了被认为符合OpenVX 1.1规范,实现者必须通过一组与该版本OpenVX规范相关联的一致性测试。因此,TI已经将我们的实现提交给Khronos,并且符合1.1规范。
OpenVX的1.1规范包含许多特性,这些特性使它成为TI soc的理想选择。OpenVX 1.1规范的基于图的框架允许在TI的soc上实现最优映射和定制算法。此外,该框架易于扩展,开发人员可以将其自定义算法作为内核插入到框架中。
除了1.1规范中提供的数据对象之外,TI还实现了1.2规范中的张量数据对象。在标准数据对象和张量对象之间,包含在TI实现中的数据对象是深度学习和视觉处理应用的理想选择。
最后,OpenVX 1.1规范包含43个计算机视觉内核,这些内核都针对TI的C66x DSP进行了优化,可以在Jacinto soc上使用。TI是Khronos OpenVX工作组的众多领导者之一,他们定义了OpenVX规范的未来版本。除了TI,许多其他著名的行业领袖也在他们的设备上实现了OpenVX API,并将其实现提交给Khronos以确保一致性。与TI类似,许多其他公司也遵循了1.1规范。
除了OpenVX的1.1规范,TI还支持多个官方的Khronos扩展。第一个扩展是管道和流扩展。这个扩展的目的是允许应用程序开发既高效又简化目标体系结构。
具体来说,此扩展中引入的流水线api允许应用程序开发人员充分利用TI的SOC的异构性,当节点在SOC的不同内核上运行时,允许执行多个正在运行的图。此外,流扩展通过提供一个简单的API来调度OpenVX图形,简化了单一传感模态应用程序的开发。通过简化OpenVX图形的调度和减少应用程序中的代码量,这有利于基于OpenVX的应用程序的开发人员。
最后,TI支持官方的Khronos OpenVX用户数据对象扩展。虽然OpenVX 1.1规范包含了创建vision和深度学习应用程序所需的许多必要数据对象,但应用程序开发人员可能需要制作定制的数据对象来提供给他们的定制内核。用户数据对象扩展允许应用程序开发人员基于定制的数据结构定义新的数据对象,该数据结构可以注册到框架中,以便在应用程序中使用。
用户数据对象通常用作OpenVX扩展内核的配置对象,因为它们通常需要自定义输入来配置给定的算法。这对OpenVX开发人员来说是一个明显的好处,因为它允许在创建OpenVX数据对象时具有更大的灵活性。
TIOVX的目标是帮助客户最大化TI平台上的性能,同时提供一个简化的开发环境,从而最小化开发成本。OpenVX有几个方面可以提高性能并降低开发成本。为了帮助最大化性能和进一步降低开发成本,TI在OpenVX工具中提供了自定义扩展,以便为客户带来最大的好处。这张幻灯片涵盖了围绕TIOVX的几个细节。
TI的OpenVX实现是如何最大化性能的?首先,它利用了基于图形的编程模型,其中所有的工作都在初始化或图形验证时定义。这允许实现最大化系统利用率和最小化运行时延迟。
此外,TI soc上可用的所有异构计算核心都在一个统一的标准API下导出。因此,可以在OpenVX API下使用TI的Jacinto 7 soc上的C7x/MMA、VPAC和DMPAC等异构内核。
接下来,OpenVX包含了作为1.1标准一部分的预定义内核。这些内核在TI的C66x DSP上进行了优化,并在适用的情况下映射到硬件加速器上,例如使用Scale Image OpenVX内核。最后,TI提供了示例OpenVX内核,展示了如何集成DMA接口来平铺访问数据缓冲区,通过并行内存访问和计算极大地提高了性能。TI的OpenVX实现通过这些不同的向量来优化性能。
TIOVX如何帮助降低开发成本?首先,作为一个开放标准,OpenVX提供了一个易于使用的API。TI的实现符合OpenVX的1.1规范,并实现了在上一个视频中描述的对该标准的某些官方OpenVX扩展。接下来,所有的软件抽象都由一个瘦平台层处理,使TIOVX能够支持不同的软件环境,如Linux、QNX和TI-RTOS。此外,这个薄平台层允许TIOVX很容易地移植到其他操作系统。
此外,硬件抽象也由实现来处理,以便相同的应用程序可以跨不同的Jacinto soc工作。这允许客户在TI的Jacinto家族的不同soc上保持他们的投资。
最后,为了便于使用,TI提供了一个基于pc的开发环境,用于创建OpenVX代码的原型。这允许在基于pc的环境中进行更快的开发。TI还提供了用于生成定制内核的代码生成工具,允许客户快速地将自己的定制算法集成到TI的OpenVX框架中。有关这些易于使用特性的信息,请参见本模块中的视频4。所有这些开发特性都使客户获得了TI的soc上的全部权利,并且通常消除了进入OpenVX开发的障碍。
这就结束了我们对TI OpenVX框架实现细节的概述。本模块的下一个视频详细介绍了TI的OpenVX框架中包含的优化。TI的OpenVX框架的源代码包含在处理器SDK Automotive中。
在上一个视频中,我们介绍了TI的OpenVX框架中包含的自定义扩展。在本视频中,我们将介绍TI实现OpenVX框架所支持的优化。
TI的OpenVX框架的图形模型实现的第一个优化是处理器间通信(IPC)的聚合。这种优化首先需要理解异构体系结构的软件框架。
第一种类型的体系结构要求每次执行目标时都要从主机到目标,然后再返回到主机。考虑到来回于主机和目标内核的数量,这种架构显然不是理想的。
第二种类型的体系结构是星型拓扑体系结构,它涉及到对给定目标的顺序进程调用的聚合。但是,在给定目标上的连续执行完成后,这个体系结构仍然需要在执行下一个目标之前返回到主机。
最后,最优的结构是网格拓扑。在主机处理器上创建一个图形之后,执行控制直接在每个核心之间传递,不需要主机干预。因此,它能够最小化主机和远程目标之间的IPC通信,这减少了系统抖动,有利于开发人员寻求其应用程序的最佳性能。
此外,这种IPC聚合释放了主机处理器上的更多计算,而不必不断地在远程目标上部署函数。这使得开发人员能够在主机处理器上部署额外的算法。OpenVX框架允许在底层IPC方案中使用星型或网状拓扑。
然而,在TI的OpenVX实现中,实现了最优的解决方案,即网格拓扑。除了IPC聚合之外,OpenVX图形还支持算法的并行执行。在创建OpenVX图形的过程中,开发人员可以选择目标核心,给定的OpenVX节点可以通过简单的OpenVX API执行目标核心。
通过将OpenVX图中的并行节点分配给不同的目标,开发人员可以轻松地利用系统提供的并行性。这使得OpenVX非常适合TI的异构soc。由于开发人员的自定义算法部署在OpenVX图的节点中,TI的OpenVX框架提供了对TI异构核心的并行访问。这种并行性减少了OpenVX图形的延迟,从而提高了开发人员应用程序的性能。
此外,使用OpenVX的基于图的执行模型允许OpenVX节点的流水线执行。通过流水线的节点执行,OpenVX图形最有效地利用了多核架构,如TI的soc。OpenVX框架在内部有多个与管道深度相等的指定图形调用。
通过这种方式,这些开放VX图的多个调用可以同时运行,从而允许在并行内核上并发执行。在所示的示例中,OpenVX图中使用了四个不同的目标核。一旦图达到稳定状态,OpenVX图就能最有效地利用多核架构。这种优化技术使用了对OpenVX规范的流水线扩展,这在本模块的视频之一中有介绍。
这张幻灯片涵盖了TI的OpenVX框架中启用的一些额外优化。第一个优化是基于块或分片的处理。在给定节点可以处理输入子集的情况下,例如使用算术或过滤操作,可以平铺显示到节点的输入和输出。
输入的分片可以首先从内存加载,具有较少的延迟,例如L2 RAM而不是DDR。然后,这个tile可以被内核处理,并在被下游的内核处理之前写入L2。对于输入中的每个tile,这个过程都将继续。
通过使用平铺,节点之间的中间数据可能永远不需要存在于外部内存中。这显然节省了宝贵的内存和带宽,这是嵌入式开发的基本要求。TI在示例节点中提供了示例自定义api,以演示如何利用该特性。
此外,由于TI的soc具有异构性质,缓存维护和地址转换对开发定制应用程序构成了严峻的挑战。为了在TI的soc上进行优化开发,在OpenVX框架中提供了简单的内存api,开发人员可以在自己的节点中实现,以执行优化的缓存维护和地址转换。
关于TI的OpenVX框架中启用的优化的视频到此结束。这次演讲的大部分内容都在IEEE论文中用OpenVX图解决系统级优化中得到了详细介绍。
在本视频中,我们将讨论TI为加速OpenVX开发而提供的易用工具。
虽然TIOVX框架的主要目的是作为TI的soc上的应用程序框架,但该框架也支持Linux PC仿真开发模式。PC仿真模式允许开发人员在EVM上开发之前,仅在PC上创建和部署他们的应用程序。这允许开发者在PC上快速创建原型,因为这减少了在目标平台上部署的周转时间。
此外,它允许开发人员在部署应用程序之前,使用他们所选择的IDE来调试应用程序代码中的问题。这种开发是通过TIOVX框架中的平台抽象层,以及PC上可用的J7硬件的精确位C模型实现的。
PC仿真支持的一个例外是能够使用捕获和显示节点。相反,开发人员可以简单地从文件中读取输入数据流,并将数据注入到OpenVX图中,并将图的结果写入到文件中,而不用使用捕获和显示节点。
TI提供的另一个易于使用的工具是PyTIOVX,这是一个基于python的API,用于加速OpenVX扩展内核的开发。这个Python工具提供了一个简单的API,用于定义扩展内核的接口。在使用这个简单的Python API定义扩展内核的参数之后,该工具生成所有必要的OpenVX代码,将这个新内核插入到框架中,以便在应用程序中使用它。
此外,该工具还提供了一个JPEG图像来可视化到新内核的接口,以及一个描述如何将开发人员的定制算法调用集成到生成的代码中的文本文件。除了定义新内核的参数列表之外,Python API还提供了一些函数来执行自定义的参数列表验证,以及一些函数来指定要在新内核中分配的本地内存。
Python工具对于开始OpenVX内核开发非常有益。通过使用这个工具,除了生成包装内核开发人员现有算法所需的所有内核代码外,开发人员还可以生成向框架注册内核和内核模块所需的所有样板代码。通过这种方式,开发人员可以在TI的soc上或使用前面讨论的PC仿真模式快速地原型化他们的新算法。
作为演示该工具有效性的示例,我们编写了一个示例内核包装器,仅使用了9行Python代码来定义内核接口。Python中的这九行代码能够生成超过600行OpenVX代码,其中大部分是容易出现手工错误的样板代码。
此外,该工具为新内核的所有参数提供错误检查和日志记录。在开发内核时,这是一个繁琐且经常被忽略的步骤,但是通过提供清晰的错误日志记录,可以节省无数的调试时间。最后,该工具的输出考虑了MISRA-C编码标准,并输出符合MISRA-C编码准则的代码。
TI的OpenVX易用工具的介绍到此结束。