plexus-engine 0.3.6

Engine integration traits for consuming Plexus plans
Documentation
Feature: vector extension positive conformance

@vector
Scenario: vector scan dot product
When executing plan mlir:
"""
func.func @vector_scan_dot() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<dot_product>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  plexus.return %1 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:1 | float:1.0 |
| node:3 | float:0.8 |
| node:2 | float:0.0 |

@vector
Scenario: vector scan cosine
When executing plan mlir:
"""
func.func @vector_scan_cosine() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<cosine>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  plexus.return %1 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:1 | float:1.0 |
| node:3 | float:0.9701425001453318 |
| node:2 | float:0.0 |

@vector
Scenario: vector scan l2
When executing plan mlir:
"""
func.func @vector_scan_l2() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<l2>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  plexus.return %1 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:1 | float:0.0 |
| node:3 | float:0.282842712474619 |
| node:2 | float:1.4142135623730951 |

@vector
Scenario: rerank by scalar relevance
When executing plan mlir:
"""
func.func @rerank_scalar() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<dot_product>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  %2 = plexus.rerank %1 {score_expr = #plexus.prop<0, "relevance">, top_k = 2 : i32, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<2>) -> !plexus.rows<2>
  plexus.return %2 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:3 | float:0.8 |
| node:1 | float:1.0 |

@vector
Scenario: rerank by vector similarity
When executing plan mlir:
"""
func.func @rerank_vector_similarity() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<dot_product>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  %2 = plexus.rerank %1 {score_expr = #plexus.vector_similarity<dot_product, #plexus.prop<0, "embedding">, #plexus.list<[#plexus.lit<0.0 : f64>, #plexus.lit<1.0 : f64>]>>, top_k = 2 : i32, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<2>) -> !plexus.rows<2>
  plexus.return %2 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:2 | float:0.0 |
| node:3 | float:0.8 |

@vector
Scenario: project vector similarity
When executing plan mlir:
"""
func.func @project_vector_similarity() {
  %0 = plexus.scan_nodes {labels = ["Doc"], schema = [#plexus.col<"d", node>]} : !plexus.rows<1>
  %1 = plexus.project %0 {exprs = [#plexus.prop<0, "title">, #plexus.vector_similarity<l2, #plexus.prop<0, "embedding">, #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>>], schema = [#plexus.col<"title", string, "string">, #plexus.col<"dist", float64, "float64">]} : (!plexus.rows<1>) -> !plexus.rows<2>
  %2 = plexus.sort %1 {keys = [1 : i32], dirs = [#plexus.sort_dir<asc>]} : (!plexus.rows<2>) -> !plexus.rows<2>
  plexus.return %2 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| string:Alpha | float:0.0 |
| string:Gamma | float:0.282842712474619 |
| string:Beta | float:1.4142135623730951 |

@vector
Scenario: vector scan top_k larger than result count
When executing plan mlir:
"""
func.func @vector_scan_topk_large() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<dot_product>, top_k = 10 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  plexus.return %1 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be, in order:
| node:1 | float:1.0 |
| node:3 | float:0.8 |
| node:2 | float:0.0 |

@vector
Scenario: vector scan empty collection returns no rows
Given an empty graph
When executing plan mlir:
"""
func.func @vector_scan_empty_collection() {
  %0 = plexus.const_row : !plexus.rows<0>
  %1 = plexus.vector_scan %0 {collection = "docs", query_vector = #plexus.list<[#plexus.lit<1.0 : f64>, #plexus.lit<0.0 : f64>]>, metric = #plexus.vector_metric<cosine>, top_k = 3 : i32, approx_hint = false, schema = [#plexus.col<"doc", node>, #plexus.col<"score", float64, "float64">]} : (!plexus.rows<0>) -> !plexus.rows<2>
  plexus.return %1 : (!plexus.rows<2>) -> ()
}
"""
Then the result should be: