@@ -43,6 +43,15 @@ public let PrimsNonStrongRef: [BenchmarkInfo] = ({
43
43
touchGlobalInfo ( )
44
44
blackHole ( weakPrimsState)
45
45
} ) )
46
+ // TODO: Stabilize weak benchmark.
47
+ benchmarks. append ( BenchmarkInfo (
48
+ name: " Prims.NonStrongRef.Weak.ClosureAccess " ,
49
+ runFunction: run_PrimsWeakClosureAccess,
50
+ tags: [ . validation, . algorithm] ,
51
+ setUpFunction: {
52
+ touchGlobalInfo ( )
53
+ blackHole ( weakPrimsState)
54
+ } ) )
46
55
#endif
47
56
benchmarks. append ( BenchmarkInfo (
48
57
name: " Prims.NonStrongRef.UnownedSafe " ,
@@ -52,6 +61,14 @@ public let PrimsNonStrongRef: [BenchmarkInfo] = ({
52
61
touchGlobalInfo ( )
53
62
blackHole ( unownedSafePrimsState)
54
63
} ) )
64
+ benchmarks. append ( BenchmarkInfo (
65
+ name: " Prims.NonStrongRef.UnownedSafe.ClosureAccess " ,
66
+ runFunction: run_PrimsUnownedSafeClosureAccess,
67
+ tags: [ . validation, . algorithm] ,
68
+ setUpFunction: {
69
+ touchGlobalInfo ( )
70
+ blackHole ( unownedSafePrimsState)
71
+ } ) )
55
72
benchmarks. append ( BenchmarkInfo (
56
73
name: " Prims.NonStrongRef.UnownedUnsafe " ,
57
74
runFunction: run_PrimsUnownedUnsafe,
@@ -60,6 +77,14 @@ public let PrimsNonStrongRef: [BenchmarkInfo] = ({
60
77
touchGlobalInfo ( )
61
78
blackHole ( unownedUnsafePrimsState)
62
79
} ) )
80
+ benchmarks. append ( BenchmarkInfo (
81
+ name: " Prims.NonStrongRef.UnownedUnsafe.ClosureAccess " ,
82
+ runFunction: run_PrimsUnownedUnsafeClosureAccess,
83
+ tags: [ . validation, . algorithm] ,
84
+ setUpFunction: {
85
+ touchGlobalInfo ( )
86
+ blackHole ( unownedUnsafePrimsState)
87
+ } ) )
63
88
benchmarks. append ( BenchmarkInfo (
64
89
name: " Prims.NonStrongRef.Unmanaged " ,
65
90
runFunction: run_PrimsUnmanaged,
@@ -68,6 +93,14 @@ public let PrimsNonStrongRef: [BenchmarkInfo] = ({
68
93
touchGlobalInfo ( )
69
94
blackHole ( unmanagedPrimsState)
70
95
} ) )
96
+ benchmarks. append ( BenchmarkInfo (
97
+ name: " Prims.NonStrongRef.Unmanaged.ClosureAccess " ,
98
+ runFunction: run_PrimsUnmanagedClosureAccess,
99
+ tags: [ . validation, . algorithm, . api] ,
100
+ setUpFunction: {
101
+ touchGlobalInfo ( )
102
+ blackHole ( unmanagedPrimsState)
103
+ } ) )
71
104
return benchmarks
72
105
} ) ( )
73
106
@@ -1059,6 +1092,41 @@ where Node.BoxType == Box, Box.ValueType == Node
1059
1092
return treeEdges
1060
1093
}
1061
1094
1095
+ func primsMainLoopClosureAccess< Node : GraphNode , Box> (
1096
+ _ graph : Array < Node > ,
1097
+ _ fun : ( Node . BoxType , Node . BoxType ) -> Double ) -> Array < Int ? >
1098
+ where Node. BoxType == Box , Box. ValueType == Node
1099
+ {
1100
+ var treeEdges = Array < Int ? > ( repeating: nil , count: graph. count)
1101
+ let queue = PriorityQueue < Node > ( count: graph. count)
1102
+
1103
+ // Make the minimum spanning tree root its own parent for simplicity.
1104
+ queue. insert ( EdgeCost ( to: graph [ 0 ] , cost: 0.0 , from: graph [ 0 ] ) )
1105
+
1106
+ // Take an element with the smallest cost from the queue and add its
1107
+ // neighbors to the queue if their cost was updated
1108
+ while !queue. isEmpty {
1109
+ // Add an edge with minimum cost to the spanning tree
1110
+ let e = queue. pop ( ) !
1111
+ let newnode : Node . BoxType = e. to
1112
+
1113
+ // Add record about the edge newnode->e.from to treeEdges
1114
+ treeEdges [ newnode. withValue { $0. id } ] = e. from. withValue { $0. id }
1115
+
1116
+ // Check all adjacent nodes and add edges, ending outside the tree, to the
1117
+ // queue. If the queue already contains an edge to an adjacent node, we
1118
+ // replace existing one with the new one in case the new one costs less.
1119
+ for toNode : Box in ( newnode. withValue { $0. adjList } ) {
1120
+ if treeEdges [ toNode. withValue { $0. id } ] != nil {
1121
+ continue
1122
+ }
1123
+ let newcost = fun ( newnode, toNode)
1124
+ queue. insertOrUpdate ( EdgeCost ( to: toNode, cost: newcost, from: newnode) )
1125
+ }
1126
+ }
1127
+ return treeEdges
1128
+ }
1129
+
1062
1130
//===----------------------------------------------------------------------===//
1063
1131
// Top Level Entrypoints
1064
1132
//===----------------------------------------------------------------------===//
@@ -1084,6 +1152,25 @@ func run_PrimsNonStrongRef<Node: GraphNode, Box>(_ state: PrimsState<Node, Box>)
1084
1152
CheckResults ( Int ( cost) == 49324 )
1085
1153
}
1086
1154
1155
+ @inline ( __always)
1156
+ func run_PrimsNonStrongRefClosureAccess< Node: GraphNode , Box> ( _ state: PrimsState < Node , Box > ) where Node. BoxType == Box , Box. ValueType == Node {
1157
+ let graph = state. graph
1158
+ let map = state. edgeToCostMap
1159
+
1160
+ // Find spanning tree
1161
+ let treeEdges = primsMainLoopClosureAccess ( graph, { ( start: Box , end: Box ) in
1162
+ return map [ Edge ( start: start, end: end) ] !
1163
+ } )
1164
+
1165
+ // Compute its cost in order to check results
1166
+ var cost = 0.0
1167
+ for i in 1 ..< treeEdges. count {
1168
+ if let n = treeEdges [ i] {
1169
+ cost += map [ Edge ( start: Box ( graph [ n] ) , end: Box ( graph [ i] ) ) ] !
1170
+ }
1171
+ }
1172
+ CheckResults ( Int ( cost) == 49324 )
1173
+ }
1087
1174
1088
1175
1089
1176
@inline ( never)
@@ -1094,6 +1181,14 @@ public func run_PrimsWeak(_ N: Int) {
1094
1181
}
1095
1182
}
1096
1183
1184
+ @inline ( never)
1185
+ public func run_PrimsWeakClosureAccess( _ N: Int ) {
1186
+ let state = weakPrimsState
1187
+ for _ in 0 ..< N {
1188
+ run_PrimsNonStrongRefClosureAccess ( state)
1189
+ }
1190
+ }
1191
+
1097
1192
@inline ( never)
1098
1193
public func run_PrimsUnownedSafe( _ N: Int ) {
1099
1194
let state = unownedSafePrimsState
@@ -1102,6 +1197,14 @@ public func run_PrimsUnownedSafe(_ N: Int) {
1102
1197
}
1103
1198
}
1104
1199
1200
+ @inline ( never)
1201
+ public func run_PrimsUnownedSafeClosureAccess( _ N: Int ) {
1202
+ let state = unownedSafePrimsState
1203
+ for _ in 0 ..< N {
1204
+ run_PrimsNonStrongRefClosureAccess ( state)
1205
+ }
1206
+ }
1207
+
1105
1208
@inline ( never)
1106
1209
public func run_PrimsUnownedUnsafe( _ N: Int ) {
1107
1210
let state = unownedUnsafePrimsState
@@ -1110,10 +1213,26 @@ public func run_PrimsUnownedUnsafe(_ N: Int) {
1110
1213
}
1111
1214
}
1112
1215
1216
+ @inline ( never)
1217
+ public func run_PrimsUnownedUnsafeClosureAccess( _ N: Int ) {
1218
+ let state = unownedUnsafePrimsState
1219
+ for _ in 0 ..< N {
1220
+ run_PrimsNonStrongRefClosureAccess ( state)
1221
+ }
1222
+ }
1223
+
1113
1224
@inline ( never)
1114
1225
public func run_PrimsUnmanaged( _ N: Int ) {
1115
1226
let state = unmanagedPrimsState
1116
1227
for _ in 0 ..< N {
1117
1228
run_PrimsNonStrongRef ( state)
1118
1229
}
1119
1230
}
1231
+
1232
+ @inline ( never)
1233
+ public func run_PrimsUnmanagedClosureAccess( _ N: Int ) {
1234
+ let state = unmanagedPrimsState
1235
+ for _ in 0 ..< N {
1236
+ run_PrimsNonStrongRefClosureAccess ( state)
1237
+ }
1238
+ }
0 commit comments