Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/codspeed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- { shard: 6, name: "Encodings 3", packages: "vortex-pco vortex-runend vortex-sequence" }
- { shard: 7, name: "Encodings 4", packages: "vortex-sparse vortex-zigzag vortex-zstd" }
- { shard: 8, name: "Storage formats & row encoding", packages: "vortex-flatbuffers vortex-proto vortex-btrblocks vortex-row" }
- { shard: 9, name: "Tensor & geo", packages: "vortex-tensor vortex-geo" }
- { shard: 9, name: "Tensor & spatial", packages: "vortex-tensor vortex-spatial" }
name: "Benchmark with Codspeed (Shard #${{ matrix.shard }})"
timeout-minutes: 30
runs-on: >-
Expand Down
58 changes: 29 additions & 29 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ members = [
"benchmarks/duckdb-bench",
"benchmarks/random-access-bench",
"benchmarks/string-bench",
"vortex-geo",
"vortex-spatial",
]
exclude = ["java/testfiles", "wasm-test"]
resolver = "2"
Expand Down Expand Up @@ -310,7 +310,6 @@ vortex-fastlanes = { version = "0.1.0", path = "./encodings/fastlanes", default-
vortex-file = { version = "0.1.0", path = "./vortex-file", default-features = false }
vortex-flatbuffers = { version = "0.1.0", path = "./vortex-flatbuffers", default-features = false }
vortex-fsst = { version = "0.1.0", path = "./encodings/fsst", default-features = false }
vortex-geo = { version = "0.1.0", path = "./vortex-geo", default-features = false }
vortex-io = { version = "0.1.0", path = "./vortex-io", default-features = false }
vortex-ipc = { version = "0.1.0", path = "./vortex-ipc", default-features = false }
vortex-json = { version = "0.1.0", path = "./vortex-json", default-features = false }
Expand All @@ -327,6 +326,7 @@ vortex-scan = { version = "0.1.0", path = "./vortex-scan", default-features = fa
vortex-sequence = { version = "0.1.0", path = "encodings/sequence", default-features = false }
vortex-session = { version = "0.1.0", path = "./vortex-session", default-features = false }
vortex-sparse = { version = "0.1.0", path = "./encodings/sparse", default-features = false }
vortex-spatial = { version = "0.1.0", path = "./vortex-spatial", default-features = false }
vortex-tensor = { version = "0.1.0", path = "./vortex-tensor", default-features = false }
vortex-utils = { version = "0.1.0", path = "./vortex-utils", default-features = false }
vortex-zigzag = { version = "0.1.0", path = "./encodings/zigzag", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion bench-orchestrator/bench_orchestrator/ci_matrix/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Format.PARQUET,
Format.VORTEX,
Format.VORTEX_COMPACT,
Format.VORTEX_NATIVE,
Format.VORTEX_SPATIAL_NATIVE,
Format.DUCKDB,
Format.LANCE,
)
Expand Down
4 changes: 2 additions & 2 deletions bench-orchestrator/bench_orchestrator/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Format(Enum):
PARQUET = "parquet"
VORTEX = "vortex"
VORTEX_COMPACT = "vortex-compact"
VORTEX_NATIVE = "vortex-geo-native"
VORTEX_SPATIAL_NATIVE = "vortex-spatial-native"
DUCKDB = "duckdb"
LANCE = "lance"

Expand Down Expand Up @@ -77,7 +77,7 @@ class Benchmark(Enum):
Format.PARQUET,
Format.VORTEX,
Format.VORTEX_COMPACT,
Format.VORTEX_NATIVE,
Format.VORTEX_SPATIAL_NATIVE,
Format.DUCKDB,
],
Engine.LANCE: [Format.LANCE],
Expand Down
22 changes: 11 additions & 11 deletions bench-orchestrator/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,21 @@ def test_parse_formats_json_accepts_ci_format_arrays() -> None:
assert formats == [Format.PARQUET, Format.VORTEX, Format.DUCKDB]


def test_parse_formats_json_accepts_vortex_native() -> None:
formats = parse_formats_json('["parquet","vortex","vortex-geo-native"]')
def test_parse_formats_json_accepts_vortex_spatial_native() -> None:
formats = parse_formats_json('["parquet","vortex","vortex-spatial-native"]')

assert formats == [Format.PARQUET, Format.VORTEX, Format.VORTEX_NATIVE]
assert formats == [Format.PARQUET, Format.VORTEX, Format.VORTEX_SPATIAL_NATIVE]


def test_resolve_axis_targets_offers_vortex_native_on_duckdb_only() -> None:
# vortex-geo-native is a DuckDB-only lane; the DataFusion axis is dropped as unsupported.
def test_resolve_axis_targets_offers_vortex_spatial_native_on_duckdb_only() -> None:
# vortex-spatial-native is a DuckDB-only lane; the DataFusion axis is dropped as unsupported.
targets, warnings = resolve_axis_targets(
[Engine.DATAFUSION, Engine.DUCKDB],
[Format.VORTEX_NATIVE],
[Format.VORTEX_SPATIAL_NATIVE],
)

assert targets == [BenchmarkTarget(engine=Engine.DUCKDB, format=Format.VORTEX_NATIVE)]
assert warnings == ["Format vortex-geo-native is not supported by engine datafusion"]
assert targets == [BenchmarkTarget(engine=Engine.DUCKDB, format=Format.VORTEX_SPATIAL_NATIVE)]
assert warnings == ["Format vortex-spatial-native is not supported by engine datafusion"]


def test_resolve_axis_targets_filters_unsupported_combinations() -> None:
Expand Down Expand Up @@ -72,19 +72,19 @@ def test_resolve_axis_targets_skips_engines_a_benchmark_cannot_run() -> None:
assert warnings == ["Benchmark spatialbench does not support engine datafusion"]


def test_resolve_axis_targets_expands_spatialbench_three_lanes() -> None:
def test_resolve_axis_targets_supports_spatialbench_three_lanes() -> None:
# The single-command three-lane comparison: parquet, WKB vortex, and native-geometry vortex, all
# on DuckDB.
targets, warnings = resolve_axis_targets(
[Engine.DUCKDB],
[Format.PARQUET, Format.VORTEX, Format.VORTEX_NATIVE],
[Format.PARQUET, Format.VORTEX, Format.VORTEX_SPATIAL_NATIVE],
Benchmark.SPATIALBENCH,
)

assert targets == [
BenchmarkTarget(engine=Engine.DUCKDB, format=Format.PARQUET),
BenchmarkTarget(engine=Engine.DUCKDB, format=Format.VORTEX),
BenchmarkTarget(engine=Engine.DUCKDB, format=Format.VORTEX_NATIVE),
BenchmarkTarget(engine=Engine.DUCKDB, format=Format.VORTEX_SPATIAL_NATIVE),
]
assert warnings == []

Expand Down
6 changes: 3 additions & 3 deletions bench-orchestrator/tests/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,17 @@ def test_build_command_adds_duckdb_cleanup_flag() -> None:
assert "scale-factor=1.0" in cmd


def test_build_command_serializes_vortex_native_format() -> None:
def test_build_command_serializes_vortex_spatial_native_format() -> None:
executor = BenchmarkExecutor(Path("/tmp/duckdb-bench"), Engine.DUCKDB)

cmd = executor.build_command(
benchmark=Benchmark.SPATIALBENCH,
formats=[Format.PARQUET, Format.VORTEX, Format.VORTEX_NATIVE],
formats=[Format.PARQUET, Format.VORTEX, Format.VORTEX_SPATIAL_NATIVE],
iterations=1,
options={"scale-factor": "1.0"},
)

assert "parquet,vortex,vortex-geo-native" in cmd
assert "parquet,vortex,vortex-spatial-native" in cmd


def test_build_command_omits_formats_for_lance_backend() -> None:
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/datafusion-bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub fn format_to_df_format(format: Format) -> Arc<dyn FileFormat> {
match format {
Format::Csv => Arc::new(CsvFormat::default()) as _,
Format::Parquet => Arc::new(ParquetFormat::new()),
Format::OnDiskVortex | Format::VortexCompact | Format::VortexNative => Arc::new(
Format::OnDiskVortex | Format::VortexCompact | Format::VortexSpatialNative => Arc::new(
VortexFormat::new_with_options(SESSION.clone(), vortex_table_options()),
),
Format::OnDiskDuckDB | Format::Lance => {
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/duckdb-bench/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl DuckClient {
Format::Parquet
| Format::OnDiskVortex
| Format::VortexCompact
| Format::VortexNative => "VIEW",
| Format::VortexSpatialNative => "VIEW",
Format::OnDiskDuckDB => "TABLE",
Format::Lance => {
anyhow::bail!(
Expand Down
2 changes: 1 addition & 1 deletion docs/concepts/expressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ such as whether the function is strict, and the actual logic for executing the f
The built-in scalar functions can be found in the `vortex-array::expr` module, with additional use-case specific
functions provided by integration and plugin crates.

In the future, we plan to add full support for geospatial functions, date-time functions, and more.
In the future, we plan to add full support for spatial functions, date-time functions, and more.

## Scalar Function Arrays

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
import org.junit.jupiter.api.io.TempDir;

/**
* Round-trips a Vortex geo extension column ({@code vortex.geo.wkb}) through the JNI boundary. Geo columns cross the
* boundary as Arrow fields tagged with the GeoArrow extension name ({@code geoarrow.wkb}) and JSON metadata carrying
* the CRS.
* Round-trips a Vortex spatial extension column ({@code vortex.st.wkb}) through the JNI boundary. Spatial columns cross
* the boundary as Arrow fields tagged with the GeoArrow extension name ({@code geoarrow.wkb}) and JSON metadata
* carrying the CRS.
*/
public final class GeoTypesTest {
public final class SpatialTypesTest {
private static final String EXTENSION_NAME_KEY = "ARROW:extension:name";
private static final String EXTENSION_METADATA_KEY = "ARROW:extension:metadata";
private static final String GEOARROW_WKB = "geoarrow.wkb";
Expand All @@ -57,7 +57,7 @@ public static void loadLibrary() {

@BeforeAll
static void setup() throws IOException {
writePath = tempDir.resolve("geo.vortex").toAbsolutePath().toUri().toString();
writePath = tempDir.resolve("spatial.vortex").toAbsolutePath().toUri().toString();

WKB_POINTS.add(wkbPoint(1.0, 2.0));
WKB_POINTS.add(wkbPoint(-111.7610, 34.8697));
Expand Down
12 changes: 6 additions & 6 deletions scripts/compare-benchmark-jsons.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ def build_statistical_analysis(df: pd.DataFrame, threshold_pct: int) -> dict[str
}


def calculate_geo_mean(df: pd.DataFrame) -> float:
def calculate_geometric_mean(df: pd.DataFrame) -> float:
"""Geometric mean of positive ratios from a DataFrame ratio column."""

valid_ratios = [r for r in df["ratio"] if r > 0 and not pd.isna(r)]
Expand Down Expand Up @@ -1019,8 +1019,8 @@ def main() -> None:
vortex_df = headline_df[headline_df["file_format"].str.startswith("vortex")]
parquet_df = headline_df[headline_df["file_format"].eq(CONTROL_FORMAT)]

vortex_geo_mean_ratio = calculate_geo_mean(vortex_df)
parquet_geo_mean_ratio = calculate_geo_mean(parquet_df)
vortex_geometric_mean_ratio = calculate_geometric_mean(vortex_df)
parquet_geometric_mean_ratio = calculate_geometric_mean(parquet_df)

statistical_analysis = build_statistical_analysis(query_df, threshold_pct)
verdict = build_verdict(statistical_analysis) if statistical_analysis is not None else None
Expand All @@ -1037,15 +1037,15 @@ def main() -> None:

if len(vortex_df) > 0:
vortex_performance = format_performance(
vortex_geo_mean_ratio,
vortex_geometric_mean_ratio,
improvement_threshold,
regression_threshold,
"vortex",
)
summary_fields.append(f"**Vortex (geomean)**: {vortex_performance}")
if len(parquet_df) > 0:
parquet_performance = format_performance(
parquet_geo_mean_ratio,
parquet_geometric_mean_ratio,
improvement_threshold,
regression_threshold,
"parquet",
Expand Down Expand Up @@ -1079,7 +1079,7 @@ def main() -> None:
for engine, file_format, unit in sorted(grouped_tables.groups.keys(), key=group_sort_key):
group_df = grouped_tables.get_group((engine, file_format, unit)).sort_values("name")
group_performance = format_performance(
calculate_geo_mean(group_df),
calculate_geometric_mean(group_df),
improvement_threshold,
regression_threshold,
"group",
Expand Down
2 changes: 1 addition & 1 deletion vortex-array/src/expr/exprs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ where
/// whose result is null exactly when any operand is null.
///
/// This is the `ScalarFnVTable::validity` for kernels that propagate nulls and never produce a
/// null from non-null inputs (comparisons, arithmetic, most geo and tensor ops). Returning it lets
/// null from non-null inputs (comparisons, arithmetic, most spatial and tensor operations). Returning it lets
/// the planner derive the output's null mask without executing the kernel. Yields `None` when the
/// expression has no children.
pub fn union_child_validities(expression: &Expression) -> VortexResult<Option<Expression>> {
Expand Down
2 changes: 1 addition & 1 deletion vortex-bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ vortex = { workspace = true, features = [
"zstd",
] }
vortex-arrow = { workspace = true }
vortex-geo = { workspace = true }
vortex-spatial = { workspace = true }
vortex-tensor = { workspace = true } # TODO(connor): In the future, this might be inside vortex.

anyhow = { workspace = true }
Expand Down
15 changes: 14 additions & 1 deletion vortex-bench/sql/spatialbench.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SpatialBench benchmark

The [Apache Sedona SpatialBench](https://sedona.apache.org/spatialbench/) geospatial
The [Apache Sedona SpatialBench](https://sedona.apache.org/spatialbench/) spatial
analytics benchmark: twelve queries (Q1 ... Q12 in [`spatialbench.sql`](./spatialbench.sql),
DuckDB dialect) over a trips/zones schema, exercising spatial predicates and functions such
as `ST_DWithin`, `ST_Intersects`, and `ST_Distance`. The query logic matches upstream
Expand All @@ -13,3 +13,16 @@ The harness lives in [`src/spatialbench`](../src/spatialbench).
```bash
vx-bench run spatialbench
```

The default command compares the Parquet and Vortex WKB representations with DuckDB. To run the
native Vortex spatial representation explicitly:

```bash
vx-bench run spatialbench --engine duckdb --format vortex-spatial-native
```

To compare all three representations in one run:

```bash
vx-bench run spatialbench --engine duckdb --format parquet,vortex,vortex-spatial-native
```
Loading
Loading