| 256 | } |
| 257 | |
| 258 | static std::pair<int, int> test_grad(ggml_backend_sched_t backend_sched, ggml_backend_t backend) { |
| 259 | int ntest = 0; |
| 260 | int npass = 0; |
| 261 | |
| 262 | struct helper_ctx_data cd = helper_get_ctx_data(backend_sched, backend, /*init_opt_ctx =*/ true, /*optimizer_defaults =*/ false, |
| 263 | /*nbatch_logical =*/ 999999, /*nbatch_physical =*/ 1); |
| 264 | |
| 265 | std::vector<float> grad_history(ndata); |
| 266 | for (int64_t idata = 0; idata < ndata; ++idata) { |
| 267 | grad_history[idata] = NAN; |
| 268 | } |
| 269 | |
| 270 | for (int idata = 0; idata < ndata; ++idata) { |
| 271 | const float idataf = idata; |
| 272 | ggml_opt_alloc(cd.opt_ctx, /*backward =*/ true); |
| 273 | ggml_backend_tensor_set(cd.inputs, &idataf, 0, ggml_nbytes(cd.inputs)); |
| 274 | ggml_opt_eval(cd.opt_ctx, cd.result); |
| 275 | ggml_backend_tensor_get(ggml_opt_grad_acc(cd.opt_ctx, cd.weights), grad_history.data() + idata, 0, sizeof(float)); |
| 276 | } |
| 277 | |
| 278 | { |
| 279 | bool subtest_ok = true; |
| 280 | for (int idata = 0; idata < ndata; ++idata) { |
| 281 | if (grad_history[idata] != idata + 1) { |
| 282 | subtest_ok = false; |
| 283 | } |
| 284 | } |
| 285 | printf(" %s(): ", __func__); |
| 286 | if (subtest_ok) { |
| 287 | printf("\033[1;32mOK\033[0m\n"); |
| 288 | npass++; |
| 289 | } else { |
| 290 | printf("\033[1;31mFAIL\033[0m\n"); |
| 291 | } |
| 292 | ntest++; |
| 293 | } |
| 294 | |
| 295 | helper_free_ctx_data(cd); |
| 296 | |
| 297 | return std::make_pair(npass, ntest); |
| 298 | } |
| 299 | |
| 300 | static void helper_after_test_forward_backward( |
| 301 | const char * func, const bool high_level, const bool shuffle, |
no test coverage detected