On Thu, Feb 7, 2019, 09:21 Simon Moll <moll at cs.uni-saarland.de> wrote:> > On 2/7/19 6:08 PM, David Greene wrote: > > Jacob Lifshay <programmerjake at gmail.com> writes: > > > >> So it would be handy for the vector length on evl intrinsics to be in > >> units of the mask length so we don't have to pattern match a division > >> in the backend. We could have 2 variants of the vector length > >> argument, one in terms of the data vector and one in terms of the mask > >> vector. we could legalize the mask vector variant for those > >> architectures that need it by pulling the multiplication out and > >> switching to the data vector variants. > > Would it make sense to have two different intrinsics? > > > > # "Normal" form, L is in terms of flat vector length. > > <scalable 2 x float> evl.fsub(<scalable 2 x float> %x, > > <scalable 2 x float> %y, > > <scalable 2 x i1> %M, i32 %L) > > > > # "Sub-vector" form, L is in terms of sub-vectors elements. > > <scalable 1 x <2 x float>> evl.fsub(<scalable 1 x <2 x float>> %x, > > <scalable 1 x <2 x float>> %y, > > <scalable 1 x <2 x i1>> %M, i32 %L > > > > Overloading types to mean two very different things is confusing to me. > > > > -David > > Allowing vector types as vector elements would solve the vlen > interpretation issue in an elegant way. >This seems like the best solution, though maybe out of scope of the current evl proposal. This would also create a decent IR representation of a matrix or other 2D vector: matMxN would be <N x <M x float>>. While we're adding this, it may be a good idea to go all in and just lift the restriction on vectors containing other non-scalable vectors, so you could do something like: <scalable 1 x <4 x <4 x float>>> to be a scalable vector of 4x4 matrices. all the standard arithmetic operations (fadd, fmul, etc.) would still be the standard operations (so fmul would be element-wise, not matrix multiplication), we would, as a separate proposal, add matrix multiplication as a separate intrinsic. Most operations would treat a <scalable I x <J x <K x <L x ... type ...>>>> as a <scalable I x <(J * K * L * ...) x type>> for everything but result type. We could have methods on Type that return the next level down vector type, the scalar type under the vector type nest (probably getScalarType), and the number of total scalar elements (getVectorNumElementsRecursive) assuming VL is the first valid non-zero integer: so <scalable I x <J x <K x <L x ... type ...>>>> returns I * J * K * L * ... We will probably want to cache the innermost scalar type and the number of total scalar elements. Since we want to avoid adding another field to Type, we could have vector types store the getVectorNumElementsRecursive instead of the getVectorNumElements value, for getVectorNumElements we would divide the stored value by the stored value of the next level down. There would be a pass to convert vector kinds for different targets.> > - Simon > > -- > > Simon Moll > Researcher / PhD Student > > Compiler Design Lab (Prof. Hack) > Saarland University, Computer Science > Building E1.3, Room 4.31 > > Tel. +49 (0)681 302-57521 : moll at cs.uni-saarland.de > Fax. +49 (0)681 302-3065 : > http://compilers.cs.uni-saarland.de/people/moll > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190207/c76708d1/attachment.html>
I agree with this. RISC-V V extension requires the variable-length vector elements for MVL and AVL and predication to be 8 bits or larger (power of two), but can do SIMD operations on subdiviisions down to 1 bit. On Thu, Feb 7, 2019 at 4:06 PM Jacob Lifshay via llvm-dev <llvm-dev at lists.llvm.org> wrote:> > On Thu, Feb 7, 2019, 09:21 Simon Moll <moll at cs.uni-saarland.de> wrote: >> >> >> On 2/7/19 6:08 PM, David Greene wrote: >> > Jacob Lifshay <programmerjake at gmail.com> writes: >> > >> >> So it would be handy for the vector length on evl intrinsics to be in >> >> units of the mask length so we don't have to pattern match a division >> >> in the backend. We could have 2 variants of the vector length >> >> argument, one in terms of the data vector and one in terms of the mask >> >> vector. we could legalize the mask vector variant for those >> >> architectures that need it by pulling the multiplication out and >> >> switching to the data vector variants. >> > Would it make sense to have two different intrinsics? >> > >> > # "Normal" form, L is in terms of flat vector length. >> > <scalable 2 x float> evl.fsub(<scalable 2 x float> %x, >> > <scalable 2 x float> %y, >> > <scalable 2 x i1> %M, i32 %L) >> > >> > # "Sub-vector" form, L is in terms of sub-vectors elements. >> > <scalable 1 x <2 x float>> evl.fsub(<scalable 1 x <2 x float>> %x, >> > <scalable 1 x <2 x float>> %y, >> > <scalable 1 x <2 x i1>> %M, i32 %L >> > >> > Overloading types to mean two very different things is confusing to me. >> > >> > -David >> >> Allowing vector types as vector elements would solve the vlen >> interpretation issue in an elegant way. > > This seems like the best solution, though maybe out of scope of the current evl proposal. This would also create a decent IR representation of a matrix or other 2D vector: matMxN would be <N x <M x float>>. > While we're adding this, it may be a good idea to go all in and just lift the restriction on vectors containing other non-scalable vectors, so you could do something like: <scalable 1 x <4 x <4 x float>>> to be a scalable vector of 4x4 matrices. > all the standard arithmetic operations (fadd, fmul, etc.) would still be the standard operations (so fmul would be element-wise, not matrix multiplication), we would, as a separate proposal, add matrix multiplication as a separate intrinsic. > > Most operations would treat a <scalable I x <J x <K x <L x ... type ...>>>> as a <scalable I x <(J * K * L * ...) x type>> for everything but result type. > > We could have methods on Type that return the next level down vector type, the scalar type under the vector type nest (probably getScalarType), and the number of total scalar elements (getVectorNumElementsRecursive) assuming VL is the first valid non-zero integer: so <scalable I x <J x <K x <L x ... type ...>>>> returns I * J * K * L * ... > We will probably want to cache the innermost scalar type and the number of total scalar elements. Since we want to avoid adding another field to Type, we could have vector types store the getVectorNumElementsRecursive instead of the getVectorNumElements value, for getVectorNumElements we would divide the stored value by the stored value of the next level down. > > There would be a pass to convert vector kinds for different targets. >> >> >> - Simon >> >> -- >> >> Simon Moll >> Researcher / PhD Student >> >> Compiler Design Lab (Prof. Hack) >> Saarland University, Computer Science >> Building E1.3, Room 4.31 >> >> Tel. +49 (0)681 302-57521 : moll at cs.uni-saarland.de >> Fax. +49 (0)681 302-3065 : http://compilers.cs.uni-saarland.de/people/moll >> > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
On Thu, Feb 7, 2019, 16:11 Bruce Hoult <brucehoult at sifive.com> wrote:> I agree with this. >Which part(s)? Just the part suggested by Simon or the whole recursive vector types suggestion?> > RISC-V V extension requires the variable-length vector elements for > MVL and AVL and predication to be 8 bits or larger (power of two), but > can do SIMD operations on subdiviisions down to 1 bit. > > On Thu, Feb 7, 2019 at 4:06 PM Jacob Lifshay via llvm-dev > <llvm-dev at lists.llvm.org> wrote: > > > > On Thu, Feb 7, 2019, 09:21 Simon Moll <moll at cs.uni-saarland.de> wrote: > >> > >> > >> On 2/7/19 6:08 PM, David Greene wrote: > >> > Jacob Lifshay <programmerjake at gmail.com> writes: > >> > > >> >> So it would be handy for the vector length on evl intrinsics to be in > >> >> units of the mask length so we don't have to pattern match a division > >> >> in the backend. We could have 2 variants of the vector length > >> >> argument, one in terms of the data vector and one in terms of the > mask > >> >> vector. we could legalize the mask vector variant for those > >> >> architectures that need it by pulling the multiplication out and > >> >> switching to the data vector variants. > >> > Would it make sense to have two different intrinsics? > >> > > >> > # "Normal" form, L is in terms of flat vector length. > >> > <scalable 2 x float> evl.fsub(<scalable 2 x float> %x, > >> > <scalable 2 x float> %y, > >> > <scalable 2 x i1> %M, i32 %L) > >> > > >> > # "Sub-vector" form, L is in terms of sub-vectors elements. > >> > <scalable 1 x <2 x float>> evl.fsub(<scalable 1 x <2 x float>> %x, > >> > <scalable 1 x <2 x float>> %y, > >> > <scalable 1 x <2 x i1>> %M, i32 > %L > >> > > >> > Overloading types to mean two very different things is confusing to > me. > >> > > >> > -David > >> > >> Allowing vector types as vector elements would solve the vlen > >> interpretation issue in an elegant way. > > > > This seems like the best solution, though maybe out of scope of the > current evl proposal. This would also create a decent IR representation of > a matrix or other 2D vector: matMxN would be <N x <M x float>>. > > While we're adding this, it may be a good idea to go all in and just > lift the restriction on vectors containing other non-scalable vectors, so > you could do something like: <scalable 1 x <4 x <4 x float>>> to be a > scalable vector of 4x4 matrices. > > all the standard arithmetic operations (fadd, fmul, etc.) would still be > the standard operations (so fmul would be element-wise, not matrix > multiplication), we would, as a separate proposal, add matrix > multiplication as a separate intrinsic. > > > > Most operations would treat a <scalable I x <J x <K x <L x ... type > ...>>>> as a <scalable I x <(J * K * L * ...) x type>> for everything but > result type. > > > > We could have methods on Type that return the next level down vector > type, the scalar type under the vector type nest (probably getScalarType), > and the number of total scalar elements (getVectorNumElementsRecursive) > assuming VL is the first valid non-zero integer: so <scalable I x <J x <K x > <L x ... type ...>>>> returns I * J * K * L * ... > > We will probably want to cache the innermost scalar type and the number > of total scalar elements. Since we want to avoid adding another field to > Type, we could have vector types store the getVectorNumElementsRecursive > instead of the getVectorNumElements value, for getVectorNumElements we > would divide the stored value by the stored value of the next level down. > > > > There would be a pass to convert vector kinds for different targets. > >> > >> > >> - Simon > >> > >> -- > >> > >> Simon Moll > >> Researcher / PhD Student > >> > >> Compiler Design Lab (Prof. Hack) > >> Saarland University, Computer Science > >> Building E1.3, Room 4.31 > >> > >> Tel. +49 (0)681 302-57521 : moll at cs.uni-saarland.de > >> Fax. +49 (0)681 302-3065 : > http://compilers.cs.uni-saarland.de/people/moll > >> > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190207/3457b06e/attachment.html>
Adding Adam and Gerolf.>This would also create a decent IR representation of a matrix or other 2D vector: matMxN would be <N x <M x float>>It may be time to consolidate the discussion with Matrix support RFC (http://lists.llvm.org/pipermail/llvm-dev/2018-December/128322.html), and talk about possible phasing-in of “features” From: Jacob Lifshay [mailto:programmerjake at gmail.com] Sent: Thursday, February 07, 2019 4:06 PM To: Simon Moll <moll at cs.uni-saarland.de> Cc: David Greene <dag at cray.com>; Robin Kruppe <robin.kruppe at gmail.com>; llvm-dev <llvm-dev at lists.llvm.org>; Maslov, Sergey V <sergey.v.maslov at intel.com>; Luke Kenneth Casson Leighton <lkcl at lkcl.net>; Saito, Hideki <hideki.saito at intel.com>; Topper, Craig <craig.topper at intel.com> Subject: Re: [llvm-dev] [RFC] Vector Predication On Thu, Feb 7, 2019, 09:21 Simon Moll <moll at cs.uni-saarland.de<mailto:moll at cs.uni-saarland.de>> wrote: On 2/7/19 6:08 PM, David Greene wrote:> Jacob Lifshay <programmerjake at gmail.com<mailto:programmerjake at gmail.com>> writes: > >> So it would be handy for the vector length on evl intrinsics to be in >> units of the mask length so we don't have to pattern match a division >> in the backend. We could have 2 variants of the vector length >> argument, one in terms of the data vector and one in terms of the mask >> vector. we could legalize the mask vector variant for those >> architectures that need it by pulling the multiplication out and >> switching to the data vector variants. > Would it make sense to have two different intrinsics? > > # "Normal" form, L is in terms of flat vector length. > <scalable 2 x float> evl.fsub(<scalable 2 x float> %x, > <scalable 2 x float> %y, > <scalable 2 x i1> %M, i32 %L) > > # "Sub-vector" form, L is in terms of sub-vectors elements. > <scalable 1 x <2 x float>> evl.fsub(<scalable 1 x <2 x float>> %x, > <scalable 1 x <2 x float>> %y, > <scalable 1 x <2 x i1>> %M, i32 %L > > Overloading types to mean two very different things is confusing to me. > > -DavidAllowing vector types as vector elements would solve the vlen interpretation issue in an elegant way. This seems like the best solution, though maybe out of scope of the current evl proposal. This would also create a decent IR representation of a matrix or other 2D vector: matMxN would be <N x <M x float>>. While we're adding this, it may be a good idea to go all in and just lift the restriction on vectors containing other non-scalable vectors, so you could do something like: <scalable 1 x <4 x <4 x float>>> to be a scalable vector of 4x4 matrices. all the standard arithmetic operations (fadd, fmul, etc.) would still be the standard operations (so fmul would be element-wise, not matrix multiplication), we would, as a separate proposal, add matrix multiplication as a separate intrinsic. Most operations would treat a <scalable I x <J x <K x <L x ... type ...>>>> as a <scalable I x <(J * K * L * ...) x type>> for everything but result type. We could have methods on Type that return the next level down vector type, the scalar type under the vector type nest (probably getScalarType), and the number of total scalar elements (getVectorNumElementsRecursive) assuming VL is the first valid non-zero integer: so <scalable I x <J x <K x <L x ... type ...>>>> returns I * J * K * L * ... We will probably want to cache the innermost scalar type and the number of total scalar elements. Since we want to avoid adding another field to Type, we could have vector types store the getVectorNumElementsRecursive instead of the getVectorNumElements value, for getVectorNumElements we would divide the stored value by the stored value of the next level down. There would be a pass to convert vector kinds for different targets. - Simon -- Simon Moll Researcher / PhD Student Compiler Design Lab (Prof. Hack) Saarland University, Computer Science Building E1.3, Room 4.31 Tel. +49 (0)681 302-57521 : moll at cs.uni-saarland.de<mailto:moll at cs.uni-saarland.de> Fax. +49 (0)681 302-3065 : http://compilers.cs.uni-saarland.de/people/moll -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190208/67878c45/attachment-0001.html>
Jacob Lifshay <programmerjake at gmail.com> writes:> > Would it make sense to have two different intrinsics? > > > > # "Normal" form, L is in terms of flat vector length. > > <scalable 2 x float> evl.fsub(<scalable 2 x float> %x, > > <scalable 2 x float> %y, > > <scalable 2 x i1> %M, i32 %L) > > > > # "Sub-vector" form, L is in terms of sub-vectors elements. > > <scalable 1 x <2 x float>> evl.fsub(<scalable 1 x <2 x float>> > %x, > > <scalable 1 x <2 x float>> %y, > > <scalable 1 x <2 x i1>> %M, i32 %L > > > > Overloading types to mean two very different things is confusing > to me. > > > > -David > > Allowing vector types as vector elements would solve the vlen > interpretation issue in an elegant way. > This seems like the best solution, though maybe out of scope of the > current evl proposal. This would also create a decent IR > representation of a matrix or other 2D vector: matMxN would be <N x <M > x float>>. > While we're adding this, it may be a good idea to go all in and just > lift the restriction on vectors containing other non-scalable vectors, > so you could do something like: <scalable 1 x <4 x <4 x float>>> to be > a scalable vector of 4x4 matrices.This is enticing to me but it does give me pause about how SIMD targets will deal with these types. This needs a lot more thought before we make a decision. This could also be useful for representing complex type operations with appropriate intrinsics. I agree that it may be out of scope for the EVL proposal, but if EVL goes ahead it would seem that it won't initially support the sub-vector operations without special intrinsics. -David
Luke Kenneth Casson Leighton via llvm-dev
2019-Feb-09 00:59 UTC
[llvm-dev] [RFC] Vector Predication
--- crowd-funded eco-conscious hardware: https://www.crowdsupply.com/eoma68 On Fri, Feb 8, 2019 at 3:42 PM David Greene <dag at cray.com> wrote:> > Jacob Lifshay <programmerjake at gmail.com> writes: > > While we're adding this, it may be a good idea to go all in and just > > lift the restriction on vectors containing other non-scalable vectors, > > so you could do something like: <scalable 1 x <4 x <4 x float>>> to be > > a scalable vector of 4x4 matrices. > > This is enticing to me but it does give me pause about how SIMD targets > will deal with these types.indeed. normally, matrices operations would be handled at the programmatic level (result: a whole diverse and disparate and often custom strategies). finding the common ground will take time. l.