Skip to content

Commit

Permalink
Adding an iree_timeout_t type to make timeouts cleaner.
Browse files Browse the repository at this point in the history
This avoids the duplication of _with_deadline/_with_timeout throughout the
HAL.

This change does not try to optimize any of the use-sites. Some of the
Vulkan methods are going rel->abs->rel (and were before, but now it's
clear and easy to fix).
  • Loading branch information
benvanik committed Apr 19, 2021
1 parent c155e7b commit aaf92fa
Show file tree
Hide file tree
Showing 29 changed files with 240 additions and 427 deletions.
59 changes: 57 additions & 2 deletions iree/base/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -781,10 +781,10 @@ typedef int64_t iree_time_t;

// Like absl::Duration, represented as relative nanoseconds.
typedef int64_t iree_duration_t;
// Like absl::InfiniteDuration.
#define IREE_DURATION_INFINITE INT64_MAX
// Like absl::ZeroDuration.
#define IREE_DURATION_ZERO 0
// Like absl::InfiniteDuration.
#define IREE_DURATION_INFINITE INT64_MAX

// Returns the current system time in unix nanoseconds.
// Depending on the system architecture and power mode this time may have a
Expand All @@ -806,6 +806,61 @@ iree_relative_timeout_to_deadline_ns(iree_duration_t timeout_ns);
IREE_API_EXPORT iree_duration_t
iree_absolute_deadline_to_timeout_ns(iree_time_t deadline_ns);

typedef enum {
// Timeout is defined by an absolute value `deadline_ns`.
IREE_TIMEOUT_ABSOLUTE = 0,
// Timeout is defined by a relative value `timeout_ns`.
IREE_TIMEOUT_RELATIVE = 1,
} iree_timeout_type_t;

// A timeout defined either by an absolute or relative value.
typedef struct {
iree_timeout_type_t type;
iree_time_t nanos;
} iree_timeout_t;

// Returns a timeout that will be exceeded immediately.
// This is useful for polling.
static inline iree_timeout_t iree_immediate_timeout() {
iree_timeout_t timeout = {IREE_TIMEOUT_ABSOLUTE, IREE_TIME_INFINITE_PAST};
return timeout;
}

// Returns a timeout that will never be reached.
static inline iree_timeout_t iree_infinite_timeout() {
iree_timeout_t timeout = {IREE_TIMEOUT_ABSOLUTE, IREE_TIME_INFINITE_FUTURE};
return timeout;
}

// Defines an absolute timeout with the given time in nanoseconds.
static inline iree_timeout_t iree_make_deadline(iree_time_t deadline_ns) {
iree_timeout_t timeout = {IREE_TIMEOUT_ABSOLUTE, deadline_ns};
return timeout;
}

// Defines a relative timeout with the given time in nanoseconds.
static inline iree_timeout_t iree_make_timeout(iree_duration_t timeout_ns) {
iree_timeout_t timeout = {IREE_TIMEOUT_RELATIVE, timeout_ns};
return timeout;
}

// Converts a timeout from relative to absolute (if it is).
// Absolute timeouts (deadlines) are significantly better for long-running
// tasks or when making calls that may complete in stages.
static inline void iree_convert_timeout_to_absolute(iree_timeout_t* timeout) {
if (timeout->type == IREE_TIMEOUT_RELATIVE) {
timeout->type = IREE_TIMEOUT_ABSOLUTE;
timeout->nanos = iree_relative_timeout_to_deadline_ns(timeout->nanos);
}
}

// Returns an absolute deadline in nanoseconds from the given timeout.
static inline iree_time_t iree_timeout_as_deadline_ns(iree_timeout_t timeout) {
return timeout.type == IREE_TIMEOUT_ABSOLUTE
? timeout.nanos
: iree_relative_timeout_to_deadline_ns(timeout.nanos);
}

