ErikBPF opened a new issue, #7570:
URL: https://github.com/apache/datafusion-comet/issues/7570

   ### What is the problem the feature request solves?
   
   Delta's `FileSizeHistogramAgg` falls back to Spark on the measured Spark 
4.2.0 /
   Delta 4.4.0 / Comet 1.2.0 runtime:
   
   ```text
   unsupported Spark aggregate function: filesizehistogramagg
   ```
   
   Correct results are returned through Spark. This is one aggregate-support
   request, with no measured speedup claim.
   
   ### Describe the potential solution
   
   Add optional support for this aggregate alone, preserving its bin boundaries,
   file counts, byte totals, null/empty behavior, update/merge and 
serialization.
   Keep Delta out of mandatory core dependencies. Use a separately agreed 
optional
   integration seam; do not design a general plugin system in this issue.
   
   Acceptance for the initial supported path:
   
   - Assert native aggregate execution and exact scalar/grouped results against 
Delta.
   - Cover sorted custom bins, boundaries, nulls, empty partitions and reference
     overflow. Ignore values below the first bin; do not ignore all negative 
values.
     With bins `[-10,0,10,100]` and values `-5,NULL,0,9,10,99,100`, return
     `[-10,0,10,100,1,2,2,1,-5,9,109,100]`. Negative values inside a bin count.
   - Test partial/merge/spill state on the admitted native pipeline. Classify 
each
     cross-engine state direction independently and retain safe fallback where
     interoperability is unproved; implementing both directions is not 
mandatory.
     Intermediate state contains counts and totals only, serialized with
     `Platform.putLong`; boundaries are prepended only to the final result. 
Preserve
     exact bytes on the target architecture, not an invented portable-endian 
format.
   - With bins `[0,10,100]` and values `0,9,10,99,100,NULL`, return
     `[0,10,100,2,2,1,9,109,100]`.
   
   **Out of scope:** deleted-record histograms, bitmap aggregation, 
snapshot-wide
   native execution, unrelated colocated aggregates, Delta reads/writes and any
   production configuration change. This issue can close while those remain 
