digitalmars.D.learn - core.simd ubyte16 initialization weirdness.
- realhet (37/37) May 07 2023 Hello,
- Richard (Rikki) Andrew Cattermole (25/27) May 08 2023 It doesn't.
- realhet (47/47) May 08 2023 On Monday, 8 May 2023 at 08:05:13 UTC, Richard (Rikki) Andrew
- Richard (Rikki) Andrew Cattermole (10/10) May 08 2023 Don't forget to type bad2 which gives the same result as the good one.
- realhet (46/48) May 08 2023 Thank You, now that's good too.
Hello,
```
import std, core.simd;
void main()
{
enum ubyte16
good1 = mixin([1, 2, 3, 4]),
bad = [1, 2, 3, 4];
static immutable ubyte16
good2 = mixin([1, 2, 3, 4]),
crash = [1, 2, 3, 4];
pragma(msg, good1);
pragma(msg, bad);
pragma(msg, good2);
pragma(msg, crash);
}
```
In the above example I tried 4 ways to initialize ubyte16
constants.
I only specify the first 4 values, the remaining is automatically
zero.
2 of them are good 2 of them are bad.
Egy enum version compiles, but after trying SSE pshufb
instruction with them, it seems like the [1, 2, 3, 4, 12 times 0]
is distorted to this: [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4]
I discovered the mixin() trick when I wanted to give them some
calculated series.
Is it a bad way to initialize these constants? Is there a better
way?
cast(immutable(__vector(ubyte[16])))[cast(ubyte)1u,
cast(ubyte)2u, cast(ubyte)3u, cast(ubyte)4u, cast(ubyte)0u,
cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u,
cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u,
cast(ubyte)0u, cast(ubyte)0u, cast(ubyte)0u]
This is how the compiler dumps it. But it's not so compact, so I
rather use the mixin() version, I just don't understand why the
int array fails -> [1, 2, 3....] It would look so nice.
May 07 2023
On 08/05/2023 9:07 AM, realhet wrote:I just don't understand why the int array fails -> [1, 2, 3....] It would look so nice.It doesn't. ```d import std, core.simd; void main() { enum ubyte16 good1 = mixin([1, 2, 3, 4]), bad = [1, 2, 3, 4]; static immutable ubyte16 good2 = mixin([1, 2, 3, 4]), crash = [1, 2, 3, 4]; writeln(good1); writeln(bad); writeln(good2); writeln(crash); } ``` ``` [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ``` Its a bug with ``pragma(msg)`` by the looks.
May 08 2023
On Monday, 8 May 2023 at 08:05:13 UTC, Richard (Rikki) Andrew
Cattermole wrote:
Yes, there is a pragma msg bug, but there is also a functionality
'bug'.
I collected some more info:
```
import std, core.simd, ldc.llvmasm;
T pshufb(T, U)(T a, in U b) { return __asm!ubyte16("pshufb $2,
$1", "=x,0,x", a, b); }
void main()
{
enum ubyte16
input = mixin(iota(100, 116).array),
good = mixin([1, 2, 3, 4, 5, 6, 7]),
bad1 = [1, 2, 3, 4, 5, 6, 7];
static immutable
bad2 = [1, 2, 3, 4, 5, 6, 7];
//pragma(msg, somewhat_good); <-crash
writeln(good);
writeln(pshufb(input, good));
writeln;
writeln(bad1);
writeln(pshufb(input, bad1));
writeln;
writeln(bad2);
writeln(pshufb(input, bad2));
}
[1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[101, 102, 103, 104, 105, 106, 107, 100, 100, 100, 100, 100, 100,
100, 100, 100]
[1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100]
[1, 2, 3, 4, 5, 6, 7]
[107, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100]
```
In the declaration of pshufb I let anything pass through to the
__asm statement.
Only the enum ubyte16 = mixin(...); variant calculates the
correct results, and luckily that can accept iota... calculated
inputs as well.
But at this point I have to memorize this and be aware when I'm
having weird results.
After all, this is the best SSE assembler I ever used so far *big
thumbs up*. I like that I don't even have to allocate registers
manually.
May 08 2023
Don't forget to type bad2 which gives the same result as the good one. Otherwise it only has 7 elements in it. ```d static immutable ubyte16 bad2 = [1, 2, 3, 4, 5, 6, 7]; ``` ``` [1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0] [101, 102, 103, 104, 105, 106, 107, 100, 100, 100, 100, 100, 100, 100, 100, 100] ```
May 08 2023
On Monday, 8 May 2023 at 11:43:33 UTC, Richard (Rikki) Andrew Cattermole wrote:Don't forget to type bad2 which gives the same result as the good one. Otherwise it only has 7 elements in it.Thank You, now that's good too. So here are the weird stuff: Pure arrays produce errors: enum ubyte16 x = [1, 2, 3] -> bad SSE calculation static immutable ubyte16 x = [1, 2, 3] -> calculates good, but pragma msg crashes And there ar 2 possible fixes: * Send the constant array through mixin() * Send the constant array through Phobos: For example .array or .dub will do. I think I will prefer the static immutable ubyte16 way with the simples looking array. The pragma will crash on it, but I can live with that. ``` import std, core.simd, ldc.llvmasm; T pshufb(T, U)(T a, in U b) { return __asm!ubyte16("pshufb $2, $1", "=x,0,x", a, b); } void main() { enum ubyte16 input = mixin(iota(100, 116).array), good = mixin([0, 1, 2, 3, 4, 5, 6, 7]), bad1 = [0, 1, 2, 3, 4, 5, 6, 7]; static immutable ubyte16 good2 = iota(8).array, goodButPragmaCrash = [0, 1, 2, 3, 4, 5, 6, 7], goodAndNoPragmaCrash = [0, 1, 2, 3, 4, 5, 6, 7].dup; //pragma(msg, goodButPragmaCrash); pragma(msg, goodAndNoPragmaCrash); void test(string s)(){ mixin(q{ writef!"%s\n%s\n%s\n\n"("$", $, pshufb(input, $)); }.replace("$", s)); } test!"good"; test!"bad1"; test!"good2"; test!"goodButPragmaCrash"; test!"goodAndNoPragmaCrash"; } ```
May 08 2023








realhet <real_het hotmail.com>