#include #include #include #include #include #include #include TEST(NoGradTest, SetsGradModeCorrectly) { torch::manual_seed(0); torch::NoGradGuard guard; torch::nn::Linear model(5, 2); auto x = torch::randn({10, 5}, torch::requires_grad()); auto y = model->forward(x); torch::Tensor s = y.sum(); s.backward(); ASSERT_FALSE(model->parameters()["weight"].grad().defined()); } struct AutogradTest : torch::test::SeedingFixture { AutogradTest() { x = torch::randn({3, 3}, torch::requires_grad()); y = torch::randn({3, 3}); z = x * y; } torch::Tensor x, y, z; }; TEST_F(AutogradTest, CanTakeDerivatives) { z.backward(); ASSERT_TRUE(x.grad().allclose(y)); } TEST_F(AutogradTest, CanTakeDerivativesOfZeroDimTensors) { z.sum().backward(); ASSERT_TRUE(x.grad().allclose(y)); } TEST_F(AutogradTest, CanPassCustomGradientInputs) { z.sum().backward(torch::ones({}) * 2); ASSERT_TRUE(x.grad().allclose(y * 2)); } TEST(NNInitTest, CanInitializeTensorThatRequiresGrad) { auto tensor = torch::empty({3, 4}, torch::requires_grad()); ASSERT_THROWS_WITH( tensor.fill_(1), "a leaf Variable that requires grad " "has been used in an in-place operation"); ASSERT_EQ(torch::nn::init::ones_(tensor).sum().item(), 12); } TEST(TempFileTest, MatchesExpectedPattern) { torch::utils::TempFile pattern = torch::utils::make_tempfile("test-pattern-"); ASSERT_NE(pattern.name.find("test-pattern-"), std::string::npos); }