Skip to content

Commit 3b02a0b

Browse files
authored
Merge pull request #10744 from brs96/harmonic-centrality-mem-est
Harmonic centrality mem est
2 parents be3ecc0 + 64c9099 commit 3b02a0b

File tree

12 files changed

+230
-5
lines changed

12 files changed

+230
-5
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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.harmonic;
21+
22+
import org.neo4j.gds.mem.MemoryEstimateDefinition;
23+
import org.neo4j.gds.collections.haa.HugeAtomicDoubleArray;
24+
import org.neo4j.gds.mem.MemoryEstimation;
25+
import org.neo4j.gds.mem.MemoryEstimations;
26+
import org.neo4j.gds.msbfs.MSBFSMemoryEstimation;
27+
28+
public final class HarmonicCentralityAlgorithmEstimateDefinition implements MemoryEstimateDefinition {
29+
30+
@Override
31+
public MemoryEstimation memoryEstimation() {
32+
return MemoryEstimations.builder(HarmonicCentrality.class)
33+
.perNode("inverse farness", HugeAtomicDoubleArray::memoryEstimation)
34+
.add("MSBFS", MSBFSMemoryEstimation.MSBFSWithANPStrategy())
35+
.build();
36+
}
37+
38+
}

algo/src/main/java/org/neo4j/gds/msbfs/MSBFSMemoryEstimation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ private static MemoryEstimations.Builder MSBFS(){
3535
.perThread("seens", HugeLongArray::memoryEstimation);
3636
}
3737

