Converting for loops to parfor format gives error "Error: Unable to classify the variable 'f_est_1' in the body of the parfor-loop."
Show older comments
Hello, I am trying to convert the for-loop into parfor loop for faster computation (because of huge amount of data).
The code and data (sample data) is attached for the reference. The code works fine when compiled with for-loop (attached code is with for-loop).
When I change the for-loop to parfor I get the error "Error: Unable to classify the variable 'f_est_1' in the body of the parfor-loop".
The attached code segments the signal based on the adaptive thresholding. Then plots the segmented data and performs the fft of it and stores the dominant frequency from each fft plots in a vector. These tasks are done using the "for-loop". I wanted to convert the for-loops to parfor, I tried changing the the way variables to be used as per the parfor variable classification but I am not bale to crack it.
how to perform this task using parfor? any help is highly appreciable.
1 Comment
Rajendra Rajak
on 15 Jul 2021
Accepted Answer
More Answers (1)
Raymond Norris
on 15 Jul 2021
I'm gathering the for-loop you're trying to re-write is
for i = 1:length(x)
Assuming you're able to re-write this, have you considered what will happen to plotting inside the parfor? Keep in mind, the entire body of code in the parfor is running elsewhere (i.e. the workers). Therefore, you won't see plotting. You have two options for plotting "parallelization" (I put this in quotes since it will need to happen outside of the parfor, where you are running serial code).
- DataQueue: look at creating a data queue to send data from the workers to the client, which then calls a function to update your plot(s).
- parfeval: you'll still need a parallel pool, but rather then using the built-in parfor, create tasks with parfeval and then update the plot(s) when the tasks come back.
This doesn't answer your parfor question, but if you implement parfeval, (A) you ought to be able to plot your data and (B) it'll probably solve your original issue.
6 Comments
Rajendra Rajak
on 16 Jul 2021
Rajendra Rajak
on 16 Jul 2021
Walter Roberson
on 16 Jul 2021
Do you still have
if h > 1
THR_SIG = nois + 0.50*(abs(threshold - nois));
end
You cannot have that inside the parfor loop.
Rajendra Rajak
on 16 Jul 2021
Walter Roberson
on 16 Jul 2021
I feel I need to emphasize even more strongly: parfor will never execute the iterations "in order" ... well except for the case you are only doing one iteration.
Imagine if instead of using
for i = 1:length(env)-k
you had instead used
for i = randperm(length(env)-k)
If the order of iterations matters to you, then you should not be using parfor.
It is not completely impossible to update a value on a worker, but most of the time it is the wrong thing to do.
To get an adaptive value:
- create the parallel pool explicitly using parpool()
- use parallel.pool.pollableDataQueue() on the controller before starting the parfor. https://www.mathworks.com/help/parallel-computing/parallel.pool.pollabledataqueue.html . Call this queue Q_master for the moment
- Then use parfevalOnAll() to run a function on each of the workers that creates a pool, parallel.pool.pollableDataQueue and sends the pool variable back by writing to Q_master from each worker. The controller should store all of the received queues
- Now parfor()
There are more steps but I am falling asleep now.
Rajendra Rajak
on 16 Jul 2021
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!