[Haskell-cafe] vector-simd: some code available, and some questions

Gábor Lehel illissius at gmail.com
Sun Jul 8 10:27:20 CEST 2012


On Sun, Jul 8, 2012 at 3:05 AM, Nicolas Trangez <nicolas at incubaid.com> wrote:
> On Sun, 2012-07-08 at 01:40 +0200, Gábor Lehel wrote:
>>  unsafeXorSSE42 :: (Storable a,
>> >     SV.AlignedToAtLeast SV.A16 o1, SV.Alignment o1,
>> >     SV.AlignedToAtLeast SV.A16 o2, SV.Alignment o2,
>> >     SV.AlignedToAtLeast SV.A16 o3, SV.Alignment o3) =>
>> >     SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a
>>
>> I wonder if you could get that a bit shorter... I suppose you could write:
>>
>> instance (AlignedToAtLeast n a, AlignedToAtLeast n b) =>
>> AlignedToAtLeast n (a, b)
>> instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast
>> n c) => AlignedToAtLeast n (a, b, c)
>> ...and so on...
>
> Once again, nifty! And implemented in [1].
>
>> though it feels a little strange semantically (relating a tuple to a
>> scalar), but I don't see what harm can come of it. And then you can
>> just write SV.AlignedToAtLeast SV.A16 (o1, o2, o3) in signatures.
>
>> You
>> can also make (Alignment n, Alignment a) a superclass constraint of
>> AlignedToAtLeast, and write instances for Alignment inductively on One
>> and Twice, and then you don't have to write Alignment o1 etc.
>> separately either. So the signature would be just:
>>
>> unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast SV.A16 (o1, o2,
>> o3)) =>      SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a
>>
>> which is friendlier.
>
> I implemented the inductive alignment calculation over One and Twice
> (good idea, and easy to do), but I don't get the thing about
> superclasses. I've been trying several approaches (including definitions
> based on forall and other trickery I never used before), but didn't get
> things to work, at least: the compiler always said I'd need
> UndecidableInstances, and that sounds scary... Care to elaborate?

All I meant was

class (Alignment n, Alignment a) => AlignedToAtLeast n a

but I got a bit ahead of myself, because that rules out the instance
on tuples. (I suppose you *could* write some kind of Alignment
instance for them, taking their minimum or something, but that's
getting a bit too subversive for me). The alternative, if you want
both Alignment as a superclass and the ability to constrain multiple
types at once, is to have the above, remove the instance on tuples,
and instead something like:

class (AlignedToAtLeast n a, AlignedToAtLeast n b) => AlignedToAtLeast2 n a b
instance (AlignedToAtLeast n a, AlignedToAtLeast n b) => AlignedToAtLeast2 n a b
class (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast n
c) => AlignedToAtLeast3 n a b c
instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast
n c) => AlignedToAtLeast3 n a b c
(feel free to think of better names!)

unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast3 SV.A16 o1 o2 o3)
=> SV.Vector o1 a -> SV.Vector o2 a -> SV.Vector o3 a

That will require UndecidableInstances, but all that means is that GHC
can't prove to itself that instance checking will terminate. So you
could end up getting the compiler into an infinite loop (or in
practice, to exceed its recursion limit). But it doesn't allow
anything unsafe to happen at runtime, and there's plenty of perfectly
good instances which terminate even if GHC can't prove it.



More information about the Haskell-Cafe mailing list