Skip to content

Commit 49f69d9

Browse files
authored
Merge pull request #4293 from DarthMax/1.8_randomwalk_2_beta
1.8 - Promote RandomWalk to beta
2 parents 147f588 + 2e2d162 commit 49f69d9

File tree

11 files changed

+90
-26
lines changed

11 files changed

+90
-26
lines changed

algo/src/main/java/org/neo4j/gds/traversal/RandomWalkAlgorithmFactory.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@
2222
import org.neo4j.gds.AlgorithmFactory;
2323
import org.neo4j.gds.api.Graph;
2424
import org.neo4j.gds.core.utils.mem.AllocationTracker;
25+
import org.neo4j.gds.core.utils.mem.MemoryEstimation;
26+
import org.neo4j.gds.core.utils.mem.MemoryEstimations;
27+
import org.neo4j.gds.core.utils.mem.MemoryRange;
2528
import org.neo4j.gds.core.utils.progress.tasks.ProgressTracker;
2629
import org.neo4j.gds.core.utils.progress.tasks.Task;
2730
import org.neo4j.gds.core.utils.progress.tasks.Tasks;
2831
import org.neo4j.gds.degree.DegreeCentralityFactory;
32+
import org.neo4j.gds.mem.MemoryUsage;
2933

3034
import java.util.ArrayList;
3135

@@ -57,4 +61,16 @@ public Task progressTask(
5761

5862
return Tasks.task(taskName(), tasks);
5963
}
64+
65+
@Override
66+
public MemoryEstimation memoryEstimation(CONFIG config) {
67+
var memoryUsagePerWalk = MemoryUsage.sizeOfLongArray(config.walkLength());
68+
var sizeOfBuffer = MemoryUsage.sizeOfObjectArray(config.walkBufferSize());
69+
70+
var maxMemoryUsage = sizeOfBuffer + MemoryUsage.sizeOfArray(config.walkBufferSize(), memoryUsagePerWalk);
71+
72+
return MemoryEstimations.builder(RandomWalk.class)
73+
.fixed("random walk buffer", MemoryRange.of(sizeOfBuffer, maxMemoryUsage))
74+
.build();
75+
}
6076
}

doc/antora/content-nav.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
*** xref:alpha-algorithms/minimum-weight-spanning-tree/index.adoc[]
8181
*** xref:alpha-algorithms/single-source-shortest-path/index.adoc[]
8282
*** xref:alpha-algorithms/all-pairs-shortest-path/index.adoc[]
83-
*** xref:alpha-algorithms/random-walk/index.adoc[]
83+
*** xref:beta-algorithms/random-walk/index.adoc[]
8484
*** xref:algorithms/bfs/index.adoc[]
8585
*** xref:algorithms/dfs/index.adoc[]
8686
** xref:algorithms/linkprediction/index.adoc[]

doc/asciidoc/algorithms/algorithms-path-finding.adoc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@ The Neo4j GDS library includes the following path finding algorithms, grouped by
1414
** <<algorithms-dijkstra-single-source, Dijkstra Single-Source>>
1515
** <<algorithms-astar, A*>>
1616
** <<algorithms-yens, Yen's algorithm>>
17+
* Beta
18+
** <<beta-algorithms-random-walk, Random Walk>>
1719
* Alpha
1820
** <<alpha-algorithms-minimum-weight-spanning-tree, Minimum Weight Spanning Tree>>
1921
** <<alpha-algorithms-single-source-shortest-path, Single Source Shortest Path>>
2022
** <<alpha-algorithm-all-pairs-shortest-path, All Pairs Shortest Path>>
21-
** <<alpha-algorithms-random-walk, Random Walk>>
2223
** <<algorithms-bfs, Breadth First Search>>
2324
** <<algorithms-dfs, Depth First Search>>
2425

@@ -30,14 +31,14 @@ include::shortest-path/astar.adoc[leveloffset=+1]
3031

3132
include::shortest-path/yens.adoc[leveloffset=+1]
3233

34+
include::beta/randomWalk/beta-random-walk.adoc[leveloffset=+1]
35+
3336
include::alpha/alpha-minimum-weight-spanning-tree.adoc[leveloffset=+1]
3437

3538
include::alpha/alpha-single-shortest-path.adoc[leveloffset=+1]
3639

3740
include::alpha/alpha-all-pairs-shortest-path.adoc[leveloffset=+1]
3841

39-
include::alpha/randomWalk/alpha-random-walk.adoc[leveloffset=+1]
40-
4142
include::alpha/alpha-bfs.adoc[leveloffset=+1]
4243

4344
include::alpha/alpha-dfs.adoc[leveloffset=+1]

