[SPARK-59339][ML][SQL] Add a SQL expression for ML vector dot products - #58626
Closed
zhengruifeng wants to merge 5 commits into
Closed
[SPARK-59339][ML][SQL] Add a SQL expression for ML vector dot products#58626zhengruifeng wants to merge 5 commits into
zhengruifeng wants to merge 5 commits into
Conversation
HyukjinKwon
approved these changes
Sep 8, 2026
zhengruifeng
marked this pull request as ready for review
September 9, 2026 03:56
zhengruifeng
force-pushed
the
ml-vector-dot-dev-5
branch
from
September 9, 2026 05:28
c57879c to
44b4186
Compare
zhengruifeng
added a commit
that referenced
this pull request
Sep 9, 2026
### What changes were proposed in this pull request? This PR adds an internal `VectorDotProduct` Catalyst expression, registered as `ml_vector_dot_product`, for MLlib dense and sparse vectors. The expression supports interpreted evaluation and whole-stage code generation for all dense/sparse input combinations. It also adds private ML helpers for vector-column and constant-coefficient inputs. This PR does not integrate the expression into any ML algorithm yet. ### Why are the changes needed? The internal expression operates directly on the vector's SQL struct representation, preserves sparse inputs without densifying them, and allows Catalyst code generation. It provides a focused building block for future ML transform optimizations without changing an algorithm in this PR. ### Does this PR introduce _any_ user-facing change? No. This changes the internal execution of ML model transforms. ### How was this patch tested? New tests cover interpreted and code-generated evaluation for dense/dense, dense/sparse, sparse/dense, and sparse/sparse inputs, as well as nulls, empty vectors, infinite and NaN values, and mismatched dimensions. The following focused suites and cases were run: ```text build/sbt 'catalyst/testOnly *VectorDotProductSuite' build/sbt 'mllib/testOnly *FunctionsSuite -- -z "vector_dot_product"' ``` `dev/scalastyle` also passed. #### Benchmark The expression was compared with a Scala UDF implementing `(v1, v2) => v1.dot(v2)`. Inputs were cached and consumed through a noop sink on Java 17 with `local[1]`. Each case had a two-second warm-up followed by five timed iterations; the table reports the best iteration. Sparse vectors had 10% density. Row counts were scaled inversely with dimensionality to keep approximately 10 million dense feature operations per iteration. | Features | Rows | Inputs | `ml_vector_dot_product` | Scala UDF | Speedup | |---------:|-----:|--------|------------------------:|----------:|--------:| | 10 | 1,000,000 | dense/dense | 105 ms | 189 ms | 1.81x | | 10 | 1,000,000 | sparse/dense | 92 ms | 205 ms | 2.22x | | 10 | 1,000,000 | sparse/sparse | 97 ms | 238 ms | 2.46x | | 100 | 100,000 | dense/dense | 45 ms | 58 ms | 1.30x | | 100 | 100,000 | sparse/dense | 29 ms | 55 ms | 1.90x | | 100 | 100,000 | sparse/sparse | 23 ms | 52 ms | 2.23x | | 1,000 | 10,000 | dense/dense | 39 ms | 51 ms | 1.31x | | 1,000 | 10,000 | sparse/dense | 21 ms | 44 ms | 2.10x | | 1,000 | 10,000 | sparse/sparse | 14 ms | 35 ms | 2.50x | | 10,000 | 1,000 | dense/dense | 36 ms | 52 ms | 1.44x | | 10,000 | 1,000 | sparse/dense | 22 ms | 41 ms | 1.82x | | 10,000 | 1,000 | sparse/sparse | 14 ms | 32 ms | 2.26x | ### Was this patch authored or co-authored using generative AI tooling? Generated-by: OpenAI Codex (GPT-5) Closes #58626 from zhengruifeng/ml-vector-dot-dev-5. Authored-by: Ruifeng Zheng <ruifengz@apache.org> Signed-off-by: Ruifeng Zheng <ruifengz@foxmail.com> (cherry picked from commit 70d1a0d) Signed-off-by: Ruifeng Zheng <ruifengz@foxmail.com>
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
This PR adds an internal
VectorDotProductCatalyst expression, registered asml_vector_dot_product, for MLlib dense and sparse vectors. The expression supports interpretedevaluation and whole-stage code generation for all dense/sparse input combinations.
It also adds private ML helpers for vector-column and constant-coefficient inputs. This PR does not
integrate the expression into any ML algorithm yet.
Why are the changes needed?
The internal expression operates directly on the vector's SQL struct representation, preserves
sparse inputs without densifying them, and allows Catalyst code generation. It provides a focused
building block for future ML transform optimizations without changing an algorithm in this PR.
Does this PR introduce any user-facing change?
No. This changes the internal execution of ML model transforms.
How was this patch tested?
New tests cover interpreted and code-generated evaluation for dense/dense, dense/sparse,
sparse/dense, and sparse/sparse inputs, as well as nulls, empty vectors, infinite and NaN values,
and mismatched dimensions.
The following focused suites and cases were run:
dev/scalastylealso passed.Benchmark
The expression was compared with a Scala UDF implementing
(v1, v2) => v1.dot(v2). Inputs werecached and consumed through a noop sink on Java 17 with
local[1]. Each case had a two-secondwarm-up followed by five timed iterations; the table reports the best iteration. Sparse vectors
had 10% density. Row counts were scaled inversely with dimensionality to keep approximately 10
million dense feature operations per iteration.
ml_vector_dot_productWas this patch authored or co-authored using generative AI tooling?
Generated-by: OpenAI Codex (GPT-5)