Skip to content

Commit db0bde9

Browse files
againullbb-ur
authored andcommitted
Query timer resolution in cycles/sec for accurate timestamp (#21279)
According to [Level Zero spec](https://oneapi-src.github.io/level-zero-spec/level-zero/latest/core/api.html#_CPPv4N22ze_device_properties_t15timerResolutionE) the meaning of `timerResolution` depends on `stype`: - `ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES` -> units are nanoseconds (`uint64`, already rounded) - `ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2` -> units are cycles/sec (exact value) Previously we queried using `ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES` and used the integer nanosecond value, which introduced rounding error and reduced timestamp accuracy. Instead, query `timerResolution` with `ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2` (cycles/sec) and compute nanoseconds-per-cycle as a double to preserve precision. This fix improves the accuracy of timestamp reported from `urDeviceGetGlobalTimestamps` and others.
1 parent 27b0151 commit db0bde9

7 files changed

Lines changed: 17 additions & 11 deletions

File tree

source/adapters/level_zero/common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ template <> ze_structure_type_t getZeStructureType<ze_driver_properties_t>() {
239239
return ZE_STRUCTURE_TYPE_DRIVER_PROPERTIES;
240240
}
241241
template <> ze_structure_type_t getZeStructureType<ze_device_properties_t>() {
242-
return ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES;
242+
return ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2;
243243
}
244244
template <>
245245
ze_structure_type_t getZeStructureType<ze_device_p2p_properties_t>() {

source/adapters/level_zero/device.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,7 @@ ur_result_t urDeviceGetInfo(
586586
return ReturnValue(static_cast<ur_bool_t>(
587587
Device->ZeDeviceProperties->flags & ZE_DEVICE_PROPERTY_FLAG_ECC));
588588
case UR_DEVICE_INFO_PROFILING_TIMER_RESOLUTION:
589-
return ReturnValue(
590-
static_cast<size_t>(Device->ZeDeviceProperties->timerResolution));
589+
return ReturnValue(static_cast<size_t>(Device->getTimerResolution()));
591590
case UR_DEVICE_INFO_LOCAL_MEM_TYPE:
592591
return ReturnValue(UR_DEVICE_LOCAL_MEM_TYPE_LOCAL);
593592
case UR_DEVICE_INFO_MAX_CONSTANT_ARGS:
@@ -1774,8 +1773,7 @@ ur_result_t urDeviceGetGlobalTimestamps(
17741773
#endif
17751774
}
17761775

1777-
const uint64_t &ZeTimerResolution =
1778-
Device->ZeDeviceProperties->timerResolution;
1776+
const double ZeTimerResolution = Device->getTimerResolution();
17791777
const uint64_t TimestampMaxCount = Device->getTimestampMask();
17801778
uint64_t DeviceClockCount, Dummy;
17811779

source/adapters/level_zero/device.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ struct ur_device_handle_t_ : ur_object {
226226
return ValidBits == 64 ? ~0ULL : (1ULL << ValidBits) - 1ULL;
227227
}
228228

229+
// Get timer resolution in nanoseconds.
230+
// With ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES_1_2, timerResolution is in
231+
// cycles/sec, so we convert to nanoseconds.
232+
double getTimerResolution() {
233+
return 1000000000.0 / ZeDeviceProperties->timerResolution;
234+
}
235+
229236
// Cache of the immutable device properties.
230237
ZeCache<ZeStruct<ze_device_properties_t>> ZeDeviceProperties;
231238
ZeCache<ZeStruct<ze_device_compute_properties_t>> ZeDeviceComputeProperties;

source/adapters/level_zero/event.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ ur_result_t urEventGetProfilingInfo(
539539
ur_device_handle_t Device =
540540
Event->UrQueue ? Event->UrQueue->Device : Event->Context->Devices[0];
541541

542-
uint64_t ZeTimerResolution = Device->ZeDeviceProperties->timerResolution;
542+
const double ZeTimerResolution = Device->getTimerResolution();
543543
const uint64_t TimestampMaxValue = Device->getTimestampMask();
544544

545545
UrReturnHelper ReturnValue(PropValueSize, PropValue, PropValueSizeRet);

source/adapters/level_zero/queue.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,7 @@ ur_result_t ur_queue_handle_t_::active_barriers::clear() {
16181618
}
16191619

16201620
void ur_queue_handle_t_::clearEndTimeRecordings() {
1621-
uint64_t ZeTimerResolution = Device->ZeDeviceProperties->timerResolution;
1621+
const double ZeTimerResolution = Device->getTimerResolution();
16221622
const uint64_t TimestampMaxValue = Device->getTimestampMask();
16231623

16241624
for (auto Entry : EndTimeRecordings) {

source/adapters/level_zero/v2/event.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
static uint64_t adjustEndEventTimestamp(uint64_t adjustedStartTimestamp,
2424
uint64_t endTimestamp,
2525
uint64_t timestampMaxValue,
26-
uint64_t timerResolution) {
26+
double timerResolution) {
2727
// End time needs to be adjusted for resolution and valid bits.
2828
uint64_t adjustedTimestamp =
2929
(endTimestamp & timestampMaxValue) * timerResolution;
@@ -78,7 +78,7 @@ void event_profiling_data_t::reset() {
7878
}
7979

8080
void event_profiling_data_t::recordStartTimestamp(ur_device_handle_t hDevice) {
81-
zeTimerResolution = hDevice->ZeDeviceProperties->timerResolution;
81+
zeTimerResolution = hDevice->getTimerResolution();
8282
timestampMaxValue = hDevice->getTimestampMask();
8383

8484
uint64_t deviceStartTimestamp = 0;
@@ -349,7 +349,7 @@ ur_result_t urEventGetProfilingInfo(
349349

350350
ze_kernel_timestamp_result_t tsResult;
351351

352-
auto zeTimerResolution = hDevice->ZeDeviceProperties->timerResolution;
352+
auto zeTimerResolution = hDevice->getTimerResolution();
353353
auto timestampMaxValue = hDevice->getTimestampMask();
354354

355355
switch (propName) {

source/adapters/level_zero/v2/event.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ struct event_profiling_data_t {
4848
uint64_t recordEventEndTimestamp = 0;
4949
uint64_t adjustedEventEndTimestamp = 0;
5050

51-
uint64_t zeTimerResolution = 0;
51+
// Timer resolution in nanoseconds (converted from cycles/sec)
52+
double zeTimerResolution = 0;
5253
uint64_t timestampMaxValue = 0;
5354

5455
bool timestampRecorded = false;

0 commit comments

Comments
 (0)