Skip to content

[SYCL][FPGA] Initial implementation of pipes feature #292

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

Merged
merged 3 commits into from
Jul 15, 2019

Conversation

MrSidims
Copy link
Contributor

@MrSidims MrSidims commented Jul 8, 2019

No description provided.

Copy link
Contributor

@keryell keryell left a comment

Choose a reason for hiding this comment

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

This looks like a super-useful feature on FPGA.
I have nevertheless a few remarks.

OpenCL 2.2 program pipe representation in SPIR-V
================================================

The SPIR-V program pipe representation is leveraged, to be an underlying
Copy link
Contributor

Choose a reason for hiding this comment

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

Spurious ,.
I do not know if "leveraged" is good here. Do you improve SPIR-V or you just recycle it for another purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SPIR-V representation is re-used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then clarify...


Global pipe creation itself is being done by SPIR-V built-in
__spirv_CreatePipeFromPipeStorage_{read|write} which has no OpenCL
representation and therefore stays in IR before and after SPIR-V tool-chain as:
Copy link
Contributor

Choose a reason for hiding this comment

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

Unclear.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have rewrote this one, please check it.


// Writing to pipe is lowered to SPIR-V instruction OpWritePipe via SPIR-V
// friendly LLVM IR.
static void write(dataT Data, bool &Success) {
Copy link
Contributor

Choose a reason for hiding this comment

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

static bool write(const dataT &Data) instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

Choose a reason for hiding this comment

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

The const reference is good. The status return code move to returned bool makes the signatures of read and write differ more than I would like. Read returns the data type in both cases. How strongly do you think that write should return bool success status, while read returns the data and takes a status ref arg?

while (!SuccessCode)
write_acc[idx] = Pipe::read(SuccessCode);
});
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any user-friendly documentation on how this Pipe extension works?
One of the things that confuses me is that, in the test above, there is nothing preventing a SYCL runtime to execute goo_nb before foo_nb, since the intersection of the requirements is empty and SYCL queues are out-of-order.

Is that relevant in your case? I figure for an FPGA it doesn't matter, but there is nothing in this extension that suggest it shouldn't work on anything that is not an FPGA but supports pipes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is there any user-friendly documentation on how this Pipe extension works?

It's going to be published. Don't really know when.
There is SYCL 2.2 spec (which is deprecated, but yet can provide some information). Also this implementation doesn't follows it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I figure for an FPGA it doesn't matter, but there is nothing in this extension that suggest it shouldn't work on anything that is not an FPGA but supports pipes.

Yeah, I shall put some code in device information quarrying.

Choose a reason for hiding this comment

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

We'll publish the extension document soon in this repo

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem is to come with a terse API and at the same time not giving up any performance on the table...
Perhaps a more explicit naming in the case of (non-)blocking? Adding a tag to pick another overload? Adding a template parameter?...
I understand that relying on an accessor to encode the blocking behavior like in SYCL 2.2 might be a too heavy syntax....

Choose a reason for hiding this comment

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

The pipes extension at SYCL level is described in the document, currently as a pending PR, at:
#635

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah thank you for the cross-reference. It prevents me from looking for it...

Copy link
Contributor

@asavonic asavonic left a comment

Choose a reason for hiding this comment

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

Current documentation mostly covers SPIR-V and LLVM IR levels.
Please describe how this feature is represented and used (with examples) at SYCL level.

@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch 2 times, most recently from f97d84a to 30ae85f Compare July 11, 2019 15:16
Copy link
Contributor

@keryell keryell left a comment

Choose a reason for hiding this comment

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

Interesting!
Still a few remarks.

