| 16 | constexpr float TAYLOR_MAX_ERR = 1e-6; |
| 17 | |
| 18 | void test_taylor( |
| 19 | thin_function<SymbolVar(SymbolVar)> tmaker, thin_function<float(float)> raw_f, |
| 20 | thin_function<float(float)> raw_g) { |
| 21 | constexpr float MAX_ERR = 1e-6; |
| 22 | HostTensorGenerator<> gen; |
| 23 | |
| 24 | auto host_x = gen({7}), host_loss_p = gen({7}); |
| 25 | auto graph = ComputingGraph::make(); |
| 26 | auto x = opr::Host2DeviceCopy::make(*graph, host_x), |
| 27 | loss_p = opr::Host2DeviceCopy::make(*graph, host_loss_p), y = tmaker(x), |
| 28 | loss = opr::Dot::make(y, loss_p), grad = cg::grad(loss, x); |
| 29 | HostTensorND host_y, host_grad; |
| 30 | auto func = graph->compile( |
| 31 | {make_callback_copy(y, host_y), make_callback_copy(grad, host_grad)}); |
| 32 | |
| 33 | for (size_t SIZE : {1, 23}) { |
| 34 | host_x->copy_from(*gen({SIZE})); |
| 35 | host_loss_p->copy_from(*gen({SIZE})); |
| 36 | func->execute(); |
| 37 | ASSERT_EQ(host_x->shape(), host_y.shape()); |
| 38 | ASSERT_EQ(host_x->shape(), host_grad.shape()); |
| 39 | for (size_t i = 0; i < SIZE; i++) { |
| 40 | auto x = host_x->ptr<float>()[i], loss_p = host_loss_p->ptr<float>()[i]; |
| 41 | MGB_ASSERT_FLOAT_NEAR(raw_f(x), host_y.ptr<float>()[i], MAX_ERR * 10) |
| 42 | << ssprintf("i: %zd; x: %.4f", i, x); |
| 43 | MGB_ASSERT_FLOAT_NEAR( |
| 44 | raw_g(x) * loss_p, host_grad.ptr<float>()[i], MAX_ERR * 10) |
| 45 | << ssprintf("i: %zd; x: %.4f; loss_p: %.4f", i, x, loss_p); |
| 46 | } |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /*! |
| 51 | * \brief calc a complex expression involving two vars |