compatible.cc 5.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// 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 "paddle/fluid/pybind/compatible.h"
16

17 18
#include <memory>
#include <string>
19

20
#include "paddle/fluid/framework/op_version_registry.h"
21
#include "paddle/fluid/pybind/pybind_variant_caster.h"
22 23 24

namespace py = pybind11;

25
using paddle::framework::compatible::OpAttrInfo;
26
using paddle::framework::compatible::OpAttrVariantT;
27 28
using paddle::framework::compatible::OpBugfixInfo;
using paddle::framework::compatible::OpCheckpoint;
29 30 31 32
using paddle::framework::compatible::OpInputOutputInfo;
using paddle::framework::compatible::OpUpdateBase;
using paddle::framework::compatible::OpUpdateInfo;
using paddle::framework::compatible::OpUpdateType;
33
using paddle::framework::compatible::OpVersion;
34
using paddle::framework::compatible::OpVersionDesc;
35 36 37 38

namespace paddle {
namespace pybind {

39 40 41
namespace {
using paddle::framework::compatible::PassVersionCheckerRegistrar;
void BindPassVersionChecker(py::module *m) {
42
  py::class_<PassVersionCheckerRegistrar>(*m, "PassVersionChecker")
43
      .def_static("IsCompatible", [](const std::string &name) -> bool {
44 45 46 47 48
        auto instance = PassVersionCheckerRegistrar::GetInstance();
        return instance.IsPassCompatible(name);
      });
}

49 50 51 52 53 54 55 56
void BindPassCompatible(py::module *m) { BindPassVersionChecker(m); }

void BindOpUpdateInfo(py::module *m) {
  py::class_<OpUpdateInfo>(*m, "OpUpdateInfo").def(py::init<>());
}

void BindOpAttrInfo(py::module *m) {
  py::class_<OpAttrInfo, OpUpdateInfo>(*m, "OpAttrInfo")
57 58
      .def(py::init<const std::string &,
                    const std::string &,
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
                    const OpAttrVariantT &>())
      .def(py::init<const OpAttrInfo &>())
      .def("name", &OpAttrInfo::name)
      .def("default_value", &OpAttrInfo::default_value)
      .def("remark", &OpAttrInfo::remark);
}

void BindOpInputOutputInfo(py::module *m) {
  py::class_<OpInputOutputInfo, OpUpdateInfo>(*m, "OpInputOutputInfo")
      .def(py::init<const std::string &, const std::string &>())
      .def(py::init<const OpInputOutputInfo &>())
      .def("name", &OpInputOutputInfo::name)
      .def("remark", &OpInputOutputInfo::remark);
}

void BindOpBugfixInfo(py::module *m) {
  py::class_<OpBugfixInfo, OpUpdateInfo>(*m, "OpBugfixInfo")
      .def(py::init<const std::string &>())
      .def(py::init<const OpBugfixInfo &>())
      .def("remark", &OpBugfixInfo::remark);
}

void BindOpCompatible(py::module *m) {
  BindOpUpdateInfo(m);
  BindOpAttrInfo(m);
  BindOpInputOutputInfo(m);
  BindOpBugfixInfo(m);
}

void BindOpUpdateType(py::module *m) {
  py::enum_<OpUpdateType>(*m, "OpUpdateType")
      .value("kInvalid", OpUpdateType::kInvalid)
      .value("kModifyAttr", OpUpdateType::kModifyAttr)
      .value("kNewAttr", OpUpdateType::kNewAttr)
      .value("kNewInput", OpUpdateType::kNewInput)
      .value("kNewOutput", OpUpdateType::kNewOutput)
      .value("kBugfixWithBehaviorChanged",
             OpUpdateType::kBugfixWithBehaviorChanged);
}

void BindOpUpdateBase(py::module *m) {
  py::class_<OpUpdateBase>(*m, "OpUpdateBase")
101
      .def("info", &OpUpdateBase::info, py::return_value_policy::reference)
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
      .def("type", &OpUpdateBase::type);
}

void BindOpVersionDesc(py::module *m) {
  py::class_<OpVersionDesc>(*m, "OpVersionDesc")
      // Pybind11 does not yet support the transfer of `const
      // std::vector<std::unique_ptr<T>>&` type objects.
      .def("infos", [](const OpVersionDesc &obj) {
        auto pylist = py::list();
        for (const auto &ptr : obj.infos()) {
          auto pyobj = py::cast(*ptr, py::return_value_policy::reference);
          pylist.append(pyobj);
        }
        return pylist;
      });
}

void BindOpCheckpoint(py::module *m) {
  py::class_<OpCheckpoint>(*m, "OpCheckpoint")
      .def("note", &OpCheckpoint::note, py::return_value_policy::reference)
122 123
      .def("version_desc",
           &OpCheckpoint::version_desc,
124 125 126 127 128
           py::return_value_policy::reference);
}

void BindOpVersion(py::module *m) {
  py::class_<OpVersion>(*m, "OpVersion")
129 130
      .def("version_id",
           &OpVersion::version_id,
131
           py::return_value_policy::reference)
132 133
      .def("checkpoints",
           &OpVersion::checkpoints,
134 135
           py::return_value_policy::reference);
  // At least pybind v2.3.0 is required because of bug #1603 of pybind11.
136 137
  m->def("get_op_version_map",
         &framework::compatible::get_op_version_map,
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
         py::return_value_policy::reference);
}

}  // namespace

void BindCompatible(py::module *m) {
  BindPassCompatible(m);
  BindOpCompatible(m);
  BindOpUpdateType(m);
  BindOpUpdateBase(m);
  BindOpVersionDesc(m);
  BindOpCheckpoint(m);
  BindOpVersion(m);
}

153 154
}  // namespace pybind
}  // namespace paddle