您好,欢迎访问本站博客!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧
  • 网站所有资源均来自网络,如有侵权请联系站长删除!

使用IPython进行高级计算 [LWN用户专用内容]

网络技术 莫问 2018-06-06 794 次浏览 0个评论

2018年6月4日

本文由李菲利普斯撰写

如果你使用Python,那么你很有可能听说过IPython,它为Python 提供了一个增强的read-eval-print循环(REPL)。但是,除了更方便的REPL之外,IPython还有更多。今天的IPython带有集成库,可以将它变成多个高级计算任务的助手。本文将讨论使用多种语言和分布式计算的两项任务。

IPython提供对文档的方便访问,与matplotlib集成,持久历史记录以及许多其他功能,这些功能极大地简化了与Python的交互工作。IPython还带有一组“魔术”命令,可以改变单行或一行代码的效果; 例如,只需%%time在输入Python语句之前在提示符处键入就可以计算代码的时间当使用带有IPython内核Jupyter笔记本电脑时,所有这些功能也可以工作,因此您可以在使用相同命令的同时在终端和基于浏览器的界面之间自由切换。

多语言计算

没有一种语言适合所有的事情。IPython和Jupyter允许您在单个笔记本或交互式会话中利用多种语言的优势。

[红宝石]

右图是Jupyter笔记本的片段,展示了使用此功能的最简单方法。所述%%ruby细胞魔术命令(双%%该魔术命令将应用到整个电池装置)导致细胞内容物由Ruby解释进行处理。--out标志将单元格输出存储到指定的变量中,然后全局可用于解释其他单元格内容的Python内核。以下单元格将Ruby代码的字符串输出转换为整数(注意,这int() 是合法的Python,但不是Ruby的一部分)。Ruby代码简单地将从1到100的整数加起来; 最终结果存储在a

这可以在不安装任何IPython或Jupyter内核或扩展的情况下完成 - 只需要Ruby。Perl,Bash或sh也可以做同样的事情; 其他解释语言可以通过编辑源文件中的列表添加[path to IPython]/core/magics/script.py

F2PY 是NumPy / SciPy的一个组件,它编译和封装Fortran子程序,以便它们可以与Python一起使用。吸引力在于能够利用Fortran的快速数字操作以及Python的高级便利性和交互性。通常,使用F2PY需要几个手动步骤。然而,名为Fortran魔术 (可安装pip的第三方扩展提供了一种单元魔术,可以F2PY在引擎盖下使用 它进行编译和界面创建。所需要的只是包含Fortran子例程或函数的单元格中的单个行(如果系统中尚不存在Fortran编译器,则可能需要安装Fortran编译器)。

下图显示了该过程。首先,我们定义一个名为python的函数,eap()它使用一个缓慢收敛的近似 e作为自然对数的基数。它计算d连续的近似值,返回最后一个。下一个单元格加载Fortran魔法机器,它会生成一个用户警告(折叠),因为它是为较旧版本的IPython / Jupyter开发的(但一切仍然有效)。load命令定义了我们在该单元中使用的单元格魔术,其中包含一个名为相同函数的Fortran版本eaf()当该单元格被执行时,IPython编译代码并生成Python接口。在最后两个单元格中,每个程序在定时开启时被调用; 他们产生可比较的输出,但Fortran版本的速度提高了大约24倍。

[Fortran的]

只需一个魔术命令,您就可以在您的会话或笔记本中打包编译的Fortran命令以便交互使用。由于您的程序的数字部分最容易转换为Fortran,并且这些部分将从过程中获益最多,因此这是加速计算的简单方法,并且很好地展示了IPython生态系统的强大功能。

并行和分布式计算

IPython提供了许多方便的解决方案,用于在单机或多台联网计算机的处理内核之间划分计算。IPython并行计算工具完成许多设置和簿记工作; 在简单的情况下,它应该允许在交互式上下文中执行并行计算,就像正常的单处理器计算一样简单。

在多个处理器上运行代码的一个常见原因是加速或增加吞吐量。然而,这只对某些类型的问题是可能的,并且只有在算术节省的时间大于处理器间移动数据的开销时才有效。

如果您的目标是最大限度地提高计算速度,那么在尝试利用并行或分布式计算之前,您需要尽可能提高其串行性能(在单个处理内核上的速度)。这套幻灯片[PDF]为您在核心语言为Python时可能处理此问题的各种方式提供了清晰简洁的介绍; 它也引入了一些并行化策略。有很多方法可以加速Python,所有这些都超出了本文的关注点(并且,不管语言如何,第一种方法应该是对算法和数据结构的关键考虑)。

除了试图加快计算速度之外,网络化分布式计算的另一个目的是从计算机集合收集信息或运行测试。例如,位于世界各地的一组Web服务器的管理员可以利用下面描述的技术利用IPython会话作为中央控制中心,利用单个命令从所有服务器收集性能数据。

首先,关于NumPy的说明。并行化Python计算最简单的方法就是将其尽可能表达为NumPy数组上的一系列数组操作。这将自动将阵列数据分配到您计算机上的所有内核中并且并行执行阵列算术(如果您有任何疑问,请在观察CPU监视器的同时提交较长时间的NumPy计算htop,并且您将看到所有内核都处于工作状态 )。并不是每个计算都可以用这种方式来表达; 但是如果您的程序已经以允许并行执行的方式使用NumPy,并且您尝试使用下面描述的技术在多核上运行程序,那么它将引入不必要的进程间通信,并且减慢速度而不是加快速度。

在你的程序不适合NumPy数组处理的情况下,IPython提供了其他几乎同样便利的方法来利用多个处理器。要使用这些设施,您必须安装该ipyparallel 库pip install ipyparallel将执行此操作)。

