Identifying lab id within a parfor
31 次查看(过去 30 天)
显示 更早的评论
Hello all,
I have an problem that I would like to run in parallel using a parfor. Within the parfor I have to call an external program that runs some calculations using system('external_command result_file_name'). This external program saves the result into a text file that I have to read after execution.
In order for the different iterations not overwrite the results of each other, I would like to know what is the labid running each iteration such that I can compose the file name such as file_name_labid.
I have tried the function labindex but it always returns 1 within a parfor. Is there any other way I can get the labid?
Many thanks,
0 个评论
采纳的回答
Edric Ellis
2012-2-27
As mentioned elsewhere, LABINDEX will not work for this purpose. You could either use
t = getCurrentTask(); t.ID
to find out which task you're running. Each worker has a unique task ID which remains the same for the duration of the MATLABPOOL.
Or, my personal preferred solution would be to use TEMPNAME to generate a unique filename to write the output to.
3 个评论
Damdae
2019-7-23
It would be better if labindex returned the value of get(getCurrentTask(),'ID') when it's in a parfor loop.
更多回答(6 个)
Jiro Doke
2012-2-26
Why not save the file based on the iteration number? Wouldn't you still overwrite the results if you were using the labindex because different iterations could be running on the same worker.
As Oleg mentioned, if you want something to happen based on the labindex, use spmd instead. You would break up your loop into n groups, where n is the number of workers. Something like this:
spmd
for id = (1:100)+(labindex-1)*100
% do some computation
save(sprintf('file_name_%d', labindex));
end
end
EDIT 1: Combine SPMD and PARFOR to write to different directories
spmd
mkdir(sprintf('worker%d', labindex));
cd(sprintf('worker%d', labindex));
end
parfor id = 1:1000
fid = fopen('myresults.txt', 'a+');
fprintf(fid, '%d\n', id);
fclose(fid);
end
spmd
cd ..
end
EDIT 2:
function [] = main_function()
function [y] = obj(x)
% write parameters x to an input file
system('external_program input_file output_file');
% read output file
y = read_output();
end
spmd
folder = sprintf('worker%d', labindex);
mkdir(folder);
cd(folder);
end
% now I can use a parfor
result = [];
c = linspace(10,100,10);
parfor k=1:10
result(k) = obj( c(k) );
end
plot(c,result);
% or I can call fmincon
problem.x0 = x0;
problem.objective = @obj;
[x,fval] = fmincon(problem);
spmd
cd ..
end
end
Creating folders and cd-ing to the appropriate folder (using spmd) ensures that each worker resides in different locations. Then file writing and reading will happen in different locations.
0 个评论
Oleg Komarov
2012-2-25
Trying a simple parfor never uses more than 1 worker:
matlabpool(2)
parfor ii = 1:10000
if numlabs > 1
disp(labindex)
end
end
matlabpool close
But the following snippet forces the execution of labindex on all workers:
matlabpool(2)
spmd
labindex
end
matlabpool close
Somebody who can enlighten us about this behaviour?
1 个评论
Edric Ellis
2012-2-27
LABINDEX always returns the value 1 when not inside an SPMD block (or the body of a parallel job). You can check e.g. "t = getCurrentTask(); t.ID" to see that different tasks work on different PARFOR loop iterations. LABINDEX and NUMLABS are designed to show you with whom you can communicate using LABSEND and LABRECEIVE. Inside a PARFOR loop, that's no-one.
Javier
2012-2-26
1 个评论
Jiro Doke
2012-2-26
With fmincon, you probably won't use parfor anyway, so I'm not sure I understand when you say you want to use the same code.
Another way I would do it is to use SPMD and PARFOR together. You can use SPMD to change the folder that each worker is in. Then you can write to a file, and the files will be unique for each worker because they're in different folders. See my edit to my answer.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Parallel for-Loops (parfor) 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!