Jos*_*ell 6 module multiprocessing julia
我的团队正在尝试使用多处理和使用julia -p #参数运行一个库(Cbc with JuMP)。我们的代码在一个 julia 包中,所以我们可以使用 运行我们的代码julia --project,它只运行一个进程。然而,尝试同时指定两者julia --project -p 8会破坏我们运行项目的能力,因为在运行using PackageName之后会导致错误。我们还打算使用该PackageCompiler库对其进行编译,因此需要使其与项目一起使用。
我们的项目位于一个文件夹中,其中包含一个 src 目录、一个 Project.toml 和一个 Manifest.toml src 包含:main.jl 和 Solver.jl
Project.toml 包含:
name = "Solver"
uuid = "5a323fe4-ce2a-47f6-9022-780aeeac18fe"
authors = ["..."]
version = "0.1.0"
Run Code Online (Sandbox Code Playgroud)
通常,我们的项目以这种方式开始(单线程)运行良好:
julia --project
julia> using Solver
julia> include("src/main.jl")
Run Code Online (Sandbox Code Playgroud)
如果我们-p 8在启动 Julia 时添加参数,则会在键入时出现错误using Solver:
ERROR: On worker 2:
ArgumentError: Package Solver [5a323fe4-ce2a-47f6-9022-780aeeac18fe] is required but does not seem to be installed:
- Run `Pkg.instantiate()` to install all recorded dependencies.
Run Code Online (Sandbox Code Playgroud)
我们已尝试运行,using Pkg; Pkg.instantiate(); using Solver但这无济于事,因为稍后(在include("src/main.jl")步骤中)发生了另一个错误:
ERROR: LoadError: On worker 2:
ArgumentError: Package Solver not found in current path:
- Run `import Pkg; Pkg.add("Solver")` to install the Solver package.
Run Code Online (Sandbox Code Playgroud)
然后按照该建议产生另一个错误:
ERROR: The following package names could not be resolved:
* Solver (not found in project, manifest or registry)
Please specify by known `name=uuid`.
Run Code Online (Sandbox Code Playgroud)
为什么这个模块导入在单进程模式下可以正常工作,但在-p 8?
预先感谢您的考虑
首先,重要的是要注意您不是在使用多线程并行,而是在使用分布式并行。当您启动时,-p 2您正在启动两个不同的进程,它们不共享相同的内存。此外,该项目仅在主进程中加载,这就是为什么其他进程无法看到项目中的任何内容。您可以在官方文档中了解有关 Julia 提供的不同类型并行的更多信息。
要在所有工作人员中加载环境,您可以将其添加到文件的开头。
using Distributed
addprocs(2; exeflags="--project")
@everywhere using Solver
@everywhere include("src/main.jl")
Run Code Online (Sandbox Code Playgroud)
并删除-p 2您启动 julia 的那部分行。这将在所有进程上加载项目。该@everywhere宏用于指示执行给定任务的所有进程。文档的这一部分对此进行了解释。
但是请注意,并行性不会自动运行,因此如果您的软件在编写时没有考虑到分布式并行性,则可能无法从新启动的工作线程中获得任何好处。
当存在未编译的模块并且多个并行进程尝试在首次使用时同时编译它时,Julia 会出现问题。
因此,如果您在一台计算机上跨多个进程运行自己的模块,则始终需要按以下方式运行(假设 Julia 进程在项目所在的同一文件夹中运行):
using Distributed, Pkg
@everywhere using Distributed, Pkg
Pkg.activate(".")
@everywhere Pkg.activate(".")
using YourModuleName
@everywhere using YourModuleName
Run Code Online (Sandbox Code Playgroud)
我认为这种方法没有记录,但我通过实验发现它是最强大的。如果您有时(并非总是!)不使用我的模式,则会发生编译器追逐,并且往往会发生奇怪的事情。
请注意,如果您正在运行分布式集群,则需要修改上面的代码以在每个节点的单个工作线程上运行初始化,而不是在所有工作线程上运行。