Search Unity

Question AppendStructuredBuffer giving nonsense results.

Discussion in 'Shaders' started by Maxeaman, Dec 17, 2022.

  1. Maxeaman

    Maxeaman

    Joined:
    May 1, 2020
    Posts:
    14
    I'm using DX12 in Unity3d, and I'm using an AppendStructuredBuffer in the compute shader. It seems to be giving the correct answer mathematically for the first time it appends to the buffer, but every subsequent time it appends, it gives extremely tiny numbers, 0, or [NaN] results that don't match up with the computation that I'm running in parallel on the CPU.

    This is the code of the Compute Shader:


    Code (Cg/HLSL):
    1. // Each #kernel tells which function to compile; you can have many kernels
    2. #pragma kernel Forward
    3. #pragma kernel LayerResults
    4. #pragma use_dxc
    5. #include "UnityCG.cginc"
    6.  
    7. StructuredBuffer<float> _biases;
    8. StructuredBuffer<float> _weights;
    9. StructuredBuffer<float> _inputs;
    10. AppendStructuredBuffer<float> _layerOutput;
    11. [numthreads(4, 1, 1)]
    12. void Forward(uint3 id : SV_DispatchThreadID)
    13. {
    14.    uint2 biasNum;
    15.    uint2 inputNum;
    16.    _biases.GetDimensions(biasNum.x, biasNum.y);
    17.    _inputs.GetDimensions(inputNum.x, inputNum.y);
    18.    float weightIndex = 0;
    19.    for (int i = 0; i < biasNum.x; i++) {
    20.        float sum = 0;
    21.        for (int j = 0; j < inputNum.x; j++) {
    22.            sum = sum + _inputs[j] * _weights[weightIndex];
    23.            weightIndex++;
    24.        }
    25.        sum = sum + _biases[i];
    26.        _layerOutput.Append(sum);
    27.    }
    28. }
    29. [numthreads(4, 1, 1)]
    30. void LayerResults(uint3 id : SV_DispatchThreadID)
    31. {
    32.    
    33. }
    34.  
    The math is right for calculating what number should be added but it only gets the first number right. What would be causing this? The c# is rather large, but this is the relevant parts:

    Code (CSharp):
    1. ComputeBuffer layerOutput = new(layerBiases.Length, sizeof(float) * (layerWeights.Length), ComputeBufferType.Append);
    2.  
    3. c.SetBuffer(kernelIndex, "_layerOutput", layerOutput);
    4.  
    5. c.Dispatch(kernelIndex, 4, 1, 1);
    6.  
    7. layerOutput.GetData(layerEnd);
    8.  
    It's storing the right number of items, but everything after the first result is nonsense.

    I'm trying to get the results from the compute buffer to match the results from the CPU. The math is done in exactly the same way.