forked from NVIDIA/spark-rapids-jni
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGpuTimeZoneDBTest.java
More file actions
113 lines (99 loc) · 4.01 KB
/
GpuTimeZoneDBTest.java
File metadata and controls
113 lines (99 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* Copyright (c) 2025, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nvidia.spark.rapids.jni;
import ai.rapids.cudf.*;
import org.junit.jupiter.api.Test;
import static ai.rapids.cudf.AssertUtils.assertColumnsAreEqual;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
public class GpuTimeZoneDBTest {
private static final long microsPerMillis = TimeUnit.MILLISECONDS.toMicros(1);
/**
* Java implementation of timezone conversion to compare against the GPU
* results.
* Refer to https://github.com/apache/orc/blob/rel/release-1.9.1/java/core/
* src/java/org/apache/orc/impl/SerializationUtils.java#L1440
*/
private static ColumnVector convertOrcTimezonesOnCPU(
long[] microseconds,
String writeTzId,
String readerTzId) {
long[] results = new long[microseconds.length];
TimeZone writeTz = TimeZone.getTimeZone(writeTzId);
TimeZone readerTz = TimeZone.getTimeZone(readerTzId);
for (int i = 0; i < microseconds.length; ++i) {
long millis = microseconds[i] / microsPerMillis;
long writerOffset = writeTz.getOffset(millis);
long readerOffset = readerTz.getOffset(millis);
long adjustedMillis = millis + writerOffset - readerOffset;
long adjustedReader = readerTz.getOffset(adjustedMillis);
long finalDiffs = writerOffset - adjustedReader;
results[i] = (millis + finalDiffs) * microsPerMillis + (microseconds[i] % microsPerMillis);
}
return ColumnVector.timestampMicroSecondsFromLongs(results);
}
@Test
void testConvertOrcTimezones() {
GpuTimeZoneDB.cacheDatabase();
GpuTimeZoneDB.verifyDatabaseCached();
// test time range: (0001-01-01 00:00:00, 9999-12-31 23:59:59)
long min = LocalDateTime.of(1, 1, 1, 0, 0, 0)
.toEpochSecond(ZoneOffset.UTC) * TimeUnit.SECONDS.toMicros(1);
long max = LocalDateTime.of(9999, 12, 31, 23, 59, 59)
.toEpochSecond(ZoneOffset.UTC) * TimeUnit.SECONDS.toMicros(1);
// use today as the random seed so we get different values each day
Random rng = new Random(LocalDate.now().toEpochDay());
List<String> timezones = Arrays.asList(
"America/Los_Angeles",
"Asia/Shanghai",
"Antarctica/DumontDUrville",
"Etc/GMT-12",
"CNT",
"Australia/Sydney",
"Asia/Tokyo");
for (String writerTz : timezones) {
if (GpuTimeZoneDB.isDST(writerTz)) {
// currently do not support DST conversions
continue;
}
for (String readerTz : timezones) {
if (GpuTimeZoneDB.isDST(readerTz)) {
// currently do not support DST conversions
continue;
}
// Use 1024 as a reasonable batch size for testing timezone conversions.
long[] microseconds = new long[1024];
for (int i = 0; i < microseconds.length; ++i) {
// range is years from 0001 to 9999
microseconds[i] = min + (long) (rng.nextDouble() * (max - min));
}
try (ColumnVector input = ColumnVector.timestampMicroSecondsFromLongs(microseconds);
// Convert on CPU
ColumnVector expected = convertOrcTimezonesOnCPU(microseconds, writerTz, readerTz);
// Convert on GPU
ColumnVector actual = GpuTimeZoneDB.convertOrcTimezones(input, writerTz, readerTz)) {
assertColumnsAreEqual(expected, actual);
}
}
}
}
}