2015-08-19 5 views
0

У меня есть функция (свертка), которая может стать очень медленной, если она работает с матрицами многих столбцов (код функции ниже). Поэтому я хочу распараллелить код.Почему работа MATLAB длится долго?

Пример MATLAB код:

x = zeros(1,100); 
x(rand(1,100)>0.8) = 1; 
x = x(:); 
c = convContinuous(1:100,x,@(t,p)p(1)*exp(-(t-p(2)).*(t-p(2))./(2*p(3).*p(3))),[1,0,3],false) 
plot(1:100,x,1:100,c) 

если x матрица из многих рубрик, код становится очень медленно ... Моя первая попытка была изменить for на parfor заявление, но это пошло не так (см Заключительные замечания ниже).

Моя вторая попытка состояла в следующем: this example, в котором показано, как планировать задания в задании, а затем отправлять задание на локальный сервер. Этот пример реализован в моей функции ниже, разрешив последнему аргументу isParalleltrue.

В примере MATLAB код будет:

x = zeros(1,100); 
x(rand(1,100)>0.8) = 1; 
x = x(:); 
c = convContinuous(1:100,x,@(t,p)p(1)*exp(-(t-p(2)).*(t-p(2))./(2*p(3).*p(3))),[1,0,3],true) 

Теперь, MATLAB говорит мне:

Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers.

Warning: This job will remain queued until the Parallel Pool is closed.

И MATLAB терминал продолжает трюме, ожидая чего-то, чтобы закончить. Затем я открываю Jobs MonitorHome -> Parallel -> Monitor jobs и вижу, что есть два задания, одно из которых имеет состояние running. Но никто из них никогда не закончит.

Вопросы

  • Почему слишком долго работать, учитывая, что это действительно простая задача?

  • Что было бы лучшим способом распараллеливать мою функцию ниже? ("Тяжелая" часть находится в отделенной функции convolveSeries)

convContinuous.m Файл

function res = convContinuous(tData, sData, smoothFun, par, isParallel) 
% performs the convolution of a series of delta with a smooth function of parameters par 
% tData = temporal space 
% sData = matrix of delta series (each column is a different series that will be convolved with smoothFunc) 
% smoothFun = function used to convolve with each column of sData 
%    must be of the form smoothFun(t, par) 
% par = parameters to smoothing function 
    if nargin < 5 || isempty(isParallel) 
     isParallel = false; 
    end 
    if isvector(sData) 
     [mm,nn] = size(sData); 
     sData = sData(:); 
    end 
    res = zeros(size(sData)); 
    [ ~, n ] = size(sData); 
    if ~isParallel 
     %parfor i = 1:n % uncomment this and comment line below for strange error 
     for i = 1:n 
      res(:,i) = convolveSeries(tData, sData(:,i), smoothFun, par); 
     end 
    else 
     myPool = gcp; % creates parallel pool if needed 
     sched = parcluster; % creates scheduler 
     job = createJob(sched); 
     task = cell(1,n); 
     for i = 1:n 
      task{i} = createTask(job, @convolveSeries, 1, {tData, sData(:,i), smoothFun, par}); 
     end 
     submit(job); 
     wait(job); 
     jobRes = fetchOutputs(job); 
     for i = 1:n 
      res(:,i) = jobRes{i,1}(:); 
     end 
     delete(job); 
    end 
    if isvector(sData) 
     res = reshape(res, mm, nn); 
    end 
end 

function r = convolveSeries(tData, s, smoothFun, par) 
    r = zeros(size(s)); 
    tSpk = s == 1; 
    j = 1; 
    for t = tData 
     for tt = tData(tSpk) 
      if (tt > t) 
       break; 
      end 
      r(j) = r(j) + smoothFun(t - tt, par); 
     end 
     j = j + 1; 
    end 
end 

Заключительные замечания

Как примечание стороны, я не был в состоянии чтобы сделать это, используя parfor, потому что MATLAB R2015a дал мне странную ошибку:

Error using matlabpool (line 27) matlabpool has been removed.

To query the size of an already started parallel pool, query the 'NumWorkers' property of the pool.

To check if a pool is already started use 'isempty(gcp('nocreate'))'.

Error in parallel_function (line 317) Nworkers = matlabpool('size');

Error in convContinuous (line 18) parfor i = 1:n

Мои version команда выводит

Parallel Computing Toolbox       Version 6.6  (R2015a) 

