Cover Spark 4.2 Arrow Python UDF columnar input [fast-ut] [reduced-it][databricks] - #15885
Conversation
Spark 4.2 CPU ArrowEvalPythonExec can retain pass-through ColumnVector references, so the test Arrow source must not free earlier batches until the reader closes. Add GPU coverage for that Arrow input path and for a CPU Python exec above a GPU scan. Signed-off-by: Firestarman <firestarmanllc@gmail.com>
Greptile SummaryAdds Spark 4.2 integration coverage for Arrow-backed Python UDF inputs and CPU fallback after a GPU Parquet scan.
Confidence Score: 5/5The PR appears safe to merge, with no outstanding correctness, security, or repository-rule issues identified. The current changes provide focused integration coverage and test-resource lifetime handling, and no new changes to the reviewed PR files were introduced after the previous review SHA. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
A[Arrow DSv2 batch] --> B[HostColumnarToGpu]
B --> C[GpuArrowEvalPythonExec]
D[GPU Parquet scan] --> E[GPU-to-host transition]
E --> F[CPU ArrowEvalPythonExec]
Reviews (5): Last reviewed commit: "Merge branch 'main' into audit/15663-arr..." | Re-trigger Greptile |
Spark 4.2 closes the partition reader before SPARK-56350 CPU ArrowEvalPythonExec drops pass-through vectors, so closing batches in reader.close() UAFs. Close the allocator only when allocated memory is zero, and use in-range ints for pandas UDF Arrow casts on Spark 4.x. Signed-off-by: Firestarman <firestarmanllc@gmail.com>
|
build |
|
build |
| private val rootAllocator = new RootAllocator(Long.MaxValue) | ||
| private val allocator: BufferAllocator = | ||
| rootAllocator.newChildAllocator(s"arrow-test-reader-$startNum", 0, Long.MaxValue) | ||
| private val allBatches = new util.ArrayList[ColumnarBatch]() |
There was a problem hiding this comment.
Forget to close this columnar batch list?
There was a problem hiding this comment.
Not forgotten — we must not close allBatches in the reader.
Spark 4.2 DataSourceRDD calls reader.close() as soon as next() returns false, while CPU ArrowEvalPythonExec (SPARK-56350) can still hold pass-through ArrowColumnVector refs. Closing this list (and the allocator) at that point UAFs; GPU HostColumnarToGpu can also still hold ArrowBufs.
allBatches only pins the wrappers. Downstream Spark/GPU consumers close the ColumnarBatchs. The reader closes the allocator only when getAllocatedMemory == 0.
Added a comment on allBatches in 3e90357 to make that explicit.
The allBatches list is a lifetime pin. Closing it in reader.close() UAFs under SPARK-56350, which can retain pass-through vectors after the reader is closed. Signed-off-by: Firestarman <firestarmanllc@gmail.com>
…estarman/cudf-spark into audit/15663-arrow-udf-columnar-input
|
build |
res-life
left a comment
There was a problem hiding this comment.
LGTM, but please excise at lease one Spark patch version for all the Spark minor versions: 33x, 34x,35x, 40x, 41x, 42x, 50x.
Locally re-ran the Arrow DSv2 / CPU Arrow UDF tests after the allocator-close change:
|
Fixes #15663.
Description
Spark 4.2 (
SPARK-56350) lets CPUArrowEvalPythonExecconsume Arrow-backedColumnarBatchinput and skipColumnarToRow. That does not change the GPU Python UDF path (GpuColumnVector-> cuDF Arrow IPC), but it does change how tests and CPU fallbacks must behave.reader.close(). Spark 4.2DataSourceRDDcloses the reader as soon asnext()is false, while CPUArrowEvalPythonExeccan still hold pass-throughColumnVectorreferences. Downstream consumers close those batches; the test reader closes the allocator only when allocated memory is zero.HostColumnarToGpu+GpuArrowEvalPythonExec.evalType=101) coverage. CPUspark.sql.execution.arrow.pythonUDF.columnarInput.enabledis disabled only to avoid the Spark 4.2.0 hang fromSPARK-58241; that is a CPU bug, not a GPU bug.ArrowEvalPythonExecsoGpuColumnVectoris not handed to Spark's CPU Arrow UDF path.There is no user-facing config or execution-path change.
Checklists
Documentation
Testing
(Please provide the names of the existing tests in the PR description.)
New/updated tests:
test_arrow_source_pandas_udftest_arrow_source_regular_udftest_pandas_udf_cpu_arrow_eval_after_gpu_scanLocally verified (
datasourcev2_read_test.pyandudf_test.py::test_pandas_udf_cpu_arrow_eval_after_gpu_scan):test_arrow_source_regular_udf+INJECT_OOM)Performance