www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12868] New: core.simd.int4 equality

https://issues.dlang.org/show_bug.cgi?id=12868

          Issue ID: 12868
           Summary: core.simd.int4 equality
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: DMD
          Assignee: nobody puremagic.com
          Reporter: bearophile_hugs eml.cc

Value equality is quite important for the usability of a type. This code is
currently refused:

void main() {
    import core.simd: int4;
    import std.algorithm: uniq;
    int4[] data = [[1, 2, 3, 4], [1, 2, 3, 4], [10, 20, 30, 40]];
    data.uniq;
}



dmd 2.066alpha gives:

test.d(5): Error: template std.algorithm.uniq does not match any function
template declaration. Candidates are:
...\ldc2\bin/../import\std\algorithm.d(3346):        std.algorithm.uniq(alias
pred = "a == b", Range)(Range r) if (isInputRange!Range &&
is(typeof(binaryFun!pred(r.front, r.front)) == bool))
test.d(5): Error: template std.algorithm.uniq(alias pred = "a == b",
Range)(Range r) if (isInputRange!Range && is(typeof(binaryFun!pred(r.front,
r.front)) == bool)) cannot deduce template function from argument types
!()(__vector(int[4])[])



A workaround is to call .array, but this is quite inefficient code:

void main() {
    import core.simd: int4;
    import std.algorithm: uniq;
    int4[] data = [[1, 2, 3, 4], [1, 2, 3, 4], [10, 20, 30, 40]];
    data.uniq!q{ a.array == b.array };
}


There are two different possible equalities among SIMD values: the first
returns a bool normally, and the second returns a SIMD value that contains N
booleans represented as zero/notzero values. The first can be computed with a
xor followed by a sum + shuffle + sum + shuffle ... for log2(N) cycles.

I think the first equality operation should be built-in. 

An alternative is to have a function like this but I think it's not a large
improvement because it has to perform the same operations as a built-in
equality:

void main() {
    import core.simd: int4;
    import std.algorithm: uniq;
    int4[] data = [[1, 2, 3, 4], [1, 2, 3, 4], [10, 20, 30, 40]];
    data.uniq!q{ simdEquality(a, b) };
}



But such simdEquality function is OK for the second kind of SIMD equality, that
returns a SIMD of booleans.

--
Jun 06 2014