小编TTo*_*Toi的帖子

Metal SIMD的最小和最大操作无法进行浮点运算

简短的问题

为什么我从带有浮动的Metal 2.1中得到未定义的行为simd_minsimd_max在其中起作用?

更新:似乎仅在Radeon Pro 560X GPU上发生,而在Intel UHD Graphics 630上则没有。

背景

根据金属着色语言指南第5.14节,simd_minsimd_max功能被支持以便共同标量或矢量,整数或浮点类型。

对于simd_max,规范指出:

T simd_max(T data)

返回SIMD组中所有活动线程中数据的最大值,并将结果广播到SIMD组中所有活动线程。

测试用例

为了测试这一点,我正在执行以下测试内核,其输入缓冲区为0..100范围内的128个随机浮点数:

kernel void simdMaxDebugKernel(
                          const device float *buffer [[ buffer(0) ]],
                          device float *output [[ buffer(1) ]],
                          uint id [[ thread_position_in_grid ]])
{
    output[id] = simd_max(buffer[id]);
}
Run Code Online (Sandbox Code Playgroud)

通过检查,将128值的缓冲区分为两个64值的SIMD组。因此,我希望输出中的前64个值将分别设置为第一个和最后一个SIMD组的最大值。

检测结果

我得到了一些意外的结果:

inputs  [simd_float1]   128 values  
[0] Float   94.3006362
[1] Float   98.1107177
[2] Float   85.3725891
[3] Float   45.1457863
...
[63] Float  36.5486336 …
Run Code Online (Sandbox Code Playgroud)

floating-point gpgpu simd compute-shader metal

5
推荐指数
0
解决办法
139
查看次数

F#使用GetEnumerator时无法枚举yield生成的序列

以下示例基于一个片段,该片段生成允许逐个枚举序列值的函数.

这里printAreEqual ()给出了真实,print2 ()给出了12345678910,但print1 ()给出了0000000000.

为什么枚举返回的函数不能返回使用yield生成的序列的值?


open System.Linq

let enumerate (xs: seq<_>)  = 
    use en = xs.GetEnumerator()
    fun () ->
        en.MoveNext() |> ignore
        en.Current

let s1 = seq { for i in 1 .. 10 do yield i }
let s2 = seq { 1 .. 10 }

let f1 = s1 |> enumerate
let f2 = s2 |> enumerate

let printAreEqual () = …
Run Code Online (Sandbox Code Playgroud)

f# enumeration yield sequence

3
推荐指数
1
解决办法
92
查看次数