andygrove commented on code in PR #4891:
URL: https://github.com/apache/datafusion-comet/pull/4891#discussion_r3572561263


##########
spark/src/main/scala/org/apache/comet/serde/CometScalaUDF.scala:
##########
@@ -70,11 +72,12 @@ object CometScalaUDF extends CometExpressionSerde[ScalaUDF] 
{
       expr: Expression,
       inputs: Seq[Attribute],
       binding: Boolean): Option[Expr] = {
+    val exprName = expr.prettyName

Review Comment:
   For a Scala/Java `ScalaUDF`, `expr.prettyName` resolves to `"scalaudf"` 
because Spark only overrides `name` on `ScalaUDF`, not `prettyName` (see 
`Expression.prettyName`, which is `nodeName.toLowerCase(Locale.ROOT)`). So 
every user UDF gets the same prefix, and because `EXTENSION_INFO` and fallback 
reasons are stored as `Set[String]`, a projection with two different UDFs will 
collapse into one entry. That undercuts the goal described in the PR body of 
keeping distinct expressions distinct. Would it be worth special-casing 
`ScalaUDF` here to use something like `s.udfName.getOrElse(s.prettyName)`? The 
`CometCodegenDispatch` subclasses (`Hypot`, `Levenshtein`, etc.) are fine 
because they're distinct expression classes with distinct `nodeName`s. Only the 
raw `ScalaUDF` path has this problem.



##########
spark/src/test/scala/org/apache/comet/CometCodegenSuite.scala:
##########
@@ -131,6 +131,42 @@ class CometCodegenSuite
     }
   }
 
+  test("explainCodegen.enabled surfaces routed expressions in COMET-INFO") {

Review Comment:
   One of the reasons cited for making this configurable was to avoid the 
annotation bleeding into golden files. Would it be worth adding a companion 
assertion in this test that flips `COMET_EXPLAIN_CODEGEN_ENABLED` to `false` 
and confirms the `hypot`/`levenshtein` info lines do NOT appear? That would pin 
down the default-off guarantee.
   
   Separately, the four new fallback-reason prefixes in 
`emitJvmCodegenDispatch` (`<exprName>: <reason>`) change user-visible explain 
and log output but don't seem to have any test asserting the new format. An 
easy one: run `SELECT hypot(a, b)` with `COMET_SCALA_UDF_CODEGEN_ENABLED=false` 
and assert the fallback reasons on the projection contain the `hypot: ` prefix.



##########
spark/src/main/scala/org/apache/comet/serde/CometScalaUDF.scala:
##########
@@ -125,6 +142,17 @@ object CometScalaUDF extends 
CometExpressionSerde[ScalaUDF] {
     udfBuilder
       .setReturnType(returnTypeProto)
       .setReturnNullable(expr.nullable)
+    // Surface the dispatch route in extended explain output when the user 
opts in via
+    // `spark.comet.explainCodegen.enabled=true`. `rollUpInfoMessages` in 
`CometExecRule` walks
+    // `op.expressions` via `TreeNode.collect` and copies each expression's 
`EXTENSION_INFO` tag
+    // onto the resulting Comet plan node, where `ExtendedExplainInfo` renders 
it as
+    // `[COMET-INFO: ...]`. Informational only: `withInfo` does not trigger 
fallback, so the
+    // projection remains a Comet operator regardless of this setting.
+    if (CometConf.COMET_EXPLAIN_CODEGEN_ENABLED.get()) {
+      withInfo(
+        expr,
+        s"${exprName.toLowerCase(Locale.ROOT)}: routes through JVM codegen 
dispatcher")

Review Comment:
   `prettyName` already returns a lowercase string 
(`nodeName.toLowerCase(Locale.ROOT)`) unless a `FUNC_ALIAS` overrides it. Is 
the extra `toLowerCase` here intentional to handle the alias case? If so, the 
fallback-reason calls above use raw `exprName` and would be inconsistent. Might 
be simpler to drop the lowercase here (and the `java.util.Locale` import) so 
the format matches the fallback paths.



##########
docs/source/user-guide/latest/understanding-comet-plans.md:
##########
@@ -108,6 +109,44 @@ when you want to see all reasons, including ones that
 not include the surrounding plan, so it is best for accumulating diagnostics
 across many queries.
 
+### `spark.comet.explainCodegen.enabled`
+
+Disabled by default. When enabled, every Spark expression that Comet routes
+through the JVM codegen dispatcher (Spark's own `doGenCode` running inside a
+Comet kernel — the path used for expressions with no native DataFusion
+implementation, gated by `spark.comet.exec.scalaUDF.codegen.enabled=true`) is
+annotated with `<expr_name>: routes through JVM codegen dispatcher`. The
+annotation rolls up onto the surrounding `CometProject` / `CometFilter` /
+etc. and is rendered inside the `[COMET-INFO: ...]` segment of extended
+explain output (verbose format). The projection stays Comet-native — this is
+informational only, useful for distinguishing "runs natively in DataFusion"
+from "runs Spark's generated code inside a Comet kernel".
+
+Example:
+
+```scala
+spark.conf.set("spark.comet.exec.scalaUDF.codegen.enabled", "true")
+spark.conf.set("spark.comet.explainCodegen.enabled", "true")
+
+val df = spark.sql("SELECT hypot(a, b), levenshtein(s1, s2) FROM t")
+println(new org.apache.comet.ExtendedExplainInfo()
+  .generateExtendedInfo(df.queryExecution.executedPlan))
+```
+
+Output:
+
+```
+CometNativeColumnarToRow
++- CometProject [COMET-INFO: hypot: routes through JVM codegen dispatcher, 
levenshtein: routes through JVM codegen dispatcher]
+   +- CometNativeScan parquet spark_catalog.default.t
+
+Comet accelerated 2 out of 2 eligible operators (100%). Final plan contains 1 
transitions between Spark and Comet.
+```
+
+Note that the operator is still `CometProject` (Comet-accelerated); only the

Review Comment:
   The prose here already explains the dispatcher path well. One small 
suggestion: could you add a sentence explicitly noting the annotation only 
appears for expressions that lack a native DataFusion implementation? A reader 
could infer this from the surrounding paragraph, but making it explicit avoids 
anyone treating the tag as a general "this expression ran here" marker.



-- 
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