运行并行时matlab看不到具体函数

Matlab can't see a specific function when running in parallel

这让我难住了。

我编写了一个函数 parObjectiveFunction,它 运行 使用 createJobcreateTask 并行进行了多个模拟。它以一个 objectiveFunction 作为参数,它被更深入地传递到代码中,以计算每个模拟的 objective 函数值。

当我从 objectiveFunction 所在的目录 运行 parObjectiveFunction 时,它按预期工作,但是当我向上一级时,它再也找不到 objectiveFunction.我得到的具体错误是

Error using parallel.Job/fetchOutputs (line 1255)
An error occurred during execution of Task with ID 1.

Error in parObjectiveFunction (line 35)
    taskoutput = fetchOutputs(job);

Caused by:
    Error using behaviourObjective/getPenalty (line 57)
    Undefined function 'objectiveFunction' for input arguments of type 'double'.

(behaviourObjective 是一个对象)

这很奇怪有几个原因。

objectiveFunction 肯定在 path 中,当我尝试 which objectiveFunction 时,它指向正确的函数。 我在其他目录中有更深层代码的其他组件,并且可以毫无问题地找到它们(它们是对象而不是函数,但这应该没有什么区别)。 parObjectiveFunction 中有一行代码 运行 是模拟,当我 运行 直接在 matlab 命令 window 中时,它发现 objectiveFunction 没有问题。 我在本地计算机和 HPC 服务器上得到了相同的结果。

我的第一个想法是,单个任务可能有自己的 path,其中不包括 objectiveFunction,但这应该会给其他组件带来问题(但不会)。问题很复杂,因为我不知道如何调试并行代码。

  1. 我做错了什么?产生问题的代码如下。

  2. 是否存在任何已知的问题,其中 matlab 在以下情况下找不到函数 使用 createJobcreateTasksubmit 的并行处理 和 fetchOutputs?.

  3. 出现问题时如何在matlab中调试 仅在并行操作时? None 的打印语句出现了。

要使某些东西用于外部测试需要大量的黑客攻击,但为了这个问题,并行函数是:

function penalty = parObjectiveFunction(params, objectiveFunction, N)

    % Takes a vector of input parameters, runs N instances of them in parallel
    % then assesses the output through the objectiveFunction

    n = params(1);
    np = params(2);
    ees = params(3);
    ms = params(4);
    cct = params(5);
    wt = params(6);
    vf = params(7);

    dt = 0.001;
    bt = 10;

    t = 10;


    c = parcluster;
    job = createJob(c);


    testFunction = @(run_number)behaviourObjective(objectiveFunction,n,np,ees,ms,cct,wt,vf,t,dt,bt,run_number);


    for i = 1:N

        createTask(job, testFunction, 1, {i});

    end

    submit(job);
    wait(job);
    taskoutput = fetchOutputs(job);

    pensum = 0;
    for i = 1:N
        pensum = pensum + taskoutput{i}.penalty;
    end

    penalty = pensum/N;

end

听起来您需要将一些额外的文件附加到您的 job。你可以通过运行listAutoAttachedFiles看到MATLAB的依赖分析拾取了哪些文件,即

job.listAutoAttachedFiles()

如果这没有显示您的 objectiveFunction,那么您可以通过修改 jobAttachedFiles 属性 手动附加它。

虽然 objectiveFunction 似乎是一个 function_handle,所以您可能需要这样的东西:

f = functions(objectiveFunction)
job.AttachedFiles = {f.file}