Julia入门
本次并行计算课程将使用Julia编程语言,与高性能计算HPC相关的课程通常使用C、C++或者Fortran语言,Julia是一种较为新的编程语言,专为科学计算而设计。它将类似python等解释用语言的高级语法与C等编译语言的性能相结合。因此,Julia允许我们使用在教学环境中方便的语法编写高效的并行算法。此外,Julia提供了对不同编程模型的轻松访问来编写分布式算法。
Basic usage
安装好Julia环境之后,在终端命令行输入julia,即可开始使用。
帮助模式
如果想要查看帮助文档,可以输入?,即可进入help模式,输入想要查询的函数,例如"println",即可查看文档。
封装和shell模式
REPL还提供了两种模式:package和shell模式,要进入打包模式,需要输入"]",要进入shell模式,需要输入分号";"。
包模式用于安装和管理包,shell模式可以键入在系统命令行上执行的命令,例如"ls",显示当前文件夹中的内容。如果要返回正常模式,按退格键。
运行Julia代码
现实世界中,Julia程序并不是在REPL中键入的,它们被写入一个或多个文件并包含在REPL中,可以创建一个新文件hello.jl。
我们可以直接使用vscode的运行按钮,也可以在Julia中使用include运行,或者是退出Julia,使用命令行运行代码。
但是实际运行时,我们应该避免从终端调用Julia代码,而是使用REPL。因为每次从终端调用Julia时,都会启动一个新的Julia会话,并且Julia需要从头编译代码,对于大型项目来说,十分耗时。相比之下,如果在REPL中执行代码,Julia就会增量编译代码,速度快很多。在集群中运行代码,例如在DAS-5中运行Julia分配,是需要从终端运行Julia代码的少数情况之一。
运行并行代码
接下来我们运行一个并行的hello world,打开REPL并写入:
在这里,我们使用的Distributed包是Julia标准库的一部分,提供分布式内存并行支持。该代码打印当前Julia会话中的进程ID和进程数。
我们只能看到一个进程的输出,需要添加更多的进程来运行该示例,这是通过addprocs来完成的。
添加三个新的流程,加上最初的,现在我们有4个进程,再次运行代码就发现四个进程的输出。
当从终端启动Julia时,可以指定进程数-p,在集群运行时很有用,如果我们从终端启动Julia,如下:
可以发现,我们像以前一样获得4个进程输出。
安装软件包
Julia最有用的功能之一是它的包管理器,它允许人们以一种简单的且独立于平台的方式安装Julia软件包。为了说明这一点,我们考虑如下并行的hello world示例。此示例使用消息传递接口MPI。
编写新的代码文件"hello_mpi.jl"如下:
我们可以看到,可以以一种干净的方式从Julia访问MPI,无需类型注释和其他复杂的C/C++代码。在运行该文件时,我们必须得安装MPI包。进入package模式,输入命令:
因为我之前已经安装过了,所以此时不会再重新安装。许多Julia包名称以.jl结尾,这只是表明包是以Julia编写的一种方式,使用此类包时,.jl需要省略,MPI.jl在这种情况下,即使我们只输入了MPI,也可以安装该包。我们安装的是MPI的Julia接口,称为MPI.jl。需要注意的是,它本身并不是一个MPI库,它只是MPI和Julia之间的一个薄包装。要使用此接口,需要在系统中安装实际的MPI库,例如OpenMPI或MPICH。
我们可以看到单个MPI等级的输出。
运行MPI代码
要运行MPI程序,我们可以在REPL运行:
此时我们可以看到四个等级的输出。
包管理器
在本地安装包
我们已经在universal范围内安装了MPI,在所有Julia会话中可用。但是,在某些情况下,我们希望使用同一个包的不同版本或者以隔离的方式安装包,避免与其他包的潜在冲突,这可以通过本地项目来完成。
项目只是硬盘中的一个文件夹,要以特定的文件夹用作项目,需要activate。首先进入包模式,然后使用activate命令,后边跟要激活的文件夹的路径:
这个命令将激活当前工作目录,点是当前文件夹的路径。激活路径后,所有与包相关的操作都是新项目的本地操作,例如,安装DataFrames包。
当使用终端打开Julia时,可以直接激活项目--project,命令“$ julia --project=.”将打开Julia并激活当前目录中的项目。也可以通过将设置环境变量JULIA_PROJECT为要激活的路径来达到相同的效果。
活动项目文件夹和当前工作目录是两个独立的概念,例如,(@v1.9) pkg> activate folderB,然后julia> cd("folderA"),将激活中的项目folderB并将当前目录改为folderA。
可以发现,在本目录下可以使用DataFrames,但是回到全局项目(activate不加路径)后,DataFrames就需要重新安装。
项目和清单文件
有关项目的信息存储在两个文件Project.toml和Manifest.toml中。
- Project.toml包含显式安装的包(直接依赖项)
- Manifest.toml包含直接和间接依赖关系以及每个包的具体版本。
换句话说,Project.toml包含与用户相关的包,而Manifest.toml是所有依赖项的详细快照,可用于在另一台机器上重现相同的环境。
在包模式下,可以使用status来查看当前到Project.toml的路径,或者使用缩写st。
Manifest.toml的信息可以通过-m flag来查看:
从项目文件安装包
项目文件可以用于安装其他人定义的包列表,例如,安装Julia应用程序的所有依赖项。
假如一位同事向我们发送了如下文件:
将这些内容复制到名为Project.toml的文件中,然后将其放在名为newproject的空文件夹下,可以使用REPL创建一个新文件夹。要安装文件中注册的所有软件包,需要激活包含Project.toml的文件夹,然后进行实例化。
在包模式下获取帮助
可以通过在特定包操作符前面写入help来获取有关特定包操作符的帮助。
Julia代码中的封装操作
在某些情况下,需要在Julia中使用包命令,例如,自动安装和部署Julia程序,可以使用Pkg包来完成:
两种方式是等价的,相当于status以封装方式调用。