Skip to content

Commit 363a14c

Browse files
Plugin clique counting memory estimation
Co-authored-by: Ioannis Panagiotas <ioannis.panagiotas@neo4j.com>
1 parent cc1845f commit 363a14c

File tree

13 files changed

+92
-106
lines changed

13 files changed

+92
-106
lines changed

applications/algorithms/community/src/main/java/org/neo4j/gds/applications/algorithms/community/CommunityAlgorithmsEstimationModeBusinessFacade.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,11 @@ public MemoryEstimateResult approximateMaximumKCut(
8282
}
8383

8484

85-
public MemoryEstimation cliqueCounting() { //fixme
85+
public MemoryEstimation cliqueCounting() {
8686
return new CliqueCountingMemoryEstimateDefinition().memoryEstimation();
87-
// throw new MemoryEstimationNotImplementedException();
8887
}
8988

90-
public MemoryEstimateResult cliqueCounting(CliqueCountingBaseConfig configuration, Object graphNameOrConfiguration) { //fixme
89+
public MemoryEstimateResult cliqueCounting(CliqueCountingBaseConfig configuration, Object graphNameOrConfiguration) {
9190
var memoryEstimation = cliqueCounting();
9291

9392
return algorithmEstimationTemplate.estimate(

doc/modules/ROOT/pages/algorithms/clique-counting.adoc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,29 @@ include::partial$/algorithms/shared/undirected-req-note.adoc[]
237237

238238
In the following examples we will demonstrate using the Clique Counting algorithm on this graph.
239239

240-
//todo: Memory Estimation
240+
[[algorithms-triangle-count-examples-memory-estimation]]
241+
=== Memory Estimation
242+
243+
:mode: write
244+
include::partial$/algorithms/shared/examples-estimate-intro.adoc[]
245+
246+
[role=query-example]
247+
--
248+
.The following will estimate the memory requirements for running the algorithm in write mode:
249+
[source, cypher, role=noplay]
250+
----
251+
CALL gds.cliqueCounting.write.estimate('myGraph', { writeProperty: 'cliqueCount' })
252+
YIELD nodeCount, relationshipCount, bytesMin, bytesMax, requiredMemory
253+
----
254+
255+
.Results
256+
[opts="header"]
257+
|===
258+
| nodeCount | relationshipCount | bytesMin | bytesMax | requiredMemory
259+
| 6 | 18 | 64 | 952 | "[64 Bytes \... 952 Bytes]"
260+
|===
261+
--
262+
241263

242264
[[algorithms-clique-counting-examples-stream]]
243265
=== Stream

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,15 @@
7676
.2+<.^|xref:algorithms/bridges.adoc[Bridges]
7777
| `gds.bridges.stream` label:procedure[Procedure]
7878
| `gds.bridges.stream.estimate` label:procedure[Procedure]
79-
.4+<.^|Clique Counting
79+
.8+<.^|xref:algorithms/clique-counting.adoc[Clique Counting]
8080
| `gds.cliqueCounting.mutate` label:procedure[Procedure]
81+
| `gds.cliqueCounting.mutate.estimate` label:procedure[Procedure]
8182
| `gds.cliqueCounting.stats` label:procedure[Procedure]
83+
| `gds.cliqueCounting.stats.estimate` label:procedure[Procedure]
8284
| `gds.cliqueCounting.stream` label:procedure[Procedure]
85+
| `gds.cliqueCounting.stream.estimate` label:procedure[Procedure]
8386
| `gds.cliqueCounting.write` label:procedure[Procedure]
87+
| `gds.cliqueCounting.write.estimate` label:procedure[Procedure]
8488
.8+<.^|xref:algorithms/closeness-centrality.adoc[Closeness Centrality]
8589
| `gds.closeness.mutate` label:procedure[Procedure]
8690
| `gds.closeness.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
@@ -77,9 +77,13 @@ class OpenGdsProcedureSmokeTest extends BaseProcTest {
7777
"gds.bridges.stream.estimate",
7878

7979
"gds.cliqueCounting.mutate",
80+
"gds.cliqueCounting.mutate.estimate",
8081
"gds.cliqueCounting.stats",
82+
"gds.cliqueCounting.stats.estimate",
8183
"gds.cliqueCounting.stream",
84+
"gds.cliqueCounting.stream.estimate",
8285
"gds.cliqueCounting.write",
86+
"gds.cliqueCounting.write.estimate",
8387

8488
"gds.collapsePath.mutate",
8589

@@ -625,7 +629,7 @@ void countShouldMatch() {
625629
);
626630

627631
// If you find yourself updating this count, please also update the count in SmokeTest.kt
628-
int expectedCount = 464;
632+
int expectedCount = 468;
629633
assertEquals(
630634
expectedCount,
631635
returnedRows,

proc/community/src/integrationTest/java/org/neo4j/gds/cliquecounting/CliqueCountingMutateProcTest.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.intellij.lang.annotations.Language;
2424
import org.junit.jupiter.api.AfterEach;
2525
import org.junit.jupiter.api.BeforeEach;
26-
import org.junit.jupiter.api.Disabled;
2726
import org.junit.jupiter.api.Test;
2827
import org.neo4j.gds.BaseProcTest;
2928
import org.neo4j.gds.GdsCypher;
@@ -53,8 +52,6 @@
5352

5453
public class CliqueCountingMutateProcTest extends BaseProcTest {
5554

56-
//todo
57-
5855
private static final String TEST_USERNAME = Username.EMPTY_USERNAME.username();
5956
private static final String CLIQUE_COUNTING_GRAPH = "myGraph";
6057
private static final String MUTATE_PROPERTY = "perNodeCount";
@@ -146,19 +143,18 @@ void testMutate() {
146143
assertThat(containsMutateProperty).isTrue();
147144
}
148145

149-
@Disabled
146+
@Test
150147
void testMutateEstimate() {
151148
@Language("Cypher")
152149
String query = GdsCypher.call(CLIQUE_COUNTING_GRAPH).algo("gds.cliqueCounting")
153150
.mutateEstimation()
154151
.addParameter("mutateProperty", "globalCount")
155-
.yields("nodePropertiesWritten", "bytesMin", "bytesMax", "requiredMemory");
152+
.yields("bytesMin", "bytesMax", "requiredMemory");
156153

157-
assertCypherResult(query, List.of(Map.of( //todo
158-
"nodePropertiesWritten", 4L,
159-
"bytesMin", 544L,
160-
"bytesMax", 544L,
161-
"requiredMemory", "544 Bytes"
154+
assertCypherResult(query, List.of(Map.of(
155+
"bytesMin", 56L,
156+
"bytesMax", 952L,
157+
"requiredMemory", "[56 Bytes ... 952 Bytes]"
162158
)));
163159
}
164160

proc/community/src/integrationTest/java/org/neo4j/gds/cliquecounting/CliqueCountingStreamProcTest.java

Lines changed: 3 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.intellij.lang.annotations.Language;
2424
import org.junit.jupiter.api.AfterEach;
2525
import org.junit.jupiter.api.BeforeEach;
26-
import org.junit.jupiter.api.Disabled;
2726
import org.junit.jupiter.api.Test;
2827
import org.neo4j.gds.BaseProcTest;
2928
import org.neo4j.gds.GdsCypher;
@@ -105,57 +104,23 @@ void testStreamingImplicit() {
105104
Assertions.assertThat(perNodeCountResult.get("e")).hasSize(0);
106105
}
107106

108-
@Disabled
107+
@Test
109108
void testStreamingEstimate() {
110109
@Language("Cypher")
111110
String query = GdsCypher.call(CLIQUE_COUNTING_GRAPH).algo("gds.cliqueCounting")
112111
.estimationMode(GdsCypher.ExecutionModes.STREAM)
113112
.yields("requiredMemory", "treeView", "bytesMin", "bytesMax");
114113

115114
runQueryWithRowConsumer(query, row -> {
116-
assertTrue(row.getNumber("bytesMin").longValue() > 0);
117-
assertTrue(row.getNumber("bytesMax").longValue() > 0);
115+
assertThat(row.getNumber("bytesMin").longValue()).isPositive();
116+
assertThat(row.getNumber("bytesMax").longValue()).isPositive();
118117

119118
String bytesHuman = Estimate.humanReadable(row.getNumber("bytesMin").longValue());
120119
assertNotNull(bytesHuman);
121120
assertTrue(row.getString("requiredMemory").contains(bytesHuman));
122121
});
123122
}
124123

125-
// static Stream<Arguments> communitySizeInputs() {
126-
// return Stream.of(
127-
// Arguments.of(Map.of("minCommunitySize", 1), Map.of(
128-
// "a", 1L,
129-
// "b", 0L,
130-
// "c", 0L,
131-
// "d", 0L
132-
// )),
133-
// Arguments.of(Map.of("minCommunitySize", 2), Map.of(
134-
// "b", 0L,
135-
// "c", 0L,
136-
// "d", 0L
137-
// ))
138-
// );
139-
// }
140-
141-
// @ParameterizedTest
142-
// @MethodSource("communitySizeInputs")
143-
// void testStreamingMinCommunitySize(Map<String, Long> parameter, Map<String, Long> expectedResult) {
144-
// @Language("Cypher")
145-
// String yields = GdsCypher.call(CLIQUE_COUNTING_GRAPH).algo("gds", "k1coloring")
146-
// .streamMode()
147-
// .addAllParameters(parameter)
148-
// .yields("nodeId", "color");
149-
//
150-
// Map<String, Long> coloringResult = new HashMap<>(4);
151-
// runQueryWithRowConsumer(yields, (row) -> {
152-
// long nodeId = row.getNumber("nodeId").longValue();
153-
// long color = row.getNumber("color").longValue();
154-
// coloringResult.put(idToVariable.of(nodeId), color);
155-
// });
156-
//
157-
// assertEquals(coloringResult, expectedResult);
158-
// }
159124

160125
@Test
161126
void testRunOnEmptyGraph() {

proc/community/src/main/java/org/neo4j/gds/cliquecounting/CliqueCountingMutateProc.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.neo4j.gds.cliquecounting;
2121

22+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2223
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2324
import org.neo4j.gds.procedures.algorithms.community.CliqueCountingMutateResult;
2425
import org.neo4j.procedure.Context;
@@ -30,6 +31,7 @@
3031
import java.util.stream.Stream;
3132

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

3537
public class CliqueCountingMutateProc {
@@ -45,12 +47,12 @@ public Stream<CliqueCountingMutateResult> mutate(
4547
return facade.algorithms().community().cliqueCountingMutate(graphName, configuration);
4648
}
4749

48-
// @Procedure(value = "gds.cliqueCounting.mutate.estimate", mode = READ)
49-
// @Description(MEMORY_ESTIMATION_DESCRIPTION)
50-
// public Stream<MemoryEstimateResult> estimate(
51-
// @Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
52-
// @Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
53-
// ) {
54-
// return facade.algorithms().community().cliqueCountingMutateEstimate(graphNameOrConfiguration, algoConfiguration);
55-
// }
50+
@Procedure(value = "gds.cliqueCounting.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().community().cliqueCountingMutateEstimate(graphNameOrConfiguration, algoConfiguration);
57+
}
5658
}

proc/community/src/main/java/org/neo4j/gds/cliquecounting/CliqueCountingStatsProc.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.neo4j.gds.cliquecounting;
2121

22+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2223
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2324
import org.neo4j.gds.procedures.algorithms.community.CliqueCountingStatsResult;
2425
import org.neo4j.procedure.Context;
@@ -30,6 +31,7 @@
3031
import java.util.stream.Stream;
3132

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

3537
public class CliqueCountingStatsProc {
@@ -45,12 +47,12 @@ public Stream<CliqueCountingStatsResult> stats(
4547
return facade.algorithms().community().cliqueCountingStats(graphName, configuration);
4648
}
4749

48-
// @Procedure(value = "gds.cliqueCounting.stats.estimate", mode = READ)
49-
// @Description(MEMORY_ESTIMATION_DESCRIPTION)
50-
// public Stream<MemoryEstimateResult> estimate(
51-
// @Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
52-
// @Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
53-
// ) {
54-
// return facade.algorithms().community().cliqueCountingStatsEstimate(graphNameOrConfiguration, algoConfiguration);
55-
// }
50+
@Procedure(value = "gds.cliqueCounting.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().community().cliqueCountingStatsEstimate(graphNameOrConfiguration, algoConfiguration);
57+
}
5658
}

proc/community/src/main/java/org/neo4j/gds/cliquecounting/CliqueCountingStreamProc.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.neo4j.gds.cliquecounting;
2121

22+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2223
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2324
import org.neo4j.gds.procedures.algorithms.community.CliqueCountingStreamResult;
2425
import org.neo4j.procedure.Context;
@@ -30,6 +31,7 @@
3031
import java.util.stream.Stream;
3132

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

3537
public class CliqueCountingStreamProc {
@@ -45,12 +47,12 @@ public Stream<CliqueCountingStreamResult> stream(
4547
return facade.algorithms().community().cliqueCountingStream(graphName, configuration);
4648
}
4749

48-
// @Procedure(value = "gds.cliqueCounting.stream.estimate", mode = READ)
49-
// @Description(MEMORY_ESTIMATION_DESCRIPTION)
50-
// public Stream<MemoryEstimateResult> estimate(
51-
// @Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
52-
// @Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
53-
// ) {
54-
// return facade.algorithms().community().cliqueCountingStreamEstimate(graphNameOrConfiguration, algoConfiguration);
55-
// }
50+
@Procedure(value = "gds.cliqueCounting.stream.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().community().cliqueCountingStreamEstimate(graphNameOrConfiguration, algoConfiguration);
57+
}
5658
}

proc/community/src/main/java/org/neo4j/gds/cliquecounting/CliqueCountingWriteProc.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020
package org.neo4j.gds.cliquecounting;
2121

22+
import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult;
2223
import org.neo4j.gds.procedures.GraphDataScienceProcedures;
2324
import org.neo4j.gds.procedures.algorithms.community.CliqueCountingWriteResult;
2425
import org.neo4j.procedure.Context;
@@ -30,14 +31,14 @@
3031
import java.util.stream.Stream;
3132

3233
import static org.neo4j.gds.cliquecounting.Constants.CLIQUE_COUNTING_DESCRIPTION;
34+
import static org.neo4j.gds.procedures.ProcedureConstants.MEMORY_ESTIMATION_DESCRIPTION;
35+
import static org.neo4j.procedure.Mode.READ;
3336
import static org.neo4j.procedure.Mode.WRITE;
3437

3538
public class CliqueCountingWriteProc {
3639
@Context
3740
public GraphDataScienceProcedures facade;
3841

39-
//todo: tests for these
40-
4142
@Procedure(name = "gds.cliqueCounting.write", mode = WRITE)
4243
@Description(CLIQUE_COUNTING_DESCRIPTION)
4344
public Stream<CliqueCountingWriteResult> write(
@@ -47,12 +48,12 @@ public Stream<CliqueCountingWriteResult> write(
4748
return facade.algorithms().community().cliqueCountingWrite(graphName, configuration);
4849
}
4950

50-
// @Procedure(value = "gds.cliqueCounting.write.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().community().cliqueCountingWriteEstimate(graphNameOrConfiguration, algoConfiguration);
57-
// }
51+
@Procedure(value = "gds.cliqueCounting.write.estimate", mode = READ)
52+
@Description(MEMORY_ESTIMATION_DESCRIPTION)
53+
public Stream<MemoryEstimateResult> estimate(
54+
@Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration,
55+
@Name(value = "algoConfiguration") Map<String, Object> algoConfiguration
56+
) {
57+
return facade.algorithms().community().cliqueCountingWriteEstimate(graphNameOrConfiguration, algoConfiguration);
58+
}
5859
}

0 commit comments

Comments
 (0)