diff --git a/docs/dev/shims.md b/docs/dev/shims.md
index 0d62eb4cae8..24252df607e 100644
--- a/docs/dev/shims.md
+++ b/docs/dev/shims.md
@@ -68,17 +68,17 @@ Using JarURLConnection URLs we create a Parallel World of the current version wi
Spark 3.0.2's URLs:
```text
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark-shared/
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark302/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark-shared/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark302/
```
Spark 3.2.0's URLs :
```text
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark-shared/
-jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark320/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark-shared/
+jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark320/
```
### Late Inheritance in Public Classes
diff --git a/docs/dev/testing.md b/docs/dev/testing.md
index 9f1c33091f1..fe6c0b94c1f 100644
--- a/docs/dev/testing.md
+++ b/docs/dev/testing.md
@@ -5,5 +5,5 @@ nav_order: 2
parent: Developer Overview
---
An overview of testing can be found within the repository at:
-* [Unit tests](https://github.com/NVIDIA/spark-rapids/tree/branch-24.12/tests#readme)
-* [Integration testing](https://github.com/NVIDIA/spark-rapids/tree/branch-24.12/integration_tests#readme)
+* [Unit tests](https://github.com/NVIDIA/spark-rapids/tree/branch-25.02/tests#readme)
+* [Integration testing](https://github.com/NVIDIA/spark-rapids/tree/branch-25.02/integration_tests#readme)
diff --git a/docs/supported_ops.md b/docs/supported_ops.md
index acf7133af40..1be5008888b 100644
--- a/docs/supported_ops.md
+++ b/docs/supported_ops.md
@@ -17702,6 +17702,154 @@ are limited.
YEARMONTH |
+TruncDate |
+`trunc` |
+Truncate the date to the unit specified by the given string format |
+None |
+project |
+date |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+S |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+format |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+S |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+result |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+S |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+TruncTimestamp |
+`date_trunc` |
+Truncate the timestamp to the unit specified by the given string format |
+None |
+project |
+format |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+S |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+date |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+PS UTC is only supported TZ for TIMESTAMP |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+result |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+PS UTC is only supported TZ for TIMESTAMP |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+ |
+
+
UnaryMinus |
`negative` |
Negate a numeric value |
@@ -17926,6 +18074,34 @@ are limited.
|
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
UnboundedPreceding$ |
|
Special boundary for a window frame, indicating all rows preceding the current row |
@@ -18079,34 +18255,6 @@ are limited.
|
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
Upper |
`ucase`, `upper` |
String uppercase operator |
@@ -18357,6 +18505,34 @@ are limited.
NS |
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
XxHash64 |
`xxhash64` |
xxhash64 hash operator |
@@ -18673,34 +18849,6 @@ are limited.
S |
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
ApproximatePercentile |
`approx_percentile`, `percentile_approx` |
Approximate percentile |
@@ -18891,6 +19039,34 @@ are limited.
|
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
Average |
`avg`, `mean` |
Average aggregate operator |
@@ -19181,34 +19357,6 @@ are limited.
|
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
CollectSet |
`collect_set` |
Collect a set of unique elements, not supported in reduction |
@@ -19354,6 +19502,34 @@ are limited.
|
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
Count |
`count` |
Count aggregate operator |
@@ -19638,38 +19814,10 @@ are limited.
NS |
PS UTC is only supported TZ for child TIMESTAMP; unsupported child types CALENDAR, UDT, DAYTIME, YEARMONTH |
PS UTC is only supported TZ for child TIMESTAMP; unsupported child types CALENDAR, UDT, DAYTIME, YEARMONTH |
-PS UTC is only supported TZ for child TIMESTAMP; unsupported child types CALENDAR, UDT, DAYTIME, YEARMONTH |
-NS |
-NS |
-NS |
-
-
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
+PS UTC is only supported TZ for child TIMESTAMP; unsupported child types CALENDAR, UDT, DAYTIME, YEARMONTH |
+NS |
+NS |
+NS |
Last |
@@ -19817,6 +19965,34 @@ are limited.
NS |
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
Max |
`max` |
Max aggregate operator |
@@ -20106,34 +20282,6 @@ are limited.
NS |
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
Min |
`min` |
Min aggregate operator |
@@ -20279,6 +20427,34 @@ are limited.
|
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
MinBy |
`min_by` |
MinBy aggregate operator. It may produce different results than CPU when multiple rows in a group have same minimum value in the ordering column and different associated values in the value column. |
@@ -20613,34 +20789,6 @@ are limited.
|
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
PivotFirst |
|
PivotFirst operator |
@@ -20785,6 +20933,34 @@ are limited.
NS |
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
StddevPop |
`stddev_pop` |
Aggregation computing population standard deviation |
@@ -21075,34 +21251,6 @@ are limited.
|
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
Sum |
`sum` |
Sum aggregate operator |
@@ -21248,6 +21396,34 @@ are limited.
|
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
VariancePop |
`var_pop` |
Aggregation computing population variance |
@@ -21538,34 +21714,6 @@ are limited.
|
-Expression |
-SQL Functions(s) |
-Description |
-Notes |
-Context |
-Param/Output |
-BOOLEAN |
-BYTE |
-SHORT |
-INT |
-LONG |
-FLOAT |
-DOUBLE |
-DATE |
-TIMESTAMP |
-STRING |
-DECIMAL |
-NULL |
-BINARY |
-CALENDAR |
-ARRAY |
-MAP |
-STRUCT |
-UDT |
-DAYTIME |
-YEARMONTH |
-
-
NormalizeNaNAndZero |
|
Normalize NaN and zero |
@@ -21645,6 +21793,34 @@ are limited.
NS |
+Expression |
+SQL Functions(s) |
+Description |
+Notes |
+Context |
+Param/Output |
+BOOLEAN |
+BYTE |
+SHORT |
+INT |
+LONG |
+FLOAT |
+DOUBLE |
+DATE |
+TIMESTAMP |
+STRING |
+DECIMAL |
+NULL |
+BINARY |
+CALENDAR |
+ARRAY |
+MAP |
+STRUCT |
+UDT |
+DAYTIME |
+YEARMONTH |
+
+
HiveGenericUDF |
|
Hive Generic UDF, the UDF can choose to implement a RAPIDS accelerated interface to get better performance |
diff --git a/integration_tests/README.md b/integration_tests/README.md
index f5237de21a0..031b318bddf 100644
--- a/integration_tests/README.md
+++ b/integration_tests/README.md
@@ -263,7 +263,7 @@ individually, so you don't risk running unit tests along with the integration te
http://www.scalatest.org/user_guide/using_the_scalatest_shell
```shell
-spark-shell --jars rapids-4-spark-tests_2.12-24.12.0-SNAPSHOT-tests.jar,rapids-4-spark-integration-tests_2.12-24.12.0-SNAPSHOT-tests.jar,scalatest_2.12-3.0.5.jar,scalactic_2.12-3.0.5.jar
+spark-shell --jars rapids-4-spark-tests_2.12-25.02.0-SNAPSHOT-tests.jar,rapids-4-spark-integration-tests_2.12-25.02.0-SNAPSHOT-tests.jar,scalatest_2.12-3.0.5.jar,scalactic_2.12-3.0.5.jar
```
First you import the `scalatest_shell` and tell the tests where they can find the test files you
@@ -286,7 +286,7 @@ If you just want to verify the SQL replacement is working you will need to add t
assumes CUDA 11.0 is being used and the Spark distribution is built with Scala 2.12.
```
-$SPARK_HOME/bin/spark-submit --jars "rapids-4-spark_2.12-24.12.0-SNAPSHOT-cuda11.jar" ./runtests.py
+$SPARK_HOME/bin/spark-submit --jars "rapids-4-spark_2.12-25.02.0-SNAPSHOT-cuda11.jar" ./runtests.py
```
You don't have to enable the plugin for this to work, the test framework will do that for you.
@@ -443,7 +443,7 @@ To run cudf_udf tests, need following configuration changes:
As an example, here is the `spark-submit` command with the cudf_udf parameter on CUDA 11.0:
```
-$SPARK_HOME/bin/spark-submit --jars "rapids-4-spark_2.12-24.12.0-SNAPSHOT-cuda11.jar,rapids-4-spark-tests_2.12-24.12.0-SNAPSHOT.jar" --conf spark.rapids.memory.gpu.allocFraction=0.3 --conf spark.rapids.python.memory.gpu.allocFraction=0.3 --conf spark.rapids.python.concurrentPythonWorkers=2 --py-files "rapids-4-spark_2.12-24.12.0-SNAPSHOT-cuda11.jar" --conf spark.executorEnv.PYTHONPATH="rapids-4-spark_2.12-24.12.0-SNAPSHOT-cuda11.jar" ./runtests.py --cudf_udf
+$SPARK_HOME/bin/spark-submit --jars "rapids-4-spark_2.12-25.02.0-SNAPSHOT-cuda11.jar,rapids-4-spark-tests_2.12-25.02.0-SNAPSHOT.jar" --conf spark.rapids.memory.gpu.allocFraction=0.3 --conf spark.rapids.python.memory.gpu.allocFraction=0.3 --conf spark.rapids.python.concurrentPythonWorkers=2 --py-files "rapids-4-spark_2.12-25.02.0-SNAPSHOT-cuda11.jar" --conf spark.executorEnv.PYTHONPATH="rapids-4-spark_2.12-25.02.0-SNAPSHOT-cuda11.jar" ./runtests.py --cudf_udf
```
### Enabling fuzz tests
diff --git a/integration_tests/ScaleTest.md b/integration_tests/ScaleTest.md
index d9f47fab5cb..8b91331abc9 100644
--- a/integration_tests/ScaleTest.md
+++ b/integration_tests/ScaleTest.md
@@ -97,7 +97,7 @@ $SPARK_HOME/bin/spark-submit \
--conf spark.sql.parquet.datetimeRebaseModeInWrite=CORRECTED \
--jars $SPARK_HOME/examples/jars/scopt_2.12-3.7.1.jar \
--class com.nvidia.spark.rapids.tests.scaletest.ScaleTest \
-./target/rapids-4-spark-integration-tests_2.12-24.12.0-SNAPSHOT-spark332.jar \
+./target/rapids-4-spark-integration-tests_2.12-25.02.0-SNAPSHOT-spark332.jar \
10 \
100 \
parquet \
diff --git a/integration_tests/pom.xml b/integration_tests/pom.xml
index aaff3455298..6054c30c795 100644
--- a/integration_tests/pom.xml
+++ b/integration_tests/pom.xml
@@ -22,11 +22,11 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-integration-tests_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
integration_tests
diff --git a/integration_tests/src/main/python/date_time_test.py b/integration_tests/src/main/python/date_time_test.py
index 1a7024dac85..d29e6a5b5fa 100644
--- a/integration_tests/src/main/python/date_time_test.py
+++ b/integration_tests/src/main/python/date_time_test.py
@@ -321,7 +321,7 @@ def test_unsupported_fallback_to_unix_timestamp(data_gen):
spark, [("a", data_gen), ("b", string_gen)], length=10).selectExpr(
"to_unix_timestamp(a, b)"),
"ToUnixTimestamp")
-
+
supported_timezones = ["Asia/Shanghai", "UTC", "UTC+0", "UTC-0", "GMT", "GMT+0", "GMT-0", "EST", "MST", "VST"]
unsupported_timezones = ["PST", "NST", "AST", "America/Los_Angeles", "America/New_York", "America/Chicago"]
@@ -681,7 +681,7 @@ def test_unsupported_fallback_to_date():
conf)
-# (-62135510400, 253402214400) is the range of seconds that can be represented by timestamp_seconds
+# (-62135510400, 253402214400) is the range of seconds that can be represented by timestamp_seconds
# considering the influence of time zone.
ts_float_gen = SetValuesGen(FloatType(), [0.0, -0.0, 1.0, -1.0, 1.234567, -1.234567, 16777215.0, float('inf'), float('-inf'), float('nan')])
seconds_gens = [LongGen(min_val=-62135510400, max_val=253402214400), IntegerGen(), ShortGen(), ByteGen(),
@@ -710,7 +710,7 @@ def test_timestamp_seconds_rounding_necessary(data_gen):
lambda spark : unary_op_df(spark, data_gen).selectExpr("timestamp_seconds(a)").collect(),
conf={},
error_message='Rounding necessary')
-
+
@pytest.mark.parametrize('data_gen', [DecimalGen(19, 6), DecimalGen(20, 6)], ids=idfn)
@allow_non_gpu(*non_utc_allow)
def test_timestamp_seconds_decimal_overflow(data_gen):
@@ -725,7 +725,7 @@ def test_timestamp_seconds_decimal_overflow(data_gen):
def test_timestamp_millis(data_gen):
assert_gpu_and_cpu_are_equal_collect(
lambda spark : unary_op_df(spark, data_gen).selectExpr("timestamp_millis(a)"))
-
+
@allow_non_gpu(*non_utc_allow)
def test_timestamp_millis_long_overflow():
assert_gpu_and_cpu_error(
@@ -751,3 +751,70 @@ def test_date_to_timestamp(parser_policy):
conf = {
"spark.sql.legacy.timeParserPolicy": parser_policy,
"spark.rapids.sql.incompatibleDateFormats.enabled": True})
+
+# Generate format strings, which are case insensitive and have some garbage rows.
+trunc_date_format_gen = StringGen('(?i:YEAR|YYYY|YY|QUARTER|MONTH|MM|MON|WEEK)') \
+ .with_special_pattern('invalid', weight=50)
+trunc_timestamp_format_gen = StringGen('(?i:YEAR|YYYY|YY|QUARTER|MONTH|MM|MON|WEEK|DAY|DD|HOUR|MINUTE|SECOND|MILLISECOND|MICROSECOND)') \
+ .with_special_pattern('invalid', weight=50)
+
+@pytest.mark.parametrize('data_gen', [date_gen], ids=idfn)
+@pytest.mark.parametrize('format_gen', [trunc_date_format_gen], ids=idfn)
+def test_trunc_date_full_input(data_gen, format_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : two_col_df(spark, data_gen, format_gen).selectExpr('trunc(a, b)'))
+
+@allow_non_gpu(*non_utc_tz_allow)
+@pytest.mark.parametrize('format_gen', [trunc_timestamp_format_gen], ids=idfn)
+@pytest.mark.parametrize('data_gen', [timestamp_gen], ids=idfn)
+def test_trunc_timestamp_full_input(format_gen, data_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : two_col_df(spark, format_gen, data_gen).selectExpr('date_trunc(a, b)'))
+
+@pytest.mark.parametrize('format_gen', [trunc_date_format_gen], ids=idfn)
+def test_trunc_date_single_value(format_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : unary_op_df(spark, format_gen).selectExpr('trunc("1980-05-18", a)'))
+
+@allow_non_gpu(*non_utc_tz_allow)
+@pytest.mark.parametrize('format_gen', [trunc_timestamp_format_gen], ids=idfn)
+def test_trunc_timestamp_single_value(format_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : unary_op_df(spark, format_gen).selectExpr(
+ 'date_trunc(a, "1980-05-18T09:32:05.359")'))
+
+@pytest.mark.parametrize('data_gen', [date_gen], ids=idfn)
+def test_trunc_date_single_format(data_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : unary_op_df(spark, data_gen).selectExpr(
+ 'trunc(a, "YEAR")',
+ 'trunc(a, "YYYY")',
+ 'trunc(a, "YY")',
+ 'trunc(a, "QUARTER")',
+ 'trunc(a, "MONTH")',
+ 'trunc(a, "MM")',
+ 'trunc(a, "MON")',
+ 'trunc(a, "WEEK")',
+ 'trunc(a, "invalid")'))
+
+@allow_non_gpu(*non_utc_tz_allow)
+@pytest.mark.parametrize('data_gen', [timestamp_gen], ids=idfn)
+def test_trunc_timestamp_single_format(data_gen):
+ assert_gpu_and_cpu_are_equal_collect(
+ lambda spark : unary_op_df(spark, data_gen).selectExpr(
+ 'date_trunc("YEAR", a)',
+ 'date_trunc("YYYY", a)',
+ 'date_trunc("YY", a)',
+ 'date_trunc("QUARTER", a)',
+ 'date_trunc("MONTH", a)',
+ 'date_trunc("MM", a)',
+ 'date_trunc("MON", a)',
+ 'date_trunc("WEEK", a)',
+ 'date_trunc("DAY", a)',
+ 'date_trunc("DD", a)',
+ 'date_trunc("HOUR", a)',
+ 'date_trunc("MINUTE", a)',
+ 'date_trunc("SECOND", a)',
+ 'date_trunc("MILLISECOND", a)',
+ 'date_trunc("MICROSECOND", a)',
+ 'date_trunc("invalid", a)'))
diff --git a/integration_tests/src/main/python/join_test.py b/integration_tests/src/main/python/join_test.py
index 936310bedeb..96021421d62 100644
--- a/integration_tests/src/main/python/join_test.py
+++ b/integration_tests/src/main/python/join_test.py
@@ -22,7 +22,8 @@
from marks import ignore_order, allow_non_gpu, incompat, validate_execs_in_gpu_plan
from spark_session import with_cpu_session, is_before_spark_330, is_databricks_runtime
-pytestmark = [pytest.mark.nightly_resource_consuming_test]
+# mark this test as ci_1 for mvn verify sanity check in pre-merge CI
+pytestmark = [pytest.mark.nightly_resource_consuming_test, pytest.mark.premerge_ci_1]
all_non_sized_join_types = ['LeftSemi', 'LeftAnti', 'Cross']
all_symmetric_sized_join_types = ['Inner', 'FullOuter']
diff --git a/integration_tests/src/main/python/json_test.py b/integration_tests/src/main/python/json_test.py
index 6e8165846e7..726225346f5 100644
--- a/integration_tests/src/main/python/json_test.py
+++ b/integration_tests/src/main/python/json_test.py
@@ -23,6 +23,9 @@
from marks import approximate_float, allow_non_gpu, ignore_order, datagen_overrides
from spark_session import *
+# mark this test as ci_1 for mvn verify sanity check in pre-merge CI
+pytestmark = [pytest.mark.premerge_ci_1]
+
TEXT_INPUT_EXEC='FileSourceScanExec'
# allow non gpu when time zone is non-UTC because of https://github.com/NVIDIA/spark-rapids/issues/9653'
@@ -1009,7 +1012,6 @@ def test_from_json_struct_of_list_with_mismatched_schema():
'struct>>',
'struct>>'])
@allow_non_gpu(*non_utc_allow)
-@pytest.mark.xfail(reason='https://github.com/rapidsai/cudf/issues/17349')
def test_from_json_struct_of_list_with_mixed_nested_types_input(schema):
json_string_gen = StringGen(r'{"teacher": "[A-Z]{1}[a-z]{2,5}",' \
r'"student": \[{"name": "[A-Z]{1}[a-z]{2,5}", "class": "junior"},' \
@@ -1396,7 +1398,6 @@ def test_spark_from_json_empty_table(data):
conf =_enable_all_types_conf)
# SPARK-20549: from_json bad UTF-8
-@pytest.mark.xfail(reason='https://github.com/NVIDIA/spark-rapids/issues/10483')
@allow_non_gpu(*non_utc_allow) # https://github.com/NVIDIA/spark-rapids/issues/10453
def test_spark_from_json_bad_json():
schema = StructType([StructField("a", IntegerType())])
diff --git a/integration_tests/src/main/python/parquet_test.py b/integration_tests/src/main/python/parquet_test.py
index 6aa234003ba..a43d48e5ce9 100644
--- a/integration_tests/src/main/python/parquet_test.py
+++ b/integration_tests/src/main/python/parquet_test.py
@@ -28,6 +28,8 @@
from spark_session import *
from conftest import is_databricks_runtime, is_dataproc_runtime
+# mark this test as ci_1 for mvn verify sanity check in pre-merge CI
+pytestmark = [pytest.mark.premerge_ci_1]
def read_parquet_df(data_path):
return lambda spark : spark.read.parquet(data_path)
diff --git a/integration_tests/src/main/python/regexp_test.py b/integration_tests/src/main/python/regexp_test.py
index c2062605ca1..b67f9dc6679 100644
--- a/integration_tests/src/main/python/regexp_test.py
+++ b/integration_tests/src/main/python/regexp_test.py
@@ -1012,14 +1012,16 @@ def test_regexp_replace_simple(regexp_enabled):
'REGEXP_REPLACE(a, "ab", "PROD")',
'REGEXP_REPLACE(a, "ae", "PROD")',
'REGEXP_REPLACE(a, "bc", "PROD")',
- 'REGEXP_REPLACE(a, "fa", "PROD")'
+ 'REGEXP_REPLACE(a, "fa", "PROD")',
+ 'REGEXP_REPLACE(a, "a\n", "PROD")',
+ 'REGEXP_REPLACE(a, "\n", "PROD")'
),
conf=conf
)
@pytest.mark.parametrize("regexp_enabled", ['true', 'false'])
def test_regexp_replace_multi_optimization(regexp_enabled):
- gen = mk_str_gen('[abcdef]{0,2}')
+ gen = mk_str_gen('[abcdef\t\n\a]{0,3}')
conf = { 'spark.rapids.sql.regexp.enabled': regexp_enabled }
@@ -1032,7 +1034,9 @@ def test_regexp_replace_multi_optimization(regexp_enabled):
'REGEXP_REPLACE(a, "aa|bb|cc|dd", "PROD")',
'REGEXP_REPLACE(a, "(aa|bb)|(cc|dd)", "PROD")',
'REGEXP_REPLACE(a, "aa|bb|cc|dd|ee", "PROD")',
- 'REGEXP_REPLACE(a, "aa|bb|cc|dd|ee|ff", "PROD")'
+ 'REGEXP_REPLACE(a, "aa|bb|cc|dd|ee|ff", "PROD")',
+ 'REGEXP_REPLACE(a, "a\n|b\a|c\t", "PROD")',
+ 'REGEXP_REPLACE(a, "a\ta|b\nb", "PROD")'
),
conf=conf
)
diff --git a/integration_tests/src/main/python/window_function_test.py b/integration_tests/src/main/python/window_function_test.py
index 7695c1adc9d..f792bd2304d 100644
--- a/integration_tests/src/main/python/window_function_test.py
+++ b/integration_tests/src/main/python/window_function_test.py
@@ -24,6 +24,9 @@
from spark_session import is_before_spark_320, is_databricks113_or_later, is_databricks133_or_later, is_spark_350_or_later, spark_version, with_cpu_session
import warnings
+# mark this test as ci_1 for mvn verify sanity check in pre-merge CI
+pytestmark = [pytest.mark.premerge_ci_1]
+
_grpkey_longs_with_no_nulls = [
('a', RepeatSeqGen(LongGen(nullable=False), length=20)),
('b', IntegerGen()),
diff --git a/jdk-profiles/pom.xml b/jdk-profiles/pom.xml
index caaa47245a8..b45da24bd58 100644
--- a/jdk-profiles/pom.xml
+++ b/jdk-profiles/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
com.nvidia
rapids-4-spark-jdk-profiles_2.12
pom
Shim JDK Profiles
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
jdk8
diff --git a/jenkins/Jenkinsfile-blossom.premerge b/jenkins/Jenkinsfile-blossom.premerge
index 474b14e66c4..ce8d9f2be28 100755
--- a/jenkins/Jenkinsfile-blossom.premerge
+++ b/jenkins/Jenkinsfile-blossom.premerge
@@ -39,6 +39,8 @@ def skipped = false
def db_build = false
def sourcePattern = 'shuffle-plugin/src/main/scala/,udf-compiler/src/main/scala/,' +
'sql-plugin/src/main/java/,sql-plugin/src/main/scala/'
+// The path where the CI_PART1 job shares rapids plugin built tars with the CI_PART job
+def plugin_built_dir = "dbfs:/cicd/$BUILD_TAG"
pipeline {
agent {
@@ -281,12 +283,14 @@ git --no-pager diff --name-only HEAD \$BASE -- ${PREMERGE_DOCKERFILE} || true"""
steps {
script {
githubHelper.updateCommitStatus("", "Running - includes databricks", GitHubCommitState.PENDING)
+ //CI_PART1 upload plugin buit tars to PLUGIN_BUILT_DIR for CI_PART2
def DBJob = build(job: 'rapids-databricks_premerge-github',
propagate: false, wait: true,
parameters: [
string(name: 'REF', value: params.REF),
string(name: 'GITHUB_DATA', value: params.GITHUB_DATA),
- string(name: 'TEST_MODE', value: 'CI_PART1')
+ string(name: 'TEST_MODE', value: 'CI_PART1'),
+ string(name: 'PLUGIN_BUILT_DIR', value: "$plugin_built_dir"),
])
if ( DBJob.result != 'SUCCESS' ) {
// Output Databricks failure logs to uploaded onto the pre-merge PR
@@ -310,7 +314,8 @@ git --no-pager diff --name-only HEAD \$BASE -- ${PREMERGE_DOCKERFILE} || true"""
parameters: [
string(name: 'REF', value: params.REF),
string(name: 'GITHUB_DATA', value: params.GITHUB_DATA),
- string(name: 'TEST_MODE', value: 'CI_PART2')
+ string(name: 'TEST_MODE', value: 'CI_PART2'),
+ string(name: 'PLUGIN_BUILT_DIR', value: "$plugin_built_dir"),
])
if ( DBJob.result != 'SUCCESS' ) {
// Output Databricks failure logs to uploaded onto the pre-merge PR
diff --git a/jenkins/Jenkinsfile-blossom.premerge-databricks b/jenkins/Jenkinsfile-blossom.premerge-databricks
index 2f8b926898a..7e0e4389cac 100644
--- a/jenkins/Jenkinsfile-blossom.premerge-databricks
+++ b/jenkins/Jenkinsfile-blossom.premerge-databricks
@@ -53,6 +53,8 @@ pipeline {
description: 'Json-formatted github data from upstream blossom-ci')
choice(name: 'TEST_MODE', choices: ['CI_PART1', 'CI_PART2'],
description: 'Separate integration tests into 2 parts, and run each part in parallell')
+ string(name: 'PLUGIN_BUILT_DIR', defaultValue: 'dbfs:/cicd',
+ description: 'CI_PART1 uploads spark-rapids built tgz for CI_PART2')
}
environment {
@@ -68,7 +70,7 @@ pipeline {
DATABRICKS_PUBKEY = credentials("SPARK_DATABRICKS_PUBKEY")
DATABRICKS_DRIVER = DbUtils.getDriver("$DB_TYPE")
DATABRICKS_WORKER = DbUtils.getWorker("$DB_TYPE")
- INIT_SCRIPTS_DIR = "/databricks/init_scripts/${BUILD_TAG}"
+ TEST_TYPE = 'pre-commit'
}
stages {
@@ -77,7 +79,7 @@ pipeline {
script {
githubHelper = GithubHelper.getInstance("${GITHUB_TOKEN}", params.GITHUB_DATA)
// desc contains the PR ID and can be accessed from different builds
- currentBuild.description = githubHelper.getBuildDescription()
+ currentBuild.description = githubHelper.getBuildDescription() + " | $TEST_MODE"
checkoutCode(githubHelper.getCloneUrl(), githubHelper.getMergedSHA())
}
}
@@ -110,12 +112,16 @@ pipeline {
BASE_SPARK_VERSION = DbUtils.getSparkVer("$DB_RUNTIME")
BASE_SPARK_VERSION_TO_INSTALL_DATABRICKS_JARS = DbUtils.getInstallVer("$DB_RUNTIME")
INIT_SCRIPTS = DbUtils.getInitScripts("$DB_RUNTIME")
+ INIT_SCRIPTS_DIR = "/databricks/init_scripts/${BUILD_TAG}-${DB_RUNTIME}"
+ EXTRA_ENVS = "TEST_MODE=$TEST_MODE"
}
steps {
script {
- unstash('source_tree')
- databricksBuild()
- deleteDir() // cleanup content if no error
+ container('cpu') {
+ unstash('source_tree')
+ databricksBuild()
+ deleteDir() // cleanup content if no error
+ }
}
}
}
@@ -133,79 +139,70 @@ String getDbType() {
void databricksBuild() {
def CLUSTER_ID = ''
def SPARK_MAJOR = BASE_SPARK_VERSION_TO_INSTALL_DATABRICKS_JARS.replace('.', '')
- def ws_path = "$INIT_SCRIPTS_DIR-$DB_TYPE"
- try {
- stage("Create $SPARK_MAJOR DB") {
- script {
- container('cpu') {
- sh "rm -rf spark-rapids-ci.tgz"
- sh "tar -zcf spark-rapids-ci.tgz *"
- def CREATE_PARAMS = " -r $DATABRICKS_RUNTIME -w $DATABRICKS_HOST -t $DATABRICKS_TOKEN" +
- " -s $DB_TYPE -n CI-${BUILD_TAG}-${BASE_SPARK_VERSION} -k \"$DATABRICKS_PUBKEY\" -i $IDLE_TIMEOUT" +
- " -d $DATABRICKS_DRIVER -o $DATABRICKS_WORKER -e $NUM_WORKERS"
-
- // handle init scripts if exist
- if (env.INIT_SCRIPTS) {
- // foo.sh,bar.sh --> /path/foo.sh,/path/bar.sh
- CREATE_PARAMS += " -f " + DbUtils.uploadFiles(this, env.INIT_SCRIPTS, ws_path)
- }
+ def dbStep = ''
+ def pluginBuiltTar = "$PLUGIN_BUILT_DIR/$DB_RUNTIME/spark-rapids-built.tgz"
+ // Map DBFS path to the local path into the cluster
+ def buildArgs = (params.TEST_MODE == 'CI_PART1') ? pluginBuiltTar.replace('dbfs:/', '/dbfs/') : ''
+ def testArgs = (params.TEST_MODE == 'CI_PART2') ? pluginBuiltTar.replace('dbfs:/', '/dbfs/') : ''
- CLUSTER_ID = sh(script: "python3 ./jenkins/databricks/create.py $CREATE_PARAMS",
- returnStdout: true).trim()
- echo CLUSTER_ID
- }
+ try {
+ // wait for all the rapids plugin tars built in CI_PART1 to be ready
+ if (params.TEST_MODE == 'CI_PART2') {
+ // Check if the comma-separated files exist in the Databricks DBFS path within timeout minutes
+ if (DbUtils.filesExist(this, "$pluginBuiltTar", 60)) {
+ println('Rapids plugin built tars are ready for CI_PART2')
+ } else {
+ println('Rapids plugin built tars are not ready, CI_PART2 starts building them')
+ testArgs = '' // To let CI_PART2 build rapids plugin after the timeout
+ buildArgs = '' // To let CI_PART2 NOT upload plugin tars
}
}
- stage("Build against $SPARK_MAJOR DB") {
- script {
- container('cpu') {
- withCredentials([file(credentialsId: 'SPARK_DATABRICKS_PRIVKEY', variable: 'DATABRICKS_PRIVKEY')]) {
- def BUILD_PARAMS = " -w $DATABRICKS_HOST -t $DATABRICKS_TOKEN -c $CLUSTER_ID -z ./spark-rapids-ci.tgz" +
- " -p $DATABRICKS_PRIVKEY -l ./jenkins/databricks/build.sh -d /home/ubuntu/build.sh" +
- " -v $BASE_SPARK_VERSION -i $BASE_SPARK_VERSION_TO_INSTALL_DATABRICKS_JARS"
-
- // add retry for build step to try
- // mitigate the issue of downloading dependencies while maven/sonatype is quite unstable
- retry(3) {
- sh "python3 ./jenkins/databricks/run-build.py $BUILD_PARAMS"
- }
+ stage("Create $SPARK_MAJOR DB") {
+ dbStep = 'CREATE'
+ // Add the init_script parameter, e.g. oo.sh,bar.sh --> /path/foo.sh,/path/bar.sh
+ def input_params = env.INIT_SCRIPTS ? " -f " + DbUtils.uploadFiles(this, env.INIT_SCRIPTS, env.INIT_SCRIPTS_DIR) : ''
+ def CREATE_PARAMS = DbUtils.getParameters(this, dbStep, input_params)
+ CLUSTER_ID = sh(script: "python3 ./jenkins/databricks/create.py $CREATE_PARAMS", returnStdout: true).trim()
+ echo CLUSTER_ID
+ }
+
+ if (params.TEST_MODE == 'CI_PART1' || (params.TEST_MODE == 'CI_PART2' && testArgs == '')) {
+ stage("Build against $SPARK_MAJOR DB") {
+ sh "rm -rf spark-rapids-ci.tgz"
+ sh "tar -zcf spark-rapids-ci.tgz * .git"
+ dbStep = 'BUILD'
+ withCredentials([file(credentialsId: 'SPARK_DATABRICKS_PRIVKEY', variable: 'DATABRICKS_PRIVKEY')]) {
+ def BUILD_PARAMS = DbUtils.getParameters(this, dbStep, "-c $CLUSTER_ID")
+ retry(3) {
+ // Back-up built tar to the path "$buildArgs" on Databricks cluster
+ // Refer to https://github.com/NVIDIA/spark-rapids/pull/11788/files#diff-dd60414e554e6bed881c3a7e14de334f3e52f36f81643412cd2497c275f8aee9R190-R194
+ sh "python3 ./jenkins/databricks/run-build.py $BUILD_PARAMS $buildArgs"
}
}
+ sh "rm spark-rapids-ci.tgz"
}
}
// TODO: Temporarily skip tests on Databricks 14.3 until the test failures are fixed
if (env.DB_RUNTIME != '14.3') {
stage("Test agaist $SPARK_MAJOR DB") {
- script {
- container('cpu') {
- try {
- withCredentials([file(credentialsId: 'SPARK_DATABRICKS_PRIVKEY', variable: 'DATABRICKS_PRIVKEY')]) {
- def TEST_PARAMS = " -w $DATABRICKS_HOST -t $DATABRICKS_TOKEN -c $CLUSTER_ID -e TEST_MODE=$TEST_MODE" +
- " -p $DATABRICKS_PRIVKEY -l ./jenkins/databricks/test.sh -v $BASE_SPARK_VERSION -d /home/ubuntu/test.sh"
- if (params.SPARK_CONF) {
- TEST_PARAMS += " -f ${params.SPARK_CONF}"
- }
- sh "python3 ./jenkins/databricks/run-tests.py $TEST_PARAMS"
- }
- } finally {
- common.publishPytestResult(this, "${STAGE_NAME}")
- }
- }
+ dbStep = 'TEST'
+ withCredentials([file(credentialsId: 'SPARK_DATABRICKS_PRIVKEY', variable: 'DATABRICKS_PRIVKEY')]) {
+ def TEST_PARAMS = DbUtils.getParameters(this, dbStep, "-c $CLUSTER_ID")
+ // Get built tar from the path "$testArgs" on Databricks cluster
+ // Refer to https://github.com/NVIDIA/spark-rapids/pull/11788/files#diff-db28879431d57d0e454a2c7ee89fdda9abdec463c61771333d6a6565bf96c062R52-R55
+ sh "python3 ./jenkins/databricks/run-tests.py $TEST_PARAMS $testArgs"
}
}
}
-
} finally {
if (CLUSTER_ID) {
- container('cpu') {
- retry(3) {
- if (env.INIT_SCRIPTS) {
- DbUtils.cleanUp(this, ws_path)
- }
- sh "python3 ./jenkins/databricks/shutdown.py -s $DATABRICKS_HOST -t $DATABRICKS_TOKEN -c $CLUSTER_ID -d"
- }
+ (dbStep == 'TEST') ? common.publishPytestResult(this, "Test against $SPARK_MAJOR DB") : ''
+ retry(3) {
+ params.TEST_MODE == 'CI_PART2' ? DbUtils.cleanUp(this, "$PLUGIN_BUILT_DIR/$DB_RUNTIME") : ''
+ env.INIT_SCRIPTS ? DbUtils.cleanUp(this, env.INIT_SCRIPTS_DIR) : ''
+ sh "python3 ./jenkins/databricks/shutdown.py -s $DATABRICKS_HOST -t $DATABRICKS_TOKEN -c $CLUSTER_ID -d"
}
}
}
diff --git a/jenkins/databricks/build.sh b/jenkins/databricks/build.sh
index f6ff6e913b6..baec99bb015 100755
--- a/jenkins/databricks/build.sh
+++ b/jenkins/databricks/build.sh
@@ -178,5 +178,17 @@ if [[ "$WITH_DEFAULT_UPSTREAM_SHIM" != "0" ]]; then
-Dincluded_buildvers=$UPSTREAM_BUILDVER,$BUILDVER
fi
+# "Delete the unused object files to reduce the size of the Spark Rapids built tar."
+rm -rf dist/target/jni-deps/
+find dist/target/parallel-world/ -mindepth 1 -maxdepth 1 ! -name META-INF -exec rm -rf {} +
+
cd /home/ubuntu
tar -zcf spark-rapids-built.tgz spark-rapids
+
+# Back up spark rapids built jars for the CI_PART2 job to run integration tests
+TEST_MODE=${TEST_MODE:-'DEFAULT'}
+PLUGIN_BUILT_TGZ=${PLUGIN_BUILT_TGZ:-"$1"}
+if [[ "$TEST_MODE" == "CI_PART1" && -n "$PLUGIN_BUILT_TGZ" ]]; then
+ mkdir -p $(dirname $PLUGIN_BUILT_TGZ)
+ cp spark-rapids-built.tgz $PLUGIN_BUILT_TGZ
+fi
diff --git a/jenkins/databricks/create.py b/jenkins/databricks/create.py
index 44c4c856466..7815f170dfb 100644
--- a/jenkins/databricks/create.py
+++ b/jenkins/databricks/create.py
@@ -27,7 +27,7 @@ def main():
workspace = 'https://dbc-9ff9942e-a9c4.cloud.databricks.com'
token = ''
sshkey = ''
- cluster_name = 'CI-GPU-databricks-24.12.0-SNAPSHOT'
+ cluster_name = 'CI-GPU-databricks-25.02.0-SNAPSHOT'
idletime = 240
runtime = '13.3.x-gpu-ml-scala2.12'
num_workers = 1
diff --git a/jenkins/databricks/init_cudf_udf.sh b/jenkins/databricks/init_cudf_udf.sh
index 16b90b95c0e..0898c230d48 100755
--- a/jenkins/databricks/init_cudf_udf.sh
+++ b/jenkins/databricks/init_cudf_udf.sh
@@ -20,7 +20,7 @@
set -ex
-CUDF_VER=${CUDF_VER:-24.12}
+CUDF_VER=${CUDF_VER:-25.02}
CUDA_VER=${CUDA_VER:-11.8}
# Need to explicitly add conda into PATH environment, to activate conda environment.
diff --git a/jenkins/databricks/params.py b/jenkins/databricks/params.py
index dce2436a6e6..183ae846208 100644
--- a/jenkins/databricks/params.py
+++ b/jenkins/databricks/params.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2023, NVIDIA CORPORATION.
+# Copyright (c) 2021-2024, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -33,6 +33,8 @@
spark_conf = ''
# can take comma separated environments, e.g., foo=abc,bar=123,...'
extra_envs = ''
+# 'nightly' is for nightly CI, 'pre-commit' is for the pre-merge CI
+test_type = 'nightly'
def usage():
@@ -51,11 +53,12 @@ def usage():
' -n '
' -f '
' -i '
- ' -e ')
+ ' -e '
+ ' -m ')
try:
- opts, script_args = getopt.getopt(sys.argv[1:], 'hw:t:c:p:l:d:z:m:v:b:j:f:i:e:',
+ opts, script_args = getopt.getopt(sys.argv[1:], 'hw:t:c:p:l:d:z:m:v:b:j:f:i:e:m:',
['workspace=',
'token=',
'clusterid=',
@@ -68,7 +71,8 @@ def usage():
'jarpath=',
'sparkconf=',
'sparkinstallver=',
- 'extraenvs='])
+ 'extraenvs=',
+ 'testtype='])
except getopt.GetoptError:
usage()
sys.exit(2)
@@ -103,6 +107,8 @@ def usage():
base_spark_version_to_install_databricks_jars = arg
elif opt in ('-e', '--extraenvs'):
extra_envs = arg
+ elif opt in ('-m', '--testtype'):
+ test_type = arg
print('-w is ' + workspace)
print('-c is ' + clusterid)
@@ -116,3 +122,4 @@ def usage():
print('-f is ' + spark_conf)
print('-i is ' + base_spark_version_to_install_databricks_jars)
print('-e is ' + extra_envs)
+print('-m is ' + test_type)
diff --git a/jenkins/databricks/run-build.py b/jenkins/databricks/run-build.py
index 277c4f7024c..45d5dcea1bd 100644
--- a/jenkins/databricks/run-build.py
+++ b/jenkins/databricks/run-build.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2023, NVIDIA CORPORATION.
+# Copyright (c) 2021-2024, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -46,10 +46,12 @@ def main():
print("ssh command: %s" % ssh_command)
subprocess.check_call(ssh_command, shell = True)
- print("Copying built tarball back")
- rsync_command = "rsync -I -Pave \"ssh %s\" ubuntu@%s:/home/ubuntu/spark-rapids-built.tgz ./" % (ssh_args, master_addr)
- print("rsync command to get built tarball: %s" % rsync_command)
- subprocess.check_call(rsync_command, shell = True)
+ # Only the nightly build needs to copy the spark-rapids-built.tgz back
+ if params.test_type == 'nightly':
+ print("Copying built tarball back")
+ rsync_command = "rsync -I -Pave \"ssh %s\" ubuntu@%s:/home/ubuntu/spark-rapids-built.tgz ./" % (ssh_args, master_addr)
+ print("rsync command to get built tarball: %s" % rsync_command)
+ subprocess.check_call(rsync_command, shell = True)
if __name__ == '__main__':
main()
diff --git a/jenkins/databricks/run-tests.py b/jenkins/databricks/run-tests.py
index cd0f8f0e04c..5d02f504061 100644
--- a/jenkins/databricks/run-tests.py
+++ b/jenkins/databricks/run-tests.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2023, NVIDIA CORPORATION.
+# Copyright (c) 2020-2024, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -37,9 +37,9 @@ def main():
subprocess.check_call(rsync_command, shell=True)
ssh_command = "ssh %s ubuntu@%s " % (ssh_args, master_addr) + \
- "'LOCAL_JAR_PATH=%s SPARK_CONF=%s BASE_SPARK_VERSION=%s EXTRA_ENVS=%s bash %s %s 2>&1 | tee testout; " \
+ "'LOCAL_JAR_PATH=%s SPARK_CONF=%s BASE_SPARK_VERSION=%s EXTRA_ENVS=%s TEST_TYPE=%s bash %s %s 2>&1 | tee testout; " \
"if [ ${PIPESTATUS[0]} -ne 0 ]; then false; else true; fi'" % \
- (params.jar_path, params.spark_conf, params.base_spark_pom_version, params.extra_envs,
+ (params.jar_path, params.spark_conf, params.base_spark_pom_version, params.extra_envs, params.test_type,
params.script_dest, ' '.join(params.script_args))
print("ssh command: %s" % ssh_command)
try:
diff --git a/jenkins/databricks/test.sh b/jenkins/databricks/test.sh
index 38728161d12..abe09b226b4 100755
--- a/jenkins/databricks/test.sh
+++ b/jenkins/databricks/test.sh
@@ -38,6 +38,22 @@
set -ex
+## 'foo=abc,bar=123,...' to 'export foo=abc bar=123 ...'
+[[ -n "$EXTRA_ENVS" ]] && export ${EXTRA_ENVS//','/' '}
+# TEST_MODE
+# - DEFAULT: all tests except cudf_udf tests
+# - DELTA_LAKE_ONLY: delta_lake tests only
+# - MULTITHREADED_SHUFFLE: shuffle tests only
+# - PYARROW_ONLY: pyarrow tests only
+# - CI_PART1 or CI_PART2 : part1 or part2 of the tests run in parallel from CI
+TEST_MODE=${TEST_MODE:-'DEFAULT'}
+
+# CI_PART2 untars the spark-rapids tgz built by C1_PART1 instead of rebuilding it
+PLUGIN_BUILT_TGZ=${PLUGIN_BUILT_TGZ:-"$1"}
+if [[ "$TEST_MODE" == "CI_PART2" && -z "$LOCAL_JAR_PATH" && -f "$PLUGIN_BUILT_TGZ" ]]; then
+ tar -zxf $PLUGIN_BUILT_TGZ
+fi
+
SOURCE_PATH="/home/ubuntu/spark-rapids"
[[ -d "$LOCAL_JAR_PATH" ]] && cd $LOCAL_JAR_PATH || cd $SOURCE_PATH
@@ -54,15 +70,6 @@ WITH_DEFAULT_UPSTREAM_SHIM=${WITH_DEFAULT_UPSTREAM_SHIM:-1}
IS_SPARK_321_OR_LATER=0
[[ "$(printf '%s\n' "3.2.1" "$BASE_SPARK_VERSION" | sort -V | head -n1)" = "3.2.1" ]] && IS_SPARK_321_OR_LATER=1
-
-# TEST_MODE
-# - DEFAULT: all tests except cudf_udf tests
-# - DELTA_LAKE_ONLY: delta_lake tests only
-# - MULTITHREADED_SHUFFLE: shuffle tests only
-# - PYARROW_ONLY: pyarrow tests only
-# - CI_PART1 or CI_PART2 : part1 or part2 of the tests run in parallel from CI
-TEST_MODE=${TEST_MODE:-'DEFAULT'}
-
# Classloader config is here to work around classloader issues with
# --packages in distributed setups, should be fixed by
# https://github.com/NVIDIA/spark-rapids/pull/5646
diff --git a/jenkins/version-def.sh b/jenkins/version-def.sh
index 8600a2f8689..6c9a9fac4cb 100755
--- a/jenkins/version-def.sh
+++ b/jenkins/version-def.sh
@@ -29,8 +29,8 @@ IFS=$PRE_IFS
CUDA_CLASSIFIER=${CUDA_CLASSIFIER:-"cuda11"}
CLASSIFIER=${CLASSIFIER:-"$CUDA_CLASSIFIER"} # default as CUDA_CLASSIFIER for compatibility
-PROJECT_VER=${PROJECT_VER:-"24.12.0-SNAPSHOT"}
-PROJECT_TEST_VER=${PROJECT_TEST_VER:-"24.12.0-SNAPSHOT"}
+PROJECT_VER=${PROJECT_VER:-"25.02.0-SNAPSHOT"}
+PROJECT_TEST_VER=${PROJECT_TEST_VER:-"25.02.0-SNAPSHOT"}
SPARK_VER=${SPARK_VER:-"3.2.0"}
SPARK_VER_213=${SPARK_VER_213:-"3.3.0"}
# Make a best attempt to set the default value for the shuffle shim.
diff --git a/pom.xml b/pom.xml
index 12828404031..bcfaf4f04af 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
rapids-4-spark-parent_2.12
RAPIDS Accelerator for Apache Spark Root Project
The root project of the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
pom
https://nvidia.github.io/spark-rapids/
@@ -813,8 +813,7 @@
-
- 350db143
+
.
@@ -829,8 +828,8 @@
spark${buildver}
cuda11
${cuda.version}
- 24.12.0-SNAPSHOT
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
2.12
2.8.0
incremental
@@ -937,13 +936,14 @@
Build and run unit tests on one specific version for each sub-version (e.g. 320, 330)
Base shim version (320 currently) should be covered in default mvn verify command of premerge script,
so base shim version is removed from the premergeUT list.
- Separate the versions to two parts (premergeUT1, premergeUT2) for balancing the duration
+ Separate the versions to two parts: premergeUT1(2 shims' UT + 1/3 of the integration tests)
+ and premergeUT2(1 shim's UT + 2/3 of the integration tests), for balancing the duration
-->
- 320
+ 320,
+ 330
- 330,
340
diff --git a/python/rapids/daemon.py b/python/rapids/daemon.py
index 31353bd92ab..3d00e609255 100644
--- a/python/rapids/daemon.py
+++ b/python/rapids/daemon.py
@@ -1,3 +1,4 @@
+# Copyright (c) 2024, NVIDIA CORPORATION.
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
diff --git a/python/rapids/daemon_databricks.py b/python/rapids/daemon_databricks.py
index 9f4552886e2..fd71bb06f4c 100644
--- a/python/rapids/daemon_databricks.py
+++ b/python/rapids/daemon_databricks.py
@@ -1,3 +1,4 @@
+# Copyright (c) 2024, NVIDIA CORPORATION.
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
diff --git a/scala2.13/aggregator/pom.xml b/scala2.13/aggregator/pom.xml
index 74956108068..d9db5bcf14e 100644
--- a/scala2.13/aggregator/pom.xml
+++ b/scala2.13/aggregator/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark-aggregator_2.13
RAPIDS Accelerator for Apache Spark Aggregator
Creates an aggregated shaded package of the RAPIDS plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
aggregator
diff --git a/scala2.13/api_validation/pom.xml b/scala2.13/api_validation/pom.xml
index f236345c301..2a2e08c6071 100644
--- a/scala2.13/api_validation/pom.xml
+++ b/scala2.13/api_validation/pom.xml
@@ -22,11 +22,11 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-api-validation_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
api_validation
diff --git a/scala2.13/datagen/pom.xml b/scala2.13/datagen/pom.xml
index d53ebc014c7..e8a07a79841 100644
--- a/scala2.13/datagen/pom.xml
+++ b/scala2.13/datagen/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
datagen_2.13
Data Generator
Tools for generating large amounts of data
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
datagen
diff --git a/scala2.13/delta-lake/delta-20x/pom.xml b/scala2.13/delta-lake/delta-20x/pom.xml
index 20c77038f40..57551a3d164 100644
--- a/scala2.13/delta-lake/delta-20x/pom.xml
+++ b/scala2.13/delta-lake/delta-20x/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../jdk-profiles/pom.xml
rapids-4-spark-delta-20x_2.13
RAPIDS Accelerator for Apache Spark Delta Lake 2.0.x Support
Delta Lake 2.0.x support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-20x
diff --git a/scala2.13/delta-lake/delta-21x/pom.xml b/scala2.13/delta-lake/delta-21x/pom.xml
index 75a41cfa8e0..6fbcf6bb8d1 100644
--- a/scala2.13/delta-lake/delta-21x/pom.xml
+++ b/scala2.13/delta-lake/delta-21x/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../jdk-profiles/pom.xml
rapids-4-spark-delta-21x_2.13
RAPIDS Accelerator for Apache Spark Delta Lake 2.1.x Support
Delta Lake 2.1.x support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-21x
diff --git a/scala2.13/delta-lake/delta-22x/pom.xml b/scala2.13/delta-lake/delta-22x/pom.xml
index c6111eb51a0..ff919c7b48c 100644
--- a/scala2.13/delta-lake/delta-22x/pom.xml
+++ b/scala2.13/delta-lake/delta-22x/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../jdk-profiles/pom.xml
rapids-4-spark-delta-22x_2.13
RAPIDS Accelerator for Apache Spark Delta Lake 2.2.x Support
Delta Lake 2.2.x support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-22x
diff --git a/scala2.13/delta-lake/delta-23x/pom.xml b/scala2.13/delta-lake/delta-23x/pom.xml
index 84d1d7275c2..fe927c7a092 100644
--- a/scala2.13/delta-lake/delta-23x/pom.xml
+++ b/scala2.13/delta-lake/delta-23x/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../pom.xml
rapids-4-spark-delta-23x_2.13
RAPIDS Accelerator for Apache Spark Delta Lake 2.3.x Support
Delta Lake 2.3.x support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-23x
diff --git a/scala2.13/delta-lake/delta-24x/pom.xml b/scala2.13/delta-lake/delta-24x/pom.xml
index 0ffe6c84e10..781f7975523 100644
--- a/scala2.13/delta-lake/delta-24x/pom.xml
+++ b/scala2.13/delta-lake/delta-24x/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../jdk-profiles/pom.xml
rapids-4-spark-delta-24x_2.13
RAPIDS Accelerator for Apache Spark Delta Lake 2.4.x Support
Delta Lake 2.4.x support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-24x
diff --git a/scala2.13/delta-lake/delta-spark330db/pom.xml b/scala2.13/delta-lake/delta-spark330db/pom.xml
index 3c30b1b0dc8..d6f2ee68e10 100644
--- a/scala2.13/delta-lake/delta-spark330db/pom.xml
+++ b/scala2.13/delta-lake/delta-spark330db/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../shim-deps/pom.xml
rapids-4-spark-delta-spark330db_2.13
RAPIDS Accelerator for Apache Spark Databricks 11.3 Delta Lake Support
Databricks 11.3 Delta Lake support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-spark330db
diff --git a/scala2.13/delta-lake/delta-spark332db/pom.xml b/scala2.13/delta-lake/delta-spark332db/pom.xml
index a3501c1003c..de53ab84f32 100644
--- a/scala2.13/delta-lake/delta-spark332db/pom.xml
+++ b/scala2.13/delta-lake/delta-spark332db/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../shim-deps/pom.xml
rapids-4-spark-delta-spark332db_2.13
RAPIDS Accelerator for Apache Spark Databricks 12.2 Delta Lake Support
Databricks 12.2 Delta Lake support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-spark332db
diff --git a/scala2.13/delta-lake/delta-spark341db/pom.xml b/scala2.13/delta-lake/delta-spark341db/pom.xml
index c740362b11f..bd6a72ea04b 100644
--- a/scala2.13/delta-lake/delta-spark341db/pom.xml
+++ b/scala2.13/delta-lake/delta-spark341db/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../shim-deps/pom.xml
rapids-4-spark-delta-spark341db_2.13
RAPIDS Accelerator for Apache Spark Databricks 13.3 Delta Lake Support
Databricks 13.3 Delta Lake support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
false
diff --git a/scala2.13/delta-lake/delta-spark350db143/pom.xml b/scala2.13/delta-lake/delta-spark350db143/pom.xml
index d6046b64578..c19c2e0ad21 100644
--- a/scala2.13/delta-lake/delta-spark350db143/pom.xml
+++ b/scala2.13/delta-lake/delta-spark350db143/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../shim-deps/pom.xml
rapids-4-spark-delta-spark350db143_2.13
RAPIDS Accelerator for Apache Spark Databricks 13.3 Delta Lake Support
Databricks 13.3 Delta Lake support for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
false
diff --git a/scala2.13/delta-lake/delta-stub/pom.xml b/scala2.13/delta-lake/delta-stub/pom.xml
index 2f90b85acd7..2a334190cea 100644
--- a/scala2.13/delta-lake/delta-stub/pom.xml
+++ b/scala2.13/delta-lake/delta-stub/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../jdk-profiles/pom.xml
rapids-4-spark-delta-stub_2.13
RAPIDS Accelerator for Apache Spark Delta Lake Stub
Delta Lake stub for the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../delta-lake/delta-stub
diff --git a/scala2.13/dist/pom.xml b/scala2.13/dist/pom.xml
index 15df1ec69f8..0c8f12a9214 100644
--- a/scala2.13/dist/pom.xml
+++ b/scala2.13/dist/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark_2.13
RAPIDS Accelerator for Apache Spark Distribution
Creates the distribution package of the RAPIDS plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
com.nvidia
diff --git a/scala2.13/integration_tests/pom.xml b/scala2.13/integration_tests/pom.xml
index 88ab2531235..67afb46c779 100644
--- a/scala2.13/integration_tests/pom.xml
+++ b/scala2.13/integration_tests/pom.xml
@@ -22,11 +22,11 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-integration-tests_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
integration_tests
diff --git a/scala2.13/jdk-profiles/pom.xml b/scala2.13/jdk-profiles/pom.xml
index 793bf0fb327..6ec2f369b96 100644
--- a/scala2.13/jdk-profiles/pom.xml
+++ b/scala2.13/jdk-profiles/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
com.nvidia
rapids-4-spark-jdk-profiles_2.13
pom
Shim JDK Profiles
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
jdk8
diff --git a/scala2.13/pom.xml b/scala2.13/pom.xml
index d52c8658423..e0aeb7af559 100644
--- a/scala2.13/pom.xml
+++ b/scala2.13/pom.xml
@@ -23,7 +23,7 @@
rapids-4-spark-parent_2.13
RAPIDS Accelerator for Apache Spark Root Project
The root project of the RAPIDS Accelerator for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
pom
https://nvidia.github.io/spark-rapids/
@@ -813,8 +813,7 @@
-
- 350db143
+
.
@@ -829,8 +828,8 @@
spark${buildver}
cuda11
${cuda.version}
- 24.12.0-SNAPSHOT
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
2.13
2.8.0
incremental
@@ -937,13 +936,14 @@
Build and run unit tests on one specific version for each sub-version (e.g. 320, 330)
Base shim version (320 currently) should be covered in default mvn verify command of premerge script,
so base shim version is removed from the premergeUT list.
- Separate the versions to two parts (premergeUT1, premergeUT2) for balancing the duration
+ Separate the versions to two parts: premergeUT1(2 shims' UT + 1/3 of the integration tests)
+ and premergeUT2(1 shim's UT + 2/3 of the integration tests), for balancing the duration
-->
- 320
+ 320,
+ 330
- 330,
340
diff --git a/scala2.13/shim-deps/cloudera/pom.xml b/scala2.13/shim-deps/cloudera/pom.xml
index 95c49a2b1ca..be06f76c136 100644
--- a/scala2.13/shim-deps/cloudera/pom.xml
+++ b/scala2.13/shim-deps/cloudera/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../pom.xml
rapids-4-spark-cdh-bom
pom
CDH Shim Dependencies
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/cloudera
diff --git a/scala2.13/shim-deps/databricks/pom.xml b/scala2.13/shim-deps/databricks/pom.xml
index 484e2896f61..6b17d31ed3c 100644
--- a/scala2.13/shim-deps/databricks/pom.xml
+++ b/scala2.13/shim-deps/databricks/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../pom.xml
rapids-4-spark-db-bom
pom
Databricks Shim Dependencies
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/databricks
diff --git a/scala2.13/shim-deps/pom.xml b/scala2.13/shim-deps/pom.xml
index 66cfa22afea..6c7a4b991a7 100644
--- a/scala2.13/shim-deps/pom.xml
+++ b/scala2.13/shim-deps/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark-shim-deps-parent_2.13
pom
Shim Dependencies Profiles
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
release321cdh
diff --git a/scala2.13/shuffle-plugin/pom.xml b/scala2.13/shuffle-plugin/pom.xml
index b9e76b2f068..6f915a66212 100644
--- a/scala2.13/shuffle-plugin/pom.xml
+++ b/scala2.13/shuffle-plugin/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-shuffle_2.13
RAPIDS Accelerator for Apache Spark Shuffle Plugin
Accelerated shuffle plugin for the RAPIDS plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
shuffle-plugin
diff --git a/scala2.13/sql-plugin-api/pom.xml b/scala2.13/sql-plugin-api/pom.xml
index 3c48d7c13f2..91802901fc0 100644
--- a/scala2.13/sql-plugin-api/pom.xml
+++ b/scala2.13/sql-plugin-api/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-sql-plugin-api_2.13
Module for Non-Shimmable API
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
sql-plugin-api
false
diff --git a/scala2.13/sql-plugin/pom.xml b/scala2.13/sql-plugin/pom.xml
index b96e1517690..e0ceea49776 100644
--- a/scala2.13/sql-plugin/pom.xml
+++ b/scala2.13/sql-plugin/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-sql_2.13
RAPIDS Accelerator for Apache Spark SQL Plugin
The RAPIDS SQL plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
sql-plugin
diff --git a/scala2.13/tests/pom.xml b/scala2.13/tests/pom.xml
index 377dc4671fb..6aa80019d27 100644
--- a/scala2.13/tests/pom.xml
+++ b/scala2.13/tests/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-tests_2.13
RAPIDS Accelerator for Apache Spark Tests
RAPIDS plugin for Apache Spark integration tests
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
tests
diff --git a/scala2.13/tools/pom.xml b/scala2.13/tools/pom.xml
index 0c3179e09ff..866987242ae 100644
--- a/scala2.13/tools/pom.xml
+++ b/scala2.13/tools/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark-tools-support
pom
RAPIDS Accelerator for Apache Spark Tools Support
Supporting code for RAPIDS Accelerator tools
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
com.nvidia
diff --git a/scala2.13/udf-compiler/pom.xml b/scala2.13/udf-compiler/pom.xml
index 10ad46a48aa..09cce00ef27 100644
--- a/scala2.13/udf-compiler/pom.xml
+++ b/scala2.13/udf-compiler/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.13
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-udf_2.13
RAPIDS Accelerator for Apache Spark Scala UDF Plugin
The RAPIDS Scala UDF plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
udf-compiler
diff --git a/shim-deps/cloudera/pom.xml b/shim-deps/cloudera/pom.xml
index a9b71366927..0505fed6bac 100644
--- a/shim-deps/cloudera/pom.xml
+++ b/shim-deps/cloudera/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../pom.xml
rapids-4-spark-cdh-bom
pom
CDH Shim Dependencies
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/cloudera
diff --git a/shim-deps/databricks/pom.xml b/shim-deps/databricks/pom.xml
index 5f36e529aa7..f3a8991255c 100644
--- a/shim-deps/databricks/pom.xml
+++ b/shim-deps/databricks/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../../pom.xml
rapids-4-spark-db-bom
pom
Databricks Shim Dependencies
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/databricks
diff --git a/shim-deps/pom.xml b/shim-deps/pom.xml
index d90dfc34190..e5a047f5169 100644
--- a/shim-deps/pom.xml
+++ b/shim-deps/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark-shim-deps-parent_2.12
pom
Shim Dependencies Profiles
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
release321cdh
diff --git a/shuffle-plugin/pom.xml b/shuffle-plugin/pom.xml
index 69d8f1b765b..fd92b6b0957 100644
--- a/shuffle-plugin/pom.xml
+++ b/shuffle-plugin/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-shuffle_2.12
RAPIDS Accelerator for Apache Spark Shuffle Plugin
Accelerated shuffle plugin for the RAPIDS plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
shuffle-plugin
diff --git a/sql-plugin-api/pom.xml b/sql-plugin-api/pom.xml
index 090a809fc05..b1080ef7d39 100644
--- a/sql-plugin-api/pom.xml
+++ b/sql-plugin-api/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-sql-plugin-api_2.12
Module for Non-Shimmable API
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
sql-plugin-api
false
diff --git a/sql-plugin-api/src/main/scala/com/nvidia/spark/rapids/ShimLoader.scala b/sql-plugin-api/src/main/scala/com/nvidia/spark/rapids/ShimLoader.scala
index 23a9ece7468..533fee141c5 100644
--- a/sql-plugin-api/src/main/scala/com/nvidia/spark/rapids/ShimLoader.scala
+++ b/sql-plugin-api/src/main/scala/com/nvidia/spark/rapids/ShimLoader.scala
@@ -48,11 +48,11 @@ import org.apache.spark.util.MutableURLClassLoader
Each shim can see a consistent parallel world without conflicts by referencing
only one conflicting directory.
E.g., Spark 3.2.0 Shim will use
- jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark-shared/
- jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark320/
+ jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark-shared/
+ jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark320/
Spark 3.3.1 will use
- jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark-shared/
- jar:file:/home/spark/rapids-4-spark_2.12-24.12.0.jar!/spark331/
+ jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark-shared/
+ jar:file:/home/spark/rapids-4-spark_2.12-25.02.0.jar!/spark331/
Using these Jar URL's allows referencing different bytecode produced from identical sources
by incompatible Scala / Spark dependencies.
*/
diff --git a/sql-plugin/pom.xml b/sql-plugin/pom.xml
index c9cfb8ce99f..2b0a62a5b90 100644
--- a/sql-plugin/pom.xml
+++ b/sql-plugin/pom.xml
@@ -22,13 +22,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-sql_2.12
RAPIDS Accelerator for Apache Spark SQL Plugin
The RAPIDS SQL plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
sql-plugin
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuAggregateExec.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuAggregateExec.scala
index d5bbe15209d..e3ca330b409 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuAggregateExec.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuAggregateExec.scala
@@ -716,7 +716,7 @@ object GpuAggregateIterator extends Logging {
val dataTypes = (0 until numCols).map {
c => batchesToConcat.head.column(c).dataType
}.toArray
- withResource(batchesToConcat.map(GpuColumnVector.from)) { tbl =>
+ withResource(batchesToConcat.safeMap(GpuColumnVector.from)) { tbl =>
withResource(cudf.Table.concatenate(tbl: _*)) { concatenated =>
val cb = GpuColumnVector.from(concatenated, dataTypes)
SpillableColumnarBatch(cb,
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuCoalesceBatches.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuCoalesceBatches.scala
index cc1196d44e4..0af5baa90db 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuCoalesceBatches.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuCoalesceBatches.scala
@@ -67,7 +67,7 @@ object ConcatAndConsumeAll {
if (arrayOfBatches.length == 1) {
arrayOfBatches(0)
} else {
- val tables = arrayOfBatches.map(GpuColumnVector.from)
+ val tables = arrayOfBatches.safeMap(GpuColumnVector.from)
try {
val combined = Table.concatenate(tables: _*)
try {
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuColumnarBatchSerializer.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuColumnarBatchSerializer.scala
index 54252253d38..5a639baafec 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuColumnarBatchSerializer.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuColumnarBatchSerializer.scala
@@ -31,6 +31,10 @@ import com.nvidia.spark.rapids.jni.kudo.{KudoSerializer, KudoTable, KudoTableHea
import org.apache.spark.TaskContext
import org.apache.spark.serializer.{DeserializationStream, SerializationStream, Serializer, SerializerInstance}
+import org.apache.spark.sql.rapids.execution.GpuShuffleExchangeExecBase.{METRIC_DATA_SIZE,
+ METRIC_SHUFFLE_DESER_STREAM_TIME, METRIC_SHUFFLE_SER_CALC_HEADER_TIME,
+ METRIC_SHUFFLE_SER_COPY_BUFFER_TIME, METRIC_SHUFFLE_SER_COPY_HEADER_TIME,
+ METRIC_SHUFFLE_SER_STREAM_TIME}
import org.apache.spark.sql.types.{DataType, NullType}
import org.apache.spark.sql.vectorized.ColumnarBatch
@@ -45,22 +49,20 @@ trait BaseSerializedTableIterator extends Iterator[(Int, ColumnarBatch)] {
def peekNextBatchSize(): Option[Long]
}
-class SerializedBatchIterator(dIn: DataInputStream)
+class SerializedBatchIterator(dIn: DataInputStream, deserTime: GpuMetric)
extends BaseSerializedTableIterator {
private[this] var nextHeader: Option[SerializedTableHeader] = None
- private[this] var toBeReturned: Option[ColumnarBatch] = None
private[this] var streamClosed: Boolean = false
// Don't install the callback if in a unit test
Option(TaskContext.get()).foreach { tc =>
onTaskCompletion(tc) {
- toBeReturned.foreach(_.close())
- toBeReturned = None
dIn.close()
+ streamClosed = true
}
}
- override def peekNextBatchSize(): Option[Long] = {
+ override def peekNextBatchSize(): Option[Long] = deserTime.ns {
if (streamClosed) {
None
} else {
@@ -80,23 +82,20 @@ class SerializedBatchIterator(dIn: DataInputStream)
}
}
- private def tryReadNext(): Option[ColumnarBatch] = {
- if (nextHeader.isEmpty) {
- None
- } else {
- withResource(new NvtxRange("Read Batch", NvtxColor.YELLOW)) { _ =>
- val header = nextHeader.get
- if (header.getNumColumns > 0) {
- // This buffer will later be concatenated into another host buffer before being
- // sent to the GPU, so no need to use pinned memory for these buffers.
- closeOnExcept(
- HostMemoryBuffer.allocate(header.getDataLen, false)) { hostBuffer =>
- JCudfSerialization.readTableIntoBuffer(dIn, header, hostBuffer)
- Some(SerializedTableColumn.from(header, hostBuffer))
- }
- } else {
- Some(SerializedTableColumn.from(header))
+ private def readNextBatch(): ColumnarBatch = deserTime.ns {
+ withResource(new NvtxRange("Read Batch", NvtxColor.YELLOW)) { _ =>
+ val header = nextHeader.get
+ nextHeader = None
+ if (header.getNumColumns > 0) {
+ // This buffer will later be concatenated into another host buffer before being
+ // sent to the GPU, so no need to use pinned memory for these buffers.
+ closeOnExcept(
+ HostMemoryBuffer.allocate(header.getDataLen, false)) { hostBuffer =>
+ JCudfSerialization.readTableIntoBuffer(dIn, header, hostBuffer)
+ SerializedTableColumn.from(header, hostBuffer)
}
+ } else {
+ SerializedTableColumn.from(header)
}
}
}
@@ -107,17 +106,10 @@ class SerializedBatchIterator(dIn: DataInputStream)
}
override def next(): (Int, ColumnarBatch) = {
- if (toBeReturned.isEmpty) {
- peekNextBatchSize()
- toBeReturned = tryReadNext()
- if (nextHeader.isEmpty || toBeReturned.isEmpty) {
- throw new NoSuchElementException("Walked off of the end...")
- }
+ if (!hasNext) {
+ throw new NoSuchElementException("Walked off of the end...")
}
- val ret = toBeReturned.get
- toBeReturned = None
- nextHeader = None
- (0, ret)
+ (0, readNextBatch())
}
}
@@ -137,30 +129,45 @@ class SerializedBatchIterator(dIn: DataInputStream)
*
* @note The RAPIDS shuffle does not use this code.
*/
-class GpuColumnarBatchSerializer(dataSize: GpuMetric, dataTypes: Array[DataType], useKudo: Boolean)
+class GpuColumnarBatchSerializer(metrics: Map[String, GpuMetric], dataTypes: Array[DataType],
+ useKudo: Boolean)
extends Serializer with Serializable {
+
+ private lazy val kudo = {
+ if (useKudo && dataTypes.nonEmpty) {
+ Some(new KudoSerializer(GpuColumnVector.from(dataTypes)))
+ } else {
+ None
+ }
+ }
+
override def newInstance(): SerializerInstance = {
if (useKudo) {
- new KudoSerializerInstance(dataSize, dataTypes)
+ new KudoSerializerInstance(metrics, dataTypes, kudo)
} else {
- new GpuColumnarBatchSerializerInstance(dataSize)
+ new GpuColumnarBatchSerializerInstance(metrics)
}
}
override def supportsRelocationOfSerializedObjects: Boolean = true
}
-private class GpuColumnarBatchSerializerInstance(dataSize: GpuMetric) extends SerializerInstance {
+private class GpuColumnarBatchSerializerInstance(metrics: Map[String, GpuMetric]) extends
+ SerializerInstance {
+ private val dataSize = metrics(METRIC_DATA_SIZE)
+ private val serTime = metrics(METRIC_SHUFFLE_SER_STREAM_TIME)
+ private val deserTime = metrics(METRIC_SHUFFLE_DESER_STREAM_TIME)
+
override def serializeStream(out: OutputStream): SerializationStream = new SerializationStream {
private[this] val dOut: DataOutputStream =
new DataOutputStream(new BufferedOutputStream(out))
- override def writeValue[T: ClassTag](value: T): SerializationStream = {
+ override def writeValue[T: ClassTag](value: T): SerializationStream = serTime.ns {
val batch = value.asInstanceOf[ColumnarBatch]
val numColumns = batch.numCols()
val columns: Array[HostColumnVector] = new Array(numColumns)
- val toClose = new ArrayBuffer[AutoCloseable]()
+ val toClose = new ArrayBuffer[AutoCloseable](numColumns)
try {
var startRow = 0
val numRows = batch.numRows()
@@ -239,7 +246,7 @@ private class GpuColumnarBatchSerializerInstance(dataSize: GpuMetric) extends Se
private[this] val dIn: DataInputStream = new DataInputStream(new BufferedInputStream(in))
override def asKeyValueIterator: Iterator[(Int, ColumnarBatch)] = {
- new SerializedBatchIterator(dIn)
+ new SerializedBatchIterator(dIn, deserTime)
}
override def asIterator: Iterator[Any] = {
@@ -339,20 +346,26 @@ object SerializedTableColumn {
* @param dataTypes data types of the columns in the batch
*/
private class KudoSerializerInstance(
- val dataSize: GpuMetric,
- val dataTypes: Array[DataType]) extends SerializerInstance {
-
- private lazy val kudo = new KudoSerializer(GpuColumnVector.from(dataTypes))
+ val metrics: Map[String, GpuMetric],
+ val dataTypes: Array[DataType],
+ val kudo: Option[KudoSerializer]
+) extends SerializerInstance {
+ private val dataSize = metrics(METRIC_DATA_SIZE)
+ private val serTime = metrics(METRIC_SHUFFLE_SER_STREAM_TIME)
+ private val serCalcHeaderTime = metrics(METRIC_SHUFFLE_SER_CALC_HEADER_TIME)
+ private val serCopyHeaderTime = metrics(METRIC_SHUFFLE_SER_COPY_HEADER_TIME)
+ private val serCopyBufferTime = metrics(METRIC_SHUFFLE_SER_COPY_BUFFER_TIME)
+ private val deserTime = metrics(METRIC_SHUFFLE_DESER_STREAM_TIME)
override def serializeStream(out: OutputStream): SerializationStream = new SerializationStream {
private[this] val dOut: DataOutputStream =
new DataOutputStream(new BufferedOutputStream(out))
- override def writeValue[T: ClassTag](value: T): SerializationStream = {
+ override def writeValue[T: ClassTag](value: T): SerializationStream = serTime.ns {
val batch = value.asInstanceOf[ColumnarBatch]
val numColumns = batch.numCols()
val columns: Array[HostColumnVector] = new Array(numColumns)
- withResource(new ArrayBuffer[AutoCloseable]()) { toClose =>
+ withResource(new ArrayBuffer[AutoCloseable](numColumns)) { toClose =>
var startRow = 0
val numRows = batch.numRows()
if (batch.numCols() > 0) {
@@ -380,7 +393,14 @@ private class KudoSerializerInstance(
}
withResource(new NvtxRange("Serialize Batch", NvtxColor.YELLOW)) { _ =>
- dataSize += kudo.writeToStream(columns, dOut, startRow, numRows)
+ val writeMetric = kudo
+ .getOrElse(throw new IllegalStateException("Kudo serializer not initialized."))
+ .writeToStreamWithMetrics(columns, dOut, startRow, numRows)
+
+ dataSize += writeMetric.getWrittenBytes
+ serCalcHeaderTime += writeMetric.getCalcHeaderTime
+ serCopyHeaderTime += writeMetric.getCopyHeaderTime
+ serCopyBufferTime += writeMetric.getCopyBufferTime
}
} else {
withResource(new NvtxRange("Serialize Row Only Batch", NvtxColor.YELLOW)) { _ =>
@@ -422,7 +442,7 @@ private class KudoSerializerInstance(
private[this] val dIn: DataInputStream = new DataInputStream(new BufferedInputStream(in))
override def asKeyValueIterator: Iterator[(Int, ColumnarBatch)] = {
- new KudoSerializedBatchIterator(dIn)
+ new KudoSerializedBatchIterator(dIn, deserTime)
}
override def asIterator: Iterator[Any] = {
@@ -495,22 +515,20 @@ object KudoSerializedTableColumn {
}
}
-class KudoSerializedBatchIterator(dIn: DataInputStream)
+class KudoSerializedBatchIterator(dIn: DataInputStream, deserTime: GpuMetric)
extends BaseSerializedTableIterator {
private[this] var nextHeader: Option[KudoTableHeader] = None
- private[this] var toBeReturned: Option[ColumnarBatch] = None
private[this] var streamClosed: Boolean = false
// Don't install the callback if in a unit test
Option(TaskContext.get()).foreach { tc =>
onTaskCompletion(tc) {
- toBeReturned.foreach(_.close())
- toBeReturned = None
dIn.close()
+ streamClosed = true
}
}
- override def peekNextBatchSize(): Option[Long] = {
+ override def peekNextBatchSize(): Option[Long] = deserTime.ns {
if (streamClosed) {
None
} else {
@@ -530,23 +548,20 @@ class KudoSerializedBatchIterator(dIn: DataInputStream)
}
}
- private def tryReadNext(): Option[ColumnarBatch] = {
- if (nextHeader.isEmpty) {
- None
- } else {
- withResource(new NvtxRange("Read Batch", NvtxColor.YELLOW)) { _ =>
- val header = nextHeader.get
- if (header.getNumColumns > 0) {
- // This buffer will later be concatenated into another host buffer before being
- // sent to the GPU, so no need to use pinned memory for these buffers.
- closeOnExcept(HostMemoryBuffer.allocate(header.getTotalDataLen, false)) { hostBuffer =>
- hostBuffer.copyFromStream(0, dIn, header.getTotalDataLen)
- val kudoTable = new KudoTable(header, hostBuffer)
- Some(KudoSerializedTableColumn.from(kudoTable))
- }
- } else {
- Some(KudoSerializedTableColumn.from(new KudoTable(header, null)))
+ private def readNextBatch(): ColumnarBatch = deserTime.ns {
+ withResource(new NvtxRange("Read Batch", NvtxColor.YELLOW)) { _ =>
+ val header = nextHeader.get
+ nextHeader = None
+ if (header.getNumColumns > 0) {
+ // This buffer will later be concatenated into another host buffer before being
+ // sent to the GPU, so no need to use pinned memory for these buffers.
+ closeOnExcept(HostMemoryBuffer.allocate(header.getTotalDataLen, false)) { hostBuffer =>
+ hostBuffer.copyFromStream(0, dIn, header.getTotalDataLen)
+ val kudoTable = new KudoTable(header, hostBuffer)
+ KudoSerializedTableColumn.from(kudoTable)
}
+ } else {
+ KudoSerializedTableColumn.from(new KudoTable(header, null))
}
}
}
@@ -557,16 +572,9 @@ class KudoSerializedBatchIterator(dIn: DataInputStream)
}
override def next(): (Int, ColumnarBatch) = {
- if (toBeReturned.isEmpty) {
- peekNextBatchSize()
- toBeReturned = tryReadNext()
- if (nextHeader.isEmpty || toBeReturned.isEmpty) {
- throw new NoSuchElementException("Walked off of the end...")
- }
+ if (!hasNext) {
+ throw new NoSuchElementException("Walked off of the end...")
}
- val ret = toBeReturned.get
- toBeReturned = None
- nextHeader = None
- (0, ret)
+ (0, readNextBatch())
}
}
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExec.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExec.scala
index 3d9b6285a91..850a04f390f 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExec.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExec.scala
@@ -327,19 +327,19 @@ trait GpuExec extends SparkPlan {
}
}
- protected def createMetric(level: MetricsLevel, name: String): GpuMetric =
+ def createMetric(level: MetricsLevel, name: String): GpuMetric =
createMetricInternal(level, SQLMetrics.createMetric(sparkContext, name))
- protected def createNanoTimingMetric(level: MetricsLevel, name: String): GpuMetric =
+ def createNanoTimingMetric(level: MetricsLevel, name: String): GpuMetric =
createMetricInternal(level, SQLMetrics.createNanoTimingMetric(sparkContext, name))
- protected def createSizeMetric(level: MetricsLevel, name: String): GpuMetric =
+ def createSizeMetric(level: MetricsLevel, name: String): GpuMetric =
createMetricInternal(level, SQLMetrics.createSizeMetric(sparkContext, name))
- protected def createAverageMetric(level: MetricsLevel, name: String): GpuMetric =
+ def createAverageMetric(level: MetricsLevel, name: String): GpuMetric =
createMetricInternal(level, SQLMetrics.createAverageMetric(sparkContext, name))
- protected def createTimingMetric(level: MetricsLevel, name: String): GpuMetric =
+ def createTimingMetric(level: MetricsLevel, name: String): GpuMetric =
createMetricInternal(level, SQLMetrics.createTimingMetric(sparkContext, name))
protected def createFileCacheMetrics(): Map[String, GpuMetric] = {
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuGenerateExec.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuGenerateExec.scala
index 239b7a3d4c0..dbf2e95dbf0 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuGenerateExec.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuGenerateExec.scala
@@ -677,27 +677,26 @@ abstract class GpuExplodeBase extends GpuUnevaluableUnaryExpression with GpuGene
outer: Boolean): Iterator[ColumnarBatch] = {
val batchesToGenerate = inputSpillables.map(new BatchToGenerate(0, _))
withRetry(batchesToGenerate, generateSplitSpillableInHalfByRows(generatorOffset)) { attempt =>
- withResource(attempt.spillable.getColumnarBatch()) { inputBatch =>
+ val (exploded, schema) = withResource(attempt.spillable.getColumnarBatch()) { inputBatch =>
require(inputBatch.numCols() - 1 == generatorOffset,
s"Internal Error ${getClass.getSimpleName} supports one and only one input attribute.")
val schema = resultSchema(GpuColumnVector.extractTypes(inputBatch), generatorOffset)
-
withResource(GpuColumnVector.from(inputBatch)) { table =>
- withResource(
- explodeFun(table, generatorOffset, outer, attempt.fixUpOffset)) { exploded =>
- child.dataType match {
- case _: ArrayType =>
- GpuColumnVector.from(exploded, schema)
- case MapType(kt, vt, _) =>
- // We need to pull the key and value of of the struct column
- withResource(convertMapOutput(exploded, generatorOffset, kt, vt, outer)) { fixed =>
- GpuColumnVector.from(fixed, schema)
- }
- case other =>
- throw new IllegalArgumentException(
- s"$other is not supported as explode input right now")
+ (explodeFun(table, generatorOffset, outer, attempt.fixUpOffset), schema)
+ }
+ }
+ withResource(exploded) { _ =>
+ child.dataType match {
+ case _: ArrayType =>
+ GpuColumnVector.from(exploded, schema)
+ case MapType(kt, vt, _) =>
+ // We need to pull the key and value of of the struct column
+ withResource(convertMapOutput(exploded, generatorOffset, kt, vt, outer)) { fixed =>
+ GpuColumnVector.from(fixed, schema)
}
- }
+ case other =>
+ throw new IllegalArgumentException(
+ s"$other is not supported as explode input right now")
}
}
}
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala
index 45905f0b9e0..0c7aa046a7c 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuOverrides.scala
@@ -593,8 +593,9 @@ object GpuOverrides extends Logging {
}
def isSupportedStringReplacePattern(strLit: String): Boolean = {
- // check for regex special characters, except for \u0000 which we can support
- !regexList.filterNot(_ == "\u0000").exists(pattern => strLit.contains(pattern))
+ // check for regex special characters, except for \u0000, \n, \r, and \t which we can support
+ val supported = Seq("\u0000", "\n", "\r", "\t")
+ !regexList.filterNot(supported.contains(_)).exists(pattern => strLit.contains(pattern))
}
def isSupportedStringReplacePattern(exp: Expression): Boolean = {
@@ -605,7 +606,6 @@ object GpuOverrides extends Logging {
if (strLit.isEmpty) {
false
} else {
- // check for regex special characters, except for \u0000 which we can support
isSupportedStringReplacePattern(strLit)
}
case _ => false
@@ -1821,6 +1821,20 @@ object GpuOverrides extends Logging {
ParamCheck("round", TypeSig.lit(TypeEnum.BOOLEAN), TypeSig.BOOLEAN))),
(a, conf, p, r) => new MonthsBetweenExprMeta(a, conf, p, r)
),
+ expr[TruncDate](
+ "Truncate the date to the unit specified by the given string format",
+ ExprChecks.binaryProject(TypeSig.DATE, TypeSig.DATE,
+ ("date", TypeSig.DATE, TypeSig.DATE),
+ ("format", TypeSig.STRING, TypeSig.STRING)),
+ (a, conf, p, r) => new TruncDateExprMeta(a, conf, p, r)
+ ),
+ expr[TruncTimestamp](
+ "Truncate the timestamp to the unit specified by the given string format",
+ ExprChecks.binaryProject(TypeSig.TIMESTAMP, TypeSig.TIMESTAMP,
+ ("format", TypeSig.STRING, TypeSig.STRING),
+ ("date", TypeSig.TIMESTAMP, TypeSig.TIMESTAMP)),
+ (a, conf, p, r) => new TruncTimestampExprMeta(a, conf, p, r)
+ ),
expr[Pmod](
"Pmod",
// Decimal support disabled https://github.com/NVIDIA/spark-rapids/issues/7553
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuShuffleCoalesceExec.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuShuffleCoalesceExec.scala
index c33c19cdd8a..62b8e36be65 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuShuffleCoalesceExec.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuShuffleCoalesceExec.scala
@@ -237,6 +237,7 @@ class KudoTableOperator(
kudoMergeHeaderTime: GpuMetric,
kudoMergeBufferTime: GpuMetric) extends SerializedTableOperator[KudoSerializedTableColumn] {
require(kudo != null, "kudo serializer should not be null")
+ private val kudoTables = new util.ArrayList[KudoTable]()
override def getDataLen(column: KudoSerializedTableColumn): Long = column.kudoTable.getHeader
.getTotalDataLen
@@ -251,7 +252,8 @@ class KudoTableOperator(
val totalRowsNum = columns.map(getNumRows).sum
RowCountOnlyMergeResult(totalRowsNum)
} else {
- val kudoTables = new util.ArrayList[KudoTable](columns.length)
+ kudoTables.clear()
+ kudoTables.ensureCapacity(columns.length)
columns.foreach { column =>
kudoTables.add(column.kudoTable)
}
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/Plugin.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/Plugin.scala
index 5127c7899a8..1c9f230e1b9 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/Plugin.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/Plugin.scala
@@ -134,11 +134,11 @@ object RapidsPluginUtils extends Logging {
val possibleRapidsJarURLs = classloader.getResources(propName).asScala.toSet.toSeq.filter {
url => {
val urlPath = url.toString
- // Filter out submodule jars, e.g. rapids-4-spark-aggregator_2.12-24.12.0-spark341.jar,
+ // Filter out submodule jars, e.g. rapids-4-spark-aggregator_2.12-25.02.0-spark341.jar,
// and files stored under subdirs of '!/', e.g.
- // rapids-4-spark_2.12-24.12.0-cuda11.jar!/spark330/rapids4spark-version-info.properties
+ // rapids-4-spark_2.12-25.02.0-cuda11.jar!/spark330/rapids4spark-version-info.properties
// We only want to find the main jar, e.g.
- // rapids-4-spark_2.12-24.12.0-cuda11.jar!/rapids4spark-version-info.properties
+ // rapids-4-spark_2.12-25.02.0-cuda11.jar!/rapids4spark-version-info.properties
!urlPath.contains("rapids-4-spark-") && urlPath.endsWith("!/" + propName)
}
}
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/RapidsConf.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/RapidsConf.scala
index e750f5688ce..c34e461b258 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/RapidsConf.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/RapidsConf.scala
@@ -2504,7 +2504,7 @@ val SHUFFLE_COMPRESSION_LZ4_CHUNK_SIZE = conf("spark.rapids.shuffle.compression.
|On startup use: `--conf [conf key]=[conf value]`. For example:
|
|```
- |${SPARK_HOME}/bin/spark-shell --jars rapids-4-spark_2.12-24.12.0-SNAPSHOT-cuda11.jar \
+ |${SPARK_HOME}/bin/spark-shell --jars rapids-4-spark_2.12-25.02.0-SNAPSHOT-cuda11.jar \
|--conf spark.plugins=com.nvidia.spark.SQLPlugin \
|--conf spark.rapids.sql.concurrentGpuTasks=2
|```
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutor.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutor.scala
index 45889bf89ac..99c3cc9ea5e 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutor.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutor.scala
@@ -20,6 +20,8 @@ import java.util.concurrent.{Callable, ExecutorService, Future, TimeUnit}
/**
* Thin wrapper around an ExecutorService that adds throttling.
+ *
+ * The given executor is owned by this class and will be shutdown when this class is shutdown.
*/
class ThrottlingExecutor(
val executor: ExecutorService, throttler: TrafficController) {
diff --git a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/TrafficController.scala b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/TrafficController.scala
index 0110f2d89ca..e69af5bf258 100644
--- a/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/TrafficController.scala
+++ b/sql-plugin/src/main/scala/com/nvidia/spark/rapids/io/async/TrafficController.scala
@@ -17,6 +17,7 @@
package com.nvidia.spark.rapids.io.async
import java.util.concurrent.Callable
+import java.util.concurrent.locks.ReentrantLock
import javax.annotation.concurrent.GuardedBy
import com.nvidia.spark.rapids.RapidsConf
@@ -85,38 +86,55 @@ class HostMemoryThrottle(val maxInFlightHostMemoryBytes: Long) extends Throttle
*
* This class is thread-safe as it is used by multiple tasks.
*/
-class TrafficController protected[rapids] (throttle: Throttle) {
+class TrafficController protected[rapids] (@GuardedBy("lock") throttle: Throttle) {
- @GuardedBy("this")
+ @GuardedBy("lock")
private var numTasks: Int = 0
+ private val lock = new ReentrantLock()
+ private val canBeScheduled = lock.newCondition()
+
/**
* Blocks the task from being scheduled until the throttle allows it. If there is no task
* currently scheduled, the task is scheduled immediately even if the throttle is exceeded.
*/
- def blockUntilRunnable[T](task: Task[T]): Unit = synchronized {
- if (numTasks > 0) {
- while (!throttle.canAccept(task)) {
- wait(100)
+ def blockUntilRunnable[T](task: Task[T]): Unit = {
+ lock.lockInterruptibly()
+ try {
+ while (numTasks > 0 && !throttle.canAccept(task)) {
+ canBeScheduled.await()
}
+ numTasks += 1
+ throttle.taskScheduled(task)
+ } finally {
+ lock.unlock()
}
- numTasks += 1
- throttle.taskScheduled(task)
}
- def taskCompleted[T](task: Task[T]): Unit = synchronized {
- numTasks -= 1
- throttle.taskCompleted(task)
- notify()
+ def taskCompleted[T](task: Task[T]): Unit = {
+ lock.lockInterruptibly()
+ try {
+ numTasks -= 1
+ throttle.taskCompleted(task)
+ canBeScheduled.signal()
+ } finally {
+ lock.unlock()
+ }
}
- def numScheduledTasks: Int = synchronized {
- numTasks
+ def numScheduledTasks: Int = {
+ lock.lockInterruptibly()
+ try {
+ numTasks
+ } finally {
+ lock.unlock()
+ }
}
}
object TrafficController {
+ @GuardedBy("this")
private var instance: TrafficController = _
/**
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/hive/rapids/GpuHiveFileFormat.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/hive/rapids/GpuHiveFileFormat.scala
index 3b5244e5c79..d39050a0c32 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/hive/rapids/GpuHiveFileFormat.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/hive/rapids/GpuHiveFileFormat.scala
@@ -127,6 +127,38 @@ object GpuHiveFileFormat extends Logging {
s"only $lazySimpleSerDe is currently supported for text")
}
+ // The check for serialization key here differs slightly from the read-side check in
+ // HiveProviderImpl::getExecs():
+ // 1. On the read-side, we do a strict check for `serialization.format == 1`, denoting
+ // '^A'-separated text. All other formatting is unsupported.
+ // 2. On the write-side too, we support only `serialization.format == 1`. But if
+ // `serialization.format` hasn't been set yet, it is still treated as `^A` separated.
+ //
+ // On the write side, there are a couple of scenarios to consider:
+ // 1. If the destination table exists beforehand, `serialization.format` should have been
+ // set already, to a non-empty value. This will look like:
+ // ```sql
+ // CREATE TABLE destination_table( col INT, ... ); --> serialization.format=1
+ // INSERT INTO TABLE destination_table SELECT * FROM ...
+ // ```
+ // 2. If the destination table is being created as part of a CTAS, without an explicit
+ // format specified, then Spark leaves `serialization.format` unpopulated, until *AFTER*
+ // the write operation is completed. Such a query might look like:
+ // ```sql
+ // CREATE TABLE destination_table AS SELECT * FROM ...
+ // --> serialization.format is absent from Storage Properties. "1" is inferred.
+ // ```
+ // 3. If the destination table is being created as part of a CTAS, with a non-default
+ // text format specified explicitly, then the non-default `serialization.format` is made
+ // available as part of the destination table's storage properties. Such a table creation
+ // might look like:
+ // ```sql
+ // CREATE TABLE destination_table
+ // ROW FORMAT DELIMITED FIELDS TERMINATED BY `,` STORED AS TEXTFILE
+ // AS SELECT * FROM ...
+ // --> serialization.format="", field.delim=",". Unsupported case.
+ // ```
+ // All these cases may be covered by explicitly checking for `serialization.format=1`.
val serializationFormat = storage.properties.getOrElse(serializationKey, "1")
if (serializationFormat != ctrlASeparatedFormat) {
meta.willNotWorkOnGpu(s"unsupported serialization format found: " +
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/GpuFileFormatDataWriter.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/GpuFileFormatDataWriter.scala
index be88e7a2937..6b6580df68f 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/GpuFileFormatDataWriter.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/GpuFileFormatDataWriter.scala
@@ -78,34 +78,35 @@ object GpuFileFormatDataWriter {
* The input batch is closed in case of error or in case we have to split it.
* It is not closed if it wasn't split.
*
- * @param batch ColumnarBatch to split (and close)
+ * @param scb Spillable ColumnarBatch to split (and close)
* @param maxRecordsPerFile max rowcount per file
* @param recordsInFile row count in the file so far
* @return array of SpillableColumnarBatch splits
*/
- def splitToFitMaxRecordsAndClose(
- batch: ColumnarBatch,
+ def splitToFitMaxRecordsAndCloseWithRetry(
+ scb: SpillableColumnarBatch,
maxRecordsPerFile: Long,
recordsInFile: Long): Array[SpillableColumnarBatch] = {
- val (types, splitIndexes) = closeOnExcept(batch) { _ =>
- val splitIndexes = getSplitIndexes(maxRecordsPerFile, recordsInFile, batch.numRows())
- (GpuColumnVector.extractTypes(batch), splitIndexes)
+ val splitIndexes = closeOnExcept(scb) { _ =>
+ getSplitIndexes(maxRecordsPerFile, recordsInFile, scb.numRows())
}
if (splitIndexes.isEmpty) {
- // this should never happen, as `splitToFitMaxRecordsAndClose` is called when
+ // this should never happen, as `splitToFitMaxRecordsAndCloseWithRetry` is called when
// splits should already happen, but making it more efficient in that case
- Array(SpillableColumnarBatch(batch, SpillPriorities.ACTIVE_ON_DECK_PRIORITY))
+ Array(scb)
} else {
// actually split it
- val tbl = withResource(batch) { _ =>
- GpuColumnVector.from(batch)
- }
- val cts = withResource(tbl) { _ =>
- tbl.contiguousSplit(splitIndexes: _*)
- }
- withResource(cts) { _ =>
- cts.safeMap(ct =>
- SpillableColumnarBatch(ct, types, SpillPriorities.ACTIVE_ON_DECK_PRIORITY))
+ withRetryNoSplit(scb) { _ =>
+ val tbl = withResource(scb.getColumnarBatch()) { batch =>
+ GpuColumnVector.from(batch)
+ }
+ val cts = withResource(tbl) { _ =>
+ tbl.contiguousSplit(splitIndexes: _*)
+ }
+ withResource(cts) { _ =>
+ cts.safeMap(ct =>
+ SpillableColumnarBatch(ct, scb.dataTypes, SpillPriorities.ACTIVE_ON_DECK_PRIORITY))
+ }
}
}
}
@@ -257,14 +258,13 @@ class GpuSingleDirectoryDataWriter(
override def write(batch: ColumnarBatch): Unit = {
val maxRecordsPerFile = description.maxRecordsPerFile
val recordsInFile = currentWriterStatus.recordsInFile
+ val scb = SpillableColumnarBatch(batch, SpillPriorities.ACTIVE_ON_DECK_PRIORITY)
if (!shouldSplitToFitMaxRecordsPerFile(
- maxRecordsPerFile, recordsInFile, batch.numRows())) {
- writeUpdateMetricsAndClose(
- SpillableColumnarBatch(batch, SpillPriorities.ACTIVE_ON_DECK_PRIORITY),
- currentWriterStatus)
+ maxRecordsPerFile, recordsInFile, scb.numRows())) {
+ writeUpdateMetricsAndClose(scb, currentWriterStatus)
} else {
- val partBatches = splitToFitMaxRecordsAndClose(
- batch, maxRecordsPerFile, recordsInFile)
+ val partBatches = splitToFitMaxRecordsAndCloseWithRetry(scb, maxRecordsPerFile,
+ recordsInFile)
val needNewWriterForFirstPart = recordsInFile >= maxRecordsPerFile
closeOnExcept(partBatches) { _ =>
partBatches.zipWithIndex.foreach { case (partBatch, partIx) =>
@@ -593,10 +593,7 @@ class GpuDynamicPartitionDataSingleWriter(
if (!shouldSplitToFitMaxRecordsPerFile(maxRecordsPerFile, recordsInFile, scb.numRows())) {
writeUpdateMetricsAndClose(scb, writerStatus)
} else {
- val batch = withRetryNoSplit(scb) { scb =>
- scb.getColumnarBatch()
- }
- val splits = splitToFitMaxRecordsAndClose(batch, maxRecordsPerFile, recordsInFile)
+ val splits = splitToFitMaxRecordsAndCloseWithRetry(scb, maxRecordsPerFile, recordsInFile)
withResource(splits) { _ =>
val needNewWriterForFirstPart = recordsInFile >= maxRecordsPerFile
splits.zipWithIndex.foreach { case (part, partIx) =>
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/RapidsShuffleInternalManagerBase.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/RapidsShuffleInternalManagerBase.scala
index 05bc76c3fab..fc255a6bfd0 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/RapidsShuffleInternalManagerBase.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/RapidsShuffleInternalManagerBase.scala
@@ -42,6 +42,7 @@ import org.apache.spark.shuffle.{ShuffleWriter, _}
import org.apache.spark.shuffle.api._
import org.apache.spark.shuffle.sort.{BypassMergeSortShuffleHandle, SortShuffleManager}
import org.apache.spark.sql.execution.metric.SQLMetric
+import org.apache.spark.sql.rapids.execution.GpuShuffleExchangeExecBase.{METRIC_DATA_READ_SIZE, METRIC_DATA_SIZE, METRIC_SHUFFLE_COMBINE_TIME, METRIC_SHUFFLE_DESERIALIZATION_TIME, METRIC_SHUFFLE_READ_TIME, METRIC_SHUFFLE_SERIALIZATION_TIME, METRIC_SHUFFLE_WRITE_IO_TIME, METRIC_SHUFFLE_WRITE_TIME}
import org.apache.spark.sql.rapids.shims.{GpuShuffleBlockResolver, RapidsShuffleThreadedReader, RapidsShuffleThreadedWriter}
import org.apache.spark.sql.vectorized.ColumnarBatch
import org.apache.spark.storage.{RapidsShuffleBlockFetcherIterator, _}
@@ -246,13 +247,13 @@ abstract class RapidsShuffleThreadedWriterBase[K, V](
with RapidsShuffleWriterShimHelper {
private val metrics = handle.metrics
private val serializationTimeMetric =
- metrics.get("rapidsShuffleSerializationTime")
+ metrics.get(METRIC_SHUFFLE_SERIALIZATION_TIME)
private val shuffleWriteTimeMetric =
- metrics.get("rapidsShuffleWriteTime")
+ metrics.get(METRIC_SHUFFLE_WRITE_TIME)
private val shuffleCombineTimeMetric =
- metrics.get("rapidsShuffleCombineTime")
+ metrics.get(METRIC_SHUFFLE_COMBINE_TIME)
private val ioTimeMetric =
- metrics.get("rapidsShuffleWriteIoTime")
+ metrics.get(METRIC_SHUFFLE_WRITE_IO_TIME)
private val dep: ShuffleDependency[K, V, V] = handle.dependency
private val shuffleId = dep.shuffleId
private val partitioner = dep.partitioner
@@ -596,9 +597,9 @@ abstract class RapidsShuffleThreadedReaderBase[K, C](
private val sqlMetrics = handle.metrics
private val dep = handle.dependency
- private val deserializationTimeNs = sqlMetrics.get("rapidsShuffleDeserializationTime")
- private val shuffleReadTimeNs = sqlMetrics.get("rapidsShuffleReadTime")
- private val dataReadSize = sqlMetrics.get("dataReadSize")
+ private val deserializationTimeNs = sqlMetrics.get(METRIC_SHUFFLE_DESERIALIZATION_TIME)
+ private val shuffleReadTimeNs = sqlMetrics.get(METRIC_SHUFFLE_READ_TIME)
+ private val dataReadSize = sqlMetrics.get(METRIC_DATA_READ_SIZE)
private var shuffleReadRange: NvtxRange =
new NvtxRange("ThreadedReader.read", NvtxColor.PURPLE)
@@ -1048,7 +1049,7 @@ class RapidsCachingWriter[K, V](
metrics: Map[String, SQLMetric])
extends RapidsCachingWriterBase[K, V](blockManager, handle, mapId, rapidsShuffleServer, catalog) {
- private val uncompressedMetric: SQLMetric = metrics("dataSize")
+ private val uncompressedMetric: SQLMetric = metrics(METRIC_DATA_SIZE)
// This is here for the special case where we have no columns like with the .count
// case or when we have 0-byte columns. We pick 100 as an arbitrary number so that
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/datetimeExpressions.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/datetimeExpressions.scala
index d08c598cba4..ad14ab400dd 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/datetimeExpressions.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/datetimeExpressions.scala
@@ -27,10 +27,10 @@ import com.nvidia.spark.rapids.Arm._
import com.nvidia.spark.rapids.ExprMeta
import com.nvidia.spark.rapids.GpuOverrides.{extractStringLit, getTimeParserPolicy}
import com.nvidia.spark.rapids.RapidsPluginImplicits._
-import com.nvidia.spark.rapids.jni.GpuTimeZoneDB
+import com.nvidia.spark.rapids.jni.{DateTimeUtils, GpuTimeZoneDB}
import com.nvidia.spark.rapids.shims.{NullIntolerantShim, ShimBinaryExpression, ShimExpression}
-import org.apache.spark.sql.catalyst.expressions.{BinaryExpression, ExpectsInputTypes, Expression, FromUnixTime, FromUTCTimestamp, ImplicitCastInputTypes, MonthsBetween, TimeZoneAwareExpression, ToUTCTimestamp}
+import org.apache.spark.sql.catalyst.expressions.{BinaryExpression, ExpectsInputTypes, Expression, FromUnixTime, FromUTCTimestamp, ImplicitCastInputTypes, MonthsBetween, TimeZoneAwareExpression, ToUTCTimestamp, TruncDate, TruncTimestamp}
import org.apache.spark.sql.catalyst.util.DateTimeConstants
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.types._
@@ -417,12 +417,11 @@ abstract class UnixTimeExprMeta[A <: BinaryExpression with TimeZoneAwareExpressi
}
trait GpuNumberToTimestampUnaryExpression extends GpuUnaryExpression {
-
override def dataType: DataType = TimestampType
override def outputTypeOverride: DType = DType.TIMESTAMP_MICROSECONDS
/**
- * Test whether if input * multiplier will cause Long-overflow. In Math.multiplyExact,
+ * Test whether if input * multiplier will cause Long-overflow. In Math.multiplyExact,
* if there is an integer-overflow, then it will throw an ArithmeticException "long overflow"
*/
def checkLongMultiplicationOverflow(input: ColumnVector, multiplier: Long): Unit = {
@@ -439,7 +438,7 @@ trait GpuNumberToTimestampUnaryExpression extends GpuUnaryExpression {
}
protected val convertTo : GpuColumnVector => ColumnVector
-
+
override def doColumnar(input: GpuColumnVector): ColumnVector = {
convertTo(input)
}
@@ -543,14 +542,14 @@ case class GpuSecondsToTimestamp(child: Expression) extends GpuNumberToTimestamp
longs.asTimestampSeconds()
}
case _ =>
- throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
+ throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
s"for SecondsToTimestamp ")
}
}
case class GpuMillisToTimestamp(child: Expression) extends GpuNumberToTimestampUnaryExpression {
protected lazy val convertTo: GpuColumnVector => ColumnVector = child.dataType match {
- case LongType =>
+ case LongType =>
(input: GpuColumnVector) => {
checkLongMultiplicationOverflow(input.getBase, DateTimeConstants.MICROS_PER_MILLIS)
input.getBase.asTimestampMilliseconds()
@@ -563,7 +562,7 @@ case class GpuMillisToTimestamp(child: Expression) extends GpuNumberToTimestampU
}
}
case _ =>
- throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
+ throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
s"for MillisToTimestamp ")
}
}
@@ -581,7 +580,7 @@ case class GpuMicrosToTimestamp(child: Expression) extends GpuNumberToTimestampU
}
}
case _ =>
- throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
+ throw new UnsupportedOperationException(s"Unsupport type ${child.dataType} " +
s"for MicrosToTimestamp ")
}
}
@@ -1110,7 +1109,7 @@ abstract class ConvertUTCTimestampExprMetaBase[INPUT <: BinaryExpression](
rule: DataFromReplacementRule)
extends BinaryExprMeta[INPUT](expr, conf, parent, rule) {
- protected[this] var timezoneId: ZoneId = null
+ protected[this] var timezoneId: ZoneId = null
override def tagExprForGpu(): Unit = {
extractStringLit(expr.right) match {
@@ -1527,3 +1526,141 @@ case class GpuLastDay(startDate: Expression)
override protected def doColumnar(input: GpuColumnVector): ColumnVector =
input.getBase.lastDayOfMonth()
}
+
+abstract class GpuTruncDateTime(fmtStr: Option[String]) extends GpuBinaryExpression
+ with ImplicitCastInputTypes with Serializable {
+ override def nullable: Boolean = true
+
+ protected def truncate(datetimeCol: GpuColumnVector, fmtCol: GpuColumnVector): ColumnVector = {
+ DateTimeUtils.truncate(datetimeCol.getBase, fmtCol.getBase)
+ }
+
+ protected def truncate(datetimeVal: GpuScalar, fmtCol: GpuColumnVector): ColumnVector = {
+ withResource(ColumnVector.fromScalar(datetimeVal.getBase, 1)) { datetimeCol =>
+ DateTimeUtils.truncate(datetimeCol, fmtCol.getBase)
+ }
+ }
+
+ protected def truncate(datetimeCol: GpuColumnVector, fmtVal: GpuScalar): ColumnVector = {
+ // fmtVal is unused, as it was extracted to `fmtStr` before.
+ fmtStr match {
+ case Some(fmt) => DateTimeUtils.truncate(datetimeCol.getBase, fmt)
+ case None => throw new IllegalArgumentException("Invalid format string.")
+ }
+ }
+
+ protected def truncate(numRows: Int, datetimeVal: GpuScalar, fmtVal: GpuScalar): ColumnVector = {
+ // fmtVal is unused, as it was extracted to `fmtStr` before.
+ fmtStr match {
+ case Some(fmt) =>
+ withResource(ColumnVector.fromScalar(datetimeVal.getBase, 1)) { datetimeCol =>
+ val truncated = DateTimeUtils.truncate(datetimeCol, fmt)
+ if (numRows == 1) {
+ truncated
+ } else {
+ withResource(truncated) { _ =>
+ withResource(truncated.getScalarElement(0)) { truncatedScalar =>
+ ColumnVector.fromScalar(truncatedScalar, numRows)
+ }
+ }
+ }
+ }
+ case None => throw new IllegalArgumentException("Invalid format string.")
+ }
+ }
+}
+
+case class GpuTruncDate(date: Expression, fmt: Expression, fmtStr: Option[String])
+ extends GpuTruncDateTime(fmtStr) {
+ override def left: Expression = date
+
+ override def right: Expression = fmt
+
+ override def inputTypes: Seq[AbstractDataType] = Seq(DateType, StringType)
+
+ override def dataType: DataType = DateType
+
+ override def prettyName: String = "trunc"
+
+ override def doColumnar(lhs: GpuColumnVector, rhs: GpuColumnVector): ColumnVector = {
+ truncate(lhs, rhs)
+ }
+
+ override def doColumnar(lhs: GpuScalar, rhs: GpuColumnVector): ColumnVector = {
+ truncate(lhs, rhs)
+ }
+
+ override def doColumnar(lhs: GpuColumnVector, rhs: GpuScalar): ColumnVector = {
+ truncate(lhs, rhs)
+ }
+
+ override def doColumnar(numRows: Int, lhs: GpuScalar, rhs: GpuScalar): ColumnVector = {
+ truncate(numRows, lhs, rhs)
+ }
+}
+
+case class GpuTruncTimestamp(fmt: Expression, timestamp: Expression, timeZoneId: Option[String],
+ fmtStr: Option[String])
+ extends GpuTruncDateTime(fmtStr) with TimeZoneAwareExpression {
+
+ override def withTimeZone(timeZoneId: String): TimeZoneAwareExpression = {
+ copy(timeZoneId = Option(timeZoneId))
+ }
+
+ override def left: Expression = fmt
+
+ override def right: Expression = timestamp
+
+ override def inputTypes: Seq[AbstractDataType] = Seq(StringType, TimestampType)
+
+ override def dataType: DataType = TimestampType
+
+ override def prettyName: String = "date_trunc"
+
+ // Since the input order of this class is opposite compared to the `GpuTruncDate` class,
+ // we need to switch `lhs` and `rhs` in the `doColumnar` methods below.
+
+ override def doColumnar(lhs: GpuColumnVector, rhs: GpuColumnVector): ColumnVector = {
+ truncate(rhs, lhs)
+ }
+
+ override def doColumnar(lhs: GpuScalar, rhs: GpuColumnVector): ColumnVector = {
+ truncate(rhs, lhs)
+ }
+
+ override def doColumnar(lhs: GpuColumnVector, rhs: GpuScalar): ColumnVector = {
+ truncate(rhs, lhs)
+ }
+
+ override def doColumnar(numRows: Int, lhs: GpuScalar, rhs: GpuScalar): ColumnVector = {
+ truncate(numRows, rhs, lhs)
+ }
+}
+
+class TruncDateExprMeta(expr: TruncDate,
+ override val conf: RapidsConf,
+ override val parent: Option[RapidsMeta[_, _, _]],
+ rule: DataFromReplacementRule)
+ extends BinaryExprMeta[TruncDate](expr, conf, parent, rule) {
+
+ // Store the format string as we need to process it on the CPU later on.
+ private val fmtStr = extractStringLit(expr.format)
+
+ override def convertToGpu(date: Expression, format: Expression): GpuExpression = {
+ GpuTruncDate(date, format, fmtStr)
+ }
+}
+
+class TruncTimestampExprMeta(expr: TruncTimestamp,
+ override val conf: RapidsConf,
+ override val parent: Option[RapidsMeta[_, _, _]],
+ rule: DataFromReplacementRule)
+ extends BinaryExprMeta[TruncTimestamp](expr, conf, parent, rule) {
+
+ // Store the format string as we need to process it on the CPU later on.
+ private val fmtStr = extractStringLit(expr.format)
+
+ override def convertToGpu(format: Expression, timestamp: Expression): GpuExpression = {
+ GpuTruncTimestamp(format, timestamp, expr.timeZoneId, fmtStr)
+ }
+}
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuBroadcastNestedLoopJoinExecBase.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuBroadcastNestedLoopJoinExecBase.scala
index b939a8c4155..21166437d36 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuBroadcastNestedLoopJoinExecBase.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuBroadcastNestedLoopJoinExecBase.scala
@@ -700,17 +700,18 @@ abstract class GpuBroadcastNestedLoopJoinExecBase(
val spillable = SpillableColumnarBatch(batch, SpillPriorities.ACTIVE_ON_DECK_PRIORITY)
withRetry(spillable, RmmRapidsRetryIterator.splitSpillableInHalfByRows) { spillBatch =>
withResource(spillBatch.getColumnarBatch()) { batch =>
- GpuColumnVector.incRefCounts(batch)
- val newCols = new Array[ColumnVector](batch.numCols + 1)
- (0 until newCols.length - 1).foreach { i =>
- newCols(i) = batch.column(i)
- }
- val existsCol = withResource(Scalar.fromBool(exists)) { existsScalar =>
- GpuColumnVector.from(cudf.ColumnVector.fromScalar(existsScalar, batch.numRows),
- BooleanType)
+ closeOnExcept(GpuColumnVector.incRefCounts(batch)) { _ =>
+ val newCols = new Array[ColumnVector](batch.numCols + 1)
+ (0 until newCols.length - 1).foreach { i =>
+ newCols(i) = batch.column(i)
+ }
+ val existsCol = withResource(Scalar.fromBool(exists)) { existsScalar =>
+ GpuColumnVector.from(cudf.ColumnVector.fromScalar(existsScalar, batch.numRows),
+ BooleanType)
+ }
+ newCols(batch.numCols) = existsCol
+ new ColumnarBatch(newCols, batch.numRows)
}
- newCols(batch.numCols) = existsCol
- new ColumnarBatch(newCols, batch.numRows)
}
}
}
diff --git a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuShuffleExchangeExecBase.scala b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuShuffleExchangeExecBase.scala
index f17cfbac13f..332545a99e1 100644
--- a/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuShuffleExchangeExecBase.scala
+++ b/sql-plugin/src/main/scala/org/apache/spark/sql/rapids/execution/GpuShuffleExchangeExecBase.scala
@@ -20,6 +20,7 @@ import scala.collection.AbstractIterator
import scala.concurrent.Future
import com.nvidia.spark.rapids._
+import com.nvidia.spark.rapids.GpuMetric.{DEBUG_LEVEL, ESSENTIAL_LEVEL, MODERATE_LEVEL}
import com.nvidia.spark.rapids.RapidsPluginImplicits._
import com.nvidia.spark.rapids.shims.{GpuHashPartitioning, GpuRangePartitioning, ShimUnaryExecNode, ShuffleOriginUtil, SparkShimImpl}
@@ -37,6 +38,7 @@ import org.apache.spark.sql.execution.exchange.{Exchange, ShuffleExchangeExec}
import org.apache.spark.sql.execution.metric._
import org.apache.spark.sql.internal.SQLConf
import org.apache.spark.sql.rapids.GpuShuffleDependency
+import org.apache.spark.sql.rapids.execution.GpuShuffleExchangeExecBase.createAdditionalExchangeMetrics
import org.apache.spark.sql.types.DataType
import org.apache.spark.sql.vectorized.ColumnarBatch
import org.apache.spark.util.MutablePair
@@ -195,24 +197,11 @@ abstract class GpuShuffleExchangeExecBase(
SQLShuffleWriteMetricsReporter.createShuffleWriteMetrics(sparkContext)
lazy val readMetrics =
SQLShuffleReadMetricsReporter.createShuffleReadMetrics(sparkContext)
- override lazy val additionalMetrics : Map[String, GpuMetric] = Map(
- // dataSize and dataReadSize are uncompressed, one is on write and the
- // other on read
- "dataSize" -> createSizeMetric(ESSENTIAL_LEVEL,"data size"),
- "dataReadSize" -> createSizeMetric(MODERATE_LEVEL, "data read size"),
- "rapidsShuffleSerializationTime" ->
- createNanoTimingMetric(DEBUG_LEVEL,"rs. serialization time"),
- "rapidsShuffleDeserializationTime" ->
- createNanoTimingMetric(DEBUG_LEVEL,"rs. deserialization time"),
- "rapidsShuffleWriteTime" ->
- createNanoTimingMetric(ESSENTIAL_LEVEL,"rs. shuffle write time"),
- "rapidsShuffleCombineTime" ->
- createNanoTimingMetric(DEBUG_LEVEL,"rs. shuffle combine time"),
- "rapidsShuffleWriteIoTime" ->
- createNanoTimingMetric(DEBUG_LEVEL,"rs. shuffle write io time"),
- "rapidsShuffleReadTime" ->
- createNanoTimingMetric(ESSENTIAL_LEVEL,"rs. shuffle read time")
- ) ++ GpuMetric.wrap(readMetrics) ++ GpuMetric.wrap(writeMetrics)
+ override lazy val additionalMetrics : Map[String, GpuMetric] = {
+ createAdditionalExchangeMetrics(this) ++
+ GpuMetric.wrap(readMetrics) ++
+ GpuMetric.wrap(writeMetrics)
+ }
// Spark doesn't report totalTime for this operator so we override metrics
override lazy val allMetrics: Map[String, GpuMetric] = Map(
@@ -233,7 +222,7 @@ abstract class GpuShuffleExchangeExecBase(
// This value must be lazy because the child's output may not have been resolved
// yet in all cases.
private lazy val serializer: Serializer = new GpuColumnarBatchSerializer(
- gpuLongMetric("dataSize"), sparkTypes, useKudo)
+ allMetrics, sparkTypes, useKudo)
@transient lazy val inputBatchRDD: RDD[ColumnarBatch] = child.executeColumnar()
@@ -276,6 +265,66 @@ abstract class GpuShuffleExchangeExecBase(
}
object GpuShuffleExchangeExecBase {
+ val METRIC_DATA_SIZE = "dataSize"
+ val METRIC_DESC_DATA_SIZE = "data size"
+ val METRIC_DATA_READ_SIZE = "dataReadSize"
+ val METRIC_DESC_DATA_READ_SIZE = "data read size"
+ val METRIC_SHUFFLE_SERIALIZATION_TIME = "rapidsShuffleSerializationTime"
+ val METRIC_DESC_SHUFFLE_SERIALIZATION_TIME = "RAPIDS shuffle serialization time"
+ val METRIC_SHUFFLE_SER_STREAM_TIME = "rapidsShuffleSerializationStreamTime"
+ val METRIC_DESC_SHUFFLE_SER_STREAM_TIME = "RAPIDS shuffle serialization to output stream time"
+ val METRIC_SHUFFLE_DESERIALIZATION_TIME = "rapidsShuffleDeserializationTime"
+ val METRIC_DESC_SHUFFLE_DESERIALIZATION_TIME = "RAPIDS shuffle deserialization time"
+ val METRIC_SHUFFLE_DESER_STREAM_TIME = "rapidsShuffleDeserializationStreamTime"
+ val METRIC_DESC_SHUFFLE_DESER_STREAM_TIME =
+ "RAPIDS shuffle deserialization from input stream time"
+ val METRIC_SHUFFLE_PARTITION_TIME = "rapidsShufflePartitionTime"
+ val METRIC_DESC_SHUFFLE_PARTITION_TIME = "RAPIDS shuffle partition time"
+ val METRIC_SHUFFLE_WRITE_TIME = "rapidsShuffleWriteTime"
+ val METRIC_DESC_SHUFFLE_WRITE_TIME = "RAPIDS shuffle shuffle write time"
+ val METRIC_SHUFFLE_COMBINE_TIME = "rapidsShuffleCombineTime"
+ val METRIC_DESC_SHUFFLE_COMBINE_TIME = "RAPIDS shuffle shuffle combine time"
+ val METRIC_SHUFFLE_WRITE_IO_TIME = "rapidsShuffleWriteIoTime"
+ val METRIC_DESC_SHUFFLE_WRITE_IO_TIME = "RAPIDS shuffle shuffle write io time"
+ val METRIC_SHUFFLE_READ_TIME = "rapidsShuffleReadTime"
+ val METRIC_DESC_SHUFFLE_READ_TIME = "RAPIDS shuffle shuffle read time"
+ val METRIC_SHUFFLE_SER_CALC_HEADER_TIME = "rapidsShuffleSerializationCalcHeaderTime"
+ val METRIC_DESC_SHUFFLE_SER_CALC_HEADER_TIME = "RAPIDS shuffle serialization calc header time"
+ val METRIC_SHUFFLE_SER_COPY_HEADER_TIME = "rapidsShuffleSerializationCopyHeaderTime"
+ val METRIC_DESC_SHUFFLE_SER_COPY_HEADER_TIME = "RAPIDS shuffle serialization copy header time"
+ val METRIC_SHUFFLE_SER_COPY_BUFFER_TIME = "rapidsShuffleSerializationCopyBufferTime"
+ val METRIC_DESC_SHUFFLE_SER_COPY_BUFFER_TIME = "RAPIDS shuffle serialization copy buffer time"
+
+ def createAdditionalExchangeMetrics(gpu: GpuExec): Map[String, GpuMetric] = Map(
+ // dataSize and dataReadSize are uncompressed, one is on write and the other on read
+ METRIC_DATA_SIZE -> gpu.createSizeMetric(ESSENTIAL_LEVEL, METRIC_DESC_DATA_SIZE),
+ METRIC_DATA_READ_SIZE -> gpu.createSizeMetric(MODERATE_LEVEL, METRIC_DESC_DATA_READ_SIZE),
+ METRIC_SHUFFLE_SERIALIZATION_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL,METRIC_DESC_SHUFFLE_SERIALIZATION_TIME),
+ METRIC_SHUFFLE_SER_STREAM_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_SER_STREAM_TIME),
+ METRIC_SHUFFLE_DESERIALIZATION_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_DESERIALIZATION_TIME),
+ METRIC_SHUFFLE_DESER_STREAM_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_DESER_STREAM_TIME),
+ METRIC_SHUFFLE_PARTITION_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_PARTITION_TIME),
+ METRIC_SHUFFLE_WRITE_TIME ->
+ gpu.createNanoTimingMetric(ESSENTIAL_LEVEL, METRIC_DESC_SHUFFLE_WRITE_TIME),
+ METRIC_SHUFFLE_COMBINE_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_COMBINE_TIME),
+ METRIC_SHUFFLE_WRITE_IO_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_WRITE_IO_TIME),
+ METRIC_SHUFFLE_READ_TIME ->
+ gpu.createNanoTimingMetric(ESSENTIAL_LEVEL, METRIC_DESC_SHUFFLE_READ_TIME),
+ METRIC_SHUFFLE_SER_CALC_HEADER_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_SER_CALC_HEADER_TIME),
+ METRIC_SHUFFLE_SER_COPY_HEADER_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_SER_COPY_HEADER_TIME),
+ METRIC_SHUFFLE_SER_COPY_BUFFER_TIME ->
+ gpu.createNanoTimingMetric(DEBUG_LEVEL, METRIC_DESC_SHUFFLE_SER_COPY_BUFFER_TIME)
+ )
+
def prepareBatchShuffleDependency(
rdd: RDD[ColumnarBatch],
outputAttributes: Seq[Attribute],
@@ -315,8 +364,11 @@ object GpuShuffleExchangeExecBase {
rdd
}
val partitioner: GpuExpression = getPartitioner(newRdd, outputAttributes, newPartitioning)
+ val partitionTime: GpuMetric = metrics(METRIC_SHUFFLE_PARTITION_TIME)
def getPartitioned: ColumnarBatch => Any = {
- batch => partitioner.columnarEvalAny(batch)
+ batch => partitionTime.ns {
+ partitioner.columnarEvalAny(batch)
+ }
}
val rddWithPartitionIds: RDD[Product2[Int, ColumnarBatch]] = {
newRdd.mapPartitions { iter =>
diff --git a/sql-plugin/src/main/spark400/scala/org/apache/spark/sql/nvidia/DFUDFShims.scala b/sql-plugin/src/main/spark400/scala/org/apache/spark/sql/nvidia/DFUDFShims.scala
index e67dfb450d8..8343fe5379b 100644
--- a/sql-plugin/src/main/spark400/scala/org/apache/spark/sql/nvidia/DFUDFShims.scala
+++ b/sql-plugin/src/main/spark400/scala/org/apache/spark/sql/nvidia/DFUDFShims.scala
@@ -24,6 +24,6 @@ import org.apache.spark.sql.catalyst.expressions.Expression
import org.apache.spark.sql.internal.ExpressionUtils.{column, expression}
object DFUDFShims {
- def columnToExpr(c: Column): Expression = c
- def exprToColumn(e: Expression): Column = e
+ def columnToExpr(c: Column): Expression = expression(c)
+ def exprToColumn(e: Expression): Column = column(e)
}
diff --git a/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutorSuite.scala b/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutorSuite.scala
index a8acf240878..86fb692cd64 100644
--- a/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutorSuite.scala
+++ b/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/ThrottlingExecutorSuite.scala
@@ -73,17 +73,17 @@ class ThrottlingExecutorSuite extends AnyFunSuite with BeforeAndAfterEach {
assertResult(0)(throttle.getTotalHostMemoryBytes)
}
- test("tasks submission fails if total weight exceeds maxWeight") {
+ test("tasks submission fails if totalHostMemoryBytes exceeds maxHostMemoryBytes") {
val task1 = new TestTask
val future1 = executor.submit(task1, 10)
assertResult(1)(trafficController.numScheduledTasks)
assertResult(10)(throttle.getTotalHostMemoryBytes)
val task2 = new TestTask
- val task2Weight = 100
+ val task2HostMemory = 100
val exec = Executors.newSingleThreadExecutor()
val future2 = exec.submit(new Runnable {
- override def run(): Unit = executor.submit(task2, task2Weight)
+ override def run(): Unit = executor.submit(task2, task2HostMemory)
})
Thread.sleep(100)
assert(!future2.isDone)
@@ -94,10 +94,10 @@ class ThrottlingExecutorSuite extends AnyFunSuite with BeforeAndAfterEach {
future1.get(longTimeoutSec, TimeUnit.SECONDS)
future2.get(longTimeoutSec, TimeUnit.SECONDS)
assertResult(1)(trafficController.numScheduledTasks)
- assertResult(task2Weight)(throttle.getTotalHostMemoryBytes)
+ assertResult(task2HostMemory)(throttle.getTotalHostMemoryBytes)
}
- test("submit one task heavier than maxWeight") {
+ test("submit one task heavier than maxHostMemoryBytes") {
val future = executor.submit(() => Thread.sleep(10), throttle.maxInFlightHostMemoryBytes + 1)
future.get(longTimeoutSec, TimeUnit.SECONDS)
assert(future.isDone)
@@ -105,7 +105,7 @@ class ThrottlingExecutorSuite extends AnyFunSuite with BeforeAndAfterEach {
assertResult(0)(throttle.getTotalHostMemoryBytes)
}
- test("submit multiple tasks such that total weight does not exceed maxWeight") {
+ test("submit multiple tasks such that totalHostMemoryBytes does not exceed maxHostMemoryBytes") {
val numTasks = 10
val taskRunTime = 10
var future: Future[Unit] = null
@@ -125,10 +125,10 @@ class ThrottlingExecutorSuite extends AnyFunSuite with BeforeAndAfterEach {
assertResult(10)(throttle.getTotalHostMemoryBytes)
val task2 = new TestTask
- val task2Weight = 100
+ val task2HostMemory = 100
val exec = Executors.newSingleThreadExecutor()
val future2 = exec.submit(new Runnable {
- override def run(): Unit = executor.submit(task2, task2Weight)
+ override def run(): Unit = executor.submit(task2, task2HostMemory)
})
executor.shutdownNow(longTimeoutSec, TimeUnit.SECONDS)
diff --git a/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/TrafficControllerSuite.scala b/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/TrafficControllerSuite.scala
index 32868ff6055..1c06755a8af 100644
--- a/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/TrafficControllerSuite.scala
+++ b/sql-plugin/src/test/scala/com/nvidia/spark/rapids/io/async/TrafficControllerSuite.scala
@@ -16,19 +16,34 @@
package com.nvidia.spark.rapids.io.async
-import java.util.concurrent.{ExecutionException, Executors, ExecutorService, TimeUnit}
+import java.util.concurrent.{ExecutionException, Executors, ExecutorService, Future, TimeUnit}
import org.scalatest.BeforeAndAfterEach
+import org.scalatest.concurrent.TimeLimitedTests
import org.scalatest.funsuite.AnyFunSuite
+import org.scalatest.time.Span
+import org.scalatest.time.SpanSugar._
-class TrafficControllerSuite extends AnyFunSuite with BeforeAndAfterEach {
+class TrafficControllerSuite extends AnyFunSuite with BeforeAndAfterEach with TimeLimitedTests {
- private var throttle: HostMemoryThrottle = _
+ class RecordingExecOrderHostMemoryThrottle(maxInFlightHostMemoryBytes: Long)
+ extends HostMemoryThrottle(maxInFlightHostMemoryBytes) {
+ var tasksScheduled = Seq.empty[TestTask]
+
+ override def taskScheduled[T](task: Task[T]): Unit = {
+ tasksScheduled = tasksScheduled :+ task.asInstanceOf[TestTask]
+ super.taskScheduled(task)
+ }
+ }
+
+ val timeLimit: Span = 10.seconds
+
+ private var throttle: RecordingExecOrderHostMemoryThrottle = _
private var controller: TrafficController = _
private var executor: ExecutorService = _
override def beforeEach(): Unit = {
- throttle = new HostMemoryThrottle(100)
+ throttle = new RecordingExecOrderHostMemoryThrottle(100)
controller = new TrafficController(throttle)
executor = Executors.newSingleThreadExecutor()
}
@@ -76,6 +91,63 @@ class TrafficControllerSuite extends AnyFunSuite with BeforeAndAfterEach {
f.get(1, TimeUnit.SECONDS)
}
+ test("big task should be scheduled after all running tasks are completed") {
+ val taskMemoryBytes = 50
+ val t1 = new TestTask(taskMemoryBytes)
+ controller.blockUntilRunnable(t1)
+
+ val t2 = new TestTask(150)
+ val f = executor.submit(new Runnable {
+ override def run(): Unit = controller.blockUntilRunnable(t2)
+ })
+ Thread.sleep(100)
+ assert(!f.isDone)
+
+ controller.taskCompleted(t1)
+ f.get(1, TimeUnit.SECONDS)
+ }
+
+ test("all tasks are bigger than the total memory limit") {
+ val bigTaskMemoryBytes = 130
+ val (tasks, futures) = (0 to 2).map { _ =>
+ val t = new TestTask(bigTaskMemoryBytes)
+ val f: Future[_] = executor.submit(new Runnable {
+ override def run(): Unit = controller.blockUntilRunnable(t)
+ })
+ (t, f.asInstanceOf[Future[Unit]])
+ }.unzip
+ while (controller.numScheduledTasks == 0) {
+ Thread.sleep(100)
+ }
+ assert(futures(0).isDone)
+ assertResult(1)(controller.numScheduledTasks)
+ assertResult(throttle.tasksScheduled.head)(tasks(0))
+
+ // The first task has been completed
+ controller.taskCompleted(tasks(0))
+ // Wait for the second task to be scheduled
+ while (controller.numScheduledTasks == 0) {
+ Thread.sleep(100)
+ }
+ assert(futures(1).isDone)
+ assertResult(1)(controller.numScheduledTasks)
+ assertResult(throttle.tasksScheduled(1))(tasks(1))
+
+ // The second task has been completed
+ controller.taskCompleted(tasks(1))
+ // Wait for the third task to be scheduled
+ while (controller.numScheduledTasks == 0) {
+ Thread.sleep(100)
+ }
+ assert(futures(2).isDone)
+ assertResult(1)(controller.numScheduledTasks)
+ assertResult(throttle.tasksScheduled(2))(tasks(2))
+
+ // The third task has been completed
+ controller.taskCompleted(tasks(2))
+ assertResult(0)(controller.numScheduledTasks)
+ }
+
test("shutdown while blocking") {
val t1 = new TestTask(10)
controller.blockUntilRunnable(t1)
diff --git a/tests/pom.xml b/tests/pom.xml
index a8fef6b7930..bc67c0c3de0 100644
--- a/tests/pom.xml
+++ b/tests/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-tests_2.12
RAPIDS Accelerator for Apache Spark Tests
RAPIDS plugin for Apache Spark integration tests
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
tests
diff --git a/tests/src/test/scala/com/nvidia/spark/rapids/StringFunctionSuite.scala b/tests/src/test/scala/com/nvidia/spark/rapids/StringFunctionSuite.scala
index 3c3933946c5..25c8c10b26d 100644
--- a/tests/src/test/scala/com/nvidia/spark/rapids/StringFunctionSuite.scala
+++ b/tests/src/test/scala/com/nvidia/spark/rapids/StringFunctionSuite.scala
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2023, NVIDIA CORPORATION.
+ * Copyright (c) 2019-2024, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -207,7 +207,8 @@ class RegExpUtilsSuite extends AnyFunSuite {
"aa|bb|cc|dd" -> Seq("aa", "bb", "cc", "dd"),
"(aa|bb)|(cc|dd)" -> Seq("aa", "bb", "cc", "dd"),
"aa|bb|cc|dd|ee" -> Seq("aa", "bb", "cc", "dd", "ee"),
- "aa|bb|cc|dd|ee|ff" -> Seq("aa", "bb", "cc", "dd", "ee", "ff")
+ "aa|bb|cc|dd|ee|ff" -> Seq("aa", "bb", "cc", "dd", "ee", "ff"),
+ "a\n|b\t|c\r" -> Seq("a\n", "b\t", "c\r")
)
regexChoices.foreach { case (pattern, choices) =>
diff --git a/tests/src/test/spark321/scala/org/apache/spark/sql/rapids/RapidsShuffleThreadedReaderSuite.scala b/tests/src/test/spark321/scala/org/apache/spark/sql/rapids/RapidsShuffleThreadedReaderSuite.scala
index 3958dce6fdb..c006031da7d 100644
--- a/tests/src/test/spark321/scala/org/apache/spark/sql/rapids/RapidsShuffleThreadedReaderSuite.scala
+++ b/tests/src/test/spark321/scala/org/apache/spark/sql/rapids/RapidsShuffleThreadedReaderSuite.scala
@@ -113,7 +113,8 @@ class RapidsShuffleThreadedReaderSuite
val shuffleId = 22
val numMaps = 6
val keyValuePairsPerMap = 10
- val serializer = new GpuColumnarBatchSerializer(NoopMetric, Array.empty, false)
+ val serializer = new GpuColumnarBatchSerializer(Map.empty.withDefaultValue(NoopMetric),
+ Array.empty, false)
// Make a mock BlockManager that will return RecordingManagedByteBuffers of data, so that we
// can ensure retain() and release() are properly called.
diff --git a/tools/generated_files/320/operatorsScore.csv b/tools/generated_files/320/operatorsScore.csv
index 19c999aa796..d8c4ca63adc 100644
--- a/tools/generated_files/320/operatorsScore.csv
+++ b/tools/generated_files/320/operatorsScore.csv
@@ -265,6 +265,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/320/supportedExprs.csv b/tools/generated_files/320/supportedExprs.csv
index e4a4db760b0..80fc939ee68 100644
--- a/tools/generated_files/320/supportedExprs.csv
+++ b/tools/generated_files/320/supportedExprs.csv
@@ -606,6 +606,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/321/operatorsScore.csv b/tools/generated_files/321/operatorsScore.csv
index 19c999aa796..d8c4ca63adc 100644
--- a/tools/generated_files/321/operatorsScore.csv
+++ b/tools/generated_files/321/operatorsScore.csv
@@ -265,6 +265,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/321/supportedExprs.csv b/tools/generated_files/321/supportedExprs.csv
index e4a4db760b0..80fc939ee68 100644
--- a/tools/generated_files/321/supportedExprs.csv
+++ b/tools/generated_files/321/supportedExprs.csv
@@ -606,6 +606,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/330/operatorsScore.csv b/tools/generated_files/330/operatorsScore.csv
index e5978fb9f1a..e86e30e606c 100644
--- a/tools/generated_files/330/operatorsScore.csv
+++ b/tools/generated_files/330/operatorsScore.csv
@@ -275,6 +275,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/330/supportedExprs.csv b/tools/generated_files/330/supportedExprs.csv
index 0073281cb32..38a6042dc5c 100644
--- a/tools/generated_files/330/supportedExprs.csv
+++ b/tools/generated_files/330/supportedExprs.csv
@@ -627,6 +627,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/331/operatorsScore.csv b/tools/generated_files/331/operatorsScore.csv
index b988344e702..229201ba885 100644
--- a/tools/generated_files/331/operatorsScore.csv
+++ b/tools/generated_files/331/operatorsScore.csv
@@ -276,6 +276,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/331/supportedExprs.csv b/tools/generated_files/331/supportedExprs.csv
index f62af4c9513..12a4d1e0cf4 100644
--- a/tools/generated_files/331/supportedExprs.csv
+++ b/tools/generated_files/331/supportedExprs.csv
@@ -629,6 +629,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/340/operatorsScore.csv b/tools/generated_files/340/operatorsScore.csv
index b1e9198e58b..16ac93a02ba 100644
--- a/tools/generated_files/340/operatorsScore.csv
+++ b/tools/generated_files/340/operatorsScore.csv
@@ -277,6 +277,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/340/supportedExprs.csv b/tools/generated_files/340/supportedExprs.csv
index 01a48b40249..f2d5a4f0736 100644
--- a/tools/generated_files/340/supportedExprs.csv
+++ b/tools/generated_files/340/supportedExprs.csv
@@ -629,6 +629,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/342/operatorsScore.csv b/tools/generated_files/342/operatorsScore.csv
index b1e9198e58b..16ac93a02ba 100644
--- a/tools/generated_files/342/operatorsScore.csv
+++ b/tools/generated_files/342/operatorsScore.csv
@@ -277,6 +277,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/342/supportedExprs.csv b/tools/generated_files/342/supportedExprs.csv
index 01a48b40249..f2d5a4f0736 100644
--- a/tools/generated_files/342/supportedExprs.csv
+++ b/tools/generated_files/342/supportedExprs.csv
@@ -629,6 +629,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/400/operatorsScore.csv b/tools/generated_files/400/operatorsScore.csv
index 53791a06705..0a099fc2233 100644
--- a/tools/generated_files/400/operatorsScore.csv
+++ b/tools/generated_files/400/operatorsScore.csv
@@ -278,6 +278,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/400/supportedExprs.csv b/tools/generated_files/400/supportedExprs.csv
index 4cfa1020889..92cb5327d10 100644
--- a/tools/generated_files/400/supportedExprs.csv
+++ b/tools/generated_files/400/supportedExprs.csv
@@ -635,6 +635,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,S,S
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/generated_files/operatorsScore.csv b/tools/generated_files/operatorsScore.csv
index 19c999aa796..d8c4ca63adc 100644
--- a/tools/generated_files/operatorsScore.csv
+++ b/tools/generated_files/operatorsScore.csv
@@ -265,6 +265,8 @@ ToUTCTimestamp,4
ToUnixTimestamp,4
TransformKeys,4
TransformValues,4
+TruncDate,4
+TruncTimestamp,4
UnaryMinus,4
UnaryPositive,4
UnboundedFollowing$,4
diff --git a/tools/generated_files/supportedExprs.csv b/tools/generated_files/supportedExprs.csv
index e4a4db760b0..80fc939ee68 100644
--- a/tools/generated_files/supportedExprs.csv
+++ b/tools/generated_files/supportedExprs.csv
@@ -606,6 +606,12 @@ TransformKeys,S,`transform_keys`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,
TransformValues,S,`transform_values`,None,project,argument,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
TransformValues,S,`transform_values`,None,project,function,S,S,S,S,S,S,S,S,PS,S,S,S,NS,NS,PS,PS,PS,NS,NS,NS
TransformValues,S,`transform_values`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncDate,S,`trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,format,NA,NA,NA,NA,NA,NA,NA,NA,NA,S,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,date,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
+TruncTimestamp,S,`date_trunc`,None,project,result,NA,NA,NA,NA,NA,NA,NA,NA,PS,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA
UnaryMinus,S,`negative`,None,project,input,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,project,result,NA,S,S,S,S,S,S,NA,NA,NA,S,NA,NA,NS,NA,NA,NA,NA,NS,NS
UnaryMinus,S,`negative`,None,AST,input,NA,NS,NS,S,S,S,S,NA,NA,NA,NS,NA,NA,NS,NA,NA,NA,NA,NS,NS
diff --git a/tools/pom.xml b/tools/pom.xml
index df919f112ef..23bae1bcd8d 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -22,14 +22,14 @@
com.nvidia
rapids-4-spark-jdk-profiles_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../jdk-profiles/pom.xml
rapids-4-spark-tools-support
pom
RAPIDS Accelerator for Apache Spark Tools Support
Supporting code for RAPIDS Accelerator tools
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
com.nvidia
diff --git a/udf-compiler/pom.xml b/udf-compiler/pom.xml
index afe827baf78..a32c1d3813f 100644
--- a/udf-compiler/pom.xml
+++ b/udf-compiler/pom.xml
@@ -21,13 +21,13 @@
com.nvidia
rapids-4-spark-shim-deps-parent_2.12
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
../shim-deps/pom.xml
rapids-4-spark-udf_2.12
RAPIDS Accelerator for Apache Spark Scala UDF Plugin
The RAPIDS Scala UDF plugin for Apache Spark
- 24.12.0-SNAPSHOT
+ 25.02.0-SNAPSHOT
udf-compiler