Skip to content

Commit 26a611d

Browse files
committed
Add memory estimation for closeness centrality
1 parent 75ad22a commit 26a611d

File tree

17 files changed

+240
-13
lines changed

17 files changed

+240
-13
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Neo4j is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
package org.neo4j.gds.closeness;
21+
22+
import org.neo4j.gds.collections.ha.HugeDoubleArray;
23+
import org.neo4j.gds.collections.haa.HugeAtomicIntArray;
24+
import org.neo4j.gds.mem.MemoryEstimateDefinition;
25+
import org.neo4j.gds.mem.MemoryEstimation;
26+
import org.neo4j.gds.mem.MemoryEstimations;
27+
import org.neo4j.gds.msbfs.MSBFSMemoryEstimation;
28+
29+
public final class ClosenessCentralityAlgorithmEstimateDefinition implements MemoryEstimateDefinition {
30+
31+
@Override
32+
public MemoryEstimation memoryEstimation() {
33+
return MemoryEstimations.builder(ClosenessCentrality.class)
34+
.perNode("farness", HugeAtomicIntArray::memoryEstimation)
35+
.perNode("component", HugeAtomicIntArray::memoryEstimation)
36+
.perNode("closeness", HugeDoubleArray::memoryEstimation)
37+
.add("MSBFS", MSBFSMemoryEstimation.MSBFSWithANPStrategy(0))
38+
.build();
39+
}
40+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Neo4j is free software: you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
package org.neo4j.gds.closeness;
21+
22+
import org.junit.jupiter.params.ParameterizedTest;
23+
import org.junit.jupiter.params.provider.CsvSource;
24+
import org.neo4j.gds.core.concurrency.Concurrency;
25+
26+
import static org.neo4j.gds.assertions.MemoryEstimationAssert.assertThat;
27+
28+
class ClosenessCentralityAlgorithmEstimateDefinitionTest {
29+
30+
@ParameterizedTest
31+
@CsvSource({
32+
"10_000, 1, 160_368",
33+
"10_000, 4, 160_632",
34+
"500_000, 4, 8_000_632",
35+
"10_000_000, 4, 160_000_632",
36+
"10_000, 2, 160_456",
37+
"10_000, 128, 171_544"
38+
})
39+
void testMemoryEstimation(long nodeCount, int concurrency, long expectedMemory) {
40+
var memoryEstimation = new ClosenessCentralityAlgorithmEstimateDefinition().memoryEstimation();
41+
assertThat(memoryEstimation)
42+
.memoryRange(nodeCount, new Concurrency(concurrency))
43+
.hasSameMinAndMaxEqualTo(expectedMemory);
44+
}
45+
}

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsEstimationModeBusinessFacade.java

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
import org.neo4j.gds.betweenness.BetweennessCentralityMemoryEstimateDefinition;
2828
import org.neo4j.gds.bridges.BridgesBaseConfig;
2929
import org.neo4j.gds.bridges.BridgesMemoryEstimateDefinition;
30+
import org.neo4j.gds.closeness.ClosenessCentralityAlgorithmEstimateDefinition;
3031
import org.neo4j.gds.closeness.ClosenessCentralityBaseConfig;
3132
import org.neo4j.gds.config.RelationshipWeightConfig;
3233
import org.neo4j.gds.degree.DegreeCentralityAlgorithmEstimateDefinition;
3334
import org.neo4j.gds.degree.DegreeCentralityConfig;
34-
import org.neo4j.gds.exceptions.MemoryEstimationNotImplementedException;
3535
import org.neo4j.gds.hits.HitsConfig;
3636
import org.neo4j.gds.hits.HitsMemoryEstimateDefinition;
3737
import org.neo4j.gds.indirectExposure.IndirectExposureMemoryEstimationDefinition;
@@ -113,8 +113,21 @@ public MemoryEstimateResult celf(InfluenceMaximizationBaseConfig configuration,
113113
);
114114
}
115115

