text: // Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved.
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  #include <gtest/gtest.h>
  
  #include "paddle/fluid/framework/ir/is_test_pass.h"
  #ifdef _WIN32
  #undef FALSE
  #undef TRUE
  #endif
  namespace paddle {
  namespace framework {
  namespace ir {
  
  enum class ISTEST_STATE { FALSE, TRUE, UNSET };
  
  void SetOp(ProgramDesc* prog, const std::string& type, const std::string& name,
             const std::vector<std::string>& inputs,
             const std::vector<std::string>& outputs, bool use_mkldnn = false,
             ISTEST_STATE is_test = ISTEST_STATE::UNSET) {
    auto* op = prog->MutableBlock(0)->AppendOp();
    op->SetType(type);
    op->SetAttr("name", name);
    op->SetInput("X", inputs);
    op->SetOutput("Out", outputs);
    op->SetAttr("use_mkldnn", use_mkldnn);
    if (is_test == ISTEST_STATE::UNSET)
      op->MutableAttrMap()->erase("is_test");
    else if (is_test == ISTEST_STATE::FALSE)
      op->SetAttr("is_test", false);
    else
      op->SetAttr("is_test", true);
  }
  
  // a->pool2d->b
  // b->relu->c
  // c,weights1)->conv2d->d
  //
  // d->pool2d->e
  // e->hard_sigmoid->f
  // (f,weights2)->conv2d->g
  //
  // g->pool2d->h
  // h->tanh->i
  // (i,weights3)->conv2d->j
  ProgramDesc BuildProgramDesc() {
    ProgramDesc prog;
    for (auto& v :
         std::vector<std::string>({"a", "b", "c", "d", "e", "f", "g", "h", "i",
                                   "j", "weights1", "weights2", "weights3"})) {
      auto* var = prog.MutableBlock(0)->Var(v);
      var->SetType(proto::VarType::SELECTED_ROWS);
      if (v == "weights1" || v == "weights2" || v == "weights3") {
        var->SetPersistable(true);
      }
    }
  
    SetOp(&prog, "pool2d", "pooling1", std::vector<std::string>({"a"}),
          std::vector<std::string>({"b"}), true, ISTEST_STATE::TRUE);
    SetOp(&prog, "relu", "activation1", std::vector<std::string>({"b"}),
          std::vector<std::string>({"c"}), true, ISTEST_STATE::TRUE);
    SetOp(&prog, "conv2d", "conv1", std::vector<std::string>({"c", "weights1"}),
          std::vector<std::string>({"d"}), true, ISTEST_STATE::TRUE);
  
    SetOp(&prog, "pool2d", "pooling2", std::vector<std::string>({"d"}),
          std::vector<std::string>({"e"}), false, ISTEST_STATE::FALSE);
    SetOp(&prog, "hard_sigmoid", "activation2", std::vector<std::string>({"e"}),
          std::vector<std::string>({"f"}), false, ISTEST_STATE::FALSE);
    SetOp(&prog, "conv2d", "conv2", std::vector<std::string>({"f", "weights2"}),
          std::vector<std::string>({"g"}), false, ISTEST_STATE::FALSE);
  
    SetOp(&prog, "pool2d", "pooling3", std::vector<std::string>({"g"}),
          std::vector<std::string>({"h"}), false, ISTEST_STATE::UNSET);
    SetOp(&prog, "tanh", "activation3", std::vector<std::string>({"h"}),
          std::vector<std::string>({"i"}), true, ISTEST_STATE::UNSET);
    SetOp(&prog, "conv2d", "conv3", std::vector<std::string>({"i", "weights3"}),
          std::vector<std::string>({"j"}), false, ISTEST_STATE::UNSET);
  
    return prog;
  }
  
  TEST(IsTestPass, basic) {
    auto prog = BuildProgramDesc();
  
    std::unique_ptr<ir::Graph> graph(new ir::Graph(prog));
  
    auto pass = PassRegistry::Instance().Get("is_test_pass");
  
    graph.reset(pass->Apply(graph.release()));
  
    for (auto* node : graph->Nodes()) {
      if (node->IsOp()) {
        auto* op = node->Op();
        auto op_name = BOOST_GET_CONST(std::string, op->GetAttr("name"));
        if (op_name == "conv3") {
          ASSERT_FALSE(op->HasAttr("is_test"));
        } else {
          ASSERT_TRUE(op->HasAttr("is_test"));
          EXPECT_TRUE(BOOST_GET_CONST(bool, op->GetAttr("is_test")));
        }
      }
    }
  }
  
  }  // namespace ir
  }  // namespace framework
  }  // namespace paddle
  
  USE_PASS(is_test_pass);
  