# Using parfor Loops: Getting Up and Running 81

Posted by **Loren Shure**,

Today I’d like to introduce a guest blogger, Sarah Wait Zaranek, who is an application engineer here at The MathWorks. Sarah previously has written about speeding up code from a customer to get acceptable performance. She again will be writing about speeding up MATLAB applications, but this time her focus will be on using the parallel computing tools.

### Contents

### Introduction

I wanted to write a post to help users better understand our parallel computing tools. In this post, I will focus on one of
the more commonly used functions in these tools: the `parfor`-loop.

This post will focus on getting a parallel code using `parfor` up and running. Performance will not be addressed in this post. I will assume that the reader has a basic knowledge of the
`parfor`-loop construct. Loren has a very nice introduction to using `parfor` in one of her previous posts. There are also some nice introductory videos.

*Note for clarity* : Since Loren's introductory post, the toolbox used for parallel computing has changed names from the Distributed Computing
Toolbox to the Parallel Computing Toolbox. These are not two separate toolboxes.

### Method

In some cases, you may only need to change a `for`-loop to a `parfor`-loop to get their code running in parallel. However, in other cases you may need to slightly alter the code so that `parfor` can work. I decided to show a few examples highlighting the main challenges that one might encounter. I have separated these
examples into four encompassing categories:

- Independence
- Globals and Transparency
- Classification
- Uniqueness

### Background on parfor-loops

In a `parfor`-loop (just like in a standard `for`-loop) a series of statements known as the loop body are iterated over a range of values. However, when using a `parfor`-loop the iterations are run not on the client MATLAB machine but are run in parallel on MATLAB workers.

Each worker has its own unique workspace. So, the data needed to do these calculations is sent from the client to workers,
and the results are sent back to the client and pieced together. The cool thing about `parfor` is this data transfer is handled for the user. When MATLAB gets to the `parfor`-loop, it statically analyzes the body of the `parfor`-loop and determines what information goes to which worker and what variables will be returning to the client MATLAB. Understanding
this concept will become important when understanding why particular constraints are placed on the use of `parfor`.

### Opening the matlabpool

Before looking at some examples, I will open up a matlabpool so I can run my loops in parallel. I will be opening up the matlabpool using my default local configuration (i.e. my workers will be running on the dual-core laptop machine where my MATLAB has been installed).

if matlabpool('size') == 0 % checking to see if my pool is already open matlabpool open 2 end

Starting matlabpool using the 'local' configuration ... connected to 2 labs.

*Note* : The `'size'` option was new in R2008b.

### Independence

The `parfor`-loop is designed for task-parallel types of problems where each iteration of the loop is independent of each other iteration.
This is a critical requirement for using a `parfor`-loop. Let's see an example of when each iteration is not independent.

`type dependentLoop.m`

% Example of a dependent for-loop a = zeros(1,10); parfor it = 1:10 a(it) = someFunction(a(it-1)); end

