开发者

MATLAB Parallel Toolbox for running two separate functions on two different cores

开发者 https://www.devze.com 2023-02-24 06:53 出处:网络
I have a MATLAB script running two copies of the same function and I want to run them in parallel on two different cores.

I have a MATLAB script running two copies of the same function and I want to run them in parallel on two different cores.

This is the function I am calling

function [outputVector] = ParallelPitchShift(inputVector, windowSize, hopSize, step)

%% Parameters

% Window size
winSize = windowSize;
% Space between windows
hop = hopSize;
% Pitch scaling factor
alpha = 2^(step/12);

% Intermediate constants
hopOut = round(alpha*hop);

% Hanning window for overlap-add
wn = hann(winSize*2+1);
wn = wn(2:2:end);

%% Source file

x = inputVector;

% Rotate if needed
if size(x,1) < size(x,2)

    x = transpose(x);

end

x = [zeros(hop*3,1) ; x];

%% Initialization

% Create a frame matrix for the current input
[y,numberFramesInput] = createFrames(x,hop,winSize);

% Create a frame matrix to receive processed frames
numberFramesOutput = numberFramesInput;
outputy = zeros(numberFramesOutput,winSize);

% Initialize cumulative phase
phaseCumulat开发者_如何转开发ive = 0;

% Initialize previous frame phase
previousPhase = 0;

for index=1:numberFramesInput

%% Analysis

    % Get current frame to be processed
    currentFrame = y(index,:);

    % Window the frame
    currentFrameWindowed = currentFrame .* wn' / sqrt(((winSize/hop)/2));

    % Get the FFT
    currentFrameWindowedFFT = fft(currentFrameWindowed);

    % Get the magnitude
    magFrame = abs((currentFrameWindowedFFT));

    % Get the angle
    phaseFrame = angle(currentFrameWindowedFFT);

%% Processing    

    % Get the phase difference
    deltaPhi = phaseFrame - previousPhase;

    previousPhase = phaseFrame;

    % Remove the expected phase difference
    deltaPhiPrime = deltaPhi - hop * 2*pi*(0:(winSize-1))/winSize;

    % Map to -pi/pi range
    deltaPhiPrimeMod = mod(deltaPhiPrime+pi, 2*pi) - pi;

    % Get the true frequency
    trueFreq = 2*pi*(0:(winSize-1))/winSize + deltaPhiPrimeMod/hop;

    % Get the final phase
    phaseCumulative = phaseCumulative + hopOut * trueFreq;    

    % Remove the 60 Hz noise. This is not done for now but could be
    % achieved by setting some bins to zero.

%% Synthesis    

    % Get the magnitude
    outputMag = magFrame;

    % Produce output frame
    outputFrame = real(ifft(outputMag .* exp(j*phaseCumulative)));

    % Save frame that has been processed
    outputy(index,:) = outputFrame .* wn' / sqrt(((winSize/hopOut)/2));

end

%% Finalize

% Overlap add in a vector
outputTimeStretched = fusionFrames(outputy,hopOut);

% Resample with linearinterpolation
outputTime = interp1((0:(length(outputTimeStretched)-1)),outputTimeStretched,(0:alpha:(length(outputTimeStretched)-1)),'linear');

% Return the result
outputVector = outputTime;

return

And this is what I am doing to call the function

clear

x = wavread('x2.wav');

y1 = ParallelPitchShift(x,1024,256,7);

y2 = ParallelPitchShift(x,1024,256,12);

output = x(1:417000)' + y1(1:417000) + y2(1:417000);

sound(x,44100)

pause

sound(output,44100)

Is it possible to do this? Please let me know Thanks!


I don't understand what you mean by two copies of the same function. Did you mean two different input arguments to the same function or that the two functions are completely different?

I'm assuming its the former (because that's what you've written). In that case, try

somethingVector=[something, something2];
parfor i=1:2
    function(something(i),otherArgs)
end

Remember, before you use a parfor loop, you should open a pool of workers like so:

matlabpool('open',2)


What you want is the Single Program Multiple Data, or spmd function from the Parallel Computing toolbox. From the documentation:

The spmd statement lets you define a block of code to run simultaneously on multiple labs.

To use it you first have to define a matlabpool.

matlabpool 3

This automatically creates a "hidden" variable in the workspace called labindex, which specifies which lab is currently doing the work.

labindex

ans =

     1 

When we use spmd we execute our code in parallel on all the labs opened by matlabpool.

spmd 
labindex
end
Lab 1: 

  ans =

       1

Lab 2: 

  ans =

       2

Lab 3: 

  ans =

       3

We can use labindex to specify different input to the same function and run everything in parallel. If we have two different matrices and want to find the eigenvalues in parallel we could do

M = {rand(10) rand(20)}; %Put matrices into cell for easy access
spmd
  if labindex < 3  %We only have two matrices, so only need two labs
     E = eig(M(labindex));
  end
end
E
E =

   Lab 1: class = double, size = [10   1]
   Lab 2: class = double, size = [20   1]
   Lab 3: No data


I've tested parallel toolbox and ended up not buying it specifically because you can not control what functions run on which core. So if you start up multiple workers (using matlabpool()) and attempt to send the function processing to a specific worker/pool, it won't work. However using parfor will distribute the workload evenly over the cores in order to optimize processing time.

For what I was trying to do, the solution was to have different sessions of matlab running. Hoping the CPU distributes the next session to another CPU

0

精彩评论

暂无评论...
验证码 换一张
取 消