| 198 | } |
| 199 | |
| 200 | void testWGSL() { |
| 201 | static const char *kGelu = R"( |
| 202 | const GELU_SCALING_FACTOR: f16 = 0.7978845608028654; // sqrt(2.0 / PI) |
| 203 | @group(0) @binding(0) var<storage, read_write> inp: array<{{precision}}>; |
| 204 | @group(0) @binding(1) var<storage, read_write> out: array<{{precision}}>; |
| 205 | @group(0) @binding(1) var<storage, read_write> dummy: array<{{precision}}>; |
| 206 | @compute @workgroup_size({{workgroupSize}}) |
| 207 | fn main( |
| 208 | @builtin(global_invocation_id) GlobalInvocationID: vec3<u32>) { |
| 209 | let i: u32 = GlobalInvocationID.x; |
| 210 | if (i < arrayLength(&inp)) { |
| 211 | let x: f16 = inp[i]; |
| 212 | out[i] = select(0.5 * x * (1.0 + tanh(GELU_SCALING_FACTOR |
| 213 | * (x + .044715 * x * x * x))), x, x > 10.0); |
| 214 | } |
| 215 | } |
| 216 | )"; |
| 217 | Context ctx = createContext( |
| 218 | {}, {}, |
| 219 | /*device descriptor, enabling f16 in WGSL*/ |
| 220 | { |
| 221 | .requiredFeatureCount = 1, |
| 222 | .requiredFeatures = std::array{WGPUFeatureName_ShaderF16}.data(), |
| 223 | }); |
| 224 | static constexpr size_t N = 10000; |
| 225 | std::array<half, N> inputArr, outputArr; |
| 226 | for (int i = 0; i < N; ++i) { |
| 227 | inputArr[i] = half(static_cast<float>(i) / 10.0f); // dummy input data |
| 228 | } |
| 229 | Tensor input = createTensor(ctx, Shape{N}, kf16, inputArr.data()); |
| 230 | Tensor output = createTensor(ctx, Shape{N}, kf16); |
| 231 | std::promise<void> promise; |
| 232 | std::future<void> future = promise.get_future(); |
| 233 | Kernel op = createKernel(ctx, {kGelu, 256, kf16}, Bindings{input, output}, |
| 234 | {cdiv(N, 256), 1, 1}); |
| 235 | dispatchKernel(ctx, op, promise); |
| 236 | wait(ctx, future); |
| 237 | toCPU(ctx, output, outputArr.data(), sizeof(outputArr)); |
| 238 | for (int i = 0; i < 12; ++i) { |
| 239 | printf(" gelu(%.2f) = %.2f\n", static_cast<float>(inputArr[i]), |
| 240 | static_cast<float>(outputArr[i])); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | int main() { |
| 245 | printf("\nHalf-precision float tests\n==========================\n"); |
no test coverage detected