IPython和ipyparallel库支持并行和分布式计算的各种样式和范例。我用一种简单的方法构建了几个例子来演示这些范例。这应该提供一些切入点,以最少的设置立即开始试验,并给出一系列可能性的概念。要了解所有选项,请参阅文档[PDF]

第一个示例在每台机器的CPU内核上复制计算。如上所述,NumPy会自动在这些内核之间划分工作,但使用IPython,您可以通过其他方式访问它们。首先,您必须创建一个计算“集群”。随着IPython的安装和ipyparallel几个命令行工具。创建集群的命令是:

    $ ipcluster start --n = x

通常,x设置为系统中的核心数量; 我的笔记本电脑有四个,所以--n = 4。 [集群示例]该命令应该会产生一条消息,说明群集已创建。您现在可以在IPython或Jupyter笔记本中与它进行交互。


右图显示了使用群集的Jupyter会话的一部分。前两个单元格导入IPython并行库并实例化一个 Client要检查所有四个核心实际上是否可用,将显示客户端实例ids列表

下一个单元格(在左边的图中) [进口]导入该choice()函数,该函数从集合中随机选择一个元素pylab进行绘图,并配置一个将图块嵌入到笔记本中的设置。

请注意细胞正在使用%%px魔法。这个咒语位于单元格的顶部,默认情况下,单元格中的计算将被复制到每个核心的独立进程中。由于我们使用四个内核启动集群,因此将有四个进程,每个进程都有其自己的所有变量的私有版本,并且每个进程独立于其他进程运行。

接下来的两个单元(下面)计算一百万步的二维随机游走。它们每个都由%%timeit细胞魔法装饰,这是细胞内的计算时间。第一个单元使用--targets 参数将计算限制为单个内核上的单个进程(内核“0”;我们可以选择0到3之间的任何数); 第二个使用%%px没有参数来使用所有内核。请注意,在这种并行计算方式中,每个变量(包括每个列表)都在内核之间复制。这与NumPy中的数组计算形成鲜明对比,其中阵列在核心之间分裂,每个核心都处理更大问题的一部分。因此,在这个例子中,每个核心会计算一个单独的,完整的百万步随机游走。

[随机游走]

如果每个版本的时间表示相同的时间,那么这意味着我们在第二种情况下在相同的时间内实际上做了四倍的工作,因为计算完成了四次。然而,第二个版本实际上花费了两倍多,这意味着我们只能实现两个加速。这是由于进程间通信和设置的开销,并且应该随着计算变得更加冗长而减少。