38-
static MemoryEstimation MSBFSWithPredecessorStrategy(){
38+
public static MemoryEstimation MSBFSWithPredecessorStrategy(){
3939
return MSBFS()
4040
.perThread("seenNext", HugeLongArray::memoryEstimation)
4141
.build();
4242
}
43-
static MemoryEstimation MSBFSWithANPStrategy(){
43+
public static MemoryEstimation MSBFSWithANPStrategy(){
4444
return MSBFS()
4545
.build();
4646
}
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.harmonic;
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 HarmonicCentralityAlgorithmEstimateDefinitionTest {
29+
30+
@ParameterizedTest
31+
@CsvSource({
32+
"10_000, 1, 80304",
33+
"10_000, 4, 80376",
34+
"500_000, 4, 4000376",
35+
"10_000_000, 4, 80000376",
36+
"10_000, 2, 80328",
37+
"10_000, 128, 83352"
38+
})
39+
void testMemoryEstimation(long nodeCount, int concurrency, long expectedMemory) {
40+
var memoryEstimation = new HarmonicCentralityAlgorithmEstimateDefinition().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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
import org.neo4j.gds.mem.MemoryEstimation;
4141
import org.neo4j.gds.pagerank.PageRankMemoryEstimateDefinition;
4242
import org.neo4j.gds.pagerank.RankConfig;
43+
import org.neo4j.gds.harmonic.HarmonicCentralityAlgorithmEstimateDefinition;
44+
import org.neo4j.gds.harmonic.HarmonicCentralityBaseConfig;
4345

4446
public class CentralityAlgorithmsEstimationModeBusinessFacade {
4547
private final AlgorithmEstimationTemplate algorithmEstimationTemplate;
@@ -133,7 +135,20 @@ public MemoryEstimateResult degreeCentrality(
133135
}
134136

135137
public MemoryEstimation harmonicCentrality() {
136-
throw new MemoryEstimationNotImplementedException();
138+
return new HarmonicCentralityAlgorithmEstimateDefinition().memoryEstimation();
139+
}
140+
141+
public MemoryEstimateResult harmonicCentrality(
142+
HarmonicCentralityBaseConfig configuration,
143+
Object graphNameOrConfiguration
144+
) {
145+
var memoryEstimation = harmonicCentrality();
146+
147+
return algorithmEstimationTemplate.estimate(
148+
configuration,
149+
graphNameOrConfiguration,
150+
memoryEstimation
151+
);
137152
}
138153

139154
public MemoryEstimation pageRank() {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,15 @@
404404
.1+<.^|xref:algorithms/all-pairs-shortest-path.adoc[All Shortest Paths]
405405
| `gds.allShortestPaths.stream` label:procedure[Procedure]
406406
| xref:alpha-algorithms/common-neighbors.adoc[Common Neighbors] | `gds.alpha.linkprediction.commonNeighbors` label:function[Function]
407-
.4+<.^|xref:algorithms/harmonic-centrality.adoc[Harmonic Centrality]
407+
.8+<.^|xref:algorithms/harmonic-centrality.adoc[Harmonic Centrality]
408408
| `gds.closeness.harmonic.mutate` label:procedure[Procedure]
409+
| `gds.closeness.harmonic.mutate.estimate` label:procedure[Procedure]
409410
| `gds.closeness.harmonic.stats` label:procedure[Procedure]
411+
| `gds.closeness.harmonic.stats.estimate` label:procedure[Procedure]
410412
| `gds.closeness.harmonic.stream` label:procedure[Procedure]
413+
| `gds.closeness.harmonic.stream.estimate` label:procedure[Procedure]
411414
| `gds.closeness.harmonic.write` label:procedure[Procedure]
415+
| `gds.closeness.harmonic.write.estimate` label:procedure[Procedure]
412416
.8+<.^|xref:algorithms/hits.adoc[HITS]
413417
| `gds.hits.mutate` label:procedure[Procedure]
414418
| `gds.hits.mutate.estimate` label:procedure[Procedure]

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,13 @@ class OpenGdsProcedureSmokeTest extends BaseProcTest {
8080
"gds.conductance.stream",
8181

8282
"gds.closeness.harmonic.mutate",
83+
"gds.closeness.harmonic.mutate.estimate",
8384
"gds.closeness.harmonic.stats",
85+
"gds.closeness.harmonic.stats.estimate",
8486
"gds.closeness.harmonic.stream",
87+
"gds.closeness.harmonic.stream.estimate",
8588
"gds.closeness.harmonic.write",
89+
"gds.closeness.harmonic.write.estimate",
8690

8791
"gds.closeness.mutate",
8892
"gds.closeness.stats",
@@ -611,7 +615,7 @@ void countShouldMatch() {
611615
);
612616

613617
// If you find yourself updating this count, please also update the count in SmokeTest.kt
614-
int expectedCount = 451;
618+
int expectedCount = 455;
615619
assertEquals(
616620
expectedCount,
617621
returnedRows,

proc/centrality/src/main/java/org/neo4j/gds/harmonic/HarmonicCentralityMutateProc.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2323
import org.neo4j.gds.procedures.algorithms.centrality.CentralityMutateResult;
24+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2425
import org.neo4j.procedure.Context;
2526
import org.neo4j.procedure.Description;
2627
import org.neo4j.procedure.Name;
@@ -30,6 +31,7 @@
3031
import java.util.stream.Stream;
3132

3233
import static org.neo4j.gds.harmonic.Constants.HARMONIC_CENTRALITY_DESCRIPTION;
34+
import static org.neo4j.gds.procedures.ProcedureConstants.MEMORY_ESTIMATION_DESCRIPTION;
3335
import static org.neo4j.procedure.Mode.READ;
3436

3537
public class HarmonicCentralityMutateProc {
@@ -44,4 +46,13 @@ public Stream<CentralityMutateResult> mutate(
4446
) {
4547
return facade.algorithms().centrality().harmonicCentralityMutate(graphName, configuration);
4648
}
49+
50+
@Procedure(name = "gds.closeness.harmonic.mutate.estimate", mode = READ)
51+
@Description(MEMORY_ESTIMATION_DESCRIPTION)
52+
public Stream<MemoryEstimateResult> estimate(
53+
@Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
54+
@Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
55+
) {
56+
return facade.algorithms().centrality().harmonicCentralityMutateEstimate(graphNameOrConfiguration, algoConfiguration);
57+
}
4758
}

proc/centrality/src/main/java/org/neo4j/gds/harmonic/HarmonicCentralityStatsProc.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2323
import org.neo4j.gds.procedures.algorithms.centrality.CentralityStatsResult;
24+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2425
import org.neo4j.procedure.Context;
2526
import org.neo4j.procedure.Description;
2627
import org.neo4j.procedure.Name;
@@ -30,6 +31,7 @@
3031
import java.util.stream.Stream;
3132

3233
import static org.neo4j.gds.harmonic.Constants.HARMONIC_CENTRALITY_DESCRIPTION;
34+
import static org.neo4j.gds.procedures.ProcedureConstants.MEMORY_ESTIMATION_DESCRIPTION;
3335
import static org.neo4j.procedure.Mode.READ;
3436

3537
public class HarmonicCentralityStatsProc {
@@ -44,4 +46,13 @@ public Stream<CentralityStatsResult> stats(
4446
) {
4547
return facade.algorithms().centrality().harmonicCentralityStats(graphName, configuration);
4648
}
49+
50+
@Procedure(name = "gds.closeness.harmonic.stats.estimate", mode = READ)
51+
@Description(MEMORY_ESTIMATION_DESCRIPTION)
52+
public Stream<MemoryEstimateResult> estimate(
53+
@Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
54+
@Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
55+
) {
56+
return facade.algorithms().centrality().harmonicCentralityStatsEstimate(graphNameOrConfiguration, algoConfiguration);
57+
}
4758
}

proc/centrality/src/main/java/org/neo4j/gds/harmonic/HarmonicCentralityStreamProc.java

Lines changed: 10 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.AlphaHarmonicStreamResult;
2424
import org.neo4j.gds.procedures.algorithms.centrality.CentralityStreamResult;
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;
@@ -48,6 +49,15 @@ public Stream<CentralityStreamResult> stream(
4849
return facade.algorithms().centrality().harmonicCentralityStream(graphName, configuration);
4950
}
5051

52+
@Procedure(name = "gds.closeness.harmonic.stream.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().harmonicCentralityStreamEstimate(graphNameOrConfiguration, algoConfiguration);
59+
}
60+
5161
@Deprecated(forRemoval = true)
5262
@Internal
5363
@Procedure(name = "gds.alpha.closeness.harmonic.stream", mode = READ, deprecatedBy = "gds.closeness.harmonic.stream")

proc/centrality/src/main/java/org/neo4j/gds/harmonic/HarmonicCentralityWriteProc.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.CentralityWriteResult;
2424
import org.neo4j.gds.procedures.algorithms.centrality.AlphaHarmonicWriteResult;
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;
@@ -33,6 +34,7 @@
3334

3435
import static org.neo4j.gds.harmonic.Constants.HARMONIC_CENTRALITY_DESCRIPTION;
3536
import static org.neo4j.gds.procedures.ProcedureConstants.MEMORY_ESTIMATION_DESCRIPTION;
37+
import static org.neo4j.procedure.Mode.READ;
3638
import static org.neo4j.procedure.Mode.WRITE;
3739

3840
public class HarmonicCentralityWriteProc {
@@ -48,6 +50,15 @@ public Stream<CentralityWriteResult> write(
4850
return facade.algorithms().centrality().harmonicCentralityWrite(graphName, configuration);
4951
}
5052

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

0 commit comments

Comments
 (0)