Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-36103: [C++] Initial device sync API #37040

Merged
merged 29 commits into from
Aug 22, 2023

Conversation

zeroshade
Copy link
Member

@zeroshade zeroshade commented Aug 7, 2023

Rationale for this change

Building on the ArrowDeviceArray we need to expand the abstractions for handling events and stream synchronization for devices.

What changes are included in this PR?

Initial Abstract implementations for the new DeviceSync API and a CPU implementation. This will be followed up by a CUDA implementation in a subsequent PR.

Are these changes tested?

Yes, tests are added for Import/Export DeviceArrays using the DeviceSync handling.

@zeroshade zeroshade requested review from bkietz and pitrou August 7, 2023 17:14
@zeroshade
Copy link
Member Author

CC @kkraus14

@github-actions
Copy link

github-actions bot commented Aug 7, 2023

⚠️ GitHub issue #36103 has been automatically assigned in GitHub to PR creator.

cpp/src/arrow/buffer.h Outdated Show resolved Hide resolved
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
}

static ArrayFactory JSONArrayFactory(const std::shared_ptr<MemoryManager>& mm,
std::shared_ptr<DataType> type, const char* json) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of a const char* here can we take a string_view? Not sure how we know what length the json is currently (unless it's assumed to be null terminated?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea it's assumed to be null terminated for these tests

Comment on lines +297 to +299
return nullptr;
// auto ev = reinterpret_cast<CUstream*>(sync_event);
// return std::make_shared<CudaDeviceSync>(ev);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this TODO?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, in the next PR I'll implement the Cuda implementations ie: a CudaDeviceSync object etc.

class ARROW_EXPORT DeviceSync {
public:
explicit DeviceSync(void* sync_event) : sync_event_{sync_event}, owns_event_{false} {}
virtual ~DeviceSync() = default;
Copy link
Member

Choose a reason for hiding this comment

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

The compiler-generated default constructor won't call release_event; I think this destructor should probably do that

Suggested change
virtual ~DeviceSync() = default;
virtual ~DeviceSync() {
if (owns_event_) {
release_event(sync_event_);
}
}

Copy link
Member Author

Choose a reason for hiding this comment

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

The problem with this is that release_event is a virtual function which is a bad idea to call from a destructor, so the current semantics require explicitly calling release_event.

return sync_event_;
}

void clear_event() {
Copy link
Member

Choose a reason for hiding this comment

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

Would this be used (instead of just destroying the DeviceSync)? I think it'd be best to keep the interface minimal until we can document the usage which each function anticipates

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this has to be used instead of just destroying the DeviceSync for the same reason as above, it's not safe to call a polymorphic virtual function from a destructor.

/// Tells the provided stream that it should wait until the
/// synchronization event is completed without blocking the CPU.
/// @param stream Should be appropriate for the underlying device
virtual Status stream_wait(void* stream) = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Similarly: it's not clear when this would be used instead of set_stream() then wait()

Copy link
Member Author

Choose a reason for hiding this comment

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

wait specifies that it blocks until the internal event is completed. stream_wait places a wait into the stream queue and will not block the CPU.

cpp/src/arrow/device.h Outdated Show resolved Hide resolved
cpp/src/arrow/device.h Outdated Show resolved Hide resolved
cpp/src/arrow/buffer.h Outdated Show resolved Hide resolved
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting committer review Awaiting committer review labels Aug 8, 2023
Co-authored-by: Benjamin Kietzman <[email protected]>
@github-actions github-actions bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Aug 9, 2023
@zeroshade zeroshade requested a review from bkietz August 9, 2023 21:39
cpp/src/arrow/device.h Outdated Show resolved Hide resolved
cpp/src/arrow/device.h Outdated Show resolved Hide resolved
@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting change review Awaiting change review labels Aug 11, 2023
@github-actions github-actions bot added the awaiting changes Awaiting changes label Aug 21, 2023
@github-actions github-actions bot added awaiting change review Awaiting change review awaiting changes Awaiting changes and removed awaiting changes Awaiting changes awaiting change review Awaiting change review labels Aug 22, 2023
@github-actions github-actions bot added awaiting change review Awaiting change review and removed awaiting changes Awaiting changes labels Aug 22, 2023
cpp/src/arrow/c/bridge.cc Outdated Show resolved Hide resolved
cpp/src/arrow/device.h Outdated Show resolved Hide resolved
cpp/src/arrow/device.h Outdated Show resolved Hide resolved
@github-actions github-actions bot added awaiting changes Awaiting changes and removed awaiting change review Awaiting change review labels Aug 22, 2023
@pitrou
Copy link
Member

pitrou commented Aug 22, 2023

I posted a couple comments but we can probably go with this regardless. We'll probably end up changing those APIs a bit once comes the time to use them concretely.

@github-actions github-actions bot added awaiting change review Awaiting change review awaiting changes Awaiting changes and removed awaiting changes Awaiting changes awaiting change review Awaiting change review labels Aug 22, 2023
@zeroshade zeroshade merged commit d062c89 into apache:main Aug 22, 2023
37 of 38 checks passed
@zeroshade zeroshade removed the awaiting changes Awaiting changes label Aug 22, 2023
@zeroshade zeroshade deleted the event-stream-abstractions branch August 22, 2023 19:08
@conbench-apache-arrow
Copy link

After merging your PR, Conbench analyzed the 6 benchmarking runs that have been run so far on merge-commit d062c89.

There were no benchmark performance regressions. 🎉

The full Conbench report has more details. It also includes information about possible false positives for unstable benchmarks that are known to sometimes produce them.

loicalleyne pushed a commit to loicalleyne/arrow that referenced this pull request Nov 13, 2023
### Rationale for this change
Building on the `ArrowDeviceArray` we need to expand the abstractions for handling events and stream synchronization for devices.

### What changes are included in this PR?
Initial Abstract implementations for the new DeviceSync API and a CPU implementation. This will be followed up by a CUDA implementation in a subsequent PR.

### Are these changes tested?
Yes, tests are added for Import/Export DeviceArrays using the DeviceSync handling.

* Closes: apache#36103

Lead-authored-by: Matt Topol <[email protected]>
Co-authored-by: Benjamin Kietzman <[email protected]>
Co-authored-by: Antoine Pitrou <[email protected]>
Signed-off-by: Matt Topol <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[C++] Add device-specific synchronization API to Buffer
4 participants