cgh.parallel_for<class foo_nb>(range<1> { dataSize }, [=](id<1> idx) {
bool SuccessCode = false;
while (!SuccessCode)
Pipe::write(42, SuccessCode); // Write '42' into a some_pipe allocated
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the memory model of a pipe in the case you are executing it in a parallel_for and not a single_task?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you expect some independent-forward-progress here in the case dataSize > 1 (the capacity of the pipe...)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I expect that. I should re-write the example code into:
cgh.parallel_for<class bar>(range<1> { 1024 }, [=](id<1> idx) { write_acc[idx] = my_pipe::read(); });

OpenCL analog of the code above is:
__kernel void foo(__read_only pipe uint in_pipe, __global uint *dst) { int gid = get_global_id(0); read_pipe(in_pipe, &dst[gid]); }

Copy link
Contributor

Choose a reason for hiding this comment

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

But it is illegal OpenCL code in general. You have to use pipe reservation for this and and I am not sure we want this anyway on FPGA...
So the assumptions are probably to be described in the document describing the extension.
What happens if there are multiple work-group on different CU using the same pipe input or output?

Copy link
Contributor Author

@MrSidims MrSidims Jul 15, 2019

Choose a reason for hiding this comment

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

But it is illegal OpenCL code in general. You have to use pipe reservation for this and and I am not sure we want this anyway on FPGA...

You are right.

What happens if there are multiple work-group on different CU using the same pipe input or output?

... to be described in the document describing the extension :) I added a quote from there:

Accesses to a single pipe within two work-items of the same kernel, and/or threads of the host program: No ordering guarantees are made on the order of pipe operations across device work-items or host threads. For example, if two work-items executing a kernel write to a pipe, there are no guarantees that the work-item with lower id (for any definition of id) executes before the pipe write from a higher id. The execution order of work-items executing a kernel are not defined by SYCL, may be dynamically reordered, and may not be deterministic. If ordering guarantees are required across work-items and/or host threads, synchronization mechanisms such as atomics or barriers must be used.

Copy link
Contributor

Choose a reason for hiding this comment

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

@keryell, are you okay to merge this PR?

Yes I am fine with merging.
It looks like in #318 there are some corrections that will be done later.

Simple example of SYCL program
==============================
.. code:: cpp
using Pipe = pipe<class some_pipe, int, 1>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it legal to have a local class some_pipe declaration like here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If I don't try to use it after - yes. It's a forward declaration that adds appropriate mangling for fields and methods of the template class pipe.

@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch from fffd69f to c627b78 Compare July 12, 2019 08:57
@MrSidims MrSidims requested a review from asavonic July 12, 2019 10:01
// OpenCL 2.0 defined this keyword. OpenCL 1.2 and earlier should
// support the "pipe" word as identifier.
Tok.getIdentifierInfo()->revertTokenIDToIdentifier();
goto DoneWithDeclSpec;
}
isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy);
break;
case tok::kw___pipe:
// __pipe is defined only for SYCL kernel language
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we add a check for that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. If this keyword appears in any other language, clang already will report it be unknown keyword.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but if there is __pipe used in an existing library, unrelated to SYCL?
But do we need such a keyword?

Copy link
Contributor Author

@MrSidims MrSidims Jul 15, 2019

Choose a reason for hiding this comment

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

Fixed.

But do we need such a keyword?

Will be reworked as attribute. Or you suggest to do some forward declaration expecting the translator to do its work?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the attribute is fine.

@bader bader self-assigned this Jul 12, 2019
@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch 2 times, most recently from 81c2eff to ec15072 Compare July 12, 2019 12:10
@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch 2 times, most recently from fdacf2e to ad598c1 Compare July 12, 2019 12:50
bader
bader previously approved these changes Jul 12, 2019
@bader bader dismissed asavonic’s stale review July 12, 2019 18:00

Documentation has been added.

@bader
Copy link
Contributor

bader commented Jul 14, 2019

@keryell, @Ruyk, @asavonic, please, "resolve conversations", which do not require follow-up actions.
I'd like to merge this pull request, but it's hard to say if all issues are resolved or not - there are 97 comment at the moment.

I think there are at least three issues left to resolve (updated by @keryell last Friday).

MrSidims added 2 commits July 15, 2019 11:22
Pipe types construction rely on keywords mechanism.
Consider following code:
    __read_only __pipe int p;

It declares a read only pipe with integer layout.
In LLVM IR this type is seen as 'pipe_ro_t'.

Write only pipe type will be looking like 'pipe_wo_t'.

Signed-off-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
Signed-off-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch from ad598c1 to a5f9027 Compare July 15, 2019 08:36
bader
bader previously approved these changes Jul 15, 2019
Pipe are supported via generation SPIR-V friendly IR
and lowering it directly to SPIR-V code.

non-blocking pipes are supported;
blocking pipes are supported as a workaround.

Signed-off-by: Dmitry Sidorov <dmitry.sidorov@intel.com>
@MrSidims MrSidims force-pushed the private/MrSidims/GlobalPipes_WOCL branch from a5f9027 to cb9c774 Compare July 15, 2019 09:52
@bader
Copy link
Contributor

bader commented Jul 15, 2019

@keryell, are you okay to merge this PR?

@bader bader merged commit 74527fc into intel:sycl Jul 15, 2019
mkinsner pushed a commit to mkinsner/llvm that referenced this pull request Nov 13, 2019
Signed-off-by: Michael Kinsner <michael.kinsner@intel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants