diff --git a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsEstimateBusinessFacade.java b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsEstimateBusinessFacade.java index d8d016be6e..d105a1f2db 100644 --- a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsEstimateBusinessFacade.java +++ b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsEstimateBusinessFacade.java @@ -20,8 +20,7 @@ package org.neo4j.gds.algorithms.embeddings; import org.neo4j.gds.algorithms.estimation.AlgorithmEstimator; -import org.neo4j.gds.embeddings.fastrp.FastRPBaseConfig; -import org.neo4j.gds.embeddings.fastrp.FastRPMemoryEstimateDefinition; +import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import org.neo4j.gds.embeddings.graphsage.algo.GraphSageBaseConfig; import org.neo4j.gds.embeddings.graphsage.algo.GraphSageMemoryEstimateDefinition; import org.neo4j.gds.embeddings.graphsage.algo.GraphSageTrainConfig; @@ -31,7 +30,6 @@ import org.neo4j.gds.embeddings.node2vec.Node2VecBaseConfig; import org.neo4j.gds.embeddings.node2vec.Node2VecMemoryEstimateDefinition; import org.neo4j.gds.modelcatalogservices.ModelCatalogService; -import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import java.util.Optional; @@ -92,18 +90,6 @@ public MemoryEstimateResult graphSageTrain( ); } - public MemoryEstimateResult fastRP( - Object graphNameOrConfiguration, - C configuration - ) { - return algorithmEstimator.estimate( - graphNameOrConfiguration, - configuration, - configuration.relationshipWeightProperty(), - new FastRPMemoryEstimateDefinition(configuration.toParameters()) - ); - } - public MemoryEstimateResult hashGNN( Object graphNameOrConfiguration, C configuration diff --git a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsFacade.java b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsFacade.java index 23a75037fe..6f6f7bbaaf 100644 --- a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsFacade.java +++ b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsFacade.java @@ -23,9 +23,6 @@ import org.neo4j.gds.algorithms.runner.AlgorithmRunner; import org.neo4j.gds.algorithms.validation.AfterLoadValidation; import org.neo4j.gds.core.model.Model; -import org.neo4j.gds.embeddings.fastrp.FastRPBaseConfig; -import org.neo4j.gds.embeddings.fastrp.FastRPFactory; -import org.neo4j.gds.embeddings.fastrp.FastRPResult; import org.neo4j.gds.embeddings.graphsage.GraphSageModelTrainer; import org.neo4j.gds.embeddings.graphsage.ModelData; import org.neo4j.gds.embeddings.graphsage.algo.GraphSageAlgorithmFactory; @@ -110,18 +107,6 @@ AlgorithmComputationResult fastRP( - String graphName, - FastRPBaseConfig config - ) { - return algorithmRunner.run( - graphName, - config, - config.relationshipWeightProperty(), - new FastRPFactory<>() - ); - } - AlgorithmComputationResult hashGNN( String graphName, HashGNNConfig config diff --git a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsWriteBusinessFacade.java b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsWriteBusinessFacade.java index c8f764837d..a298fa9311 100644 --- a/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsWriteBusinessFacade.java +++ b/algo/src/main/java/org/neo4j/gds/algorithms/embeddings/NodeEmbeddingsAlgorithmsWriteBusinessFacade.java @@ -23,14 +23,13 @@ import org.neo4j.gds.algorithms.NodePropertyWriteResult; import org.neo4j.gds.algorithms.embeddings.specificfields.Node2VecSpecificFields; import org.neo4j.gds.algorithms.runner.AlgorithmRunner; -import org.neo4j.gds.applications.algorithms.machinery.WriteNodePropertyService; import org.neo4j.gds.api.ResultStore; import org.neo4j.gds.api.properties.nodes.NodePropertyValues; import org.neo4j.gds.api.properties.nodes.NodePropertyValuesAdapter; +import org.neo4j.gds.applications.algorithms.machinery.WriteNodePropertyService; import org.neo4j.gds.config.AlgoBaseConfig; import org.neo4j.gds.config.ArrowConnectionInfo; import org.neo4j.gds.core.concurrency.Concurrency; -import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; import org.neo4j.gds.embeddings.graphsage.algo.GraphSageWriteConfig; import org.neo4j.gds.embeddings.node2vec.Node2VecWriteConfig; @@ -102,31 +101,6 @@ public NodePropertyWriteResult graphSage( ); } - public NodePropertyWriteResult fastRP( - String graphName, - FastRPWriteConfig configuration - ) { - // 1. Run the algorithm and time the execution - var intermediateResult = AlgorithmRunner.runWithTiming( - () -> nodeEmbeddingsAlgorithmsFacade.fastRP(graphName, configuration) - ); - - return writeToDatabase( - intermediateResult.algorithmResult, - configuration, - (result) -> NodePropertyValuesAdapter.adapt(result.embeddings()), - (result) -> intermediateResult.algorithmResult.graph().nodeCount(), - intermediateResult.computeMilliseconds, - () -> 0L, - "FastRPWrite", - configuration.writeConcurrency(), - configuration.writeProperty(), - configuration.arrowConnectionInfo(), - - configuration.resolveResultStore(intermediateResult.algorithmResult.resultStore()) - ); - } - NodePropertyWriteResult writeToDatabase( AlgorithmComputationResult algorithmResult, CONFIG configuration, diff --git a/applications/algorithms/node-embeddings/build.gradle b/applications/algorithms/node-embeddings/build.gradle index f03d827728..6c968064d7 100644 --- a/applications/algorithms/node-embeddings/build.gradle +++ b/applications/algorithms/node-embeddings/build.gradle @@ -10,6 +10,7 @@ dependencies { implementation project(":algorithms-machinery") implementation project(":config-api") implementation project(":core") + implementation project(":logging") implementation project(":memory-usage") implementation project(":ml-core") implementation project(":progress-tracking") diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/FastRPWriteStep.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/FastRPWriteStep.java new file mode 100644 index 0000000000..d31c35ddbd --- /dev/null +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/FastRPWriteStep.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gds.applications.algorithms.embeddings; + +import org.neo4j.gds.api.Graph; +import org.neo4j.gds.api.GraphStore; +import org.neo4j.gds.api.ResultStore; +import org.neo4j.gds.api.properties.nodes.NodePropertyValuesAdapter; +import org.neo4j.gds.applications.algorithms.machinery.MutateOrWriteStep; +import org.neo4j.gds.applications.algorithms.machinery.WriteToDatabase; +import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten; +import org.neo4j.gds.core.utils.progress.JobId; +import org.neo4j.gds.embeddings.fastrp.FastRPResult; +import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; + +import static org.neo4j.gds.applications.algorithms.metadata.LabelForProgressTracking.WCC; + +class FastRPWriteStep implements MutateOrWriteStep { + private final WriteToDatabase writeToDatabase; + private final FastRPWriteConfig configuration; + + FastRPWriteStep(WriteToDatabase writeToDatabase, FastRPWriteConfig configuration) { + this.writeToDatabase = writeToDatabase; + this.configuration = configuration; + } + + @Override + public NodePropertiesWritten execute( + Graph graph, + GraphStore graphStore, + ResultStore resultStore, + FastRPResult result, + JobId jobId + ) { + var nodePropertyValues = NodePropertyValuesAdapter.adapt(result.embeddings()); + + return writeToDatabase.perform( + graph, + graphStore, + resultStore, + configuration, + configuration, + WCC, + jobId, + nodePropertyValues + ); + } +} diff --git a/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java new file mode 100644 index 0000000000..cf71b5ba2a --- /dev/null +++ b/applications/algorithms/node-embeddings/src/main/java/org/neo4j/gds/applications/algorithms/embeddings/NodeEmbeddingAlgorithmsWriteModeBusinessFacade.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gds.applications.algorithms.embeddings; + +import org.neo4j.gds.api.GraphName; +import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate; +import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; +import org.neo4j.gds.applications.algorithms.machinery.ResultBuilder; +import org.neo4j.gds.applications.algorithms.machinery.WriteNodePropertyService; +import org.neo4j.gds.applications.algorithms.machinery.WriteToDatabase; +import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten; +import org.neo4j.gds.embeddings.fastrp.FastRPResult; +import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; +import org.neo4j.gds.logging.Log; + +import java.util.Optional; + +import static org.neo4j.gds.applications.algorithms.metadata.LabelForProgressTracking.FastRP; + +public final class NodeEmbeddingAlgorithmsWriteModeBusinessFacade { + private final NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationFacade; + private final NodeEmbeddingAlgorithms algorithms; + private final AlgorithmProcessingTemplate algorithmProcessingTemplate; + private final WriteToDatabase writeToDatabase; + + private NodeEmbeddingAlgorithmsWriteModeBusinessFacade( + NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationFacade, + NodeEmbeddingAlgorithms algorithms, + AlgorithmProcessingTemplate algorithmProcessingTemplate, + WriteToDatabase writeToDatabase + ) { + this.estimationFacade = estimationFacade; + this.algorithms = algorithms; + this.algorithmProcessingTemplate = algorithmProcessingTemplate; + this.writeToDatabase = writeToDatabase; + } + + public static NodeEmbeddingAlgorithmsWriteModeBusinessFacade create( + Log log, + RequestScopedDependencies requestScopedDependencies, + NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationFacade, + NodeEmbeddingAlgorithms algorithms, + AlgorithmProcessingTemplate algorithmProcessingTemplate + ) { + var writeNodePropertyService = new WriteNodePropertyService(log, requestScopedDependencies); + var writeToDatabase = new WriteToDatabase(writeNodePropertyService); + + return new NodeEmbeddingAlgorithmsWriteModeBusinessFacade( + estimationFacade, + algorithms, + algorithmProcessingTemplate, + writeToDatabase + ); + } + + public RESULT fastRP( + GraphName graphName, + FastRPWriteConfig configuration, + ResultBuilder resultBuilder + ) { + var writeStep = new FastRPWriteStep(writeToDatabase, configuration); + + return algorithmProcessingTemplate.processAlgorithm( + graphName, + configuration, + FastRP, + () -> estimationFacade.fastRP(configuration), + graph -> algorithms.fastRP(graph, configuration), + Optional.of(writeStep), + resultBuilder + ); + } +} diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java index e79f19784c..b0c326d097 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/ApplicationsFacade.java @@ -133,6 +133,7 @@ public static ApplicationsFacade create( ); var nodeEmbeddingApplications = NodeEmbeddingApplications.create( + log, requestScopedDependencies, algorithmEstimationTemplate, algorithmProcessingTemplate, diff --git a/applications/facade/src/main/java/org/neo4j/gds/applications/NodeEmbeddingApplications.java b/applications/facade/src/main/java/org/neo4j/gds/applications/NodeEmbeddingApplications.java index fdc2f93408..ae29215a56 100644 --- a/applications/facade/src/main/java/org/neo4j/gds/applications/NodeEmbeddingApplications.java +++ b/applications/facade/src/main/java/org/neo4j/gds/applications/NodeEmbeddingApplications.java @@ -24,31 +24,37 @@ import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsMutateModeBusinessFacade; import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsStatsModeBusinessFacade; import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsStreamModeBusinessFacade; +import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsWriteModeBusinessFacade; import org.neo4j.gds.applications.algorithms.machinery.AlgorithmEstimationTemplate; import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTemplate; import org.neo4j.gds.applications.algorithms.machinery.MutateNodeProperty; import org.neo4j.gds.applications.algorithms.machinery.ProgressTrackerCreator; import org.neo4j.gds.applications.algorithms.machinery.RequestScopedDependencies; +import org.neo4j.gds.logging.Log; public final class NodeEmbeddingApplications { private final NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationMode; private final NodeEmbeddingAlgorithmsMutateModeBusinessFacade mutateMode; private final NodeEmbeddingAlgorithmsStatsModeBusinessFacade statsMode; private final NodeEmbeddingAlgorithmsStreamModeBusinessFacade streamMode; + private final NodeEmbeddingAlgorithmsWriteModeBusinessFacade writeMode; private NodeEmbeddingApplications( NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationMode, NodeEmbeddingAlgorithmsMutateModeBusinessFacade mutateMode, NodeEmbeddingAlgorithmsStatsModeBusinessFacade statsMode, - NodeEmbeddingAlgorithmsStreamModeBusinessFacade streamMode + NodeEmbeddingAlgorithmsStreamModeBusinessFacade streamMode, + NodeEmbeddingAlgorithmsWriteModeBusinessFacade writeMode ) { this.estimationMode = estimationMode; this.mutateMode = mutateMode; this.statsMode = statsMode; this.streamMode = streamMode; + this.writeMode = writeMode; } static NodeEmbeddingApplications create( + Log log, RequestScopedDependencies requestScopedDependencies, AlgorithmEstimationTemplate algorithmEstimationTemplate, AlgorithmProcessingTemplate algorithmProcessingTemplate, @@ -77,8 +83,15 @@ static NodeEmbeddingApplications create( algorithms, algorithmProcessingTemplate ); + var writeMode = NodeEmbeddingAlgorithmsWriteModeBusinessFacade.create( + log, + requestScopedDependencies, + estimationMode, + algorithms, + algorithmProcessingTemplate + ); - return new NodeEmbeddingApplications(estimationMode, mutateMode, statsMode, streamMode); + return new NodeEmbeddingApplications(estimationMode, mutateMode, statsMode, streamMode, writeMode); } public NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimate() { @@ -96,4 +109,8 @@ public NodeEmbeddingAlgorithmsStatsModeBusinessFacade stats() { public NodeEmbeddingAlgorithmsStreamModeBusinessFacade stream() { return streamMode; } + + public NodeEmbeddingAlgorithmsWriteModeBusinessFacade write() { + return writeMode; + } } diff --git a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteProc.java b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteProc.java index 7dc8d8056e..a6c3d4c1c5 100644 --- a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteProc.java +++ b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteProc.java @@ -21,7 +21,7 @@ import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; import org.neo4j.procedure.Name; @@ -45,7 +45,7 @@ public Stream write( @Name(value = "graphName") String graphName, @Name(value = "configuration", defaultValue = "{}") Map configuration ) { - return facade.oldNodeEmbeddings().fastRP().write(graphName, configuration); + return facade.algorithms().nodeEmbeddings().fastRPWrite(graphName, configuration); } @Procedure(value = "gds.fastRP.write.estimate", mode = READ) @@ -54,6 +54,6 @@ public Stream estimate( @Name(value = "graphNameOrConfiguration") Object graphNameOrConfiguration, @Name(value = "algoConfiguration") Map algoConfiguration ) { - return facade.oldNodeEmbeddings().fastRP().writeEstimate(graphNameOrConfiguration, algoConfiguration); + return facade.algorithms().nodeEmbeddings().fastRPWriteEstimate(graphNameOrConfiguration, algoConfiguration); } } diff --git a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteSpec.java b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteSpec.java index 0063bb679e..2d3ae7dcae 100644 --- a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteSpec.java +++ b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/fastrp/FastRPWriteSpec.java @@ -26,7 +26,7 @@ import org.neo4j.gds.executor.ExecutionMode; import org.neo4j.gds.executor.GdsCallable; import org.neo4j.gds.procedures.algorithms.configuration.NewConfigFunction; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; import java.util.stream.Stream; diff --git a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteProc.java b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteProc.java index 86fa7f7fa3..4be628b291 100644 --- a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteProc.java +++ b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteProc.java @@ -20,7 +20,7 @@ package org.neo4j.gds.embeddings.graphsage; import org.neo4j.gds.procedures.GraphDataScienceProcedures; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import org.neo4j.procedure.Context; import org.neo4j.procedure.Description; diff --git a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteSpec.java b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteSpec.java index 567eac7784..5653de145a 100644 --- a/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteSpec.java +++ b/proc/embeddings/src/main/java/org/neo4j/gds/embeddings/graphsage/GraphSageWriteSpec.java @@ -30,7 +30,7 @@ import org.neo4j.gds.executor.GdsCallable; import org.neo4j.gds.executor.validation.ValidationConfiguration; import org.neo4j.gds.procedures.algorithms.configuration.NewConfigFunction; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; import java.util.stream.Stream; diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/results/DefaultNodeEmbeddingsWriteResult.java b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/DefaultNodeEmbeddingsWriteResult.java similarity index 79% rename from procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/results/DefaultNodeEmbeddingsWriteResult.java rename to procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/DefaultNodeEmbeddingsWriteResult.java index ec0d2ccc3d..220dba912e 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/results/DefaultNodeEmbeddingsWriteResult.java +++ b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/DefaultNodeEmbeddingsWriteResult.java @@ -17,14 +17,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.neo4j.gds.procedures.embeddings.results; +package org.neo4j.gds.procedures.algorithms.embeddings; +import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTimings; import org.neo4j.gds.result.AbstractResultBuilder; import java.util.Map; public final class DefaultNodeEmbeddingsWriteResult { - public final long nodeCount; public final long nodePropertiesWritten; public final long preProcessingMillis; @@ -48,9 +48,21 @@ public DefaultNodeEmbeddingsWriteResult( this.configuration = configuration; } - @SuppressWarnings("unused") - public static class Builder extends AbstractResultBuilder { + static DefaultNodeEmbeddingsWriteResult emptyFrom( + AlgorithmProcessingTimings timings, + Map configurationMap + ) { + return new DefaultNodeEmbeddingsWriteResult( + 0, + 0, + timings.preProcessingMillis, + timings.computeMillis, + timings.mutateOrWriteMillis, + configurationMap + ); + } + public static class Builder extends AbstractResultBuilder { @Override public DefaultNodeEmbeddingsWriteResult build() { return new DefaultNodeEmbeddingsWriteResult( diff --git a/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/FastRPResultBuilderForWriteMode.java b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/FastRPResultBuilderForWriteMode.java new file mode 100644 index 0000000000..27e9e5850c --- /dev/null +++ b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/FastRPResultBuilderForWriteMode.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gds.procedures.algorithms.embeddings; + +import org.neo4j.gds.api.Graph; +import org.neo4j.gds.api.GraphStore; +import org.neo4j.gds.applications.algorithms.machinery.AlgorithmProcessingTimings; +import org.neo4j.gds.applications.algorithms.machinery.ResultBuilder; +import org.neo4j.gds.applications.algorithms.metadata.NodePropertiesWritten; +import org.neo4j.gds.embeddings.fastrp.FastRPResult; +import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; + +import java.util.Optional; +import java.util.stream.Stream; + +class FastRPResultBuilderForWriteMode implements ResultBuilder, NodePropertiesWritten> { + @Override + public Stream build( + Graph graph, + GraphStore graphStore, + FastRPWriteConfig configuration, + Optional result, + AlgorithmProcessingTimings timings, + Optional nodePropertiesWritten + ) { + if (result.isEmpty()) return Stream.of(DefaultNodeEmbeddingsWriteResult.emptyFrom( + timings, + configuration.toMap() + )); + + var defaultNodeEmbeddingsWriteResult = new DefaultNodeEmbeddingsWriteResult( + graph.nodeCount(), + nodePropertiesWritten.orElseThrow().value, + timings.preProcessingMillis, + timings.computeMillis, + timings.mutateOrWriteMillis, + configuration.toMap() + ); + + return Stream.of(defaultNodeEmbeddingsWriteResult); + } +} diff --git a/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/NodeEmbeddingsProcedureFacade.java b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/NodeEmbeddingsProcedureFacade.java index 1d99d1b1f6..0f10bb122f 100644 --- a/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/NodeEmbeddingsProcedureFacade.java +++ b/procedures/algorithms-facade/src/main/java/org/neo4j/gds/procedures/algorithms/embeddings/NodeEmbeddingsProcedureFacade.java @@ -23,9 +23,11 @@ import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsEstimationModeBusinessFacade; import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsStatsModeBusinessFacade; import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsStreamModeBusinessFacade; +import org.neo4j.gds.applications.algorithms.embeddings.NodeEmbeddingAlgorithmsWriteModeBusinessFacade; import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import org.neo4j.gds.embeddings.fastrp.FastRPStatsConfig; import org.neo4j.gds.embeddings.fastrp.FastRPStreamConfig; +import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; import org.neo4j.gds.procedures.algorithms.embeddings.stubs.FastRPMutateStub; import org.neo4j.gds.procedures.algorithms.runners.AlgorithmExecutionScaffolding; import org.neo4j.gds.procedures.algorithms.runners.EstimationModeRunner; @@ -135,6 +137,34 @@ public Stream fastRPStreamEstimate( return Stream.of(result); } + public Stream fastRPWrite( + String graphName, + Map configuration + ) { + var resultBuilder = new FastRPResultBuilderForWriteMode(); + + return algorithmExecutionScaffolding.runAlgorithm( + graphName, + configuration, + FastRPWriteConfig::of, + writeMode()::fastRP, + resultBuilder + ); + } + + public Stream fastRPWriteEstimate( + Object graphNameOrConfiguration, + Map algorithmConfiguration + ) { + var result = estimationMode.runEstimation( + algorithmConfiguration, + FastRPWriteConfig::of, + configuration -> estimationMode().fastRP(configuration, graphNameOrConfiguration) + ); + + return Stream.of(result); + } + private NodeEmbeddingAlgorithmsEstimationModeBusinessFacade estimationMode() { return applicationsFacade.nodeEmbeddings().estimate(); } @@ -146,4 +176,8 @@ private NodeEmbeddingAlgorithmsStatsModeBusinessFacade statsMode() { private NodeEmbeddingAlgorithmsStreamModeBusinessFacade streamMode() { return applicationsFacade.nodeEmbeddings().stream(); } + + private NodeEmbeddingAlgorithmsWriteModeBusinessFacade writeMode() { + return applicationsFacade.nodeEmbeddings().write(); + } } diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/DefaultNodeEmbeddingsComputationalResultTransformer.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/DefaultNodeEmbeddingsComputationalResultTransformer.java index 427ca93b98..9695d86242 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/DefaultNodeEmbeddingsComputationalResultTransformer.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/DefaultNodeEmbeddingsComputationalResultTransformer.java @@ -22,7 +22,7 @@ import org.neo4j.gds.algorithms.NodePropertyMutateResult; import org.neo4j.gds.algorithms.NodePropertyWriteResult; import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingMutateResult; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; public class DefaultNodeEmbeddingsComputationalResultTransformer { diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/OldNodeEmbeddingsProcedureFacade.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/OldNodeEmbeddingsProcedureFacade.java index 897abe3d0b..42ed5a6c12 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/OldNodeEmbeddingsProcedureFacade.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/OldNodeEmbeddingsProcedureFacade.java @@ -25,14 +25,12 @@ import org.neo4j.gds.algorithms.embeddings.NodeEmbeddingsAlgorithmsTrainBusinessFacade; import org.neo4j.gds.algorithms.embeddings.NodeEmbeddingsAlgorithmsWriteBusinessFacade; import org.neo4j.gds.procedures.algorithms.configuration.ConfigurationCreator; -import org.neo4j.gds.procedures.embeddings.fastrp.FastRPProcedure; import org.neo4j.gds.procedures.embeddings.graphsage.GraphSageProcedure; import org.neo4j.gds.procedures.embeddings.hashgnn.HashGNNProcedure; import org.neo4j.gds.procedures.embeddings.node2vec.Node2VecProcedure; public class OldNodeEmbeddingsProcedureFacade { - private final FastRPProcedure fastRP; private final HashGNNProcedure hashGNN; private final Node2VecProcedure node2Vec; private final GraphSageProcedure graphSage; @@ -46,13 +44,6 @@ public OldNodeEmbeddingsProcedureFacade( NodeEmbeddingsAlgorithmsTrainBusinessFacade trainBusinessFacade, NodeEmbeddingsAlgorithmsWriteBusinessFacade writeBusinessFacade ) { - - - this.fastRP = new FastRPProcedure( - configurationCreator, - estimateBusinessFacade, - writeBusinessFacade - ); this.hashGNN = new HashGNNProcedure( configurationCreator, estimateBusinessFacade, @@ -78,10 +69,6 @@ public OldNodeEmbeddingsProcedureFacade( ); } - public FastRPProcedure fastRP() { - return fastRP; - } - public HashGNNProcedure hashGNN() { return hashGNN; } diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/fastrp/FastRPProcedure.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/fastrp/FastRPProcedure.java deleted file mode 100644 index 9458529f8c..0000000000 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/fastrp/FastRPProcedure.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) "Neo4j" - * Neo4j Sweden AB [http://neo4j.com] - * - * This file is part of Neo4j. - * - * Neo4j is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package org.neo4j.gds.procedures.embeddings.fastrp; - -import org.neo4j.gds.algorithms.embeddings.NodeEmbeddingsAlgorithmsEstimateBusinessFacade; -import org.neo4j.gds.algorithms.embeddings.NodeEmbeddingsAlgorithmsWriteBusinessFacade; -import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; -import org.neo4j.gds.embeddings.fastrp.FastRPWriteConfig; -import org.neo4j.gds.procedures.algorithms.configuration.ConfigurationCreator; -import org.neo4j.gds.procedures.embeddings.DefaultNodeEmbeddingsComputationalResultTransformer; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; - -import java.util.Map; -import java.util.stream.Stream; - -public class FastRPProcedure { - private final ConfigurationCreator configurationCreator; - private final NodeEmbeddingsAlgorithmsEstimateBusinessFacade estimateBusinessFacade; - private final NodeEmbeddingsAlgorithmsWriteBusinessFacade writeBusinessFacade; - - public FastRPProcedure( - ConfigurationCreator configurationCreator, - NodeEmbeddingsAlgorithmsEstimateBusinessFacade estimateBusinessFacade, - NodeEmbeddingsAlgorithmsWriteBusinessFacade writeBusinessFacade - ) { - this.configurationCreator = configurationCreator; - this.estimateBusinessFacade = estimateBusinessFacade; - this.writeBusinessFacade= writeBusinessFacade; - } - - public Stream write( - String graphName, - Map configuration - ) { - var writeConfig = configurationCreator.createConfiguration(configuration, FastRPWriteConfig::of); - - var computationResult = writeBusinessFacade.fastRP( - graphName, - writeConfig - ); - - return Stream.of(DefaultNodeEmbeddingsComputationalResultTransformer.toWriteResult(computationResult)); - } - - public Stream writeEstimate( - Object graphNameOrConfiguration, - Map configuration - ) { - var config = configurationCreator.createConfiguration(configuration, FastRPWriteConfig::of); - - return Stream.of(estimateBusinessFacade.fastRP(graphNameOrConfiguration, config)); - } -} diff --git a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/graphsage/GraphSageProcedure.java b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/graphsage/GraphSageProcedure.java index 3c58381f8a..3a071d77fa 100644 --- a/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/graphsage/GraphSageProcedure.java +++ b/procedures/facade/src/main/java/org/neo4j/gds/procedures/embeddings/graphsage/GraphSageProcedure.java @@ -32,7 +32,7 @@ import org.neo4j.gds.procedures.embeddings.DefaultNodeEmbeddingsComputationalResultTransformer; import org.neo4j.gds.procedures.embeddings.GraphSageComputationalResultTransformer; import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingMutateResult; -import org.neo4j.gds.procedures.embeddings.results.DefaultNodeEmbeddingsWriteResult; +import org.neo4j.gds.procedures.algorithms.embeddings.DefaultNodeEmbeddingsWriteResult; import org.neo4j.gds.applications.algorithms.machinery.MemoryEstimateResult; import java.util.Map;