neo4j / graph-data-science

Source code for the Neo4j Graph Data Science library of graph algorithms.
https://neo4j.com/docs/graph-data-science/current/
Other
639 stars 161 forks source link

Eigenvector [Failed to invoke procedure `gds.eigenvector.write`: ArrayIndexOutOfBoundsException] #152

Closed apappascs closed 2 years ago

apappascs commented 2 years ago

Describe the bug

Having a named graph 'countries'

All centralities run without any issue for write but eigenvector fails if YIELD centralityDistribution.

To Reproduce

GDS version: 1.8.1 Neo4j version: 4.3.3 Operating system: (macOs)

Steps to reproduce the behavior:

Additional context


Caused by: java.lang.ArrayIndexOutOfBoundsException: Cannot resize histogram covered range beyond (1L << 63) / (1L << 17) - 1.
Caused by: java.lang.ArrayIndexOutOfBoundsException: Operation would underflow and lose precision of already recorded value counts
    at com.neo4j.gds.shaded.org.HdrHistogram.DoubleHistogram.autoAdjustRangeForValueSlowPath(DoubleHistogram.java:412) ~[graph-data-science-1.8.1.jar:?]
    at com.neo4j.gds.shaded.org.HdrHistogram.DoubleHistogram.autoAdjustRangeForValue(DoubleHistogram.java:378) ~[graph-data-science-1.8.1.jar:?]
    at com.neo4j.gds.shaded.org.HdrHistogram.DoubleHistogram.recordSingleValue(DoubleHistogram.java:345) ~[graph-data-science-1.8.1.jar:?]
    at com.neo4j.gds.shaded.org.HdrHistogram.DoubleHistogram.recordValue(DoubleHistogram.java:290) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.result.CentralityStatistics$RecordTask.lambda$run$0(CentralityStatistics.java:82) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.core.utils.partition.Partition.consume(Partition.java:50) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.result.CentralityStatistics$RecordTask.run(CentralityStatistics.java:81) ~[graph-data-science-1.8.1.jar:?]
    at java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?]
    at org.neo4j.gds.core.concurrency.ParallelUtil.run(ParallelUtil.java:326) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.core.concurrency.ParallelUtil.run(ParallelUtil.java:313) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.core.concurrency.ParallelUtil.run(ParallelUtil.java:305) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.result.CentralityStatistics.histogram(CentralityStatistics.java:55) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.result.AbstractCentralityResultBuilder.computeCentralityHistogram(AbstractCentralityResultBuilder.java:90) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.result.AbstractCentralityResultBuilder.build(AbstractCentralityResultBuilder.java:74) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.WriteProc.lambda$write$0(WriteProc.java:69) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.BaseProc.runWithExceptionLogging(BaseProc.java:186) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.WriteProc.write(WriteProc.java:56) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.pagerank.PageRankWriteProc.write(PageRankWriteProc.java:55) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.gds.pagerank.EigenvectorWriteProc.write(EigenvectorWriteProc.java:46) ~[graph-data-science-1.8.1.jar:?]
    at org.neo4j.kernel.impl.proc.GeneratedProcedure_write986282814880155.apply(Unknown Source) ~[?:?]
    at org.neo4j.procedure.impl.ProcedureRegistry.callProcedure(ProcedureRegistry.java:240) ~[neo4j-procedure-4.3.3.jar:4.3.3]
    at org.neo4j.procedure.impl.GlobalProceduresRegistry.callProcedure(GlobalProceduresRegistry.java:364) ~[neo4j-procedure-4.3.3.jar:4.3.3]
    at org.neo4j.kernel.impl.newapi.AllStoreHolder.callProcedure(AllStoreHolder.java:981) ~[neo4j-kernel-4.3.3.jar:4.3.3]
    at org.neo4j.kernel.impl.newapi.AllStoreHolder.procedureCallWrite(AllStoreHolder.java:912) ~[neo4j-kernel-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.interpreted.CallSupport$.$anonfun$callReadWriteProcedure$1(CallSupport.scala:48) ~[neo4j-cypher-interpreted-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.interpreted.CallSupport$.callProcedure(CallSupport.scala:63) ~[neo4j-cypher-interpreted-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.interpreted.CallSupport$.callReadWriteProcedure(CallSupport.scala:48) ~[neo4j-cypher-interpreted-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.interpreted.TransactionBoundQueryContext.callReadWriteProcedure(TransactionBoundQueryContext.scala:1130) ~[neo4j-cypher-interpreted-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.planning.ExceptionTranslatingQueryContext.callReadWriteProcedure(ExceptionTranslatingQueryContext.scala:287) ~[neo4j-cypher-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.EagerReadWriteCallMode.callProcedure(ProcedureCallMode.scala:67) ~[neo4j-cypher-runtime-util-4.3.3.jar:4.3.3]
    at org.neo4j.codegen.OperatorTaskPipeline0_99.compiledOperate(Unknown Source) ~[?:?]
    at org.neo4j.cypher.internal.runtime.pipelined.operators.CompiledTask.operateWithProfile(OperatorCodeGenBaseTemplates.scala:450) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.pipelined.PipelineTask.executeOperators(PipelineTask.scala:62) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.pipelined.PipelineTask.executeWorkUnit(PipelineTask.scala:52) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.pipelined.Worker.executeTask(Worker.scala:138) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.pipelined.Worker.workOnQuery(Worker.scala:92) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.runtime.pipelined.execution.CallingThreadExecutingQuery.request(CallingThreadExecutingQuery.scala:39) ~[neo4j-cypher-pipelined-runtime-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.PipelinedRuntimeResult.request(PipelinedRuntime.scala:493) ~[neo4j-enterprise-cypher-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.result.StandardInternalExecutionResult.request(StandardInternalExecutionResult.scala:90) ~[neo4j-cypher-4.3.3.jar:4.3.3]
    at org.neo4j.cypher.internal.result.ClosingExecutionResult.request(ClosingExecutionResult.scala:144) ~[neo4j-cypher-4.3.3.jar:4.3.3]
    at org.neo4j.fabric.stream.QuerySubject$BasicQuerySubject$1.doRequest(QuerySubject.java:184) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at org.neo4j.fabric.stream.QuerySubject$BasicQuerySubject$1.request(QuerySubject.java:167) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.request(Operators.java:2158) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at reactor.core.publisher.StrictSubscriber.request(StrictSubscriber.java:138) ~[reactor-core-3.4.8.jar:3.4.8]
    at org.neo4j.fabric.stream.Rx2SyncStream$RecordSubscriber.request(Rx2SyncStream.java:129) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at org.neo4j.fabric.stream.Rx2SyncStream.maybeRequest(Rx2SyncStream.java:91) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at org.neo4j.fabric.stream.Rx2SyncStream.readRecord(Rx2SyncStream.java:50) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at org.neo4j.fabric.bolt.BoltQueryExecutionImpl$QueryExecutionImpl.request(BoltQueryExecutionImpl.java:179) ~[neo4j-fabric-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.AbstractCypherAdapterStream.handleRecords(AbstractCypherAdapterStream.java:104) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v3.messaging.ResultHandler.onPullRecords(ResultHandler.java:41) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v4.messaging.PullResultConsumer.consume(PullResultConsumer.java:42) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine$State.consumeResult(TransactionStateMachine.java:514) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine$State$2.streamResult(TransactionStateMachine.java:358) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine.streamResult(TransactionStateMachine.java:97) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v4.runtime.InTransactionState.processStreamResultMessage(InTransactionState.java:76) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v4.runtime.AbstractStreamingState.processUnsafe(AbstractStreamingState.java:49) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v4.runtime.InTransactionState.processUnsafe(InTransactionState.java:63) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.v3.runtime.FailSafeBoltStateMachineState.process(FailSafeBoltStateMachineState.java:48) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.statemachine.impl.AbstractBoltStateMachine.nextState(AbstractBoltStateMachine.java:151) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.statemachine.impl.AbstractBoltStateMachine.process(AbstractBoltStateMachine.java:99) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.messaging.BoltRequestMessageReader.lambda$doRead$1(BoltRequestMessageReader.java:93) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.DefaultBoltConnection.lambda$enqueue$0(DefaultBoltConnection.java:156) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatchInternal(DefaultBoltConnection.java:252) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:187) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:177) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.scheduling.ExecutorBoltScheduler.executeBatch(ExecutorBoltScheduler.java:257) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at org.neo4j.bolt.runtime.scheduling.ExecutorBoltScheduler.lambda$scheduleBatchOrHandleError$3(ExecutorBoltScheduler.java:240) ~[neo4j-bolt-4.3.3.jar:4.3.3]
    at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700) [?:?]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-all-4.1.66.Final.jar:4.1.66.Final]
    at java.lang.Thread.run(Thread.java:834) [?:?]
vnickolov commented 2 years ago

@alexpappasc thank you for reporting this, is there any way you can share the underlying Neo4j database and/or any graph dimensions, i.e. node count, relationship count?

apappascs commented 2 years ago

Thank you for @vnickolov I am providing some data prof here:

Store Size

Total | 112.37 MiB Database | 13.35 MiB

Id Allocation

Node ID | 4744 Property ID | 164965 Relationship ID | 163371 Relationship Type ID | 3

Page Cache

Hits | 23036 Page Faults | 1879 Hit Ratio | 100.00% Usage Ratio | 0.69%

Transactions

Last Tx Id | 1392 Current Read | 1 Current Write | 0 Peak Transactions | 6 Committed Read | 129 Committed Write | 1

Index Name Type Uniqueness EntityType LabelsOrTypes Properties State
graphxrIndex FULLTEXT NONUNIQUE NODE [ "COUNTRY" ] [ "name" ] ONLINE
index_343aff4e LOOKUP NONUNIQUE NODE [] [] ONLINE
index_f7700477 LOOKUP NONUNIQUE RELATIONSHIP [] [] ONLINE
╒════════════════════════════════════════════════════════╤═══════════════╕
│"nodes"                                                 │"relationships"│
╞════════════════════════════════════════════════════════╪═══════════════╡
│[{"name":"COUNTRY","indexes":["name"],"constraints":[]}]│[{},{}]        │
└────────────────────────────────────────────────────────┴───────────────┘
CALL gds.graph.create(
  'countries',
  'COUNTRY',
  {
    SENDING: {
      orientation: 'NATURAL',
      properties: ['total']
    }
  }
)
╒═══════════════════════════════════════════════╤══════════════════════════════════════════════════════════════════════╤═══════════╤═══════════╤═══════════════════╤══════════════╕
│"nodeProjection"                               │"relationshipProjection"                                              │"graphName"│"nodeCount"│"relationshipCount"│"createMillis"│
╞═══════════════════════════════════════════════╪══════════════════════════════════════════════════════════════════════╪═══════════╪═══════════╪═══════════════════╪══════════════╡
│{"COUNTRY":{"label":"COUNTRY","properties":{}}}│{"SENDING":{"orientation":"NATURAL","aggregation":"DEFAULT","type":"SE│"countries"│120        │2371               │157           │
│                                               │NDING","properties":{"total":{"defaultValue":null,"property":"total","│           │           │                   │              │
│                                               │aggregation":"DEFAULT"}}}}                                            │           │           │                   │              │
└───────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────┴───────────┴───────────┴───────────────────┴──────────────┘
CALL gds.eigenvector.write('countries', {maxIterations: 20, writeProperty: 'centrality'})
Neo.ClientError.Procedure.ProcedureCallFailed
Failed to invoke procedure `gds.eigenvector.write`: Caused by: java.lang.ArrayIndexOutOfBoundsException: The value 0.15111707420831302 is out of bounds for histogram, current covered range [8.433758354584419E-81, 1.448908652612274E-70) cannot be extended any further.
Caused by: java.lang.ArrayIndexOutOfBoundsException: Cannot resize histogram covered range beyond (1L << 63) / (1L << 17) - 1.
Caused by: java.lang.ArrayIndexOutOfBoundsException: Operation would underflow and lose precision of already recorded value counts
CALL gds.betweenness.write('countries', {writeProperty: 'centrality'})
╒═══════════════════════╤═════════════╤══════════════════════════════════════════════════════════════════════╤══════════════╤════════════════╤═════════════════╤══════════════════════╤══════════════╤═══════════════╤══════════════════════════════════════════════════════════════════════╕
│"nodePropertiesWritten"│"writeMillis"│"centralityDistribution"                                              │"minimumScore"│"maximumScore"  │"scoreSum"       │"postProcessingMillis"│"createMillis"│"computeMillis"│"configuration"                                                       │
╞═══════════════════════╪═════════════╪══════════════════════════════════════════════════════════════════════╪══════════════╪════════════════╪═════════════════╪══════════════════════╪══════════════╪═══════════════╪══════════════════════════════════════════════════════════════════════╡
│120                    │36           │{"p99":67.74804306030273,"min":0.0,"max":5630.093746185303,"mean":60.1│0.0           │5630.09027182152│7212.999999999999│123                   │0             │39             │{"writeConcurrency":4,"writeProperty":"centrality","nodeLabels":["*"],│
│                       │             │08238252003986,"p90":51.820552825927734,"p50":0.0,"p999":5630.09374618│              │                │                 │                      │              │               │"sudo":false,"relationshipTypes":["*"],"username":null,"concurrency":4│
│                       │             │5303,"p95":67.74804306030273,"p75":18.148433685302734}                │              │                │                 │                      │              │               │}                                                                     │
└───────────────────────┴─────────────┴──────────────────────────────────────────────────────────────────────┴──────────────┴────────────────┴─────────────────┴──────────────────────┴──────────────┴───────────────┴──────────────────────────────────────────────────────────────────────┘

Lets fetch stat results with cypher

    CALL gds.eigenvector.stream('countries') 
    Yield nodeId, score
    Return min(score) as min, max(score) as max,  
    percentileDisc(score,0.50) as p50, percentileDisc(score,0.75) as p75,
    percentileDisc(score,0.90) as p90, percentileDisc(score,0.95) as p95,
    percentileDisc(score,0.99) as p99, percentileDisc(score,0.999) as p999,
    avg(score) as avg, stDev(score) as stDev
╒══════════════════════╤═══════════════════╤═════════════════════╤══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╤═══════════════════╕
│"min"                 │"max"              │"p50"                │"p75"             │"p90"              │"p95"              │"p99"              │"p999"             │"avg"              │"stDev"            │
╞══════════════════════╪═══════════════════╪═════════════════════╪══════════════════╪═══════════════════╪═══════════════════╪═══════════════════╪═══════════════════╪═══════════════════╪═══════════════════╡
│1.5998814952422848e-80│0.16057834684707384│0.0035554138994582643│0.1310891025405734│0.15962357714750902│0.16057834684707384│0.16057834684707384│0.16057834684707384│0.05965645441326826│0.06938704584621574│
└──────────────────────┴───────────────────┴─────────────────────┴──────────────────┴───────────────────┴───────────────────┴───────────────────┴───────────────────┴───────────────────┴───────────────────┘

It works! The problem is if and only if you include on YIELD fields the centralityDistribution

L4R4 commented 2 years ago

I have same problem I create a graph with all nodes and relationships, and this error happen

Failed to invoke procedure gds.eigenvector.stats: Caused by: java.lang.ArrayIndexOutOfBoundsException: The value 4.6794376646547155E-55 is out of bounds for histogram, current covered range [4.930380657631324E-32, 8.470329472543003E-22) cannot be extended any further. Caused by: java.lang.ArrayIndexOutOfBoundsException: Cannot resize histogram covered range beyond (1L << 63) / (1L << 17) - 1. Caused by: java.lang.ArrayIndexOutOfBoundsException: Operation would overflow, would discard recorded value counts

jjaderberg commented 2 years ago

The problem is in the library we use to compute the distribution. We have introduced a workaround that will prevent the algorithm failing hard. Instead, we will capture the error and show it as part of the result. We have raised the issue upstream, but no response yet. https://github.com/HdrHistogram/HdrHistogram#190

Feel free to provide feedback on our workaround. We have no further work planned on this issue, I will leave the issue open for a little bit to see if there is further feedback.