-
Notifications
You must be signed in to change notification settings - Fork 1
/
binpack.pl
124 lines (101 loc) · 4.94 KB
/
binpack.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
% :-['../data/infrs/infr16_20230303_114939.pl', '../data/apps/speakToMe.pl'].
:-['../pl-utils/requirements.pl', '../pl-utils/costs.pl'].
:- set_prolog_flag(answer_write_options,[max_depth(0)]). % write answers' text entirely
:- set_prolog_flag(stack_limit, 32 000 000 000).
:- set_prolog_flag(last_call_optimisation, true).
stats(App, Placement, Cost, Bins, Infs, Time) :-
statistics(inferences, InfA),
statistics(cputime, TimeA),
best(App, Placement, Cost),
countDistinct(Placement, Bins),
statistics(cputime, TimeB),
statistics(inferences, InfB),
Infs is InfB - InfA,
Time is TimeB - TimeA.
best(App, Placement, Cost) :-
application(App, Functions, Services),
checkThings,
ranking(Functions, Services, RankedComps), % RankedComps: [(Rank, Comp)|Rest] --> sort "Comp" by increasing HWReqs
findCompatibles(RankedComps, Components), % Components: [(Comp, Compatibles)|Rest]--> sort "Compatibles" nodes by decreasing HWCaps
findBudget(Components, Budget),
placement(Components, Placement, Budget, Cost),
qosOK(Placement).
findBudget(C, B) :- findBudget(C, 0, B).
findBudget([(_, Comps)|Cs], OldB, NewB) :-
maxCost(Comps, CB), TmpB is OldB + CB,
findBudget(Cs, TmpB, NewB).
findBudget([], B, B).
maxCost(Comps, MaxCost) :- member((MaxCost,_,N), Comps), \+ (member((CostM,_,M), Comps), dif(N,M), CostM > MaxCost).
checkThings :-
findall(T, thingInstance(T, _), Things),
findall(T, (node(_, _, _, _, IoTCaps), member(T, IoTCaps)), IoT),
subset(Things, IoT).
countDistinct(P, L) :-
findall(N, distinct(member((_,N), P)), S),
sort(S, Ss), length(Ss, L).
findCompatibles(Compatibles, Components) :- findCompatibles(Compatibles, [], Components).
findCompatibles([(_,C)|Cs], OldC, NewC):-
findall((Cost, H, M), lightNodeOK(C, M, H, Cost), [Comp|Atibles]),
sort([Comp|Atibles], SCompatibles), % cannot be empty
findCompatibles(Cs, [(C,SCompatibles)|OldC], NewC).
findCompatibles([], C, C).
lightNodeOK(S,N,H,SCost) :-
serviceInstance(S, SId), service(SId, SWReqs, (Arch, HWReqs)),
node(N, SWCaps, (Arch, HWCaps), _, _),
requirements(SId, N),
subset(SWReqs, SWCaps),
HWCaps >= HWReqs, H is 1/HWCaps, % H used to sort Compatibles (ascending H --> descending HWCaps))
nodeType(N, Type), cost(Type, S, SCost).
lightNodeOK(F,N,H,FCost) :-
functionInstance(F, FId, _), function(FId, SWPlatform, (Arch, HWReqs)),
node(N, SWCaps, (Arch, HWCaps), _, _),
requirements(FId, N),
member(SWPlatform, SWCaps),
HWCaps >= HWReqs, H is 1/HWCaps,
nodeType(N, Type), cost(Type, F, FCost).
placement(Cs, Placement, Budget, NewCost) :- placement(Cs, [], Placement, Budget, 0, NewCost).
placement([(C, Comps)|Cs], OldP, NewP, Budget, OldCost, NewCost) :-
componentPlacement(C, Comps, N, OldP, CCost),
TCost is OldCost + CCost, TCost < Budget,
placement(Cs, [(C,N)|OldP], NewP, Budget, TCost, NewCost).
placement([], P, P, _, Cost, Cost).
componentPlacement(F, Comps, N, Ps, FCost) :-
functionInstance(F, FId, _), function(FId, _, HWReqs),
member((_,N), Ps), member((FCost,_,N), Comps),
compatible(N, HWReqs, Ps).
componentPlacement(F, Comps, N, Ps, FCost) :-
functionInstance(F, FId, _), function(FId, _, HWReqs),
member((FCost,_,N), Comps), \+ member((_,N),Ps),
compatible(N, HWReqs, Ps).
componentPlacement(S, Comps, N, Ps, SCost) :-
serviceInstance(S, SId), service(SId, _, HWReqs),
member((_,N), Ps), member((SCost,_,N), Comps),
compatible(N, HWReqs, Ps).
componentPlacement(S, Comps, N, Ps, SCost) :-
serviceInstance(S, SId), service(SId, _, HWReqs),
member((SCost,_,N), Comps), \+ member((_,N),Ps),
compatible(N, HWReqs, Ps).
compatible(N, (Arch,HWReqs), Ps) :- node(N, _, (Arch, HWCaps), _, _), hwOK(N, HWCaps, HWReqs, Ps).
hwOK(N,HWCaps,HWReqs,Ps) :-
findall(HW, hwOnN(N, Ps, HW), HWs), sum_list(HWs,TotHW),
hwTh(T), HWCaps >= TotHW + HWReqs + T.
hwOnN(N, Ps, HW) :- serviceInstance(S, SId), service(SId,_,(_,HW)), member((S,N), Ps).
hwOnN(N, Ps, HW) :- functionInstance(F, FId,_), function(FId,_,(_,HW)), member((F,N), Ps).
qosOK(Ps) :- findall((N1N2, Lat, Sec), relevant(N1N2, Ps, Lat, _, Sec), DataFlows), checkDF(DataFlows, Ps).
checkDF([((N1,N2),ReqLat,SecReqs)|DFs], Ps) :-
(link(N1, N2, FeatLat, FeatBW); link(N2, N1, FeatLat, FeatBW)),
secOK(N1, N2, SecReqs),
FeatLat =< ReqLat, bwOK((N1,N2), FeatBW, Ps),
checkDF(DFs, Ps).
checkDF([], _).
bwOK(N1N2, FeatBW, Ps):-
findall(BW, relevant(N1N2, Ps, _, BW, _), BWs), sum_list(BWs, OkAllocBW),
bwTh(T), FeatBW >= OkAllocBW + T.
secOK(N1, N2, SecReqs) :-
node(N1, _, _, SecCaps1, _), subset(SecReqs, SecCaps1),
node(N2, _, _, SecCaps2, _), subset(SecReqs, SecCaps2).
relevant((N1,N2), Ps, Lat, BW, Sec):-
dataFlow(T1, T2, _, Sec, Size, Rate, Lat),
(member((T1,N1), Ps); node(N1, _, _, _, IoTCaps), member(T1, IoTCaps)),
(member((T2,N2), Ps); node(N2, _, _, _, IoTCaps), member(T2, IoTCaps)),
BW is Size*Rate.