LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
LayeredNetworkGenerator.m
1classdef LayeredNetworkGenerator < handle
2 % A generator object that generates layered queueing network models
3 % based on user specification. Characteristics of generated
4 % models can be configured via the generator's properties. See
5 % user guide in report for detailed usage instructions.
6
7 properties
8 populationRange (1, 2) double
9 thinkTimeRange (1, 2) double
10 taskInfProbability (1, 1) double
11 procInfProbability (1, 1) double
12 taskMultiRange (1, 2) double
13 procMultiRange (1, 2) double
14 hostDemandRange (1, 2) double
15 synchCallRange (1, 2) double
16 end
17
18 properties (SetAccess = private)
19 cActivities;
20 cEntries;
21 cTasks;
22 cProcessors;
23 activities;
24 entries;
25 tasks;
26 processors;
27 numTasksPerLevel;
28 numTasksPerProcessor;
29 end
30
31 methods
32 function obj = LayeredNetworkGenerator(varargin)
33 p = inputParser();
34 addParameter(p, 'populationRange', [1, 1]);
35 addParameter(p, 'thinkTimeRange', [1, 1]);
36 addParameter(p, 'taskInfProbability', 0);
37 addParameter(p, 'procInfProbability', 0);
38 addParameter(p, 'taskMultiRange', [1, 1]);
39 addParameter(p, 'procMultiRange', [1, 1]);
40 addParameter(p, 'hostDemandRange', [1, 1]);
41 addParameter(p, 'synchCallRange', [1, 1]);
42 parse(p, varargin{:});
43
44 obj.populationRange = p.Results.populationRange;
45 obj.thinkTimeRange = p.Results.thinkTimeRange;
46 obj.taskInfProbability = p.Results.taskInfProbability;
47 obj.procInfProbability = p.Results.procInfProbability;
48 obj.taskMultiRange = p.Results.taskMultiRange;
49 obj.procMultiRange = p.Results.procMultiRange;
50 obj.hostDemandRange = p.Results.hostDemandRange;
51 obj.synchCallRange = p.Results.synchCallRange;
52 end
53
54 function set.populationRange(obj, range)
55 if range(1) > 0 && range(1) <= range(2)
56 obj.populationRange(1) = range(1);
57 obj.populationRange(2) = range(2);
58 else
59 error('NG:populationRange', 'Population range is not valid');
60 end
61 end
62
63 function set.thinkTimeRange(obj, range)
64 if range(1) >= 0 && range(1) <= range(2)
65 obj.thinkTimeRange(1) = range(1);
66 obj.thinkTimeRange(2) = range(2);
67 else
68 error('NG:thinkTimeRange', 'Think time range is not valid');
69 end
70 end
71
72 function set.taskInfProbability(obj, probability)
73 if probability >= 0 && probability <= 1
74 obj.taskInfProbability = probability;
75 else
76 error('NG:taskInfProbability', 'Task infinite probability is not valid');
77 end
78 end
79
80 function set.procInfProbability(obj, probability)
81 if probability >= 0 && probability <= 1
82 obj.procInfProbability = probability;
83 else
84 error('NG:procInfProbability', 'Processor infinite probability is not valid');
85 end
86 end
87
88 function set.taskMultiRange(obj, range)
89 if range(1) > 0 && range(1) <= range(2)
90 obj.taskMultiRange(1) = range(1);
91 obj.taskMultiRange(2) = range(2);
92 else
93 error('NG:taskMultiRange', 'Task multiplicity range is not valid');
94 end
95 end
96
97 function set.procMultiRange(obj, range)
98 if range(1) > 0 && range(1) <= range(2)
99 obj.procMultiRange(1) = range(1);
100 obj.procMultiRange(2) = range(2);
101 else
102 error('NG:procMultiRange', 'Processor multiplicity range is not valid');
103 end
104 end
105
106 function set.hostDemandRange(obj, range)
107 if range(1) >= 0 && range(1) <= range(2)
108 obj.hostDemandRange(1) = range(1);
109 obj.hostDemandRange(2) = range(2);
110 else
111 error('NG:hostDemandRange', 'Host demand range is not valid');
112 end
113 end
114
115 function set.synchCallRange(obj, range)
116 if range(1) > 0 && range(1) <= range(2)
117 obj.synchCallRange(1) = range(1);
118 obj.synchCallRange(2) = range(2);
119 else
120 error('NG:synchCallRange', 'Synchronous call range is not valid');
121 end
122 end
123
124 % Main function to call. Returns a generated LQN model according to
125 % specified properties of the LayeredNetworkGenerator object
126 function model = generate(obj, numClients, numLevels, numTasks, numProcessors)
127 obj.validateArgs(numClients, numLevels, numTasks, numProcessors);
128 model = LayeredNetwork('lnw');
129 obj.createClients(model, numClients);
130 obj.createTasks(model, numTasks);
131 obj.createProcessors(model, numProcessors);
132 obj.assignTasks(numLevels, numTasks, numProcessors);
133 obj.connectClientsToTasks(numClients);
134 obj.connectTasksToTasks(numLevels);
135 obj.connectTasksToProcessors(numProcessors);
136 end
137 end
138
139 methods (Access = private)
140 % Validates that parameter values for the network are sound
141 function validateArgs(~, numClients, numLevels, numTasks, numProcessors)
142 if numClients < 1
143 error('NG:invalidArgs', 'Number of clients is less than one');
144 elseif numLevels < 1
145 error('NG:invalidArgs', 'Number of levels is less than one');
146 elseif numTasks < 1
147 error('NG:invalidArgs', 'Number of tasks is less than one');
148 elseif numProcessors < 1
149 error('NG:invalidArgs', 'Number of processors is less than one');
150 elseif numLevels > numTasks
151 error('NG:invalidArgs', 'Number of levels is greater than that of tasks');
152 elseif numProcessors > numTasks
153 error('NG:invalidArgs', 'Number of processors is greater than that of tasks');
154 end
155 end
156
157 % Creates the clients in the layered network
158 function createClients(obj, model, numClients)
159 obj.cActivities = cell(numClients, 1);
160 obj.cEntries = cell(numClients, 1);
161 obj.cTasks = cell(numClients, 1);
162 obj.cProcessors = cell(numClients, 1);
163 for c = 1 : numClients
164 population = LayeredNetworkGenerator.sampleIntegerValue(obj.populationRange);
165 thinkTime = LayeredNetworkGenerator.sampleRealValue(obj.thinkTimeRange);
166
167 obj.cActivities{c} = Activity(model, ['c_activity_', int2str(c)], thinkTime);
168 obj.cEntries{c} = Entry(model, ['c_entry_', int2str(c)]);
169 obj.cTasks{c} = Task(model, ['c_task_', int2str(c)], population, SchedStrategy.REF);
170 obj.cProcessors{c} = Processor(model, ['c_processor_', int2str(c)], Inf, SchedStrategy.INF);
171
172 obj.cActivities{c}.on(obj.cTasks{c}).boundTo(obj.cEntries{c});
173 obj.cEntries{c}.on(obj.cTasks{c});
174 obj.cTasks{c}.on(obj.cProcessors{c});
175 end
176 end
177
178 % Creates the tasks in the layered network
179 function createTasks(obj, model, numTasks)
180 obj.activities = cell(numTasks, 1);
181 obj.entries = cell(numTasks, 1);
182 obj.tasks = cell(numTasks, 1);
183 for t = 1 : numTasks
184 isInfinite = LayeredNetworkGenerator.chooseBooleanValue(obj.taskInfProbability);
185 if isInfinite
186 multiplicity = Inf;
187 scheduling = SchedStrategy.INF;
188 else
189 multiplicity = LayeredNetworkGenerator.sampleIntegerValue(obj.taskMultiRange);
190 scheduling = SchedStrategy.FCFS;
191 end
192 hostDemand = LayeredNetworkGenerator.sampleRealValue(obj.hostDemandRange);
193
194 obj.activities{t} = Activity(model, ['activity_', int2str(t)], hostDemand);
195 obj.entries{t} = Entry(model, ['entry_', int2str(t)]);
196 obj.tasks{t} = Task(model, ['task_', int2str(t)], multiplicity, scheduling);
197
198 obj.activities{t}.on(obj.tasks{t}).boundTo(obj.entries{t}).repliesTo(obj.entries{t});
199 obj.entries{t}.on(obj.tasks{t});
200 end
201 end
202
203 % Creates the processors in the layered network
204 function createProcessors(obj, model, numProcessors)
205 obj.processors = cell(numProcessors, 1);
206 for i = 1 : numProcessors
207 isInfinite = LayeredNetworkGenerator.chooseBooleanValue(obj.procInfProbability);
208 if isInfinite
209 multiplicity = Inf;
210 scheduling = SchedStrategy.INF;
211 else
212 multiplicity = LayeredNetworkGenerator.sampleIntegerValue(obj.procMultiRange);
213 scheduling = SchedStrategy.PS;
214 end
215
216 obj.processors{i} = Processor(model, ['processor_', int2str(i)], multiplicity, scheduling);
217 end
218 end
219
220 % Assigns the tasks to different levels and processors
221 function assignTasks(obj, numLevels, numTasks, numProcessors)
222 obj.numTasksPerLevel = LayeredNetworkGenerator.makeIntegerVector(numLevels, numTasks);
223 obj.numTasksPerProcessor = LayeredNetworkGenerator.makeIntegerVector(numProcessors, numTasks);
224 end
225
226 % Connects the clients to the tasks
227 function connectClientsToTasks(obj, numClients)
228 clientConnected = false(1, numClients);
229 for t = 1 : obj.numTasksPerLevel(1)
230 synchCall = LayeredNetworkGenerator.sampleRealValue(obj.synchCallRange);
231
232 c = LayeredNetworkGenerator.sampleIntegerValue([1, numClients]);
233 obj.cActivities{c}.synchCall(obj.entries{t}, synchCall);
234 clientConnected(c) = true;
235 end
236
237 for c = 1 : numClients
238 if clientConnected(c)
239 continue
240 end
241
242 synchCall = LayeredNetworkGenerator.sampleRealValue(obj.synchCallRange);
243
244 t = LayeredNetworkGenerator.sampleIntegerValue([1, obj.numTasksPerLevel(1)]);
245 obj.cActivities{c}.synchCall(obj.entries{t}, synchCall);
246 clientConnected(c) = true;
247 end
248 end
249
250 % Connects the tasks between adjacent levels
251 function connectTasksToTasks(obj, numLevels)
252 numTasks = obj.numTasksPerLevel(1);
253 for l = 2 : numLevels
254 for t2 = numTasks + (1 : obj.numTasksPerLevel(l))
255 synchCall = LayeredNetworkGenerator.sampleRealValue(obj.synchCallRange);
256
257 t1 = LayeredNetworkGenerator.sampleIntegerValue(numTasks - [obj.numTasksPerLevel(l - 1) - 1, 0]);
258 obj.activities{t1}.synchCall(obj.entries{t2}, synchCall);
259 end
260 numTasks = numTasks + obj.numTasksPerLevel(l);
261 end
262 end
263
264 % Connects the tasks to the processors
265 function connectTasksToProcessors(obj, numProcessors)
266 numTasks = 0;
267 for p = 1 : numProcessors
268 for t = numTasks + (1 : obj.numTasksPerProcessor(p))
269 obj.tasks{t}.on(obj.processors{p});
270 end
271 numTasks = numTasks + obj.numTasksPerProcessor(p);
272 end
273 end
274 end
275
276 methods (Static)
277 % Samples an integer value from a given range
278 function value = sampleIntegerValue(range)
279 value = randi([ceil(range(1)), floor(range(2))]);
280 end
281
282 % Samples a real value from a given range
283 function value = sampleRealValue(range)
284 value = range(1) + (range(2) - range(1)) * rand();
285 end
286
287 % Chooses a boolean value for a given probability
288 function value = chooseBooleanValue(probability)
289 value = rand() < probability;
290 end
291
292 % Makes an integer vector with given length and sum
293 function vector = makeIntegerVector(length, sum)
294 vector = ones(length, 1);
295 for s = 1 : sum - length
296 i = randi([1, length]);
297 vector(i) = vector(i) + 1;
298 end
299 end
300 end
301
302end