Skip to content

Commit 6f42548

Browse files
Add progress tracking for clique counting
1 parent 3824e35 commit 6f42548

File tree

6 files changed

+123
-10
lines changed

6 files changed

+123
-10
lines changed

algo/src/main/java/org/neo4j/gds/CommunityAlgorithmTasks.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel;
2424
import org.neo4j.gds.approxmaxkcut.ApproxMaxKCutParameters;
2525
import org.neo4j.gds.approxmaxkcut.ApproximateKCutTaskFactory;
26+
import org.neo4j.gds.cliqueCounting.CliqueCountingTaskFactory;
27+
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
2628
import org.neo4j.gds.core.utils.progress.tasks.Task;
2729
import org.neo4j.gds.core.utils.progress.tasks.Tasks;
2830
import org.neo4j.gds.hdbscan.HDBScanProgressTrackerCreator;
@@ -51,8 +53,8 @@ public Task approximateMaximumKCut(Graph graph, ApproxMaxKCutParameters paramete
5153
return ApproximateKCutTaskFactory.createTask(graph, parameters);
5254
}
5355

54-
public Task cliqueCounting(Graph graph) {
55-
return Tasks.leaf(AlgorithmLabel.CliqueCounting.asString(), -1); //todo
56+
public Task cliqueCounting(Graph graph, CliqueCountingParameters parameters) {
57+
return CliqueCountingTaskFactory.createTask(graph, parameters);
5658
}
5759

5860
public Task conductance(Graph graph) {

algo/src/main/java/org/neo4j/gds/cliqueCounting/CliqueCounting.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ private Collection<? extends Runnable> createTasks(){
175175
return countingMode == CliqueCountingMode.ForGivenSubcliques ?
176176
ParallelUtil.tasks(
177177
concurrency,
178-
() -> new SubcliqueCliqueCountingTask(graph.concurrentCopy())
178+
() -> new SubcliqueCliqueCountingTask(graph.concurrentCopy(), progressTracker)
179179
) :
180180
ParallelUtil.tasks(
181181
concurrency,
182-
() -> new GlobalCliqueCountingTask(graph.concurrentCopy(), cliqueCountsHandler.takeOrCreate())
182+
() -> new GlobalCliqueCountingTask(graph.concurrentCopy(), cliqueCountsHandler.takeOrCreate(), progressTracker)
183183
);
184184

185185
}
@@ -364,10 +364,12 @@ long[] rootNodeNeighbors(long rootNode, boolean filter){
364364
private class GlobalCliqueCountingTask implements Runnable {
365365
Graph graph;
366366
SizeFrequencies sizeFrequencies;
367+
ProgressTracker progressTracker;
367368

368-
GlobalCliqueCountingTask(Graph graph, SizeFrequencies sizeFrequencies) {
369+
GlobalCliqueCountingTask(Graph graph, SizeFrequencies sizeFrequencies, ProgressTracker progressTracker) {
369370
this.graph = graph;
370371
this.sizeFrequencies = sizeFrequencies;
372+
this.progressTracker = progressTracker;
371373
}
372374

373375
public void run() {
@@ -380,16 +382,19 @@ public void run() {
380382
long[][] feasibleNeighborhoods = computeIntersections(positiveNeighborhood);
381383
recursiveSctCliqueCount(positiveNeighborhood, feasibleNeighborhoods, cliqueNodes, sizeFrequencies);
382384

385+
progressTracker.logProgress();
383386
}
384387
cliqueCountsHandler.giveBack(sizeFrequencies);
385388
}
386389
}
387390

388391
private class SubcliqueCliqueCountingTask implements Runnable {
389392
Graph graph;
393+
ProgressTracker progressTracker;
390394

391-
SubcliqueCliqueCountingTask(Graph graph) {
395+
SubcliqueCliqueCountingTask(Graph graph, ProgressTracker progressTracker) {
392396
this.graph = graph;
397+
this.progressTracker = progressTracker;
393398
}
394399

395400
public void run() {
@@ -412,6 +417,7 @@ public void run() {
412417
}
413418
long[][] feasibleNeighborhoods = computeIntersections(subset);
414419
recursiveSctCliqueCount(subset, feasibleNeighborhoods, cliqueNodes, sizeFrequencies);
420+
progressTracker.logProgress();
415421
}
416422
}
417423
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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.cliqueCounting;
21+
22+
import org.neo4j.gds.api.Graph;
23+
import org.neo4j.gds.applications.algorithms.machinery.AlgorithmLabel;
24+
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
25+
import org.neo4j.gds.core.utils.progress.tasks.Task;
26+
import org.neo4j.gds.core.utils.progress.tasks.Tasks;
27+
28+
public final class CliqueCountingTaskFactory {
29+
30+
private CliqueCountingTaskFactory() {}
31+
32+
private static long volume(Graph graph, CliqueCountingParameters parameters) {
33+
return parameters.subcliques().isEmpty() ? graph.nodeCount() : parameters.subcliques().size();
34+
}
35+
36+
public static Task createTask(Graph graph, CliqueCountingParameters parameters) {
37+
return Tasks.leaf(AlgorithmLabel.CliqueCounting.asString(), volume(graph, parameters));
38+
}
39+
40+
41+
42+
}

algo/src/test/java/org/neo4j/gds/cliqueCounting/CliqueCountingTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,20 @@
1919
*/
2020
package org.neo4j.gds.cliqueCounting;
2121

22+
import org.assertj.core.api.Assertions;
2223
import org.junit.jupiter.api.Test;
2324
import org.junit.jupiter.params.ParameterizedTest;
2425
import org.junit.jupiter.params.provider.Arguments;
2526
import org.junit.jupiter.params.provider.MethodSource;
27+
import org.neo4j.gds.CommunityAlgorithmTasks;
2628
import org.neo4j.gds.Orientation;
29+
import org.neo4j.gds.TestProgressTrackerHelper;
2730
import org.neo4j.gds.TestSupport;
2831
import org.neo4j.gds.api.Graph;
2932
import org.neo4j.gds.cliquecounting.CliqueCountingMode;
3033
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
3134
import org.neo4j.gds.collections.ha.HugeObjectArray;
35+
import org.neo4j.gds.compat.TestLog;
3236
import org.neo4j.gds.core.concurrency.Concurrency;
3337
import org.neo4j.gds.core.concurrency.DefaultPool;
3438
import org.neo4j.gds.core.utils.progress.tasks.ProgressTracker;
@@ -38,9 +42,12 @@
3842
import java.io.InputStream;
3943
import java.nio.charset.StandardCharsets;
4044
import java.util.Arrays;
45+
import java.util.List;
4146
import java.util.stream.Stream;
4247

4348
import static org.junit.jupiter.api.Assertions.assertEquals;
49+
import static org.neo4j.gds.assertj.Extractors.removingThreadId;
50+
import static org.neo4j.gds.assertj.Extractors.replaceTimings;
4451

4552
class CliqueCountingTest {
4653

@@ -190,4 +197,61 @@ void biggerGraph() throws IOException {
190197
assertEquals(6L, result.globalCount()[10 - 3]);
191198
}
192199

200+
@Test
201+
void shouldLogProgress(){
202+
Graph graph = fromGdl("CREATE (a1)-[:T]->(a2)-[:T]->(a3)-[:T]->(a4), (a2)-[:T]->(a4)-[:T]->(a1)-[:T]->(a3), (a1)-[:T]->(a2), (a1)-[:T1]->(a3)");
203+
var params = new CliqueCountingParameters(CliqueCountingMode.ForEveryNode, List.of(), new Concurrency(4));
204+
205+
var progressTrackerWithLog = TestProgressTrackerHelper.create(
206+
new CommunityAlgorithmTasks().cliqueCounting(graph, params),
207+
new Concurrency(4)
208+
);
209+
210+
var progressTracker = progressTrackerWithLog.progressTracker();
211+
var log = progressTrackerWithLog.log();
212+
213+
var cliques = CliqueCounting.create(graph, params, DefaultPool.INSTANCE, progressTracker, TerminationFlag.RUNNING_TRUE);
214+
cliques.compute();
215+
216+
Assertions.assertThat(log.getMessages(TestLog.INFO))
217+
.extracting(removingThreadId())
218+
.extracting(replaceTimings())
219+
.containsExactly(
220+
"Clique Counting :: Start",
221+
"Clique Counting 25%",
222+
"Clique Counting 50%",
223+
"Clique Counting 75%",
224+
"Clique Counting 100%",
225+
"Clique Counting :: Finished"
226+
);
227+
}
228+
229+
@Test
230+
void shouldLogProgressSubclique(){
231+
Graph graph = fromGdl("CREATE (a1)-[:T]->(a2)-[:T]->(a3)-[:T]->(a4), (a2)-[:T]->(a4)-[:T]->(a1)-[:T]->(a3), (a1)-[:T]->(a2), (a1)-[:T1]->(a3)");
232+
var params = new CliqueCountingParameters(CliqueCountingMode.ForEveryNode, List.of(new long[] {0L, 1L}, new long[] {3L}), new Concurrency(4));
233+
234+
var progressTrackerWithLog = TestProgressTrackerHelper.create(
235+
new CommunityAlgorithmTasks().cliqueCounting(graph, params),
236+
new Concurrency(4)
237+
);
238+
239+
var progressTracker = progressTrackerWithLog.progressTracker();
240+
var log = progressTrackerWithLog.log();
241+
242+
var cliques = CliqueCounting.create(graph, params, DefaultPool.INSTANCE, progressTracker, TerminationFlag.RUNNING_TRUE);
243+
cliques.compute();
244+
245+
Assertions.assertThat(log.getMessages(TestLog.INFO))
246+
.extracting(removingThreadId())
247+
.extracting(replaceTimings())
248+
.containsExactly(
249+
"Clique Counting :: Start",
250+
"Clique Counting 50%",
251+
"Clique Counting 100%",
252+
"Clique Counting :: Finished"
253+
);
254+
}
255+
256+
193257
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.neo4j.gds.beta.pregel.PregelResult;
2828
import org.neo4j.gds.cliqueCounting.CliqueCounting;
2929
import org.neo4j.gds.cliqueCounting.CliqueCountingResult;
30-
import org.neo4j.gds.cliquecounting.CliqueCountingParameters;
3130
import org.neo4j.gds.collections.ha.HugeLongArray;
3231
import org.neo4j.gds.conductance.Conductance;
3332
import org.neo4j.gds.conductance.ConductanceParameters;
@@ -103,7 +102,7 @@ public ApproxMaxKCutResult approximateMaximumKCut(
103102
).compute();
104103
}
105104

106-
public CliqueCountingResult cliqueCounting(Graph graph, CliqueCountingParameters parameters, ProgressTracker progressTracker) {
105+
public CliqueCountingResult cliqueCounting(Graph graph, org.neo4j.gds.cliquecounting.CliqueCountingParameters parameters, ProgressTracker progressTracker) {
107106
return CliqueCounting.create(
108107
graph,
109108
parameters,

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ ApproxMaxKCutResult approximateMaximumKCut(Graph graph, ApproxMaxKCutBaseConfig
8989
}
9090

9191
public CliqueCountingResult cliqueCounting(Graph graph, CliqueCountingBaseConfig configuration) {
92-
var task = tasks.cliqueCounting(graph);
93-
var progressTracker = progressTrackerCreator.createProgressTracker(task, configuration);
9492
var params = configuration.toParameters();
93+
var task = tasks.cliqueCounting(graph, params);
94+
var progressTracker = progressTrackerCreator.createProgressTracker(task, configuration);
9595

9696
return algorithmMachinery.getResult(
9797
() -> algorithms.cliqueCounting(graph, params, progressTracker),

0 commit comments

Comments
 (0)