yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f02b08490
master
1//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -d3d12 2//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -vk 3//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -metal 4//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -cuda 5//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -cpu 6//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -wgpu 7 8// Note: there is a bug in fxc compiler errorneously reporting infinite loop for this shader. 9// Skipping d3d11 test to avoid the bug. 10//DISABLE_TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-output-using-type -d3d11 11 12struct GradientBuffer<let D : int> 13{ 14 RWStructuredBuffer<float> primal; 15 StructuredBuffer<float> grad; 16 int strides[D]; 17 18 int toIndex(int idx[D]) { 19 int result = 0; 20 for (int i = 0; i < D; ++i) 21 result += strides[i] * idx[i]; 22 return result; 23 } 24 25 [Differentiable] 26 void write(int[D] idx, float v) { primal[toIndex(idx)] = detach(v); } 27 28 [BackwardDerivativeOf(write)] 29 void write_bwd(int[D] idx, inout DifferentialPair<float> d) { d = diffPair(d.p, grad[toIndex(idx)]); } 30 31 [Differentiable] 32 void store<let N : int>(int context[D - 1], in float value[N]) 33 { 34 int idx[D]; 35 //[ForceUnroll] /* Using ForceUnroll instead of MaxIters makes it work */ 36 [MaxIters(2)] 37 for (int i = 0; i < D - 1; ++i) 38 idx[i] = context[i]; 39 [ForceUnroll] 40 for (int i = 0; i < N; i++) { 41 idx[D - 1] = i; 42 write(idx, value[i]); 43 } 44 } 45} 46 47[Differentiable] 48void test(GradientBuffer<2> buf, int[1] base, float[3] value) 49{ 50 buf.store(base, value); 51} 52 53float3 repro(RWStructuredBuffer<float> primal, StructuredBuffer<float> grad) 54{ 55 float input[3]; 56 input[0] = input[1] = input[2] = 1.0f; 57 var result = diffPair(input); 58 GradientBuffer<2> buf = { primal, grad, {3, 1} }; 59 bwd_diff(test)(buf, { 1 }, result); 60 return float3(result.d[0], result.d[1], result.d[2]); 61} 62 63//TEST_INPUT: set grad_in = ubuffer(data=[101.0 102.0 103.0 104.0], stride=4) 64uniform StructuredBuffer<float> grad_in; 65 66//TEST_INPUT: set grad_out = ubuffer(data=[0 0 0 0], stride=4) 67uniform RWStructuredBuffer<float> grad_out; 68 69//TEST_INPUT: set output = out ubuffer(data=[0 0 0 0], stride=4) 70uniform RWStructuredBuffer<float> output; 71 72[shader("compute")] 73[numthreads(1,1,1)] 74void computeMain() 75{ 76 let result = repro(grad_out, grad_in); 77 // CHECK: 104.0 78 output[0] = result.x; 79 output[1] = result.y; 80 output[2] = result.z; 81}