Spark.
   
   ### Additional context
   
   
   [Delta 
FileSizeHistogramAgg](https://github.com/delta-io/delta/blob/v4.4.0/spark/src/main/scala/org/apache/spark/sql/delta/stats/FileSizeHistogramUtils.scala)
   extends 
[FileStatsHistogramAggBase](https://github.com/delta-io/delta/blob/v4.4.0/spark/src/main/scala/org/apache/spark/sql/delta/stats/FileStatsHistogram.scala).
   Use those implementations as the state/result oracle, alongside
   [Spark 4.2 null/aggregate 
semantics](https://spark.apache.org/docs/4.2.0/sql-ref-null-semantics.html).
   Related aggregate-state audit: #5975. The separately proposed
   `DeletedRecordCountsHistogramAgg` support is not a prerequisite.
   
   Observed runtime: Spark 4.2.0 / Scala 2.13.18 / Java 17, Delta 4.4.0 and 
released Comet 1.2.0 (`ab46419fcc99bcd34aa4d89f7b545d5d51694a88`). Current main 
inspected at `4de6704391c9a7832a2079fc4e8d80fc09e9b209` was not executed. This 
is missing support, not a current-main regression or a wrong-results report. No 
measured native-kernel speedup is claimed. Optional integration design still 
needs maintainer agreement.
   
   <details>
   <summary>Self-contained FileSizeHistogramRepro reproducer and launch 
commands</summary>
   
   Save as `FileSizeHistogramRepro.scala`. Each mode creates its own fresh 
synthetic Parquet fixture. The Comet control must contain Comet operators 
before this expression is tested; passing expected rows alone does not 
establish native execution of the requested expression.
   
   ```scala
   package org.apache.spark.sql.comet.repro
   
   import java.nio.file.{Files, Paths}
   import org.apache.spark.sql.{Column, SparkSession}
   import org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute
   import org.apache.spark.sql.classic.ClassicConversions._
   import org.apache.spark.sql.functions._
   import 
org.apache.spark.sql.delta.stats.FileSizeHistogramUtils.FileSizeHistogramAgg
   
   object FileSizeHistogramRepro {
     def main(args: Array[String]): Unit = {
       require(args.length == 2, "usage: stock|comet <fresh output>")
       val mode = args(0); require(Set("stock", "comet")(mode))
       val out = Paths.get(args(1)); Files.createDirectory(out)
       val spark = SparkSession.builder
         .config("spark.sql.extensions", 
"io.delta.sql.DeltaSparkSessionExtension" +
           (if (mode == "comet") 
",org.apache.comet.CometSparkSessionExtensions" else ""))
         .config("spark.sql.catalog.spark_catalog", 
"org.apache.spark.sql.delta.catalog.DeltaCatalog")
         .config("spark.comet.enabled", (mode == "comet").toString)
         .config("spark.comet.exec.enabled", (mode == "comet").toString)
         .config("spark.comet.explain.fallback.enabled", "true")
         .config("spark.comet.explain.fallback.log.enabled", "true")
         .config("spark.shuffle.manager", if (mode == "comet")
           "org.apache.spark.sql.comet.execution.shuffle.CometShuffleManager"
           else "org.apache.spark.shuffle.sort.SortShuffleManager")
         .config("spark.memory.offHeap.enabled", "true")
         .config("spark.memory.offHeap.size", "512m")
         .config("spark.sql.shuffle.partitions", "2")
         .getOrCreate()
       try {
         val control = spark.range(20).selectExpr("sum(id) AS total")
         require(control.collect().head.getLong(0) == 190L)
         if (mode == "comet") 
require(control.queryExecution.executedPlan.toString.contains("Comet"))
         val path = out.resolve("input").toString
         spark.sql("SELECT CAST(v AS BIGINT) v, CAST(v AS INT) x, payload FROM 
VALUES " +
           "(0,'a'),(9,'b'),(10,'c'),(99,'d'),(100,'e'),(NULL,'f') AS 
t(v,payload)")
           .repartition(2).write.parquet(path)
         val input = spark.read.parquet(path)
         val query = 
input.agg(Column(FileSizeHistogramAgg(UnresolvedAttribute("v"),
           IndexedSeq(0L,10L,100L)).toAggregateExpression()).as("sizes"))
         require(query.collect().head.getSeq[Long](0) ==
           Seq(0L,10L,100L,2L,2L,1L,9L,109L,100L))
         println(query.queryExecution.executedPlan.toString)
         println("PASS: FileSizeHistogramRepro " + mode)
       } finally spark.stop()
     }
   }
   ```
   
   Use Spark 4.2.0 with Java 17. Maven coordinates:
   
   - `io.delta:delta-spark_4.2_2.13:4.4.0`
   - `io.delta:delta-storage:4.4.0`
   - `org.apache.datafusion:comet-spark-spark4.2_2.13:1.2.0`
   
   Set `SPARK_HOME`, `JAVA_HOME`, `DELTA_JARS` (two Delta JAR paths, comma 
separated), and `COMET_JAR` to these local artifacts. The Comet release 
contains its matching native library. No Delta contrib JAR is required for this 
reproducer. Bash commands:
   
   ```bash
   set -euo pipefail
   export SPARK_LOCAL_IP=127.0.0.1
   export COMET_WORKER_THREADS=2
   export COMET_MAX_BLOCKING_THREADS=4
   repro_root=$(mktemp -d /tmp/comet-delta-expression.XXXXXX)
   mkdir "$repro_root/classes"
   "$JAVA_HOME/bin/java" -Xmx512m -XX:ActiveProcessorCount=2 \
     -cp "$SPARK_HOME/jars/*" scala.tools.nsc.Main \
     -classpath "$SPARK_HOME/jars/*:${DELTA_JARS//,/:}" \
     -d "$repro_root/classes" FileSizeHistogramRepro.scala
   "$JAVA_HOME/bin/jar" cf "$repro_root/probe.jar" -C "$repro_root/classes" .
   for mode in stock comet; do
     jars="$DELTA_JARS"
     if [ "$mode" = comet ]; then jars="$jars,$COMET_JAR"; fi
     "$SPARK_HOME/bin/spark-submit" --master 'local[2]' --driver-memory 2g \
       --conf spark.driver.extraJavaOptions=-XX:ActiveProcessorCount=2 \
       --jars "$jars" --class 
org.apache.spark.sql.comet.repro.FileSizeHistogramRepro \
       "$repro_root/probe.jar" "$mode" "$repro_root/$mode"
   done
   ```
   
   Expected: both modes exit zero and print `PASS: FileSizeHistogramRepro 
<mode>`. On the measured Comet 1.2.0 runtime, the requested private expression 
remains on Spark and the fallback reason appears in the log. The source above 
pins exact expected results; it does not implement the feature.
   
   </details>
   
   ### Willingness to contribute
   
   I would be willing to contribute a fix for this bug with guidance from the 
DataFusion community.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to