| 209 | } |
| 210 | |
| 211 | static bool check_gradient( |
| 212 | const char * op_name, |
| 213 | struct ggml_context * ctx0, |
| 214 | struct ggml_tensor * x[], |
| 215 | struct ggml_tensor * f, |
| 216 | int ndims, |
| 217 | int nargs, |
| 218 | float eps, |
| 219 | float max_error_abs, |
| 220 | float max_error_rel) { |
| 221 | |
| 222 | static int n_threads = -1; |
| 223 | if (n_threads < 0) { |
| 224 | n_threads = GGML_DEFAULT_N_THREADS; |
| 225 | |
| 226 | const char *env = getenv("GGML_N_THREADS"); |
| 227 | if (env) { |
| 228 | n_threads = atoi(env); |
| 229 | } |
| 230 | |
| 231 | printf("GGML_N_THREADS = %d\n", n_threads); |
| 232 | } |
| 233 | |
| 234 | struct ggml_cgraph * gf = ggml_new_graph_custom(ctx0, GGML_DEFAULT_GRAPH_SIZE, true); |
| 235 | struct ggml_cgraph * gb = ggml_new_graph_custom(ctx0, GGML_DEFAULT_GRAPH_SIZE, true); |
| 236 | ggml_build_forward_expand(gf, f); |
| 237 | ggml_graph_cpy(gf, gb); |
| 238 | ggml_build_backward_expand(ctx0, gf, gb, false); |
| 239 | |
| 240 | ggml_graph_compute_with_ctx(ctx0, gf, n_threads); |
| 241 | |
| 242 | ggml_graph_reset (gf); |
| 243 | ggml_set_f32 (f->grad, 1.0f); |
| 244 | |
| 245 | ggml_graph_compute_with_ctx(ctx0, gb, n_threads); |
| 246 | |
| 247 | // ggml_graph_dump_dot(gf, NULL, "test-grad0-forward.dot"); |
| 248 | // ggml_graph_dump_dot(gb, gf, "test-grad0-backward.dot"); |
| 249 | |
| 250 | for (int i = 0; i < nargs; ++i) { |
| 251 | const int nelements = ggml_nelements(x[i]); |
| 252 | for (int k = 0; k < nelements; ++k) { |
| 253 | // compute gradient using finite differences |
| 254 | const float x0 = ggml_get_f32_1d(x[i], k); |
| 255 | const float xm = x0 - eps; |
| 256 | const float xp = x0 + eps; |
| 257 | ggml_set_f32_1d(x[i], k, xp); |
| 258 | |
| 259 | ggml_graph_compute_with_ctx(ctx0, gf, n_threads); |
| 260 | |
| 261 | const double f0 = ggml_get_f32_1d(f, 0); |
| 262 | |
| 263 | ggml_set_f32_1d(x[i], k, xm); |
| 264 | |
| 265 | ggml_graph_compute_with_ctx(ctx0, gf, n_threads); |
| 266 | |
| 267 | const double f1 = ggml_get_f32_1d(f, 0); |
| 268 | const double g0 = (f0 - f1)/(2.0*(double) eps); |
no test coverage detected