如果我们将追加命令添加到单元格,看看随机走线的样子会发生什么?下图显示了每个过程如何产生自己的图(使用自己的随机种子)。这种多处理方式可以方便地比较并行计算不同版本的计算,而不必一个接一个地运行每个迭代。

[平行散步]

您也可以使用%pxmagic命令的单行版本在集群上执行单行命令。使用这个,你可以在单个单元中混合使用串行和并行代码。所以在导入随机整数函数(randint())之后:

    %px randint(0,9)
    出[0:8]:1
    出[1:8]:3
    出去[2:8]:9
    Out [3:8]:0

像往常一样,输出单元按照顺序标记(这里是我的会话中的 8 计算),但也指示四个计算核心中的哪一个产生每个结果。

%%px%px魔术的命令是简单的方法,当你想每个处理器对数据的自己的私人拷贝操作复制处理器的集群中的计算。通过使用多个处理器来加速列表上的计算的经典技术遵循不同的模式:列表在处理器之间被分开,每个处理器在其单独的段上工作,并且结果被重新组装成单个列表。如果每个数组元素上的计算不依赖于其他元素,这种效果最好。

IPython提供了一些便利功能,使这些计算易于表达。在这里,我们将看看最常用的那个。首先,考虑Python的map() 功能 ; 例如:

    列表(map(lambda x:f(x),range(16)))

这会将该函数 f()应用于列表的每个元素[0..15]并返回结果列表。它将一次在一个处理器上执行此操作。

但是如果我们像上面那样启动了一个集群,我们可以这样写:

    rp [:]。map_sync(lambda x:f(x),range(16))

这将把列表分成四段长度相等的段,将每段发送到一个单独的处理器,并将结果重新放回原处。你可以控制哪些处理器被索引使用rp,所以你可以很容易地告诉rp[0:1]在一个阵列上工作,而你有rp[2:3]其他的事情。


使用的处理器不需要是本地计算机上的核心。他们可以驻留在任何可通过互联网或本地网络访问的计算机上。通过网络进行计算的最简单的设置是当您的计算群集由可通过SSH访问的计算机组成时。自然地,配置比简单地输入ipcluster命令更复杂一点我已经创建了一个文档[PDF]来描述一个最小化的示例配置,可以让您开始通过SSH在网络群集上进行计算。

20多年来,计算科学家依靠并行计算的各种方法作为执行真正大计算的唯一方法。随着人们对更精确的气候建模,处理越来越大的机器学习数据集,更好地模拟银河系演进以及在许多不同领域进行更强大的计算超过单个处理器的能力的需求,采用并行处理来打破瓶颈,我们希望获得更精确的气候模型。这曾经是人们愿意重写算法的专属领域,将特殊的并行库合并到他们的Fortran和C程序中,并针对个别超级计算机的特性定制程序。

IPython ipyparallel提供了前所未有的能力,将科学Python的探索能力与几乎即时访问多个计算核心相结合。该系统提供了高级抽象,使得直观地与本地或网络集群的计算节点进行交互,而不管集群如何实施。交互式使用的这种简便性帮助IPython和Python成为跨各种学科的科学计算和数据科学的流行工具。就最近的一个例子而言,本文[PDF]介绍了机器学习和生物化学交叉问题的研究,受益于易用性 ipyparallel它包括一节讨论系统的优点。

有时候用另一种语言更容易表达一个想法,或者计算速度会更快。多语言计算过去需要复杂的接口来使用多个编译器或在不同的解释器中工作。通过允许用户使用不同语言进行编码,能够增强IPython和Jupyter已经实现的计算流畅性和探索性,从而实现了一种真正全新的与计算机交互的方式。

IPython和Jupyter不仅仅是解释器的接口。本文所描述的计算体验的增强功能相当新颖,但不仅仅是软件开发人员的好奇心 - 它们已经被科学家和工程师用于应用程序中。像这些工具是创造力的杠杆; 这将有助于我们看到未来的发展。

本文摘自LWN

已有 794 位网友参与,快来吐槽:

发表评论

验证码