1classdef HostDemand < opt.DecisionVariable
2 % HostDemand Optimize the mean host demand D of an LQN Activity
3 % (continuous). The processor-layer service rate
is mu = 1/D;
this is the
4 % primary LQN tuning knob (analogous to ServiceRate
for a flat station).
5 % Exposes the partial-sensitivity gradient hooks
6 % (sensKey/sensMetricTargets/rateJacobian/decodeJacobian). Mirrors
7 % native-Python HostDemand.
10 activity % activity name (
char)
16 function obj = HostDemand(activity, bounds, name)
17 actName = opt.Layered.elemName(activity);
18 if nargin < 3 || isempty(name)
19 name = [actName
'_hostdemand'];
21 obj@opt.DecisionVariable(name);
22 obj.activity = actName;
23 obj.minDemand = bounds(1);
24 obj.maxDemand = bounds(2);
27 function a = getActivity(obj), a = obj.activity; end
28 function b = getBounds(obj), b = opt.DecisionVariable.unitBounds(1); end
30 function v = decode(obj, x)
31 v = obj.minDemand + x(1) * (obj.maxDemand - obj.minDemand);
34 function apply(obj, model, value)
35 act = opt.Layered.resolveActivity(model, obj.activity);
37 act.setHostDemand(
double(value));
41 function t = getVariableType(obj), t =
'host_demand'; end
43 function layers = getLayer(obj, model)
44 proc = opt.Layered.activityProcessorName(model, obj.activity);
45 if isempty(proc), layers = {};
else, layers = {proc}; end
48 function v = currentValue(obj, model)
50 act = opt.Layered.resolveActivity(model, obj.activity);
52 v = act.getHostDemandMean();
56 % ---- partial-sensitivity gradient hooks ---------------------------
58 function k = sensKey(obj, model)
59 % Row key
'Station||JobClass' in the per-layer sensitivity table.
60 % Host-layer rows are (Layer=processor,
Station=processor,
61 % JobClass=activity); the value
is d(metric)/d(service rate).
63 proc = opt.Layered.activityProcessorName(model, obj.activity);
64 if isempty(proc),
return; end
65 k = [proc
'||' obj.activity];
68 function targets = sensMetricTargets(obj, model)
69 % Map each layer-row metric to the EvaluationResult key it
70 % approximates: the host-layer row utilization tracks the processor
71 % node
's utilization (keyed by node name); its throughput/queue-
72 % length/response-time track the activity node's (keyed
'act||act').
73 proc = opt.Layered.activityProcessorName(model, obj.activity);
75 targets =
struct(
'Util', proc,
'Tput', [act
'||' act], ...
76 'QLen', [act
'||' act],
'RespT', [act
'||' act]);
79 function j = rateJacobian(~, value)
80 % d(service rate)/d(demand) = d(1/D)/dD = -1/D^2 at D=value.
82 if v <= 0, j = 0.0;
else, j = -1.0 / (v * v); end
85 function j = decodeJacobian(obj, ~)
86 j = obj.maxDemand - obj.minDemand;