[Parallel_libs-commits] [PATCH] D23333: [StreamExecutor] Add basic Stream operations
Jason Henline via Parallel_libs-commits
parallel_libs-commits at lists.llvm.org
Tue Aug 9 17:57:31 PDT 2016
jhen added inline comments.
================
Comment at: streamexecutor/include/streamexecutor/Stream.h:72
@@ +71,3 @@
+ StreamExecutorKey &operator=(const StreamExecutorKey &) = default;
+};
+
----------------
jlebar wrote:
> This is intriguing...
>
> Is the idea that you don't want to make SE a friend of Stream, because that's too much of a layering violation?
>
> I wonder if you could make SEKey a (private?) type inside Stream.
> Is the idea that you don't want to make SE a friend of Stream, because that's too much of a layering violation?
Yes, I thought it would be nice to clarify the interface between StreamExecutor and Stream. Maybe this is overkill, but I thought it seemed lightweight enough to be OK.
> I wonder if you could make SEKey a (private?) type inside Stream.
I put SEKey into Stream, but I don't know if there is any way to make it a private type. I think StreamExecutor has to be able to see the definition so it can create an instance of SEKey, but maybe I'm missing something.
================
Comment at: streamexecutor/include/streamexecutor/Stream.h:122
@@ +121,3 @@
+ const TypedKernel<Params...> &Kernel,
+ Params... Arguments) {
+ auto ArgumentArray = make_kernel_argument_pack(Arguments...);
----------------
jlebar wrote:
> Do you want `Params&&...` and `std::forward(Arguments...)` below?
Ugh, thanks for catching that ugly copy. I changed the arguments to `const Params &... Arguments` instead of `Params &&...` for the following horrifying reason:
When I tried to use `Params &&...`, I got a compiler error when I tried to call `thenLaunch` with one `int` argument and one `GlobalDeviceMemory<int>` argument. The error said the compiler could not infer the types for `Params` because the `TypedKernel<Params...>` argument made it infer `int, GlobalDeviceMemory<int>` and the `Params &&...` argument made it infer `int, GlobalDeviceMemory<int> &`.
So, the `&&` seems to make the compiler infer a reference type for some arguments and that conflicts with the types from `TypedKernel<Params...>`.
Actually, I think const ref is the right signature for this function anyway, so I don't think we need to figure out a solution for the conflicting type inference. What do you think?
================
Comment at: streamexecutor/include/streamexecutor/Stream.h:124
@@ +123,3 @@
+ auto ArgumentArray = make_kernel_argument_pack(Arguments...);
+ return thenRawLaunch(BlockSize, GridSize, Kernel, ArgumentArray);
+ }
----------------
jlebar wrote:
> Do we want `std::move(ArgumentArray)`? (At the moment it doesn't make sense because thenRawLaunch takes a const ref to the pack, but see below...)
Maybe I missed it, but I didn't see the comment below about thenRawLaunch. I didn't change anything for now until we clear up the confusion.
================
Comment at: streamexecutor/include/streamexecutor/Stream.h:136
@@ +135,3 @@
+ llvm::MutableArrayRef<T> HostDst, bool FullCopy = true,
+ size_t ElementCount = 0) {
+ if (FullCopy) {
----------------
jlebar wrote:
> These default args seem weird...would this be better as two functions, one that does a full copy and one that takes an ElementCount?
Thanks for the idea. I was struggling with that design. Multiple functions is much nicer.
================
Comment at: streamexecutor/include/streamexecutor/Stream.h:216
@@ +215,3 @@
+ if (ErrorMessage == nullptr) {
+ ErrorMessage =
+ llvm::make_unique<std::string>(consumeAndGetMessage(std::move(E)));
----------------
jlebar wrote:
> Could we store an `Error` internally, instead of a string?
The problem I had with trying to use an `Error` is that the method to get out the error string destroys the error object. This is a side-effect of the way LLVM `Error` enforces the law that users cannot ignore their errors. So it looked like I was going to have to keep destroying and rebuilding the saved `Error` every time somebody queried it.
================
Comment at: streamexecutor/include/streamexecutor/StreamExecutor.h:57
@@ -33,2 +56,3 @@
- // TODO(jhen): Add other methods.
+ Expected<std::unique_ptr<Stream>> createStream() {
+ // TODO(jhen): Get the real implementation pointer.
----------------
jlebar wrote:
> It looks like Stream is concrete and movable, so can we get rid of the unique_ptr?
Oops, I was experimenting with moving streams and forgot to delete the stuff. Streams shouldn't be movable, so we'll stick with a pointer here.
================
Comment at: streamexecutor/lib/Stream.cpp:36
@@ +35,3 @@
+ return *this;
+}
+
----------------
jlebar wrote:
> So...it's illegal to move a stream if there are any outstanding operations? (Among other reasons, we're not taking a mutex here.) Maybe we should have a comment.
Sorry I forgot to delete this garbage before. It's gone now and Streams are no longer movable.
================
Comment at: streamexecutor/lib/Stream.cpp:38
@@ +37,3 @@
+
+Stream::~Stream() { consumeError(Parent->deallocateStream(this)); }
+
----------------
jlebar wrote:
> Is it important for us to have an API that would let consumers capture this error, if they wanted to?
I think we can do that in a sane way. I change `StreamExecutor::deallocateStream` to return void and added a comment that says it will record an error if it fails. I left it as a TODO for now to design the interface for fetching stream destruction errors.
https://reviews.llvm.org/D23333
More information about the Parallel_libs-commits
mailing list