, который совместим с моей версией MATLAB. Почти all other tests У меня все в порядке. Затем я вынужден думать, что это ошибка MATLAB.

Я попытался изменить matlabpool к gcp, а затем извлечения числа рабочих по parPoolObj.NumWorkers, и после изменения этой детали в двух различных встроенных функций, я получил еще одну ошибку:

Error in convContinuous>makeF%1/F% (line 1)

function res = convContinuous(tData, sData, smoothFun, par)

Output argument "res" (and maybe others) not assigned during call to "convContinuous>makeF%1/F%".

Error in parallel_function>iParFun (line 383) output.data = processInfo.fun(input.base, input.limit, input.data);

Error in parProcess (line 167) data = processFunc(processInfo, data);

Error in parallel_function (line 358) stateInfo = parProcess(@iParFun, @iConsume, @iSupply, ...

Error in convContinuous (line 14) parfor i = 1:numel(sData(1,:))

Я подозреваю, что это последнее ошибка возникает, потому что вызов функции внутри цикла parfor требует много аргументов, но я этого не знаю.

Решения ошибки

Благодаря осторожным комментариям людей здесь (говорят, что они не смогли воспроизвести мои ошибки), я продолжал искать источник ошибки. Я понял, что это была локальная ошибка из-за наличия pforfun в моем pathdef.m, который I downloaded long ago from File Exchange.

Как только я удалил pforfun из моего pathdef.m, parfor (строка 18 в convContinuous функция) начал хорошо работать.

Спасибо заранее!

+0

Что касается вашей последней ошибки: Это полный стек ошибок? К какому коду это принадлежит, я не могу найти строки в вашем коде. – Daniel

+0

Я заметил, что параллельный пул удерживает задания на неопределенный срок, пытаясь запустить примеры партий из документации. Он просто уходит куда-то, и когда вы ждете (работа), он просто занят, пока вы не нажмете kill matlab. – Adriaan

+0

'convContinuous> makeF% 1/F%' - это имя функции, созданной машиной 'parfor'. Было бы полезно иметь исполняемые шаги воспроизведения, чтобы увидеть, что происходит неправильно. Мне не сразу понятно, почему вы это видите - безусловно, ваша функция 'convolveSeries' безоговорочно предоставляет свой выходной аргумент. – Edric

ответ

3

Параллельный пул, который вы создали, блокирует работу. Когда вы используете API заданий и задач, вам не нужен (и не должен) пул открыт. Когда вы смотрели в Job Monitor, работа, которую вы видели, была заданием, которое поддерживает параллельный пул, который заканчивается только при удалении пула.

Если вы удалите строку в convContinuous, которая говорит myPool = gcp, тогда она должна работать. В качестве оптимизации вы можете использовать vectorised форму CreateTask, который является гораздо более эффективным, чем создание задач в цикле, т.е.

inputCell = cell(1, n); 
for i = 1:n 
    inputCell{i} = {tData, sData(:,i), smoothFun, par}; 
end 
task = createTask(job, @convolveSeries, 1, inputCell); 

Однако, сказав все, что вы должны быть в состоянии сделать этот код работать, используя parfor. Первая ошибка, с которой вы столкнулись, связана с удалением matlabpool, теперь она заменена на parpool.

Вторая ошибка, по-видимому, вызвана тем, что ваша функция не возвращает правильные выходы, но сообщение об ошибке не соответствует коду, который вы отправили, поэтому я не уверен. В частности, я не знаю, к чему относится convContinuous>makeF%1/F% (line 1).

+0

, чтобы воспроизвести ошибку, вам просто нужно раскомментировать строку 18 функции convContinuous, где указано выражение 'parfor' и прокомментировать строку под ним с помощью инструкции' for'. Однако, поскольку вы не смогли воспроизвести проблему, я пошел искать, если у меня возникла локальная проблема, а не ошибка MATLAB. Функция 'parallel_function' является оболочкой для' pforfun', которую я давно загрузил из File Exchange и имел ее в моем 'pathdef.m'. Я удалил его из 'pathdef.m', и' parfor' начал нормально работать. – Girardi

0

Благодаря настороженным комментариям людей здесь (говоря, что они не могут воспроизвести мои ошибки), я продолжал искать источник ошибки. Я понял, что это была локальная ошибка из-за наличия pforfun в моем pathdef.m, который I downloaded long ago from File Exchange.

Как только я удалил pforfun из моего pathdef.m, parfor (строка 18 в convContinuous функция) начал хорошо работать.

Смежные вопросы