Skip to content

Commit cc1845f

Browse files
Implement super-upperbounded memory estimation for clique counting
Co-authored-by: Ioannis Panagiotas <ioannis.panagiotas@neo4j.com>
1 parent b4dcc38 commit cc1845f

File tree

3 files changed

+85
-14
lines changed

3 files changed

+85
-14
lines changed

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

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,44 @@
2020
package org.neo4j.gds.cliqueCounting;
2121

2222
//import org.neo4j.gds.collections.ha.HugeLongArray;
23-
import org.neo4j.gds.exceptions.MemoryEstimationNotImplementedException;
24-
//import org.neo4j.gds.k1coloring.ColoringStep;
25-
//import org.neo4j.gds.k1coloring.K1Coloring;
26-
//import org.neo4j.gds.mem.Estimate;
23+
2724
import org.neo4j.gds.mem.MemoryEstimateDefinition;
2825
import org.neo4j.gds.mem.MemoryEstimation;
26+
import org.neo4j.gds.mem.MemoryEstimations;
27+
import org.neo4j.gds.mem.MemoryRange;
2928
//import org.neo4j.gds.mem.MemoryEstimations;
3029

3130
public final class CliqueCountingMemoryEstimateDefinition implements MemoryEstimateDefinition {
31+
32+
public CliqueCountingMemoryEstimateDefinition() {
33+
}
34+
3235
@Override
3336
public MemoryEstimation memoryEstimation() {
34-
throw new MemoryEstimationNotImplementedException();
35-
// return MemoryEstimations.builder(K1Coloring.class)
36-
// .perNode("colors", HugeLongArray::memoryEstimation)
37-
// .perNode("nodesToColor", Estimate::sizeOfBitset)
38-
// .perThread("coloring", MemoryEstimations.builder()
39-
// .field("coloringStep", ColoringStep.class)
40-
// .perNode("forbiddenColors", Estimate::sizeOfBitset)
41-
// .build())
42-
// .build();
37+
38+
return MemoryEstimations.builder(CliqueCounting.class)
39+
.perThread("intersection cost per thread", thread())
40+
.build();
4341
}
42+
43+
private MemoryEstimation thread(){
44+
return MemoryEstimations.builder()
45+
.rangePerGraphDimension("Intersections",((graphDimensions, concurrency) -> {
46+
var bound1 = (long)(graphDimensions.averageDegree()*2.7);
47+
var bound2 = (long) (0.48*Math.sqrt(graphDimensions.relCountUpperBound())); //a theoretical bound ¯\_(ツ)_/¯
48+
var cost1 = cost(bound1);
49+
var cost2 = cost(bound2);
50+
return MemoryRange.of(Math.min(cost1, cost2), Math.max(cost1, cost2));
51+
}))
52+
.build();
53+
54+
}
55+
56+
private long cost(long bound) {
57+
//very very loose bounds
58+
long recursionLevels = bound;
59+
long intersectionsPerLevel = (bound * (bound-1))/2;
60+
return recursionLevels * intersectionsPerLevel;
61+
}
62+
4463
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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.junit.jupiter.params.ParameterizedTest;
23+
import org.junit.jupiter.params.provider.Arguments;
24+
import org.junit.jupiter.params.provider.MethodSource;
25+
import org.neo4j.gds.assertions.MemoryEstimationAssert;
26+
import org.neo4j.gds.core.concurrency.Concurrency;
27+
28+
import java.util.stream.Stream;
29+
30+
class CliqueCountingMemoryEstimateDefinitionTest {
31+
32+
33+
static Stream<Arguments> memoryEstimationTuples() {
34+
return Stream.of(
35+
Arguments.of(1, 1744377118L),
36+
Arguments.of(4, 6977508304L)
37+
);
38+
}
39+
40+
@ParameterizedTest
41+
@MethodSource("memoryEstimationTuples")
42+
void shouldEstimateMemoryAccurately(int concurrency, long expectedMemory) {
43+
var memoryEstimation = new CliqueCountingMemoryEstimateDefinition().memoryEstimation();
44+
45+
MemoryEstimationAssert.assertThat(memoryEstimation)
46+
.memoryRange(1_000_000, 10_000_000, new Concurrency(concurrency))
47+
.hasMax(expectedMemory);
48+
}
49+
50+
// 29858008xxx
51+
// 1408353856
52+
53+
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,5 +253,4 @@ void shouldLogProgressSubclique(){
253253
);
254254
}
255255

256-
257256
}

0 commit comments

Comments
 (0)