Как передать несколько параметров в параллельную операцию в Octave? - PullRequest
1 голос
/ 30 мая 2020

Я написал функцию, которая действует на каждую комбинацию столбцов входной матрицы. Он использует несколько циклов for и работает очень медленно, поэтому я пытаюсь распараллелить его, чтобы использовать максимальное количество потоков на моем компьютере.

Мне трудно найти правильный синтаксис для его настройки. Я использую пакет Parallel в октаве и пробовал несколько способов настроить вызовы. Вот два из них в упрощенной форме, а также непараллельная версия, которая, как мне кажется, работает:

function A = parallelExample(M)
pkg load parallel;

# Get total count of columns
ct = columns(M);

# Generate column pairs
I = nchoosek([1:ct],2);
ops = rows(I);
slice = ones(1, ops);
Ic = mat2cell(I, slice, 2);

##  # Non-parallel
##  A = zeros(1, ops);
##  for i = 1:ops
##      A(i) = cmbtest(Ic{i}, M);
##  endfor

# Parallelized call v1
A = parcellfun(nproc, @cmbtest, Ic, {M});

## # Parallelized call v2
## afun = @(x) cmbtest(x, M);
## A = parcellfun(nproc, afun, Ic);

endfunction

# function to apply
function P = cmbtest(indices, matrix)

colset = matrix(:,indices);
product = colset(:,1) .* colset(:,2);
P = sum(product);

endfunction

Для обоих этих примеров я генерирую каждую комбинацию двух столбцов и конвертирую эти пары в массив ячеек, который должна разделить функция parcellfun. В первом я пытаюсь преобразовать входную матрицу M в массив ячеек 1x1, чтобы она передавалась каждому параллельному экземпляру в той же форме. Я получаю сообщение об ошибке: «C должен быть массивом ячеек», но это должно быть внутренним для функции parcellfun. Во втором я пытаюсь определить анонимную функцию, включающую матрицу. Ошибка, которую я здесь получаю, указывает, что cmbtest не определено.

(Естественно, фактическая функция, которую я пытаюсь применить, намного сложнее, чем здесь cmbtest)

Другие вещи, которые я пробовал :

  • Поместите M в глобальную переменную, чтобы ее не нужно было передавать. Казалось, что невозможно поместить глобальную переменную в файл функции, хотя у меня могут быть проблемы с синтаксисом.
  • Сделайте cmbtest вложенной функцией, чтобы она могла получить доступ к M (parcellfun не поддерживает это)

На данный момент у меня нет идей, и мне нужна помощь, чтобы выяснить, как заставить это работать.

1 Ответ

1 голос
/ 09 июня 2020

Преобразование моих комментариев выше в ответ.

При выполнении параллельных операций полезно думать о каждом параллельном работнике, который приведет к отдельным и независимым экземплярам октавы, которые должны иметь соответствующий доступ ко всем функциям и переменные, которые им потребуются для выполнения своей независимой работы.

Поэтому не полагайтесь на подфункции при вызове parcellfun из основной функции, так как это может привести к ошибкам, если рабочий не сможет получить доступ к подфункция прямо под капотом.

В этом случае разделение подфункции в отдельный файл устранило проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...