


PARALLEL CONTEXT
In parallel context this function is used to determine the total number of available CPUs,
and the number of threads to run on each CPU.
INPUTS
o Parallel [struct vector] copy of options_.parallel
o fBlock [int] index number of the first job (e.g. MC iteration or MH block)
(between 1 and nBlock)
o nBlock [int] index number of the last job.
OUTPUT
o nBlockPerCPU [int vector] for each CPU used, indicates the number of
threads run on that CPU
o totCPU [int] total number of CPU used (can be lower than
the number of CPU declared in "Parallel", if
the number of required threads is lower!)
o nCPU the number of CPU in user format.
o totSLAVES the number of cluster's node currently
involved in parallel computing step.
It is a number between 1 and length(Parallel).

0001 function [nCPU, totCPU, nBlockPerCPU, totSLAVES] = distributeJobs(Parallel, fBlock, nBlock) 0002 % PARALLEL CONTEXT 0003 % In parallel context this function is used to determine the total number of available CPUs, 0004 % and the number of threads to run on each CPU. 0005 % 0006 % INPUTS 0007 % o Parallel [struct vector] copy of options_.parallel 0008 % o fBlock [int] index number of the first job (e.g. MC iteration or MH block) 0009 % (between 1 and nBlock) 0010 % o nBlock [int] index number of the last job. 0011 % 0012 % OUTPUT 0013 % o nBlockPerCPU [int vector] for each CPU used, indicates the number of 0014 % threads run on that CPU 0015 % o totCPU [int] total number of CPU used (can be lower than 0016 % the number of CPU declared in "Parallel", if 0017 % the number of required threads is lower!) 0018 % o nCPU the number of CPU in user format. 0019 % o totSLAVES the number of cluster's node currently 0020 % involved in parallel computing step. 0021 % It is a number between 1 and length(Parallel). 0022 0023 0024 % Copyright (C) 2010-2011 Dynare Team 0025 % 0026 % This file is part of Dynare. 0027 % 0028 % Dynare is free software: you can redistribute it and/or modify 0029 % it under the terms of the GNU General Public License as published by 0030 % the Free Software Foundation, either version 3 of the License, or 0031 % (at your option) any later version. 0032 % 0033 % Dynare is distributed in the hope that it will be useful, 0034 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0035 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0036 % GNU General Public License for more details. 0037 % 0038 % You should have received a copy of the GNU General Public License 0039 % along with Dynare. If not, see <http://www.gnu.org/licenses/>. 0040 0041 0042 % The Parallel vector has already been sorted 0043 % (in accord with the CPUWeight values) in DESCENDING order in 0044 % InitializeComputationalEnvironment! 0045 0046 totCPU=0; 0047 0048 lP=length(Parallel); 0049 CPUWeight=ones(1,length(Parallel))*(-1); 0050 0051 for j=1:lP, 0052 nCPU(j)=length(Parallel(j).CPUnbr); 0053 totCPU=totCPU+nCPU(j); 0054 CPUWeight(j)=str2num(Parallel(j).NodeWeight); 0055 end 0056 0057 0058 % Copy of original nCPU. 0059 nCPUoriginal=nCPU; 0060 0061 nCPU=cumsum(nCPU); 0062 0063 0064 % Number of Nodes in Cluster. 0065 nC=lP; 0066 0067 % Numbers of Jobs. 0068 NumbersOfJobs=nBlock-fBlock+1; 0069 0070 SumOfJobs=0; 0071 JobsForNode=zeros(1,nC); 0072 0073 for j=1:lP, 0074 CPUWeight(j)=str2num(Parallel(j).NodeWeight)*nCPUoriginal(j); 0075 end 0076 CPUWeight=CPUWeight./sum(CPUWeight); 0077 0078 % Redistributing the jobs among the cluster nodes according to the 0079 % CPUWeight. 0080 for i=1:nC 0081 0082 JobsForNode(i)=CPUWeight(i)*NumbersOfJobs; 0083 0084 % Many choices are possible: 0085 0086 % JobsForNode(i)=round(JobsForNode(i)); 0087 % JobsForNode(i)=floor(JobsForNode(i)); 0088 JobsForNode(i)=ceil(JobsForNode(i)); 0089 0090 end 0091 0092 % Check if there are more (fewer) jobs. 0093 % This can happen when we use ceil, round, ... functions. 0094 SumOfJobs=sum(JobsForNode); 0095 0096 if SumOfJobs~=NumbersOfJobs 0097 0098 if SumOfJobs>NumbersOfJobs 0099 0100 % Many choices are possible: 0101 0102 % - Remove the excess works at the node that has the greatest 0103 % number of jobs. 0104 % - Remove the excess works at the node slower. 0105 0106 VerySlow=nC; 0107 0108 while SumOfJobs>NumbersOfJobs 0109 0110 if JobsForNode(VerySlow)==0 0111 VerySlow=VerySlow-1; 0112 continue 0113 end 0114 JobsForNode(VerySlow)=JobsForNode(VerySlow)-1; 0115 SumOfJobs=SumOfJobs-1; 0116 end 0117 0118 end 0119 0120 if SumOfJobs<NumbersOfJobs 0121 0122 % Many choices are possible: 0123 % - ... (see above). 0124 0125 [NonServe VeryFast]= min(CPUWeight); 0126 0127 while SumOfJobs<NumbersOfJobs 0128 JobsForNode(VeryFast)=JobsForNode(VeryFast)+1; 0129 SumOfJobs=SumOfJobs+1; 0130 end 0131 0132 end 0133 end 0134 0135 0136 % Redistributing the jobs among the cpu/core nodes. 0137 0138 JobsForCpu=zeros(1,nCPU(nC)); 0139 JobAssignedCpu=0; 0140 0141 RelativePosition=1; 0142 0143 for i=1:nC 0144 0145 % Many choices are possible: 0146 % - ... (see above). 0147 0148 JobAssignedCpu=max(1,floor(JobsForNode(i)/nCPUoriginal(i))); 0149 0150 ChekOverFlow=0; 0151 0152 for j=RelativePosition:nCPU(i) 0153 JobsForCpu(j)=JobAssignedCpu; 0154 ChekOverFlow=ChekOverFlow+JobAssignedCpu; 0155 0156 if ChekOverFlow>=JobsForNode(i) 0157 break; 0158 end 0159 0160 end 0161 0162 % Check if there are more (fewer) jobs. 0163 % This can happen when we use ceil, round, ... functions. 0164 0165 if ChekOverFlow ~=(JobsForNode(i)) 0166 0167 if ChekOverFlow >(JobsForNode(i)) 0168 while ChekOverFlow>JobsForNode(i) 0169 JobsForCpu(nCPU(i))=JobsForCpu(nCPU(i))-1; 0170 ChekOverFlow=ChekOverFlow-1; 0171 end 0172 end 0173 0174 if ChekOverFlow <(JobsForNode(i)) 0175 while ChekOverFlow<JobsForNode(i) 0176 JobsForCpu(nCPU(i))=JobsForCpu(nCPU(i))+1; 0177 ChekOverFlow=ChekOverFlow+1; 0178 end 0179 end 0180 end 0181 0182 RelativePosition=nCPU(i)+1; 0183 0184 end 0185 0186 % Reshape the variables totCPU,totSLAVES and nBlockPerCPU in accord with 0187 % the syntax rquired by a previous version of parallel package ... 0188 0189 totCPU=0; 0190 totSLAVES=0; 0191 nBlockPerCPU=[]; 0192 0193 for i=1:nCPU(nC) 0194 if JobsForCpu(i)~=0 0195 totCPU=totCPU+1; 0196 end 0197 end 0198 0199 for i=1:nC 0200 if JobsForNode(i)~=0; 0201 totSLAVES=totSLAVES+1; 0202 end 0203 end 0204 0205 RelativeCounter=1; 0206 for i=1:nCPU(nC) 0207 if JobsForCpu(i)~=0 0208 nBlockPerCPU(RelativeCounter)=JobsForCpu(i); 0209 RelativeCounter=RelativeCounter+1; 0210 end 0211 end 0212 0213