intel/executor: Add examples for srnd

srnd_edge_cases.lua is checking edge cases.
srnd_randomized.lua is shared by Caio and it serves as a good example for
understanding the randomness and probability of rounding.

Reviewed-by: Caio Oliveira <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36529>
This commit is contained in:
Sushma Venkatesh Reddy 2025-07-30 18:19:23 +00:00 committed by Marge Bot
parent a1c5f1ccf6
commit 95669ad5df
2 changed files with 117 additions and 0 deletions

View file

@ -0,0 +1,55 @@
check_ver(20)
local r = execute {
src = [[
@id g1
// Prepare F32 input data in g2
mov(8) g2<1>UD 0x00000000UD {A@1}; // 0.0f
mov(8) g2.1<1>UD 0x80000000UD {A@1}; // -0.0f
mov(8) g2.2<1>UD 0x7f7fffffUD {A@1}; // FLT_MAX
mov(8) g2.3<1>UD 0xff7fffffUD {A@1}; // -FLT_MAX
mov(8) g2.4<1>UD 0x00800000UD {A@1}; // smallest normal
mov(8) g2.5<1>UD 0x7fc00000UD {A@1}; // NaN
mov(8) g2.6<1>UD 0x7f800000UD {A@1}; // +inf
mov(8) g2.7<1>UD 0xff800000UD {A@1}; // -inf
mov(8) g3<2>UW 42UW {A@1};
// Stochastic rounding: F32 -> HF16 using g3 as random, packed
srnd(8) g4<2>HF g2<1,1,0>F g3<1,1,0>F {nomask};
// Convert back to F32 for checking, using supported regioning
mov(8) g5<1>F g4<2,1,0>HF {A@1};
@write g1 g5
@eot
]],
}
print("result")
dump(r, 8)
print("expected")
expected = {
[0] = 0x00000000,
0x80000000,
0x7f800000, -- FLT_MAX rounds to +inf in HF16
0xff800000, -- -FLT_MAX rounds to -inf in HF16
0x00000000, -- smallest F32 normal rounds to zero in HF16
0x7fc00000,
0x7f800000,
0xff800000
}
dump(expected, 8)
for i=0,7 do
if r[i] ~= expected[i] then
print("FAIL at index", i, string.format("got 0x%08x expected 0x%08x", r[i], expected[i]))
return
end
end
print("OK")

View file

@ -0,0 +1,62 @@
check_ver(20)
F32_VALUE = 0x3F8016F0 -- 1.0007
-- F32_VALUE = 0x3F8009D5 -- 1.0003
F16_ROUNDED_UP = 0x3C01 -- 1.001
F16_ROUNDED_DOWN = 0x3C00 -- 1.000
N = 16 * 4
math.randomseed(os.time())
local random_data = {}
for i = 0, N-1 do
random_data[i] = math.random(1 << 32) - 1
end
src = [[
@id g10
@mov g20 ]] .. F32_VALUE .. [[
]]
for i = 0, (N/16)-1 do
src = src .. [[
@read g30 g10
@mov g40 0
srnd(16) g40<2>HF g20<1,1,0>F g30<1,1,0>F {nomask};
// Change g30 to g40 to see the random values.
@write g10 g40
add(16) g10<1>UD g10<1,1,0>UD 0x10UD {A@1};
]]
end
src = src .. [[
@eot
]]
local r = execute {
data = random_data,
src = src,
}
up = 0
down = 0
invalid = 0
for i = 0, N-1 do
if r[i] == F16_ROUNDED_UP then
up = up + 1
elseif r[i] == F16_ROUNDED_DOWN then
down = down + 1
else
invalid = invalid + 1
end
end
dump(r, N)
print()
print("rounded up ", up/N, "%")
print("rounded down ", down/N, "%")
print("invalid ", invalid/N, "%")