116-
public MemoryEstimation closenessCentrality(ClosenessCentralityBaseConfig ignored) {
117-
throw new MemoryEstimationNotImplementedException();
116+
public MemoryEstimation closenessCentrality() {
117+
return new ClosenessCentralityAlgorithmEstimateDefinition().memoryEstimation();
118+
}
119+
120+
public MemoryEstimateResult closenessCentrality(
121+
ClosenessCentralityBaseConfig configuration,
122+
Object graphNameOrConfiguration
123+
) {
124+
var memoryEstimation = closenessCentrality();
125+
126+
return algorithmEstimationTemplate.estimate(
127+
configuration,
128+
graphNameOrConfiguration,
129+
memoryEstimation
130+
);
118131
}
119132

120133
public MemoryEstimation degreeCentrality(RelationshipWeightConfig configuration) {

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsMutateModeBusinessFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ public <RESULT> RESULT closenessCentrality(
166166
graphName,
167167
configuration,
168168
ClosenessCentrality,
169-
() -> estimation.closenessCentrality(configuration),
169+
estimation::closenessCentrality,
170170
(graph, __) -> algorithms.closenessCentrality(graph, configuration),
171171
mutateStep,
172172
resultBuilder

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStatsModeBusinessFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public <RESULT> RESULT closenessCentrality(
140140
graphName,
141141
configuration,
142142
ClosenessCentrality,
143-
() -> estimationFacade.closenessCentrality(configuration),
143+
estimationFacade::closenessCentrality,
144144
(graph, __) -> centralityAlgorithms.closenessCentrality(graph, configuration),
145145
resultBuilder
146146
);

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsStreamModeBusinessFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public <RESULT> Stream<RESULT> closenessCentrality(
162162
graphName,
163163
configuration,
164164
ClosenessCentrality,
165-
() -> estimationFacade.closenessCentrality(configuration),
165+
estimationFacade::closenessCentrality,
166166
(graph, __) -> centralityAlgorithms.closenessCentrality(graph, configuration),
167167
streamResultBuilder
168168
);

applications/algorithms/centrality/src/main/java/org/neo4j/gds/applications/algorithms/centrality/CentralityAlgorithmsWriteModeBusinessFacade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public <RESULT> RESULT closenessCentrality(
181181
graphName,
182182
configuration,
183183
ClosenessCentrality,
184-
() -> estimationFacade.closenessCentrality(configuration),
184+
estimationFacade::closenessCentrality,
185185
(graph, __) -> centralityAlgorithms.closenessCentrality(graph, configuration),
186186
writeStep,
187187
resultBuilder

doc/modules/ROOT/pages/operations-reference/algorithm-references.adoc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,15 @@
7373
.2+<.^|xref:algorithms/bridges.adoc[Bridges]
7474
| `gds.bridges.stream` label:procedure[Procedure]
7575
| `gds.bridges.stream.estimate` label:procedure[Procedure]
76-
.4+<.^|xref:algorithms/closeness-centrality.adoc[Closeness Centrality]
76+
.8+<.^|xref:algorithms/closeness-centrality.adoc[Closeness Centrality]
7777
| `gds.closeness.mutate` label:procedure[Procedure]
78+
| `gds.closeness.mutate.estimate` label:procedure[Procedure]
7879
| `gds.closeness.stats` label:procedure[Procedure]
80+
| `gds.closeness.stats.estimate` label:procedure[Procedure]
7981
| `gds.closeness.stream` label:procedure[Procedure]
82+
| `gds.closeness.stream.estimate` label:procedure[Procedure]
8083
| `gds.closeness.write` label:procedure[Procedure]
84+
| `gds.closeness.write.estimate` label:procedure[Procedure]
8185
.1+<.^| xref:algorithms/conductance.adoc[Conductance]
8286
| `gds.conductance.stream` label:procedure[Procedure]
8387
.8+<.^| xref:algorithms/degree-centrality.adoc[Degree Centrality]

open-packaging/src/test/java/org/neo4j/gds/OpenGdsProcedureSmokeTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,13 @@ class OpenGdsProcedureSmokeTest extends BaseProcTest {
8989
"gds.closeness.harmonic.write.estimate",
9090

9191
"gds.closeness.mutate",
92+
"gds.closeness.mutate.estimate",
9293
"gds.closeness.stats",
94+
"gds.closeness.stats.estimate",
9395
"gds.closeness.stream",
96+
"gds.closeness.stream.estimate",
9497
"gds.closeness.write",
98+
"gds.closeness.write.estimate",
9599

96100
"gds.leiden.mutate",
97101
"gds.leiden.mutate.estimate",
@@ -615,7 +619,7 @@ void countShouldMatch() {
615619
);
616620

617621
// If you find yourself updating this count, please also update the count in SmokeTest.kt
618-
int expectedCount = 455;
622+
int expectedCount = 459;
619623
assertEquals(
620624
expectedCount,
621625
returnedRows,

proc/centrality/src/main/java/org/neo4j/gds/closeness/ClosenessCentralityMutateProc.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2323
import org.neo4j.gds.procedures.algorithms.centrality.BetaClosenessCentralityMutateResult;
2424
import org.neo4j.gds.procedures.algorithms.centrality.CentralityMutateResult;
25+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2526
import org.neo4j.procedure.Context;
2627
import org.neo4j.procedure.Description;
2728
import org.neo4j.procedure.Internal;
@@ -32,6 +33,7 @@
3233
import java.util.stream.Stream;
3334

3435
import static org.neo4j.gds.closeness.Constants.CLOSENESS_DESCRIPTION;
36+
import static org.neo4j.gds.procedures.ProcedureConstants.MEMORY_ESTIMATION_DESCRIPTION;
3537
import static org.neo4j.procedure.Mode.READ;
3638

3739
public class ClosenessCentralityMutateProc {
@@ -47,6 +49,15 @@ public Stream<CentralityMutateResult> mutate(
4749
return facade.algorithms().centrality().closenessCentralityMutate(graphName, configuration);
4850
}
4951

52+
@Procedure(name = "gds.closeness.mutate.estimate", mode = READ)
53+
@Description(MEMORY_ESTIMATION_DESCRIPTION)
54+
public Stream<MemoryEstimateResult> estimate(
55+
@Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
56+
@Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
57+
) {
58+
return facade.algorithms().centrality().closenessCentralityMutateEstimate(graphNameOrConfiguration, algoConfiguration);
59+
}
60+
5061
@Deprecated(forRemoval = true)
5162
@Internal
5263
@Procedure(value = "gds.beta.closeness.mutate", mode = READ, deprecatedBy = "gds.closeness.mutate")

0 commit comments

Comments
 (0)