LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
spaceGeneratorNodes.m
1function [nodeStateSpace, sn, capacityc] = spaceGeneratorNodes(sn, cutoff, options)
2if nargin<3
3 options = Solver.defaultOptions;
4end
5N = sn.njobs';
6sn.space = {};
7capacityc = zeros(sn.nnodes, sn.nclasses);
8% Draft SPN support
9% for n=1:sn.nnodes
10% if isfield(sn.varsparam{n}, "capacityc")
11% capacityc(n) = sn.varsparam{n}.capacityc;
12% end
13% end
14for ind=1:sn.nnodes
15 if sn.isstation(ind) % place jobs across stations
16 ist = sn.nodeToStation(ind);
17 isf = sn.nodeToStateful(ind);
18 for r=1:sn.nclasses %cut-off open classes to finite capacity
19 c = find(sn.chains(:,r));
20 if ~isempty(sn.visits{c}) && sn.visits{c}(isf,r) == 0
21 capacityc(ind,r) = 0;
22 % Draft SPN support
23 %elseif isfield(sn.varsparam{ind}, 'capacityc')
24 % capacityc(ind,r) = min(cutoff(ist,r), sn.classcap(ist,r));
25 elseif sn.nodetype(ind) ~= NodeType.Place && ~isempty(sn.proc) && ~isempty(sn.proc{ist}{r}) && any(any(isnan(sn.proc{ist}{r}{1}))) % disabled (not Places - they hold tokens without service)
26 capacityc(ind,r) = 0;
27 else
28 if isinf(N(r))
29 capacityc(ind,r) = min(cutoff(ist,r), sn.classcap(ist,r));
30 else
31 capacityc(ind,r) = sum(sn.njobs(sn.chains(c,:)));
32 end
33 end
34 end
35 if sn.isstation(ind)
36 % in this case, the local variables are produced within
37 % fromMarginalBounds, e.g., for RROBIN routing
38 sn.space{isf} = State.fromMarginalBounds(sn, ind, [], capacityc(ind,:), sn.cap(ist), options);
39 else
40 % this is the case for example of cache nodes
41 state_bufsrv = State.fromMarginalBounds(sn, ind, [], capacityc(ind,:), sn.cap(ist), options);
42 state_var = State.spaceLocalVars(sn, ind);
43 sn.space{isf} = State.cartesian(state_bufsrv,state_var); % generate all possible states for local variables
44 end
45 if isinf(sn.nservers(ist))
46 sn.nservers(ist) = sum(capacityc(ind,:));
47 end
48 elseif sn.isstateful(ind) % generate state space of other stateful nodes that are not stations
49 %ist = sn.nodeToStation(ind);
50 isf = sn.nodeToStateful(ind);
51 switch sn.nodetype(ind)
52 case NodeType.Cache
53 for r=1:sn.nclasses % restrict state space generation to immediate events
54 if isnan(sn.nodeparam{ind}.pread{r})
55 capacityc(ind,r) = 1; %
56 else
57 capacityc(ind,r) = 1; %
58 end
59 end
60 case NodeType.Router
61 % For Router nodes, only allow capacity for classes that have
62 % non-zero nodevisits (classes that actually visit the Router)
63 for r=1:sn.nclasses
64 c = find(sn.chains(:,r));
65 if ~isempty(sn.nodevisits{c}) && sn.nodevisits{c}(ind,r) > 0
66 capacityc(ind,r) = 1;
67 else
68 capacityc(ind,r) = 0;
69 end
70 end
71 case NodeType.Transition
72 capacityc(ind,:) = 0; % Transitions don't hold class-based jobs
73 % Generate per-mode state space (bypass fromMarginalBounds)
74 nmodes = sn.nodeparam{ind}.nmodes;
75 firingphases = sn.nodeparam{ind}.firingphases;
76 if any(isnan(firingphases))
77 firingphases = zeros(1, nmodes);
78 for m = 1:nmodes
79 if iscell(sn.nodeparam{ind}.firingproc) && ~isempty(sn.nodeparam{ind}.firingproc{m})
80 firingphases(m) = size(sn.nodeparam{ind}.firingproc{m}{1}, 1);
81 else
82 firingphases(m) = 1;
83 end
84 end
85 end
86 fK = firingphases;
87 nmodeservers = sn.nodeparam{ind}.nmodeservers;
88 max_jobs = sum(sn.njobs(~isinf(sn.njobs)));
89 if any(isinf(sn.njobs))
90 max_jobs = max_jobs + sum(cutoff(1,:));
91 end
92 mode_spaces = cell(1, nmodes);
93 for m = 1:nmodes
94 max_srv_m = nmodeservers(m);
95 if isinf(max_srv_m)
96 max_srv_m = max_jobs;
97 end
98 max_srv_m = min(max_srv_m, max_jobs);
99 mode_states = [];
100 for total = 0:max_srv_m
101 phase_combs = multichoose(fK(m), total);
102 buf_m = nmodeservers(m);
103 if isinf(buf_m)
104 buf_m = GlobalConstants.MaxInt();
105 end
106 buf_m = buf_m - total;
107 mode_states = [mode_states; repmat(buf_m, size(phase_combs,1), 1), phase_combs]; %#ok<AGROW>
108 end
109 mode_spaces{m} = mode_states;
110 end
111 trans_space = mode_spaces{1};
112 for m = 2:nmodes
113 trans_space = State.cartesian(trans_space, mode_spaces{m});
114 end
115 trans_space = [trans_space, zeros(size(trans_space,1), nmodes)]; % append fired counts
116 state_var = State.spaceLocalVars(sn, ind);
117 sn.space{isf} = State.cartesian(trans_space, state_var);
118 continue; % skip fromMarginalBounds below
119 otherwise
120 capacityc(ind,:) = 1; %
121 end
122 state_bufsrv = State.fromMarginalBounds(sn, ind, [], capacityc(ind,:), 1, options);
123 state_var = State.spaceLocalVars(sn, ind);
124 sn.space{isf} = State.cartesian(state_bufsrv,state_var); % generate all possible states for local variables
125 end
126end
127nodeStateSpace = sn.space;
128end