//===----------------------------------------------------------------------===//
// iree_allocator_t (std::allocator-like interface)
//===----------------------------------------------------------------------===//
Expand Down
4 changes: 2 additions & 2 deletions iree/hal/cts/cts_test_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ class CtsTestBase : public ::testing::TestWithParam<std::string> {
/*queue_affinity=*/0,
/*batch_count=*/1, &submission_batch);
if (iree_status_is_ok(status)) {
status = iree_hal_semaphore_wait_with_deadline(signal_semaphore, 1ull,
IREE_TIME_INFINITE_FUTURE);
status = iree_hal_semaphore_wait(signal_semaphore, 1ull,
iree_infinite_timeout());
}

iree_hal_semaphore_release(signal_semaphore);
Expand Down
4 changes: 2 additions & 2 deletions iree/hal/cts/event_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ TEST_P(EventTest, SubmitWithChainedCommandBuffers) {
iree_hal_device_queue_submit(device_, IREE_HAL_COMMAND_CATEGORY_DISPATCH,
/*queue_affinity=*/0,
/*batch_count=*/1, &submission_batch));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
signal_semaphore, 1ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(
iree_hal_semaphore_wait(signal_semaphore, 1ull, iree_infinite_timeout()));

iree_hal_command_buffer_release(command_buffer_1);
iree_hal_command_buffer_release(command_buffer_2);
Expand Down
16 changes: 8 additions & 8 deletions iree/hal/cts/semaphore_submission_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ TEST_P(SemaphoreSubmissionTest, SubmitWithNoCommandBuffers) {
iree_hal_device_queue_submit(device_, IREE_HAL_COMMAND_CATEGORY_DISPATCH,
/*queue_affinity=*/0,
/*batch_count=*/1, &submission_batch));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
signal_semaphore, 1ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(
iree_hal_semaphore_wait(signal_semaphore, 1ull, iree_infinite_timeout()));

iree_hal_semaphore_release(signal_semaphore);
}
Expand Down Expand Up @@ -83,8 +83,8 @@ TEST_P(SemaphoreSubmissionTest, SubmitAndSignal) {
iree_hal_device_queue_submit(device_, IREE_HAL_COMMAND_CATEGORY_DISPATCH,
/*queue_affinity=*/0,
/*batch_count=*/1, &submission_batch));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
signal_semaphore, 1ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(
iree_hal_semaphore_wait(signal_semaphore, 1ull, iree_infinite_timeout()));

iree_hal_command_buffer_release(command_buffer);
iree_hal_semaphore_release(signal_semaphore);
Expand Down Expand Up @@ -132,8 +132,8 @@ TEST_P(SemaphoreSubmissionTest, SubmitWithWait) {

// Signal the wait semaphore, work should begin and complete.
IREE_ASSERT_OK(iree_hal_semaphore_signal(wait_semaphore, 1ull));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
signal_semaphore, 101ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(signal_semaphore, 101ull,
iree_infinite_timeout()));

iree_hal_command_buffer_release(command_buffer);
iree_hal_semaphore_release(wait_semaphore);
Expand Down Expand Up @@ -196,9 +196,9 @@ TEST_P(SemaphoreSubmissionTest, SubmitWithMultipleSemaphores) {
signal_semaphore_list.semaphores = signal_semaphore_ptrs;
uint64_t payload_values[] = {1ull, 1ull};
signal_semaphore_list.payload_values = payload_values;
IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_deadline(
IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ALL, &signal_semaphore_list,
IREE_TIME_INFINITE_FUTURE));
iree_infinite_timeout()));

iree_hal_command_buffer_release(command_buffer);
iree_hal_semaphore_release(wait_semaphore_1);
Expand Down
66 changes: 35 additions & 31 deletions iree/hal/cts/semaphore_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,19 @@ TEST_P(SemaphoreTest, Failure) {

// Tests waiting on no semaphores.
TEST_P(SemaphoreTest, EmptyWait) {
IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_deadline(
device_, IREE_HAL_WAIT_MODE_ANY, NULL, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_deadline(
device_, IREE_HAL_WAIT_MODE_ALL, NULL, IREE_TIME_INFINITE_FUTURE));

IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_timeout(
device_, IREE_HAL_WAIT_MODE_ANY, NULL, IREE_DURATION_INFINITE));
IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_timeout(
device_, IREE_HAL_WAIT_MODE_ALL, NULL, IREE_DURATION_INFINITE));
IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ANY, NULL,
iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));
IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ALL, NULL,
iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));

IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ANY, NULL,
iree_make_timeout(IREE_DURATION_INFINITE)));
IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ALL, NULL,
iree_make_timeout(IREE_DURATION_INFINITE)));
}

// Tests waiting on a semaphore that has already been signaled.
Expand All @@ -103,15 +107,15 @@ TEST_P(SemaphoreTest, DISABLED_WaitAlreadySignaled) {
IREE_ASSERT_OK(iree_hal_semaphore_create(device_, 2ull, &semaphore));

// Test both previous and current values.
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
semaphore, 1ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
semaphore, 2ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
semaphore, 1ull, iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
semaphore, 2ull, iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));

IREE_ASSERT_OK(iree_hal_semaphore_wait_with_timeout(semaphore, 1ull,
IREE_DURATION_INFINITE));
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_timeout(semaphore, 2ull,
IREE_DURATION_INFINITE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
semaphore, 1ull, iree_make_timeout(IREE_DURATION_INFINITE)));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
semaphore, 2ull, iree_make_timeout(IREE_DURATION_INFINITE)));

iree_hal_semaphore_release(semaphore);
}
Expand All @@ -124,8 +128,8 @@ TEST_P(SemaphoreTest, WaitUnsignaled) {
// NOTE: we don't actually block here because otherwise we'd lock up.
// Result status is undefined - some backends may return DeadlineExceededError
// while others may return success.
IREE_IGNORE_ERROR(iree_hal_semaphore_wait_with_deadline(
semaphore, 3ull, IREE_TIME_INFINITE_PAST));
IREE_IGNORE_ERROR(iree_hal_semaphore_wait(
semaphore, 3ull, iree_make_deadline(IREE_TIME_INFINITE_PAST)));

iree_hal_semaphore_release(semaphore);
}
Expand All @@ -150,9 +154,9 @@ TEST_P(SemaphoreTest, WaitAllButNotAllSignaled) {
// NOTE: we don't actually block here because otherwise we'd lock up.
// Result status is undefined - some backends may return DeadlineExceededError
// while others may return success.
IREE_IGNORE_ERROR(iree_hal_device_wait_semaphores_with_deadline(
IREE_IGNORE_ERROR(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ALL, &semaphore_list,
IREE_TIME_INFINITE_PAST));
iree_make_deadline(IREE_TIME_INFINITE_PAST)));

iree_hal_semaphore_release(semaphore_a);
iree_hal_semaphore_release(semaphore_b);
Expand All @@ -175,9 +179,9 @@ TEST_P(SemaphoreTest, WaitAllAndAllSignaled) {
// NOTE: we don't actually block here because otherwise we'd lock up.
// Result status is undefined - some backends may return DeadlineExceededError
// while others may return success.
IREE_IGNORE_ERROR(iree_hal_device_wait_semaphores_with_deadline(
IREE_IGNORE_ERROR(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ALL, &semaphore_list,
IREE_TIME_INFINITE_FUTURE));
iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));

