0

这让我很难过。

我编写了一个函数parObjectiveFunction,它使用createJob和并行运行多个模拟createTask。它将参数 an 作为参数objectiveFunction传递到代码中,以计算每个模拟的目标函数值。

当我parObjectiveFunctionobjectiveFunction找到的目录运行时,它按预期工作,但是当我上一层时,它再也找不到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 命令窗口中运行它时,它发现objectiveFunction没有问题。我在本地机器和 HPC 服务器上得到了相同的结果。

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

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

  2. createJob是否有任何已知问题导致 matlab 在使用、 和?进行并行处理createTask时找不到函数?submitfetchOutputs

  3. 当问题仅在并行操作时,您如何在 matlab 中进行调试?我的打印语句都没有出现。

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

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
4

1 回答 1

3

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

job.listAutoAttachedFiles()

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

这似乎objectiveFunction是一个function_handle虽然,所以你可能需要这样的事情:

f = functions(objectiveFunction)
job.AttachedFiles = {f.file}
于 2019-11-26T09:18:41.090 回答