| 131 | } |
| 132 | |
| 133 | void testGelu(Context &ctx) { |
| 134 | static constexpr size_t N = 3072; |
| 135 | std::array<float, N> inputArr; |
| 136 | // range(inputArr); |
| 137 | auto gen = std::mt19937(31415); |
| 138 | // TODO(avh): investigate - on metal tanh seems to produce nan for values > 10 |
| 139 | randint(inputArr, gen, 0, 10); // for debugging |
| 140 | std::array<float, N> outputArr; |
| 141 | Tensor geluIn = createTensor(ctx, {N}, kf32, inputArr.data()); |
| 142 | Tensor geluOut = createTensor(ctx, {N}, kf32, outputArr.data()); |
| 143 | LOG(kDefLog, kInfo, "Creating GELU Shader"); |
| 144 | KernelCode shader = {kShaderGelu, 256, kf32}; |
| 145 | Kernel op = createKernel(ctx, shader, Bindings{geluIn, geluOut}, |
| 146 | {cdiv(N, 256), 1, 1}); |
| 147 | LOG(kDefLog, kInfo, "Workgroup size: %s", |
| 148 | toString(shader.workgroupSize).c_str()); |
| 149 | LOG(kDefLog, kInfo, "dispatching GELU Shader"); |
| 150 | std::promise<void> promise; |
| 151 | std::future<void> future = promise.get_future(); |
| 152 | dispatchKernel(ctx, op, promise); |
| 153 | wait(ctx, future); |
| 154 | toCPU(ctx, geluOut, outputArr.data(), sizeof(outputArr)); |
| 155 | LOG(kDefLog, kInfo, "%s", show<float, N, 1>(inputArr, "GELU Input").c_str()); |
| 156 | LOG(kDefLog, kInfo, "%s", |
| 157 | show<float, N, 1>(outputArr, "GELU Output").c_str()); |
| 158 | std::array<float, N> refOutputArr; |
| 159 | ref::gelu_forward_cpu(refOutputArr.data(), inputArr.data(), N); |
| 160 | LOG(kDefLog, kInfo, "%s", |
| 161 | show<float, N, 1>(refOutputArr, "GELU Reference Output").c_str()); |
| 162 | bool passed = isclose(outputArr.data(), refOutputArr.data(), N); |
| 163 | assert(passed); |
| 164 | LOG(kDefLog, kInfo, "Gelu passed? %d", passed); |
| 165 | LOG(kDefLog, kInfo, "Done with Gelu Test"); |
| 166 | } |
| 167 | |
| 168 | void testLayerNorm(Context &ctx) { |
| 169 | struct LNParam { |
no test coverage detected