iree_hal_semaphore_release(semaphore_a);
iree_hal_semaphore_release(semaphore_b);
Expand All @@ -198,9 +202,9 @@ TEST_P(SemaphoreTest, DISABLED_WaitAny) {
uint64_t payload_values[] = {1ull, 1ull};
semaphore_list.payload_values = payload_values;

IREE_ASSERT_OK(iree_hal_device_wait_semaphores_with_deadline(
IREE_ASSERT_OK(iree_hal_device_wait_semaphores(
device_, IREE_HAL_WAIT_MODE_ANY, &semaphore_list,
IREE_TIME_INFINITE_FUTURE));
iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));

iree_hal_semaphore_release(semaphore_a);
iree_hal_semaphore_release(semaphore_b);
Expand All @@ -215,16 +219,16 @@ TEST_P(SemaphoreTest, PingPong) {
IREE_ASSERT_OK(iree_hal_semaphore_create(device_, 0ull, &b2a));
std::thread thread([&]() {
// Should advance right past this because the value is already set.
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
a2b, 0ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
a2b, 0ull, iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));
IREE_ASSERT_OK(iree_hal_semaphore_signal(b2a, 1ull));
// Jump ahead (blocking at first).
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
a2b, 4ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
a2b, 4ull, iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));
});
// Block until thread signals.
IREE_ASSERT_OK(iree_hal_semaphore_wait_with_deadline(
b2a, 1ull, IREE_TIME_INFINITE_FUTURE));
IREE_ASSERT_OK(iree_hal_semaphore_wait(
b2a, 1ull, iree_make_deadline(IREE_TIME_INFINITE_FUTURE)));
IREE_ASSERT_OK(iree_hal_semaphore_signal(a2b, 4ull));
thread.join();

Expand Down
55 changes: 10 additions & 45 deletions iree/hal/cuda/cuda_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,52 +251,30 @@ static iree_status_t iree_hal_cuda_device_queue_submit(
return iree_ok_status();
}