Checking the above code using M-Lint (MATLAB's static code analyzer) gives a warning message that these iterations are dependent
and will not work with the `parfor` construct. M-Lint can either be accessed via the editor or command line. In this case, I use the command line and have defined
a simple function `displayMlint` so that the display is compact.

```
output = mlint('dependentLoop.m');
displayMlint(output)
```

The PARFOR loop cannot run due to the way variable 'a' is used. In a PARFOR loop, variable 'a' is indexed in different ways, potentially causing dependencies between iterations.

Sometimes loops are intrinsically or unavoidably dependent, and therefore `parfor` is not a good fit for that type of calculation. However, in some cases it is possible to reformulate the body of the loop
to eliminate the dependency or separate it from the main time-consuming calculation.

### Globals and Transparency

All variables within the body of a `parfor`-loop must be transparent. This means that all references to variables must occur in the text of the program. Since MATLAB
is statically analyzing the loops to figure out what data goes to what worker and what data comes back, this seems like an
understandable restriction.

Therefore, the following commands cannot be used within the body of a `parfor`-loop : `evalc`, `eval`, `evalin`, and `assignin`. `load` can also not be used unless the output of load is assigned to a variable name. It is possible to use the above functions within a function called by `parfor`, due to the fact that the function has its own workspace. I have found that this is often the easiest workaround for the
transparency issue.

Additionally, you cannot define global variables or persistent variables within the body of the `parfor` loop. I would also suggest being careful with the use of globals since changes in global values on workers are not automatically
reflected in local global values.

### Classification

A detailed description of the classification of variables in a `parfor`-loop is in the documentation. I think it is useful to view classification as representing the different ways a variable is
passed between client and worker and the different ways it is used within the body of the `parfor`-loop.

*Challenges with Classification*

Often challenges arise when first converting `for`-loops to `parfor`-loops due to issues with this classification. An often seen issue is the conversion of nested `for`-loops, where sliced variables are not indexed appropriately.

Sliced variables are variables where each worker is calculating on a different part of that variable. Therefore, sliced variables are sliced or divided amongst the workers. Sliced variables are used to prevent unneeded data transfer from client to worker.

*Using parfor with Nested for-Loops*

The loop below is nested and encounters some of the restrictions placed on `parfor` for sliced variables.

`type parforNestTry.m`

A1 = zeros(10,10); parfor ix = 1:10 for jx = 1:10 A1(ix, jx) = ix + jx; end end

```
output = mlint('parforNestTry.m');
displayMlint(output);
```

The PARFOR loop cannot run due to the way variable 'A1' is used. Valid indices for 'A1' are restricted in PARFOR loops.

In this case, `A1` is a sliced variable. For sliced variables, the restrictions are placed on the first-level variable indices. This allows
`parfor` to easily distribute the right part of the variable to the right workers.

The first level indexing ,in general, refers to indexing within the first set of parenthesis or braces. This is explained in more detail in the same section as classification in the documentation.

One of these first-level indices must be the loop counter variable or the counter variable plus or minus a constant. *Every other first-level index must be a constant, a non-loop counter variable, a colon, or an end.*

In this case, `A1` has an loop counter variable for both first level indices (`ix` and `jx`).

The solution to this is make sure a loop counter variable is only one of the indices of `A1` and make the other index a colon. To implement this, the results of the inner loop can be saved to a new variable and then
that variable can be saved to the desired variable outside the nested loop.

A2 = zeros(10,10); parfor ix = 1:10 myTemp = zeros(1,10); for jx = 1:10 myTemp(jx) = ix + jx; end A2(ix,:) = myTemp; end

You can also solve this issue by using cells. Since `jx` is now in the second level of indexing, it can be an loop counter variable.

A3 = cell(10,1); parfor ix = 1:10 for jx = 1:10 A3{ix}(jx) = ix + jx; end end A3 = cell2mat(A3);

I have found that both solutions have their benefits. While cells may be easier to implement in your code, they also result
in `A3` using more memory due to the additional memory requirements for cells. The call to `cell2mat` also adds additional processing time.

A similar technique can be used for several levels of nested `for`-loops.

### Uniqueness

*Doing Machine Specific Calculations*

This is a way, while using `parfor`-loops, to determine which machine you are on and do machine specific instructions within the loop. An example of why you
would want to do this is if different machines have data files in different directories, and you wanted to make sure to get
into the right directory. Do be careful if you make the code machine-specific since it will be harder to port.

% Getting the machine host name [~,hostname] = system('hostname'); % If the loop iterations are the same as the size of matlabpool, the % command is run once per worker. parfor ix = 1:matlabpool('size') [~,hostnameID{ix}] = system('hostname'); end % Can then do host/machine specific commands hostnames = unique(hostnameID); checkhost = hostnames(1); parfor ix = 1:matlabpool('size') [~,myhost] = system('hostname'); if strcmp(myhost,checkhost) display('On Machine 1') else display('NOT on Machine 1') end end

On Machine 1 On Machine 1

In my case since I am running locally -- all of the workers are on the same machine.

Here's the same code running on a non-local cluster.

matlabpool close matlabpool open speedy parfor ix = 1:matlabpool('size') [~,hostnameID{ix}] = system('hostname'); end % Can then do host/machine specific commands hostnames = unique(hostnameID); checkhost = hostnames(1); parfor ix = 1:matlabpool('size') [~,myhost] = system('hostname'); if strcmp(myhost,checkhost) display('On Machine 1') else display('NOT on Machine 1') end end

Sending a stop signal to all the labs ... stopped. Starting matlabpool using the 'speedy' configuration ... connected to 16 labs. On Machine 1 On Machine 1 On Machine 1 NOT on Machine 1 On Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1 NOT on Machine 1

*Note*: The `~` feature is new in R2009b and discussed as a new feature in one of Loren's previous blog posts.

*Doing Worker Specific Calculations*

I would suggest using the new `spmd` functionality to do worker specific calculations. For more information about `spmd`, check out the documentation.

Clean up

`matlabpool close`

Sending a stop signal to all the labs ... stopped.

### Your examples

Tell me about some of the ways you have used `parfor`-loops or feel free to post questions regarding non-performance related issues that haven't been addressed here. Post your
questions and thoughts here.

Get the MATLAB code

Published with MATLAB® 7.9

**Category:**- Best Practice,
- Parallel

### Note

Comments are closed.

## 81 CommentsOldest to Newest

**1**of 81

**2**of 81

**3**of 81

global test; test.val=10; parfor i=1:10 global_test_function(i); end________________________________________

function global_test_function(i) global test; fprintf('%d\n',i*test.val);But it does not.. I get error ??? Error using ==> parallel_function at 594 Error in ==> global_test_function at 3 Attempt to reference field of non-structure array. Error in ==> global_test_script at 7 parfor i=1:10 Can you please explain me if/how I can get around this?

**4**of 81

**5**of 81

global test; test.val=10; parfor i=1:10 globalBridge(test, i); end ------------------------------ function globalBridge(testVar, i) % Sets all the necessary global variables before calling function % that uses them. global test test = testVar; global_test_function(i); endBy using the variable test in the parfor body, it is clear that the variable test is needed on the workers. MATLAB will only transfer the value of test once to each worker per calling of the parfor loop. If you call the parfor loop multiple times, the value of the variable test is always propagated from the client to the workers. Therefore, the workers will not accidentally get out of sync. Cheers, Sarah

**6**of 81

**7**of 81

**8**of 81

**9**of 81

b=cell(length(10000),1); tic; for i=1:10000 b{i}=rand(1,1000); end; toc matlabpool open 1 tic; parfor i=1:10000 b = rand(1,1000); end; toc tic; parfor i=1:10000 b{i} = rand(1,1000); end; toc matlabpool closeMy resulting times were as follows: Elapsed time is 0.338584 seconds. Elapsed time is 0.387303 seconds. Elapsed time is 1.057302 seconds. We see then that the data transfer is the issue. For a more realistic example, I would run a longer running calculation within the loop. A simple thing to do is to add a pause command. Also, there is a nice section in the documentation regarding performance. Cheers, Sarah

**10**of 81

**11**of 81

**12**of 81

workerNo = get(getCurrentTask,'ID');Each worker will have a different task ID - one task will exist for each worker if you are using a matlabpool. Cheers, Sarah

**13**of 81

fce=@test1; parfor i=1:10 result(i)=feval(fce,i); end(where fce is my own function, in the same directory as the script which calls the function), but the error message "Undefined function or method 'test1' for input arguments of type 'double'." displays. I think it is because the file dependencies are not set. How can I do it?

**14**of 81

k = [1 2 3]; parfor h = 1:3 z.var = k(h) disp(z.var) endReturns the error "The variable z in a parfor cannot be classified." In this simplistic example I feel like z should definitely be a temporary variable. If I remove the ".var" portion, the loop works perfectly. Is parfor incapable of segmenting structures?

**15**of 81

a.field1 = rand(10,1); a.field2 = rand(10,1); % Converting a into a structure you can use (b) b = cell2struct(num2cell([a.field1 a.field2]), {'field1','field2'}, 2); % parfor will not let you index into a's fields % parfor ii = 1:10 % a.field1(ii) = a.field1(ii)*rand; % a.field2(ii) = a.field2(ii)*rand; % end % But it will let you index into b if b is a structure % array parfor ii = 1:10 b(ii).field1 = b(ii).field1*rand; b(ii).field2 = b(ii).field2*rand; end %% Convert b back into a a.field1 = [b.field1]'; a.field2 = [b.field2]';Note: b will use more memory than a - so be careful of that if your calculation is memory intensive. Let me know if this example isn't clear. Cheers, Sarah

**16**of 81

function testMain %The body of a parfor-loop cannot make reference to a % nested function. %However, it can call a nested function by means of a % function handle. fce=@myNest; result = zeros(1,10); parfor ii=1:10 result(ii) = fce(ii); end disp(result) function d = myNest(ii) d = rand*ii; end endLet me know if you have any follow up questions. Cheers, Sarah

**17**of 81

function testMain %The body of a parfor-loop cannot make reference to a % nested function. %However, it can call a nested function by means of a % function handle. a = 5; fce=@myNest; result = zeros(1,10); parfor ii=1:10 result(ii) = fce(); end disp(result) function d = myNest d = a*rand; end endFor your above example - the following should work and not give an error.

function testMain %The body of a parfor-loop cannot make reference to a % nested function. %However, it can call a nested function by means of a % function handle. fce=@myNest; result = zeros(1,10); parfor ii=1:10 result(ii) = feval(fce,ii); end disp(result) function d = myNest(ii) d = rand*ii; end endCheers, Sarah

**18**of 81

**19**of 81

clc; clear all; matlabpool open 4 parfor ix1 = 1:10 A = zeros(1,10); for ix3 = 1:10 A(ix3) = ix3; end end matlabpool close

**20**of 81

variable.field1 = result; variable.field2 = parameter1; variable.field3 = parameter2;etc. This is a separate variable for each instance of the variable. I've tried creating the variable using struct() before the loop begins, and that didn't help. It still says it can't classify the variable. Oddly enough, if you create a function that does the exact same operations and call that function from inside the loop, it works just fine. Is this a bug or a quirk of MATLAB's distributed toolbox?

**21**of 81

**22**of 81

%% In this case A will not be brought back parfor ix1 = 1:10 A = zeros(1,10); for ix3 = 1:10 A(ix3) = ix3; end end clear ix3 %% In this case A will be brought back for each iteration parfor ix1 = 1:10 A = zeros(1,10); for ix3 = 1:10 A(ix3) = ix3; end Akept2(ix1,:) = A; end display(Akept2) clear ix3 %% In this case A will only be brought back for last iteration clear all Akept3 = []; parfor ix1 = 1:10 A = zeros(1,10); for ix3 = 1:10 A(ix3) = ix3; end if ix1 < 10 A = []; end Akept3 = [Akept3 ; A]; end display(Akept3)Hopefully this is useful to you. Cheers, Sarah

**23**of 81

**24**of 81

**25**of 81

**26**of 81

%% This doesn't work with parfor in terms of sliced variable indexing particle = cell(10,4); swarm = ones(10,10); s = 10; n = 5; for j=1:s particle{j,2} = zeros(5,n); particle{j,2}(1,:) = 0.9; particle{j,2}(2,:) = 0.1; particle{j,2}(3,:) = swarm(j,1:n); % particle{j,2}(5,:) = swarm(j,1:n); % Set BestValue particle{j,3} = ones(2,2); end particleSafe = particle; % saving it so we can compare later %% This does work in terms of indexing of sliced variables % Swarm shows a message that it is a broadcast variable, that is fine particle = cell(10,4); swarm = ones(10,10); s = 10; n = 5; % Converting particle to particle2 format % We want a matrix of this format: % particle2 = repmat({cell(1,4)},[10 1]); % This would be a 10 x 1 cell with every element holding % a 1 x 4 cell particle2 = mat2cell(particle,ones(10,1),4); parfor j=1:s particle2{j}{2} = zeros(5,n); particle2{j}{2}(1,:) = 0.9; particle2{j}{2}(2,:) = 0.1; particle2{j}{2}(3,:) = swarm(j,1:n); % particle2{j}{2}(5,:) = swarm(j,1:n); % Set BestValue particle2{j}{3} = ones(2,2); end particle2 = vertcat(particle2{:}); isequal(particle2,particleSafe)Let me know if you have any questions on this. Cheers, Sarah

**27**of 81

iter = 0; parfor k = 1:N iter = iter + 1; fprintf('Iteration %d of %d\n',iter, N); %Do something end %the parforMatlab complains that iter is being used illegally. On one hand, I can see why this violates the parfor-restrictions, but OTOH, the fprintf has no side-effects, and is only to help the user see what's going on. Any obvious workarounds?

**28**of 81

function myTestFunc iter = 1; N = 20; parfor k = 1:N counter = myCounter(iter); fprintf('Iteration Total %d of %d\n',counter, N); %Do something end %the parfor end function currentTotal = myCounter(iter) persistent testCounter if isempty(testCounter) testCounter = iter; else testCounter = testCounter + 1; end currentTotal = testCounter; endOutput would be something like this: Iteration Total 1 of 20 Iteration Total 2 of 20 Iteration Total 3 of 20 Iteration Total 4 of 20 Iteration Total 5 of 20 Iteration Total 6 of 20 Iteration Total 7 of 20 Iteration Total 1 of 20 Iteration Total 2 of 20 Iteration Total 3 of 20 Iteration Total 4 of 20 Iteration Total 5 of 20 Iteration Total 6 of 20 Iteration Total 7 of 20 Iteration Total 8 of 20 Iteration Total 9 of 20 Iteration Total 8 of 20 Iteration Total 9 of 20 Iteration Total 10 of 20 Iteration Total 10 of 20 Hope this is useful. Cheers, Sarah

**29**of 81

**30**of 81

parfor n = 1:100000 for A = 1:1:36 for B = -1:-1:-40 for C = 0:1:35 for D = -0:-1:-25 Results{n}(A,B,C,D) = X; end end end end end2. It might be possible to limit the number of internal loops using vectorization. Not only would this make your code easier to put in parallel, but it may very well speed up your serial code. An example of this can be found in my previous guest blog post here - https://blogs.mathworks.com/loren/2008/06/25/speeding-up-matlab-applications/ Cheers, Sarah

**31**of 81

??? Error using ==> parallel_function at 598 Error in ==> syms at 77 Attempt to add "x" to a static workspace. See MATLAB Programming, Restrictions on Assigning to Variables for details. Error in ==> main at 16 parfor i=1:16Could youplease help me to decode it

clear all clc tic r=0.4; t=0.7; L=4; E=72000; alp=3/2; nu=0.33; G=E/(2*(1+nu)); h=12.8; i=1; j=1; Kxx=zeros(17,17); K=1; for i=1:16 r=0.2+i*0.05; for j=1:16 t=0.2+j*0.05; J=[r,t,L]; syms x; M=myfun(x,J); y1=M(1); y2=M(2); y3=M(3); y4=M(4); y5=M(5); I1=quad(inline(y1),0,r); I2=quad(inline(y2),r,2*r); I3=quad(inline(y3),2*r,(L-(r*2))); I4=abs(quad(inline(y4),(L-(r*2)),(L-r))); I5=abs(quad(inline(y5),(L-r),L)); z1=M(6); z2=M(7); z3=M(8); z4=M(9); z5=M(10); I6=quad(inline(z1),0,r); I7=quad(inline(z2),r,2*r); I8=quad(inline(z3),2*r,(L-(r*2))); I9=abs(quad(inline(z4),(L-(r*2)),(L-r))); I10=abs(quad(inline(z5),(L-r),L)); K=abs((((6/(E*h))*(I1+I2+I3+I4+I5))+(((alp*L)/(G*h))*(I6+I7+I8+I9+I10)))^-1); Kxx(i,:)=K; end end r=0.2:0.05:1; t=0.2:0.05:1; surf(r,t,Kxx') toc

function [M] = myfun(x,J) d1=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(J(1)-x)^2))^3); d2=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-J(1))^2))^3); d3=((x.^2)/(J(2)+(2*J(1))).^3); d4=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-(J(3)-(2*J(1))))^2))^3); d5=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-(J(3)-(J(1))))^2))^3); c1=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(J(1)-x)^2))); c2=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-J(1))^2))); c3=((x.^2)/(J(2)+(2*J(1)))); c4=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-(J(3)-(2*J(1))))^2))); c5=((x.^2)/(J(2)+(2*J(1))-2*sqrt(J(1)^2-(x-(J(3)-(J(1))))^2))); M=[d1 d2 d3 d4 d5 c1 c2 c3 c4 c5];

