Skip to content

Adapt SQL RAPIDS callers to columnar helpers#15033

Open
gerashegalov wants to merge 4 commits into
codex/unshim-stack-02o-core-execution-callersfrom
codex/unshim-stack-02p-sql-rapids-callers
Open

Adapt SQL RAPIDS callers to columnar helpers#15033
gerashegalov wants to merge 4 commits into
codex/unshim-stack-02o-core-execution-callersfrom
codex/unshim-stack-02p-sql-rapids-callers

Conversation

@gerashegalov

@gerashegalov gerashegalov commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

Related to #14834.

Description

This PR is one reviewable layer in the unshim stack introduced by #15025. It updates SQL RAPIDS callers to use the moved columnar helpers. This follows the lower-level execution caller changes and keeps SQL-facing call-site changes grouped together.

Stack context

Testing and validation notes

  • No standalone behavior change is intended in this layer. It is covered by the full-stack packaging/build validation described in Add default common unshim packaging flow #15025 and the existing tests for the affected subsystem.
  • The full split stack was verified to be tree-equivalent to the pre-split stack top.

Checklists

Documentation

  • Updated for new or modified user-facing features or behaviors
  • No user-facing change

Testing

  • Added or modified tests to cover new code paths
  • Covered by existing tests
    (Covered by the validation notes in the PR description.)
  • Not required

Performance

  • Tests ran and results are added in the PR description
  • Issue filed with a link in the PR description
  • Not required

@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from 9792db2 to fb9aa40 Compare June 10, 2026 20:49
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch 3 times, most recently from f061f44 to 6f4f246 Compare June 10, 2026 21:32
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch 2 times, most recently from 830cf4e to b6bb8fe Compare June 10, 2026 21:36
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 6f4f246 to 5f9363a Compare June 10, 2026 21:36
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from b6bb8fe to bba66bf Compare June 10, 2026 22:20
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 5f9363a to 1457c07 Compare June 10, 2026 22:20
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from bba66bf to c7d443e Compare June 10, 2026 22:37
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 1457c07 to 64a238d Compare June 10, 2026 22:37
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from c7d443e to b8602d4 Compare June 10, 2026 22:41
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 64a238d to 1f90438 Compare June 10, 2026 22:41
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from b8602d4 to b0f5b13 Compare June 10, 2026 22:46
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch 2 times, most recently from 6011c26 to fea9cb1 Compare June 10, 2026 23:12
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from 05f51a5 to cac80aa Compare June 10, 2026 23:15
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch 2 times, most recently from 7160eb5 to 3c8769b Compare June 10, 2026 23:33
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch 2 times, most recently from 43e499a to 94fc626 Compare June 10, 2026 23:59
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch 2 times, most recently from 7bbdcc0 to d35c3a9 Compare June 11, 2026 00:25
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from 94fc626 to eb42a47 Compare June 11, 2026 00:25
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from d35c3a9 to cf518aa Compare June 11, 2026 00:37
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from eb42a47 to 916ddb5 Compare June 11, 2026 00:37
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from cf518aa to f714012 Compare June 11, 2026 00:51
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch 2 times, most recently from e69ce28 to bc1ad84 Compare June 11, 2026 01:58
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from 0434223 to 98459fb Compare June 13, 2026 12:13
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 7b50024 to 3848638 Compare June 13, 2026 12:13
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02p-sql-rapids-callers branch from 3848638 to e505feb Compare June 13, 2026 12:20
@gerashegalov gerashegalov force-pushed the codex/unshim-stack-02o-core-execution-callers branch from 98459fb to 8b9f3f0 Compare June 13, 2026 12:20
@gerashegalov gerashegalov marked this pull request as ready for review June 13, 2026 12:49
@greptile-apps