static iree_status_t iree_hal_cuda_device_submit_and_wait_with_deadline(
static iree_status_t iree_hal_cuda_device_submit_and_wait(
iree_hal_device_t* base_device,
iree_hal_command_category_t command_categories,
iree_hal_queue_affinity_t queue_affinity, iree_host_size_t batch_count,
const iree_hal_submission_batch_t* batches,
iree_hal_semaphore_t* wait_semaphore, uint64_t wait_value,
iree_time_t deadline_ns) {
iree_timeout_t timeout) {
// Submit...
IREE_RETURN_IF_ERROR(iree_hal_cuda_device_queue_submit(
base_device, command_categories, queue_affinity, batch_count, batches));

// ...and wait.
return iree_hal_semaphore_wait_with_deadline(wait_semaphore, wait_value,
deadline_ns);
return iree_hal_semaphore_wait(wait_semaphore, wait_value, timeout);
}

static iree_status_t iree_hal_cuda_device_submit_and_wait_with_timeout(
iree_hal_device_t* base_device,
iree_hal_command_category_t command_categories,
iree_hal_queue_affinity_t queue_affinity, iree_host_size_t batch_count,
const iree_hal_submission_batch_t* batches,
iree_hal_semaphore_t* wait_semaphore, uint64_t wait_value,
iree_duration_t timeout_ns) {
return iree_hal_cuda_device_submit_and_wait_with_deadline(
base_device, command_categories, queue_affinity, batch_count, batches,
wait_semaphore, wait_value,
iree_relative_timeout_to_deadline_ns(timeout_ns));
}

static iree_status_t iree_hal_cuda_device_wait_semaphores_with_timeout(
static iree_status_t iree_hal_cuda_device_wait_semaphores(
iree_hal_device_t* base_device, iree_hal_wait_mode_t wait_mode,
const iree_hal_semaphore_list_t* semaphore_list,
iree_duration_t timeout_ns) {
const iree_hal_semaphore_list_t* semaphore_list, iree_timeout_t timeout) {
return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
"semaphore not implemented");
}

static iree_status_t iree_hal_cuda_device_wait_semaphores_with_deadline(
iree_hal_device_t* base_device, iree_hal_wait_mode_t wait_mode,
const iree_hal_semaphore_list_t* semaphore_list, iree_time_t deadline_ns) {
return iree_make_status(IREE_STATUS_UNIMPLEMENTED,
"semaphore not implemented");
}

static iree_status_t iree_hal_cuda_device_wait_idle_with_deadline(
iree_hal_device_t* base_device, iree_time_t deadline_ns) {
static iree_status_t iree_hal_cuda_device_wait_idle(
iree_hal_device_t* base_device, iree_timeout_t timeout) {
iree_hal_cuda_device_t* device = iree_hal_cuda_device_cast(base_device);
// Wait until the stream is done.
// TODO(thomasraoux): CUDA doesn't support a deadline for wait, figure out how
Expand All @@ -307,12 +285,6 @@ static iree_status_t iree_hal_cuda_device_wait_idle_with_deadline(
return iree_ok_status();
}

static iree_status_t iree_hal_cuda_device_wait_idle_with_timeout(
iree_hal_device_t* base_device, iree_duration_t timeout_ns) {
return iree_hal_cuda_device_wait_idle_with_deadline(
base_device, iree_relative_timeout_to_deadline_ns(timeout_ns));
}

const iree_hal_device_vtable_t iree_hal_cuda_device_vtable = {
.destroy = iree_hal_cuda_device_destroy,
.id = iree_hal_cuda_device_id,
Expand All @@ -328,14 +300,7 @@ const iree_hal_device_vtable_t iree_hal_cuda_device_vtable = {
.create_executable_layout = iree_hal_cuda_device_create_executable_layout,
.create_semaphore = iree_hal_cuda_device_create_semaphore,
.queue_submit = iree_hal_cuda_device_queue_submit,
.submit_and_wait_with_deadline =
iree_hal_cuda_device_submit_and_wait_with_deadline,
.submit_and_wait_with_timeout =
iree_hal_cuda_device_submit_and_wait_with_timeout,
.wait_semaphores_with_deadline =
iree_hal_cuda_device_wait_semaphores_with_deadline,
.wait_semaphores_with_timeout =
iree_hal_cuda_device_wait_semaphores_with_timeout,
.wait_idle_with_deadline = iree_hal_cuda_device_wait_idle_with_deadline,
.wait_idle_with_timeout = iree_hal_cuda_device_wait_idle_with_timeout,
.submit_and_wait = iree_hal_cuda_device_submit_and_wait,
.wait_semaphores = iree_hal_cuda_device_wait_semaphores,
.wait_idle = iree_hal_cuda_device_wait_idle,
};
14 changes: 3 additions & 11 deletions iree/hal/cuda/event_semaphore.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,18 @@ static iree_status_t iree_hal_cuda_semaphore_signal(
static void iree_hal_cuda_semaphore_fail(iree_hal_semaphore_t* base_semaphore,
iree_status_t status) {}

static iree_status_t iree_hal_cuda_semaphore_wait_with_deadline(
static iree_status_t iree_hal_cuda_semaphore_wait(
iree_hal_semaphore_t* base_semaphore, uint64_t value,
iree_time_t deadline_ns) {
iree_timeout_t timeout) {
// TODO: Support semaphores completely. Return OK currently as everything is
// synchronized for each submit to allow things to run.
return iree_ok_status();
}

static iree_status_t iree_hal_cuda_semaphore_wait_with_timeout(
iree_hal_semaphore_t* base_semaphore, uint64_t value,
iree_duration_t timeout_ns) {
return iree_hal_cuda_semaphore_wait_with_deadline(
base_semaphore, value, iree_relative_timeout_to_deadline_ns(timeout_ns));
}

const iree_hal_semaphore_vtable_t iree_hal_cuda_semaphore_vtable = {
.destroy = iree_hal_cuda_semaphore_destroy,
.query = iree_hal_cuda_semaphore_query,
.signal = iree_hal_cuda_semaphore_signal,
.fail = iree_hal_cuda_semaphore_fail,
.wait_with_deadline = iree_hal_cuda_semaphore_wait_with_deadline,
.wait_with_timeout = iree_hal_cuda_semaphore_wait_with_timeout,
.wait = iree_hal_cuda_semaphore_wait,
};
Loading

0 comments on commit aaf92fa

Please sign in to comment.