doc/asciidoc/algorithms/alpha/randomWalk/alpha-random-walk.adoc renamed to doc/asciidoc/algorithms/beta/randomWalk/beta-random-walk.adoc

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
[[alpha-algorithms-random-walk]]
2-
[.alpha]
1+
[[beta-algorithms-random-walk]]
2+
[.beta]
33
= Random Walk
44

55
[abstract]
@@ -27,6 +27,12 @@ A relationship property value greater than 1 will increase the likelihood of a r
2727
[NOTE]
2828
To obtain a random walk where the transition probability is independent of the previously visited nodes both the `returnFactor` and the `inOutFactor` can be set to 1.0.
2929

30+
[NOTE]
31+
====
32+
Running this algorithm requires sufficient memory availability.
33+
Before running this algorithm, we recommend that you read <<memory-estimation>>.
34+
====
35+
3036
[[algorithms-random-walk-syntax]]
3137
== Syntax
3238

@@ -39,7 +45,7 @@ To obtain a random walk where the transition probability is independent of the p
3945
.Run RandomWalk in stream mode on a named graph.
4046
[source, cypher, role=noplay]
4147
----
42-
CALL gds.alpha.randomWalk.stream(
48+
CALL gds.beta.randomWalk.stream(
4349
graphName: String,
4450
configuration: Map
4551
) YIELD
@@ -111,7 +117,7 @@ CALL gds.graph.create(
111117
.Run the RandomWalk algorithm on `myGraph`
112118
[source, cypher, role=noplay]
113119
----
114-
CALL gds.alpha.randomWalk.stream(
120+
CALL gds.beta.randomWalk.stream(
115121
'myGraph',
116122
{
117123
walkLength: 3,
@@ -147,7 +153,7 @@ RETURN nodeIds, [node IN nodes(path) | node.name ] AS pages
147153
MATCH (page:Page)
148154
WHERE page.name IN ['Home', 'About']
149155
WITH COLLECT(page) as sourceNodes
150-
CALL gds.alpha.randomWalk.stream(
156+
CALL gds.beta.randomWalk.stream(
151157
'myGraph',
152158
{
153159
sourceNodes: sourceNodes,

doc/asciidoc/operations-reference/appendix-a-graph-algos.adoc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ include::../algorithms/algorithm-tiers.adoc[]
201201
| `gds.beta.node2vec.stream.estimate`
202202
| `gds.beta.node2vec.write`
203203
| `gds.beta.node2vec.write`.estimate
204+
.2+<.^|<<beta-algorithms-random-walk, Random Walk>>
205+
| `gds.beta.randomWalk.stream`
206+
| `gds.beta.randomWalk.stream.estimate`
204207
|===
205208

206209
[[alpha-tier]]
@@ -239,8 +242,6 @@ include::../algorithms/algorithm-tiers.adoc[]
239242
| `gds.alpha.hits.stream.estimate`
240243
| `gds.alpha.hits.write`
241244
| `gds.alpha.hits.write.estimate`
242-
.1+<.^|<<alpha-algorithms-random-walk, Random Walk>>
243-
| `gds.alpha.randomWalk.stream`
244245
.2+<.^|<<algorithms-strongly-connected-components, Strongly Connected Components>>
245246
| `gds.alpha.scc.stream`
246247
| `gds.alpha.scc.write`

doc/docbook/content-map.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,8 @@
239239
<d:tocentry linkend="alpha-algorithm-all-pairs-shortest-path">
240240
<?dbhtml filename="alpha-algorithms/all-pairs-shortest-path/index.html"?>
241241
</d:tocentry>
242-
<d:tocentry linkend="alpha-algorithms-random-walk">
243-
<?dbhtml filename="alpha-algorithms/random-walk/index.html"?>
242+
<d:tocentry linkend="beta-algorithms-random-walk">
243+
<?dbhtml filename="beta-algorithms/random-walk/index.html"?>
244244
</d:tocentry>
245245
<d:tocentry linkend="algorithms-bfs">
246246
<?dbhtml filename="algorithms/bfs/index.html"?>

doc/src/test/java/org/neo4j/gds/doc/RandomWalkDocTest.java

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

22+
import org.neo4j.gds.beta.randomwalk.RandomWalkStreamProc;
2223
import org.neo4j.gds.catalog.GraphCreateProc;
23-
import org.neo4j.gds.walking.RandomWalkStreamProc;
2424

2525
import java.util.List;
2626

@@ -36,6 +36,6 @@ protected List<Class<?>> procedures() {
3636

3737
@Override
3838
protected String adocFile() {
39-
return "algorithms/alpha/randomWalk/alpha-random-walk.adoc";
39+
return "algorithms/beta/randomWalk/beta-random-walk.adoc";
4040
}
4141
}

alpha/alpha-proc/src/main/java/org/neo4j/gds/walking/RandomWalkStreamProc.java renamed to proc/beta/src/main/java/org/neo4j/gds/beta/randomwalk/RandomWalkStreamProc.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717
* You should have received a copy of the GNU General Public License
1818
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1919
*/
20-
package org.neo4j.gds.walking;
20+
package org.neo4j.gds.beta.randomwalk;
2121

2222
import org.neo4j.gds.AlgoBaseProc;
2323
import org.neo4j.gds.AlgorithmFactory;
24+
import org.neo4j.gds.BaseProc;
2425
import org.neo4j.gds.api.IdMapping;
2526
import org.neo4j.gds.config.GraphCreateConfig;
2627
import org.neo4j.gds.core.CypherMapWrapper;
2728
import org.neo4j.gds.paths.PathFactory;
29+
import org.neo4j.gds.results.MemoryEstimateResult;
2830
import org.neo4j.gds.traversal.RandomWalk;
2931
import org.neo4j.gds.traversal.RandomWalkAlgorithmFactory;
3032
import org.neo4j.gds.traversal.RandomWalkStreamConfig;
@@ -50,7 +52,7 @@ public class RandomWalkStreamProc extends AlgoBaseProc<RandomWalk, Stream<long[]
5052
"Random Walk is an algorithm that provides random paths in a graph. " +
5153
"It’s similar to how a drunk person traverses a city.";
5254

53-
@Procedure(name = "gds.alpha.randomWalk.stream", mode = READ)
55+
@Procedure(name = "gds.beta.randomWalk.stream", mode = READ)
5456
@Description(DESCRIPTION)
5557
public Stream<RandomWalkResult> stream(
5658
@Name(value = "graphName") Object graphNameOrConfig,
@@ -80,6 +82,15 @@ public Stream<RandomWalkResult> stream(
8082
});
8183
}
8284

85+
@Procedure(value = "gds.beta.randomWalk.stream.estimate", mode = READ)
86+
@Description(BaseProc.ESTIMATE_DESCRIPTION)
87+
public Stream<MemoryEstimateResult> estimate(
88+
@Name(value = "graphName") Object graphNameOrConfig,
89+
@Name(value = "configuration", defaultValue = "{}") Map<String, Object> configuration
90+
) {
91+
return computeEstimate(graphNameOrConfig, configuration);
92+
}
93+
8394
@Override
8495
protected RandomWalkStreamConfig newConfig(
8596
String username,

alpha/alpha-proc/src/test/java/org/neo4j/gds/RandomWalkStreamProcTest.java renamed to proc/beta/src/test/java/org/neo4j/gds/beta/randomwalk/RandomWalkStreamProcTest.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,32 @@
1717
* You should have received a copy of the GNU General Public License
1818
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1919
*/
20-
package org.neo4j.gds;
20+
package org.neo4j.gds.beta.randomwalk;
2121

2222
import org.junit.jupiter.api.BeforeEach;
2323
import org.junit.jupiter.api.DynamicTest;
2424
import org.junit.jupiter.api.Test;
25+
import org.neo4j.gds.AlgoBaseProc;
26+
import org.neo4j.gds.AlgoBaseProcTest;
27+
import org.neo4j.gds.BaseProcTest;
28+
import org.neo4j.gds.GdsCypher;
29+
import org.neo4j.gds.MemoryEstimateTest;
30+
import org.neo4j.gds.Orientation;
31+
import org.neo4j.gds.SourceNodesConfigTest;
32+
import org.neo4j.gds.catalog.GraphCreateProc;
2533
import org.junit.jupiter.api.TestFactory;
2634
import org.neo4j.gds.core.CypherMapWrapper;
2735
import org.neo4j.gds.test.config.ConcurrencyConfigProcTest;
2836
import org.neo4j.gds.test.config.RelationshipWeightConfigProcTest;
2937
import org.neo4j.gds.traversal.RandomWalk;
3038
import org.neo4j.gds.traversal.RandomWalkStreamConfig;
31-
import org.neo4j.gds.walking.RandomWalkStreamProc;
3239
import org.neo4j.graphdb.Path;
3340
import org.neo4j.kernel.internal.GraphDatabaseAPI;
3441

3542
import java.util.ArrayList;
3643
import java.util.Collection;
3744
import java.util.List;
45+
import java.util.Map;
3846
import java.util.Optional;
3947
import java.util.concurrent.atomic.AtomicInteger;
4048
import java.util.stream.Collectors;
@@ -46,8 +54,9 @@
4654
@SuppressWarnings("unchecked")
4755
class RandomWalkStreamProcTest extends BaseProcTest implements
4856
AlgoBaseProcTest<RandomWalk, RandomWalkStreamConfig, Stream<long[]>>,
49-
SourceNodesConfigTest<RandomWalk, RandomWalkStreamConfig, Stream<long[]>>
50-
{
57+
SourceNodesConfigTest<RandomWalk, RandomWalkStreamConfig, Stream<long[]>>,
58+
MemoryEstimateTest<RandomWalk, RandomWalkStreamConfig, Stream<long[]>> {
59+
5160
private static final String DB_CYPHER =
5261
"CREATE" +
5362
" (a:Node1)" +
@@ -65,14 +74,15 @@ class RandomWalkStreamProcTest extends BaseProcTest implements
6574
@BeforeEach
6675
void setup() throws Exception {
6776
registerProcedures(RandomWalkStreamProc.class);
77+
registerProcedures(GraphCreateProc.class);
6878
runQuery(DB_CYPHER);
6979
}
7080

7181
@Test
7282
void shouldRunSimpleConfig() {
7383
String query = GdsCypher.call()
7484
.loadEverything(Orientation.UNDIRECTED)
75-
.algo("gds", "alpha", "randomWalk")
85+
.algo("gds", "beta", "randomWalk")
7686
.streamMode()
7787
.addParameter("walksPerNode", 3)
7888
.addParameter("walkLength", 10)
@@ -96,7 +106,7 @@ void shouldRunSimpleConfig() {
96106
void shouldReturnPath() {
97107
String query = GdsCypher.call()
98108
.loadEverything(Orientation.UNDIRECTED)
99-
.algo("gds", "alpha", "randomWalk")
109+
.algo("gds", "beta", "randomWalk")
100110
.streamMode()
101111
.addParameter("walksPerNode", 3)
102112
.addParameter("walkLength", 10)
@@ -123,7 +133,7 @@ void shouldReturnPath() {
123133
void shouldThrowOnUnknownStartNode() {
124134
String query = GdsCypher.call()
125135
.loadEverything(Orientation.UNDIRECTED)
126-
.algo("gds", "alpha", "randomWalk")
136+
.algo("gds", "beta", "randomWalk")
127137
.streamMode()
128138
.addParameter("walksPerNode", 3)
129139
.addParameter("walkLength", 10)
@@ -137,7 +147,7 @@ void shouldThrowOnUnknownStartNode() {
137147
void shouldThrowOnUnselectedStartNode() {
138148
String query = GdsCypher.call()
139149
.loadEverything(Orientation.UNDIRECTED)
140-
.algo("gds", "alpha", "randomWalk")
150+
.algo("gds", "beta", "randomWalk")
141151
.streamMode()
142152
.addParameter("walksPerNode", 3)
143153
.addParameter("walkLength", 10)
@@ -148,6 +158,23 @@ void shouldThrowOnUnselectedStartNode() {
148158
assertError(query, "Source nodes do not exist in the in-memory graph for the labels ['Node1', 'Node2']: ['3']");
149159
}
150160

161+
@Test
162+
void shouldRunMemoryEstimation() {
163+
String query = GdsCypher.call()
164+
.loadEverything(Orientation.UNDIRECTED)
165+
.algo("gds", "beta", "randomWalk")
166+
.estimationMode(GdsCypher.ExecutionModes.STREAM)
167+
.addParameter("walksPerNode", 3)
168+
.addParameter("walkLength", 10)
169+
.yields("bytesMin", "bytesMax");
170+
171+
172+
assertCypherResult(query, List.of(Map.of(
173+
"bytesMin", 299440L,
174+
"bytesMax", 395456L
175+
)));
176+
}
177+
151178
@Override
152179
public Class<? extends AlgoBaseProc<RandomWalk, Stream<long[]>, RandomWalkStreamConfig>> getProcedureClazz() {
153180
return RandomWalkStreamProc.class;

proc/src/test/java/org/neo4j/gds/ListProcTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ class ListProcTest extends BaseProcTest {
125125

126126
"gds.alpha.shortestPath.deltaStepping.write",
127127
"gds.alpha.shortestPath.deltaStepping.stream",
128-
"gds.alpha.randomWalk.stream",
129128
"gds.alpha.similarity.cosine.write",
130129
"gds.alpha.similarity.cosine.stream",
131130
"gds.alpha.similarity.cosine.stats",
@@ -214,6 +213,9 @@ class ListProcTest extends BaseProcTest {
214213
"gds.beta.modularityOptimization.write",
215214
"gds.beta.modularityOptimization.write.estimate",
216215

216+
"gds.beta.randomWalk.stream",
217+
"gds.beta.randomWalk.stream.estimate",
218+
217219
"gds.allShortestPaths.dijkstra.stream",
218220
"gds.allShortestPaths.dijkstra.stream.estimate",
219221
"gds.allShortestPaths.dijkstra.mutate",

0 commit comments

Comments
 (0)