**32**of 81

x = sym('x','real');I think that should fix things for you. Cheers, Sarah

**33**of 81

**34**of 81

**35**of 81

**36**of 81

**37**of 81

load H_180_R12.mat [m n]=size(H); k=n-m; % lenc=fec.ldpcenc(H); % % ldec=fec.ldpcdec(H); % ldec.DecisionType = 'hard decision'; % ldec.OutputFormat = 'whole codeword'; % ldec.NumIterations = 50; % ldec.DoParityChecks='Yes'; matlabpool open local 2; for i=1:1 PsdB(i)=2+1*(i-1); % PsdB=2; Ps_dB=PsdB(i); Ps=10^(Ps_dB/10); FrameNum=100; fernum=0; parfor j=1:FrameNum lenc=fec.ldpcenc(H); ldec=fec.ldpcdec(H); ldec.DecisionType = 'hard decision'; ldec.OutputFormat = 'whole codeword'; ldec.NumIterations = 50; ldec.DoParityChecks='Yes'; msg=randint(1,k); codeword=encode(lenc,msg); s_bpsk=-sign(codeword-0.5); noise=wgn(1,n,1,'linear'); recv=sqrt(Ps).*s_bpsk+noise; llr=(2*sqrt(Ps)).*recv; codeword_dec=decode(ldec,llr); ber=sum(xor(codeword,codeword_dec)); if ber~=0 fernum=fernum+1; end end FER(i)=fernum/FrameNum end matlabpool close; figure(1);semilogy(PsdB,FER,'-*');grid on; xlabel('Ps');ylabel('BER'); title('H\_CodeLength=180\_Rate=1/2 FER performance');

**38**of 81

matlabpool firstConfig 2 addpath('.'); % should point to fgeneric.m etc. FUN.ifun = 1; FUN.iinstance = 1; DIM = 2; tic solution = parPSO(FUN, DIM); toc matlabpool close % this is the parPSO function definition function gbest = parPSO(FUN, DIM) fgeneric('initialize', FUN.ifun, FUN.iinstance, FUN.datapath, FUN.opt); x = 2 * 5 * rand(3,DIM) - 5; fgen = @fgeneric; parfor ind = 1:3 gbest(1,ind) = feval(fgen, x(ind,:)'); end fgeneric('finalize'); endPlease, I did all you explained before but nothing works, it gives me the same error always. I don't know what to do. Please, help me! Thanks, Yenny

**39**of 81

**40**of 81

function myTestFunc N = 20; parfor ii = 1:N myData = myLoadData(); %#ok % Do something with the data here end end function myData = myLoadData() persistent loadedData if isempty(loadedData) loadedData = load('accidents.mat'); end myData = loadedData; endCheers, Sarah

**41**of 81

**42**of 81

numWorkers = matlabpool('size'); parfor ii = 1:numWorkers fgeneric('initialize', FUN.ifun, FUN.iinstance, FUN.datapath, FUN.opt); endDepending on what exactly fgeneric is doing, this may solve your problem. Cheers, Sarah

**43**of 81

**44**of 81

**45**of 81

**46**of 81

node = xxxx; parfor e=1:TNELMS hx_elem=hx(node(e,1:6)); Gx=somefunction(hx_elem); G_globalx(node(e,1:6))=G_globalx(node(e,1:6))+Gx; end

**47**of 81

for x = 1:100 d_x = d_3x(x,:); for y = 1:10 d_y = d_3y(y,:); parfor z = 1:10 k1 = [ d_x ; d_y ; d_3z(z,:) ]; %Where d_x, d_y & d_3z(z,:) are 1x4 double k1 = sum(k1); [r t] = corr_spear(k1 , mod3d_3); if abs(r) > abs(r3d_3(z,1)) r3d_3(z,1) = r; k3d_3(z,1) = k1; end end end endWhile running the above code, I get the following error: ??? Error using ==> parallel_function at 587 Error in ==> parallel_function>make_general_channel/channel_general at 864 Subscripted assignment dimension mismatch. Any thoughts on the cause? I did figure out that it was something to do with "if" condition within the parfor look, but am not sure what the issue is.

**48**of 81

TNELMS = 100; node = ones(TNELMS, 10); parfor e=1:TNELMS hx_elem=hx(node(e,1:6)); Gx=somefunction(hx_elem); G_globalx(node(e,1:6))=G_globalx(node(e,1:6))+Gx; end %% Workarounds --- % If node has more than 6 columns - crop it and only act on the 6 columns, % otherwise replace with a : parfor e=1:TNELMS hx_elem=hx(node(e,:)); Gx=somefunction(hx_elem); end % OR nodec = node(:,1:6); parfor e=1:TNELMS hx_elem=hx(nodec(e,:)); Gx=somefunction(hx_elem); end node(:,1:6) = nodec;The bigger issue is with the function G_globalx. MATLAB has no idea that you are indexing into it uniquely for each iteration. node(e,1:6) could always return the same value, breaking the independence of each loop. You must be able to index it like described in the blogpost above. I can try to help you with that. Cheers, Sarah

**49**of 81

d_3x = rand(100,4); d_3y = rand(10,4); d_3z = rand(10,4); r3d_3 = rand(10,4); k3d_3 = rand(10,4); for x = 1:100 d_x = d_3x(x,:); for y = 1:10 d_y = d_3y(y,:); parfor z = 1:10 k1 = [ d_x ,d_y , d_3z(z,:) ]; %Where d_x, d_y & d_3z(z,:) are 1x4 double k1 = sum(k1); %[r t] = corr_spear(k1 , mod3d_3); % don't have function, so set r equal to % random number r = rand; if abs(r) < abs(r3d_3(z,1)) r3d_3(z,1) = r; k3d_3(z,1) = k1; end end end endCheers, Sarah

**50**of 81

**51**of 81

**52**of 81

**53**of 81

**54**of 81

**55**of 81

**56**of 81

clear all; close all; clc; tic; format long N=30; Mi=50; Mf1=100; Mf2=150; dt=20; nMax=75; tlist=0:dt:dt*nMax; t1_list=[900, 1500, 2100, 2700]; weight=sqrt([2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43]); fk0_list=zeros(length(t1_list),length(tlist)); disp(['N=',int2str(N),', Mi=',int2str(Mi),', Mf1=',int2str(Mf1),', Mf2=',int2str(Mf2)]) Hi=zeros(Mi,Mi); for s=1:Mi-1 Hi(s,s+1)=-1; Hi(s+1,s)=-1; end [Vi,Di]=eig(Hi); Pi=zeros(Mf2,N); Pi((Mf2-Mi)/2+1:Mf2/2+Mi/2,1:N)=Vi(1:Mi,1:N); Vf1=zeros(Mf1,Mf1); for s=1:Mf1 Vf1(:,s)=sqrt(2/(Mf1+1))*sin(pi*s*(1:Mf1)'/(Mf1+1)); end dd1=-2*cos(pi*(1:Mf1)/(Mf1+1))'; Vf2=zeros(Mf2,Mf2); for s=1:Mf2 Vf2(:,s)=sqrt(2/(Mf2+1))*sin(pi*s*(1:Mf2)'/(Mf2+1)); end dd2=-2*cos(pi*(1:Mf2)/(Mf2+1))'; matlabpool parfor s10=1:length(t1_list) disp(['s10=',int2str(s10)]) holdtime=t1_list(s10); P=Pi; P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N)=Vf1'*P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N); P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N)=kron(exp(-i*holdtime*dd1),ones(1,N)).*P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N); P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N)=Vf1*P((Mf2-Mf1)/2+1:Mf2/2+Mf1/2,1:N); PP=Vf2'*P; Pa=zeros(Mf2,N+1); Pb=zeros(Mf2,N+1); sDen=zeros(Mf2,Mf2); for s=1:length(tlist) t=tlist(s); P=kron(exp(-i*t*dd2),ones(1,N)).*PP; P=Vf2*P; Pa(:,1:N)=P; Pa(:,N+1)=zeros(Mf2,1); Pa(1,N+1)=1; for s1=1:Mf2-1 if s1>1 Pa(s1-1,1:N)=-Pa(s1-1,1:N); Pa(:,N+1)=zeros(Mf2,1); Pa(s1,N+1)=1; end Pa(s1,N+1)=1; Pa2=Pa'; sDen(s1,s1)=det(Pa2*Pa); Pb=Pa; for s2=s1+1:Mf2 Pb(s2-1,1:N)=-Pb(s2-1,1:N); Pb(:,N+1)=zeros(Mf2,1); Pb(s2,N+1)=1; sDen(s1,s2)=det(Pa2*Pb); sDen(s2,s1)=sDen(s1,s2)'; end end Pa(Mf2-1,1:N)=-Pa(Mf2-1,1:N); Pa(:,N+1)=zeros(Mf2,1); Pa(Mf2,N+1)=1; sDen(Mf2,Mf2)=det(Pa'*Pa); fk0_list(s10,s)=(sum(sum(sDen))-sum(diag(sDen))+N)/Mf2; end end matlabpool close toc

**57**of 81

**58**of 81

for i=1:num1 parfor j=1:num2, idx=fold(j).idx; data=myData(idx,:); label=myLabel(idx); % perform some processes below... ... end end Kevin

**59**of 81

**60**of 81

**61**of 81

for i=1:num1 for j=1:num2, data2{j}=myData(fold(j).idx),:); label2{j}=myLabel(fold(j).idx); end parfor j=1:num2, data=data2{j}; label=label2{j}; % perform some processes below… … end end

**62**of 81

**63**of 81

**64**of 81

**65**of 81

**66**of 81

**67**of 81

function testCode r=1; ss = 2:1:4; mtotal = []; parfor ii = 1:length(ss); s = ss(ii); m = mSetUp(s,r); if ~isempty(m) mtotal = [mtotal;m]; end end display(mtotal) function mtotal = mSetUp(s,r) mtotal = []; for t=3:1:8 if t>s for u=4:1:10 if u>t for v=5:1:12 if v>u m=[r s t u v]; display(m) mtotal = [mtotal;m]; else end end end end end endCheers, Sarah

**68**of 81

**69**of 81

**70**of 81

**71**of 81

**72**of 81

**73**of 81

**74**of 81

matlabpool(4); Msize = 100; Nloop = 1000; c1 = zeros(Msize, Nloop); c2 = zeros(Msize, Nloop); % initialization loop (runs fine!) MatSet = cell(Nloop, 1); parfor i=1:Nloop MatSet{i} = rand(Msize); % in real life this would contain an extremely expensive code operation end % real-time parallel loop (SLOW!) tic; parfor i=1:Nloop c1(:,i) = MatSet{i} * rand(Msize, 1); end time1 = toc; % real-time serial loop tic; for i=1:Nloop c2(:,i) = MatSet{i} * rand(Msize, 1); end time2 = toc; fprintf('Parallel time: %2.4f ms, Serial Time: %2.4f ms\n', 1000*time1, 1000*time2);

**75**of 81

**76**of 81

**77**of 81

topNodes = [2 3 4 5 6 7]; bottomNodes = [1 2 3 4 5 6]; polarity = [1 1 1 -1 -1 -1]; nodes = max([topNodes bottomNodes]); T = zeros(nodes,numel(polarity)); for i = 1:numel(polarity); if polarity(i) < 0 T(i,bottomNodes(i)) = -1; T(i,topNodes(i)) = 1; else T(i,bottomNodes(i)) = 1; T(i,topNodes(i)) = -1; end endOkay, so now if I use a parfor loop this does not work. There are many of my applications where I have an array with values that represent index values of a matrix and for some reason this is a challenge for me when I try to implement a par for loop. Hope to hear from you soon. Kind regards, Barend

**78**of 81

topNodes = [2 3 4 5 6 7]; bottomNodes = [1 2 3 4 5 6]; polarity = [1 1 -1 1 1 1]; nodes = max([topNodes bottomNodes]); T = zeros(numel(polarity),nodes); parfor i = 1:numel(polarity); myData = T(i,:); if polarity(i) < 0 myData(i,bottomNodes(i)) = -1; myData(i,topNodes(i)) = 1; else myData(i,bottomNodes(i)) = 1; myData(i,topNodes(i)) = -1; end T(i,:) = myData; end

**79**of 81

**80**of 81

**81**of 81

## Recent Comments