greptile-apps Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR is the SQL-layer step in the "unshim stack" (#15025): it decouples SQL-facing callers from versioned shim imports by replacing direct class/object references with reflective lazy-val dispatch, converting case class to plain class throughout, and migrating org.apache.spark.internal.Logging mixins to RapidsLocalLog or local SLF4J loggers. No behavioral change is intended.

  • Reflective dispatch introduced for TrampolineConnectShims, DFUDFShims, and PerfIO; RapidsAnalysisException is converted from a subclass of AnalysisException to a factory object that probes the constructor shape at call time.
  • case classclass for DFUDF*, JDFUDF*, PartialFile, CompressedRecord, BatchState, and several converter types in InternalColumnarRddConverter, removing auto-generated equals/hashCode/copy to satisfy cross-module visibility rules.
  • Three new ShimPredicate shim files added for spark330–358, spark400–402, and spark411 to cover contextIndependentFoldable across all supported Spark versions.

Confidence Score: 4/5

The change is a pure mechanical refactor with no intended behavior change; the vast majority of diffs are import/mixin swaps, case-class-to-class conversions, and local logger migrations.

Two call sites in RapidsAnalysisException re-run reflective constructor scans and re-allocate the emptyQueryContextArray on every error throw rather than caching them at initialization. The joinStrategy/buildSideSelection accessors rely on unchecked asInstanceOf casts on Enumeration.Value fields whose types are defined in a lower stack layer not visible in this diff. Both issues are on non-hot paths and consistent with the layered unshim design, but they warrant a second look.

TrampolineUtil.scala (RapidsAnalysisException factory — constructor caching), GpuHashJoin.scala (asInstanceOf casts on JoinOptions enum fields)

Important Files Changed

Filename Overview
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/TrampolineUtil.scala Replaces direct import of TrampolineConnectShims and JsonAST with reflective dispatch; converts class RapidsAnalysisException into a factory object with multi-version constructor probing — the emptyQueryContextArray helper is an uncached def that repeats class-lookup and array-allocation on every error throw.
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuHashJoin.scala Removes case class JoinOptions and JoinCardinalityStats (now in a lower layer); adds joinStrategy / buildSideSelection accessor properties with asInstanceOf casts on Enumeration.Value; replaces joinOptions.strategy / buildSideSelection at all 14 call sites.
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/GpuTaskMetrics.scala Removes NanoTime/SizeInBytes/PerfIO direct imports; accesses PerfIO through reflective lazy-val dispatch; replaces Logging mixin with a static SLF4J logger. Looks correct.
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/RapidsShuffleInternalManagerBase.scala Switches Logging mixin to RapidsLocalLog; converts three internal case classes (PartialFile, CompressedRecord, BatchState) to plain class with explicit val fields. Purely mechanical change; behavior unchanged.
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/BridgeGenerateUnsafeProjection.scala Decouples BridgeUnsafeProjection from CodeGeneratorWithInterpretedFallback; introduces a private BridgeUnsafeProjectionCodegen object that wraps the NonFatal-based fallback pattern and delegates logging via SLF4J. Clean refactor.
sql-plugin/src/main/spark330/scala/com/nvidia/spark/rapids/shims/ShimPredicate.scala New shim file covering spark330–358; defines contextIndependentFoldable as a plain def (no override) delegating to .foldable, which is correct for Spark versions that lack the method in Predicate.
sql-plugin/src/main/spark411/scala/com/nvidia/spark/rapids/shims/ShimPredicate.scala New shim file for spark411; overrides contextIndependentFoldable and delegates to children.forall(_.contextIndependentFoldable), matching Spark 4.11's base Predicate API. Correct override keyword.
sql-plugin/src/main/scala/org/apache/spark/sql/nvidia/LogicalPlanRules.scala Replaces direct DFUDFShims and RapidsConf calls with reflective lazy dispatch; reads DFUDF enabled flag directly from SQLConf rather than through RapidsConf. Correct mechanical refactor.
sql-plugin/src/main/scala/org/apache/spark/sql/nvidia/dataframe_udfs.scala Converts all DFUDF0–DFUDF10 and JDFUDF0–JDFUDF10 from case class to plain class with explicit val f. No behavioral change; necessary for cross-module compatibility in the unshim stack.
sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/InternalColumnarRddConverter.scala Converts internal case classes (MapConverter, ArrayConverter, StructConverter, etc.) to plain classes; switches from Spark Logging to a local SLF4J logger with guard. Mechanical refactor.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[SQL RAPIDS Callers\nthis PR] -->|reflective lazy dispatch| B[TrampolineConnectShims]
    A -->|reflective lazy dispatch| C[DFUDFShims]
    A -->|reflective lazy dispatch| D[PerfIO]
    A -->|RapidsLocalLog mixin| E[SLF4J Logger]
    A -->|factory apply| F[RapidsAnalysisException\nobject - probes AnalysisException\nconstructor shape]
    A -->|case class to class| G[DFUDF*/JDFUDF*\nPartialFile/CompressedRecord\nBatchState/Converters]
    A -->|new shim files| H[ShimPredicate\nspark330-spark411]
    B --> I[Lower Execution Layer\nprev PR 15051]
    C --> I
    D --> I
Loading

Reviews (1): Last reviewed commit: "Keep ShimPredicate version-specific" | Re-trigger Greptile

Comment on lines +347 to +349
private def emptyQueryContextArray: AnyRef = {
java.lang.reflect.Array.newInstance(Class.forName("org.apache.spark.QueryContext"), 0)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 emptyQueryContextArray re-creates on every call

emptyQueryContextArray is a plain def that calls Class.forName("org.apache.spark.QueryContext") and java.lang.reflect.Array.newInstance on each invocation. Because rawMessageCtor7, rawMessageCtor8, and rawMessageCtorWithStringParameters each call it afresh (and they themselves rescan classOf[AnalysisException].getConstructors every time), every single RapidsAnalysisException(msg) site performs multiple full reflective constructor scans plus class-lookup + array-allocation per call. The AnalysisException constructor shape is fixed at JVM load time, so the lookup and the resolved constructor should be cached in lazy vals at object initialization. The empty context-array can similarly be a private lazy val.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 1150 to +1155
* Compute cardinality statistics for both sides of the join.
* This is used for diagnostic logging when logJoinCardinality is enabled.
*/
protected def joinStrategy: JoinStrategy.JoinStrategy =
joinOptions.strategy.asInstanceOf[JoinStrategy.JoinStrategy]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 asInstanceOf on Enumeration.Value fields is fragile

joinOptions.strategy.asInstanceOf[JoinStrategy.JoinStrategy] (and the buildSideSelection equivalent) casts an AnyRef-typed field to a Value type alias from a specific Enumeration. If the actual stored value was ever populated from the wrong Enumeration singleton (e.g., due to a cross-layer type mismatch introduced by moving JoinOptions to a lower module), this silently succeeds at the cast but fails later at call sites that distinguish values. Could you clarify why the cast is necessary here rather than simply typing the accessors as joinOptions.strategy directly? If the new JoinOptions class exposes strategy as AnyRef intentionally for cross-module compatibility, a comment explaining this design choice would help future maintainers. Why does joinOptions.strategy need an asInstanceOf[JoinStrategy.JoinStrategy] cast rather than being directly typed as JoinStrategy.JoinStrategy in the new JoinOptions definition?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants