683 lines
25 KiB
C++
683 lines
25 KiB
C++
/* Copyright (c) 2021 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. */
|
|
#pragma once
|
|
|
|
#if defined(_MSC_VER)
|
|
#include <BaseTsd.h>
|
|
typedef SSIZE_T ssize_t;
|
|
#endif
|
|
|
|
#include <Python.h>
|
|
|
|
#include "paddle/fluid/eager/grad_node_info.h"
|
|
#include "paddle/fluid/eager/hooks.h"
|
|
#include "paddle/fluid/framework/dense_tensor_array.h"
|
|
#include "paddle/fluid/framework/lod_tensor.h"
|
|
#include "paddle/fluid/framework/tensor.h"
|
|
#include "paddle/fluid/jit/function.h"
|
|
#include "paddle/phi/api/lib/kernel_dispatch.h"
|
|
#include "paddle/phi/common/backend.h"
|
|
#include "paddle/phi/common/data_type.h"
|
|
#include "paddle/phi/common/int_array.h"
|
|
#include "paddle/phi/common/place.h"
|
|
#include "paddle/phi/common/scalar.h"
|
|
#include "paddle/phi/core/dense_tensor.h"
|
|
#include "paddle/phi/core/distributed/auto_parallel/dist_attr.h"
|
|
#include "paddle/phi/core/distributed/auto_parallel/dist_tensor.h"
|
|
#include "paddle/phi/core/distributed/auto_parallel/process_mesh.h"
|
|
#include "paddle/phi/core/enforce.h"
|
|
#include "paddle/phi/core/selected_rows.h"
|
|
#include "paddle/phi/core/vocab/string_array.h"
|
|
#include "paddle/pir/include/core/value.h"
|
|
#include "paddle/utils/pybind.h"
|
|
#include "pybind11/pybind11.h"
|
|
#include "pybind11/stl.h"
|
|
|
|
namespace paddle {
|
|
class CustomOpKernelContext;
|
|
namespace framework {
|
|
class Scope;
|
|
}
|
|
namespace pybind {
|
|
|
|
namespace py = ::pybind11;
|
|
|
|
template <typename T>
|
|
static T PyObjectCast(PyObject* obj) {
|
|
try {
|
|
return py::cast<T>(py::handle(obj));
|
|
} catch (py::cast_error&) {
|
|
PADDLE_THROW(common::errors::InvalidArgument(
|
|
"Python object is not type of %s, the real type is %s",
|
|
typeid(T).name(),
|
|
obj->ob_type->tp_name));
|
|
}
|
|
}
|
|
|
|
int TensorDtype2NumpyDtype(DataType dtype);
|
|
|
|
bool PyObject_CheckStr(PyObject* obj);
|
|
bool PyObject_CheckIRValue(PyObject* obj);
|
|
bool PyObject_CheckIRVectorOfValue(PyObject* obj);
|
|
bool PyObject_CheckIRVectorOfValueOrLong(PyObject* obj);
|
|
bool CastPyArg2AttrBoolean(PyObject* obj, ssize_t arg_pos);
|
|
int CastPyArg2AttrInt(PyObject* obj, ssize_t arg_pos);
|
|
int64_t CastPyArg2AttrLong(PyObject* obj, ssize_t arg_pos);
|
|
size_t CastPyArg2AttrSize_t(PyObject* obj, ssize_t arg_pos);
|
|
float CastPyArg2AttrFloat(PyObject* obj, ssize_t arg_pos);
|
|
double CastPyArg2AttrDouble(PyObject* obj, ssize_t arg_pos);
|
|
std::string CastPyArg2AttrString(PyObject* obj, ssize_t arg_pos);
|
|
std::shared_ptr<imperative::VarBase> CastPyArg2VarBase(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
std::vector<Tensor> CastPyArg2VectorOfTensor(
|
|
PyObject* obj,
|
|
ssize_t arg_pos,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
Place CastPyArg2Place(PyObject* obj, ssize_t arg_pos);
|
|
DenseTensor CastPyArg2FrameworkTensor(PyObject* obj, ssize_t arg_pos);
|
|
std::vector<DenseTensor> CastPyArg2VectorOfTensorBase(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
std::vector<int> CastPyArg2VectorOfInt(PyObject* obj, size_t arg_pos);
|
|
std::vector<int64_t> CastPyArg2VectorOfInt64(PyObject* obj, size_t arg_pos);
|
|
std::vector<size_t> CastPyArg2VectorOfSize_t(PyObject* obj, size_t arg_pos);
|
|
std::vector<float> CastPyArg2VectorOfFloat(PyObject* obj, size_t arg_pos);
|
|
pir::Value CastPyArg2Value(PyObject* obj,
|
|
const std::string& op_type,
|
|
size_t arg_pos,
|
|
bool dispensable = false);
|
|
paddle::optional<pir::Value> CastPyArg2OptionalValue(PyObject* obj,
|
|
const std::string& op_type,
|
|
size_t arg_pos,
|
|
bool dispensable = false);
|
|
std::vector<pir::Value> CastPyArg2VectorOfValue(PyObject* obj,
|
|
const std::string& op_type,
|
|
size_t arg_pos,
|
|
bool dispensable = false);
|
|
std::vector<pir::Value> CastPyArg2VectorOfValueOrLong(
|
|
PyObject* obj,
|
|
const std::string& op_type,
|
|
size_t arg_pos,
|
|
bool dispensable = false);
|
|
paddle::optional<std::vector<pir::Value>> CastPyArg2OptionalVectorOfValue(
|
|
PyObject* obj,
|
|
const std::string& op_type,
|
|
size_t arg_pos,
|
|
bool dispensable = false);
|
|
std::vector<std::vector<size_t>> CastPyArg2VectorOfVectorOfSize_t(
|
|
PyObject* obj, size_t arg_pos);
|
|
framework::proto::VarType::Type CastPyArg2ProtoType(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
phi::Vocab CastPyArg2Vocab(PyObject* obj, ssize_t arg_pos);
|
|
std::vector<std::string> CastPyArg2VectorOfString(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
std::shared_ptr<jit::Function> CastPyArg2JitFunction(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
void SetPythonStack();
|
|
std::string GetPythonStack();
|
|
|
|
PyObject* ToPyObject(int value);
|
|
PyObject* ToPyObject(uint32_t value);
|
|
PyObject* ToPyObject(bool value);
|
|
PyObject* ToPyObject(int64_t value);
|
|
PyObject* ToPyObject(size_t value);
|
|
PyObject* ToPyObject(float value);
|
|
PyObject* ToPyObject(double value);
|
|
PyObject* ToPyObject(const char* value);
|
|
PyObject* ToPyObject(const std::string& value);
|
|
PyObject* ToPyObject(const Tensor& value,
|
|
PyObject* args,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map);
|
|
PyObject* ToPyObject(PyObject* args, ssize_t arg_idx);
|
|
PyObject* ToPyObject(
|
|
const Tensor& value,
|
|
PyObject* args,
|
|
PyObject* kwargs,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map,
|
|
const std::map<ssize_t, std::vector<std::string>>& inplace_var_name_map);
|
|
PyObject* ToPyObject(PyObject* args,
|
|
PyObject* kwargs,
|
|
ssize_t arg_idx,
|
|
std::vector<std::string> arg_names);
|
|
PyObject* ToPyObject(const std::vector<bool>& value);
|
|
PyObject* ToPyObject(const std::vector<int>& value);
|
|
PyObject* ToPyObject(const std::vector<int64_t>& value);
|
|
PyObject* ToPyObject(const std::vector<size_t>& value);
|
|
PyObject* ToPyObject(const std::vector<float>& value);
|
|
PyObject* ToPyObject(const std::vector<double>& value);
|
|
PyObject* ToPyObject(const std::vector<std::vector<size_t>>& value);
|
|
PyObject* ToPyObject(const std::vector<Tensor>& value,
|
|
bool return_py_none_if_not_initialize = false);
|
|
PyObject* ToPyObject(const std::vector<std::vector<Tensor>>& value,
|
|
bool return_py_none_if_not_initialize = false);
|
|
PyObject* ToPyObject(const Place& value);
|
|
PyObject* ToPyObject(const phi::DenseTensor* value);
|
|
PyObject* ToPyObject(const phi::distributed::DistTensor* value);
|
|
PyObject* ToPyObject(const phi::distributed::TensorDistAttr* value);
|
|
PyObject* ToPyObject(const phi::distributed::ProcessMesh* value);
|
|
PyObject* ToPyObject(const phi::distributed::Placements& value);
|
|
PyObject* ToPyObject(const phi::SelectedRows* value);
|
|
PyObject* ToPyObject(const paddle::framework::proto::VarType::Type& dtype);
|
|
PyObject* ToPyObject(const paddle::framework::proto::VarType& type);
|
|
PyObject* ToPyObject(const std::vector<DataType>& dtypes);
|
|
PyObject* ToPyObject(const void* value);
|
|
PyObject* ToPyObject(const std::unordered_map<int, int>& value);
|
|
PyObject* ToPyObject(
|
|
const std::unordered_map<std::string, std::vector<std::string>>& value);
|
|
PyObject* ToPyObject(const phi::Vocab& value);
|
|
|
|
PyObject* ToPyObject(std::shared_ptr<egr::GradNodeBase> grad_node);
|
|
PyObject* ToPyObject(const pir::Value& value);
|
|
PyObject* ToPyObject(pir::Operation* op);
|
|
PyObject* ToPyObject(const std::vector<pir::Value>& value);
|
|
|
|
class PyTensorHook : public egr::TensorHook {
|
|
public:
|
|
explicit PyTensorHook(PyObject* func) : py_func_(func) {
|
|
Py_INCREF(py_func_);
|
|
}
|
|
|
|
~PyTensorHook() {
|
|
py::gil_scoped_acquire gil;
|
|
Py_DECREF(py_func_);
|
|
}
|
|
|
|
Tensor operator()(const Tensor& var) override;
|
|
|
|
private:
|
|
PyObject* py_func_;
|
|
};
|
|
|
|
class PyVoidHook : public egr::VoidHook {
|
|
public:
|
|
explicit PyVoidHook(PyObject* func) : py_func_(func) { Py_INCREF(py_func_); }
|
|
|
|
~PyVoidHook() {
|
|
py::gil_scoped_acquire gil;
|
|
Py_DECREF(py_func_);
|
|
}
|
|
|
|
void operator()() override;
|
|
|
|
private:
|
|
PyObject* py_func_;
|
|
};
|
|
|
|
class PyObjectHolder : public egr::PyObjectHolderBase {
|
|
public:
|
|
PyObjectHolder() { ptr_ = nullptr; }
|
|
explicit PyObjectHolder(PyObject* ptr);
|
|
~PyObjectHolder() override;
|
|
void* get() override;
|
|
void reset(void* ptr) override;
|
|
void inc_ref() override;
|
|
void dec_ref() override;
|
|
|
|
private:
|
|
PyObject* ptr_{nullptr};
|
|
};
|
|
|
|
class PackHook : public egr::PackHookBase {
|
|
public:
|
|
explicit PackHook(PyObject* hook);
|
|
|
|
~PackHook();
|
|
|
|
std::shared_ptr<egr::PyObjectHolderBase> operator()(
|
|
const Tensor& tensor) override;
|
|
|
|
void* operator()(void* py_tensor) override;
|
|
|
|
private:
|
|
PyObject* hook_;
|
|
};
|
|
|
|
class UnPackHook : public egr::UnPackHookBase {
|
|
public:
|
|
explicit UnPackHook(PyObject* hook);
|
|
|
|
~UnPackHook();
|
|
|
|
Tensor operator()(
|
|
std::shared_ptr<egr::PyObjectHolderBase> packed_value) override;
|
|
|
|
void* operator()(void* packed_value, void* other) override;
|
|
|
|
private:
|
|
PyObject* hook_;
|
|
};
|
|
|
|
#pragma GCC visibility push(hidden)
|
|
class NodePostHook : public egr::NodePostHookBase {
|
|
public:
|
|
explicit NodePostHook(py::object hook) : hook_(hook) {}
|
|
|
|
~NodePostHook() {}
|
|
|
|
paddle::small_vector<std::vector<Tensor>, egr::kSlotSmallVectorSize>
|
|
operator()(
|
|
const paddle::small_vector<std::vector<Tensor>,
|
|
egr::kSlotSmallVectorSize>& grad_outputs,
|
|
const paddle::small_vector<std::vector<Tensor>,
|
|
egr::kSlotSmallVectorSize>& grad_inputs)
|
|
override;
|
|
|
|
private:
|
|
py::object hook_;
|
|
};
|
|
#pragma GCC visibility pop
|
|
|
|
template <typename Tuple, size_t N>
|
|
struct TupleTensorResult {
|
|
static void Run(const Tuple& out, PyObject* result) {
|
|
TupleTensorResult<Tuple, N - 1>::Run(out, result);
|
|
PyTuple_SET_ITEM(result, N - 1, ToPyObject(std::get<N - 1>(out)));
|
|
}
|
|
|
|
static void Run(const Tuple& out,
|
|
PyObject* result,
|
|
PyObject* args,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map) {
|
|
TupleTensorResult<Tuple, N - 1>::Run(
|
|
out, result, args, inplace_var_idx_map);
|
|
if (!inplace_var_idx_map.empty() && inplace_var_idx_map.count(N - 1)) {
|
|
PyTuple_SET_ITEM(
|
|
result, N - 1, ToPyObject(args, inplace_var_idx_map.at(N - 1)));
|
|
} else {
|
|
PyTuple_SET_ITEM(result, N - 1, ToPyObject(std::get<N - 1>(out)));
|
|
}
|
|
}
|
|
|
|
static void Run(
|
|
const Tuple& out,
|
|
PyObject* result,
|
|
PyObject* args,
|
|
PyObject* kwargs,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map,
|
|
const std::map<ssize_t, std::vector<std::string>>& inplace_var_name_map) {
|
|
TupleTensorResult<Tuple, N - 1>::Run(
|
|
out, result, args, kwargs, inplace_var_idx_map, inplace_var_name_map);
|
|
if (!inplace_var_idx_map.empty() && inplace_var_idx_map.count(N - 1)) {
|
|
PyTuple_SET_ITEM(result,
|
|
N - 1,
|
|
ToPyObject(args,
|
|
kwargs,
|
|
inplace_var_idx_map.at(N - 1),
|
|
inplace_var_name_map.at(N - 1)));
|
|
} else {
|
|
PyTuple_SET_ITEM(result, N - 1, ToPyObject(std::get<N - 1>(out)));
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename Tuple>
|
|
struct TupleTensorResult<Tuple, 1> {
|
|
static void Run(const Tuple& out, PyObject* result) {
|
|
PyTuple_SET_ITEM(result, 0, ToPyObject(std::get<0>(out)));
|
|
}
|
|
|
|
static void Run(const Tuple& out,
|
|
PyObject* result,
|
|
PyObject* args,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map) {
|
|
if (!inplace_var_idx_map.empty() && inplace_var_idx_map.count(0)) {
|
|
PyTuple_SET_ITEM(result, 0, ToPyObject(args, inplace_var_idx_map.at(0)));
|
|
} else {
|
|
PyTuple_SET_ITEM(result, 0, ToPyObject(std::get<0>(out)));
|
|
}
|
|
}
|
|
|
|
static void Run(
|
|
const Tuple& out,
|
|
PyObject* result,
|
|
PyObject* args,
|
|
PyObject* kwargs,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map,
|
|
const std::map<ssize_t, std::vector<std::string>>& inplace_var_name_map) {
|
|
if (!inplace_var_idx_map.empty() && inplace_var_idx_map.count(0)) {
|
|
PyTuple_SET_ITEM(result,
|
|
0,
|
|
ToPyObject(args,
|
|
kwargs,
|
|
inplace_var_idx_map.at(0),
|
|
inplace_var_name_map.at(0)));
|
|
} else {
|
|
PyTuple_SET_ITEM(result, 0, ToPyObject(std::get<0>(out)));
|
|
}
|
|
}
|
|
};
|
|
|
|
template <typename... Args>
|
|
PyObject* ToPyObject(const std::tuple<Args...>& out) {
|
|
auto len = sizeof...(Args);
|
|
PyObject* result = PyTuple_New(len);
|
|
|
|
TupleTensorResult<decltype(out), sizeof...(Args)>::Run(out, result);
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename... Args>
|
|
PyObject* ToPyObject(const std::tuple<Args...>& out,
|
|
PyObject* args,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map) {
|
|
// For inplace op, directly return the input PyObject of the inplace tensor.
|
|
// [Parameter]
|
|
// out: Outputs tuple after executing op.
|
|
// args: Input PyObject.
|
|
// inplace_var_idx_map: Index of Tensors in inplace_map, e.g. {{value_idx,
|
|
// arg_idx}}.
|
|
// - value_idx: Index of inplace tensor in outputs tuple. Used to find the
|
|
// output inplace tensor.
|
|
// - arg_idx: Index of inplace PyObject in input args. Used to find the input
|
|
// inplace PyObject.
|
|
auto len = sizeof...(Args);
|
|
PyObject* result = PyTuple_New(len);
|
|
|
|
TupleTensorResult<decltype(out), sizeof...(Args)>::Run(
|
|
out, result, args, inplace_var_idx_map);
|
|
|
|
return result;
|
|
}
|
|
|
|
template <typename... Args>
|
|
PyObject* ToPyObject(
|
|
const std::tuple<Args...>& out,
|
|
PyObject* args,
|
|
PyObject* kwargs,
|
|
const std::map<ssize_t, ssize_t>& inplace_var_idx_map,
|
|
const std::map<ssize_t, std::vector<std::string>>& inplace_var_name_map) {
|
|
// For inplace op, directly return the input PyObject of the inplace tensor.
|
|
// [Parameter]
|
|
// out: Outputs tuple after executing op.
|
|
// args: Input PyObject.
|
|
// kwargs: Input PyObject.
|
|
// inplace_var_idx_map: Index of Tensors in inplace_map, e.g. {{value_idx,
|
|
// arg_idx}}.
|
|
// - value_idx: Index of inplace tensor in outputs tuple. Used to find the
|
|
// output inplace tensor.
|
|
// - arg_idx: Index of inplace PyObject in input args. Used to find the input
|
|
// inplace PyObject.
|
|
// inplace_var_name_map: Name of Tensors in inplace_map
|
|
auto len = sizeof...(Args);
|
|
PyObject* result = PyTuple_New(len);
|
|
|
|
TupleTensorResult<decltype(out), sizeof...(Args)>::Run(
|
|
out, result, args, kwargs, inplace_var_idx_map, inplace_var_name_map);
|
|
|
|
return result;
|
|
}
|
|
|
|
paddle::experimental::Scalar CastPyArg2Scalar(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
paddle::experimental::Scalar CastPyArg2Scalar(
|
|
PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
paddle::experimental::Scalar default_value);
|
|
paddle::experimental::Scalar CastNumpy2Scalar(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
|
|
std::vector<phi::Scalar> CastPyArg2ScalarArray(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
std::vector<phi::Scalar> CastPyArg2ScalarArray(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
std::vector<phi::Scalar>);
|
|
|
|
paddle::experimental::IntArray CastPyArg2IntArray(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
paddle::experimental::IntArray CastPyArg2IntArray(
|
|
PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
paddle::experimental::IntArray default_value);
|
|
Place CastPyArg2Place(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
Place CastPyArg2Place(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
Place default_place);
|
|
|
|
DataType CastPyArg2DataType(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
DataType CastPyArg2DataType(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
DataType default_value);
|
|
|
|
DataType CastPyArg2DataTypeDirectly(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos);
|
|
DataType CastPyArg2DataTypeDirectly(PyObject* obj,
|
|
const std::string& op_type,
|
|
ssize_t arg_pos,
|
|
DataType default_value);
|
|
|
|
phi::distributed::TensorDistAttr CastPyArg2DistAttr(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
|
|
phi::distributed::ProcessMesh CastPyArg2ProcessMesh(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
|
|
std::vector<phi::distributed::ProcessMesh> CastPyArg2VectorOfProcessMesh(
|
|
PyObject* obj, ssize_t arg_pos);
|
|
|
|
phi::distributed::Placements CastPyArg2VectorOfPlacement(PyObject* obj,
|
|
ssize_t arg_pos);
|
|
|
|
paddle::optional<Tensor> GetOptionalTensorFromArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
paddle::optional<Tensor> GetOptionalTensorFromArgsOrKWArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
PyObject* kwargs,
|
|
const std::vector<std::string>& keywords,
|
|
const int nargs,
|
|
int* remaining_kwargs,
|
|
bool dispensable = false,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
Tensor& GetTensorFromArgs(const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false);
|
|
|
|
paddle::optional<std::vector<Tensor>> GetOptionalTensorListFromArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
std::vector<Tensor> GetTensorListFromArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
std::vector<Tensor> GetTensorListFromArgsOrKWArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
PyObject* kwargs,
|
|
const std::vector<std::string>& keywords,
|
|
const int nargs,
|
|
int* remaining_kwargs,
|
|
bool dispensable,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
Tensor* GetTensorPtrFromArgs(const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false);
|
|
|
|
std::vector<Tensor*> GetTensorPtrListFromArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable = false,
|
|
const phi::distributed::ProcessMesh* mesh = nullptr);
|
|
|
|
std::vector<Tensor*> GetTensorPtrListFromPyObject(PyObject* obj);
|
|
|
|
std::vector<Tensor> GetTensorListFromPyObject(PyObject* obj,
|
|
bool allow_none = false);
|
|
Tensor& UnSafeGetTensorFromPyObject(PyObject* obj);
|
|
|
|
PyObject* GetEmptyTensorsWithVarDesc(PyObject* self, PyObject* args);
|
|
|
|
PyObject* GetEmptyTensorsWithValue(PyObject* self, PyObject* args);
|
|
|
|
// end of Slice related methods
|
|
|
|
std::vector<paddle::framework::Scope*> GetScopePtrListFromArgs(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable);
|
|
|
|
paddle::framework::AttributeMap* GetProgramAttributesMapPtrFromPyArgs(
|
|
const std::string& op_type, PyObject* args, ssize_t arg_idx);
|
|
|
|
class eager_gil_scoped_release {
|
|
public:
|
|
eager_gil_scoped_release() { tstate = PyEval_SaveThread(); }
|
|
~eager_gil_scoped_release() {
|
|
if (!tstate) return;
|
|
PyEval_RestoreThread(tstate);
|
|
}
|
|
|
|
private:
|
|
PyThreadState* tstate{nullptr};
|
|
};
|
|
|
|
class TensorListBufferAllocator {
|
|
private:
|
|
struct TensorListBuffer {
|
|
bool is_available;
|
|
std::vector<Tensor> buffer;
|
|
TensorListBuffer() = default;
|
|
explicit TensorListBuffer(ssize_t len) : is_available(true), buffer(len) {}
|
|
};
|
|
|
|
using MapType =
|
|
std::unordered_multimap<ssize_t, std::unique_ptr<TensorListBuffer>>;
|
|
using MapIterType = MapType::iterator;
|
|
|
|
ssize_t key_;
|
|
TensorListBuffer* buffer_ptr_ = nullptr;
|
|
static MapType s_tensor_vector_map_;
|
|
|
|
public:
|
|
explicit TensorListBufferAllocator(ssize_t len);
|
|
TensorListBufferAllocator(const TensorListBufferAllocator&) = delete;
|
|
TensorListBufferAllocator& operator=(const TensorListBufferAllocator&) =
|
|
delete;
|
|
~TensorListBufferAllocator();
|
|
std::vector<Tensor>& GetAllocatedBuffer() const {
|
|
return buffer_ptr_->buffer;
|
|
}
|
|
};
|
|
|
|
std::pair<PyObject*, ssize_t> GetPyArgumentInfo(const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
bool dispensable);
|
|
|
|
std::vector<Tensor>& GetTensorListFromArgsWithBuffer(
|
|
const std::string& op_type,
|
|
const std::string& arg_name,
|
|
ssize_t arg_idx,
|
|
const phi::distributed::ProcessMesh* mesh,
|
|
PyObject* list,
|
|
ssize_t list_len,
|
|
const TensorListBufferAllocator& allocator);
|
|
|
|
/* ------------------ for SetStaticOpArgPreCastHook ----------------------- */
|
|
|
|
inline static PyObject* static_op_arg_pre_cast_hook_get();
|
|
|
|
inline static void static_op_arg_pre_cast_hook_set(PyObject* obj);
|
|
|
|
static PyObject* set_static_op_arg_pre_cast_hook(PyObject* new_callback,
|
|
PyThreadState* tstate);
|
|
|
|
PyObject* SetStaticOpArgPreCastHook(PyObject* callback);
|
|
|
|
PyMODINIT_FUNC PyInit__static_op_arg_pre_cast_hook();
|
|
|
|
/* ------------------ for auto parallel ----------------------- */
|
|
void BindEagerUtils(PyObject* module);
|
|
|
|
std::tuple<std::vector<int64_t>,
|
|
paddle::flat_hash_map<int64_t, phi::ReduceType>>
|
|
CvtPlacements(phi::distributed::Placements placements, int ndim);
|
|
|
|
void EagerSetDeviceId();
|
|
|
|
paddle::optional<Tensor*> GetInputOutTensorFromKwargs(PyObject* kwargs);
|
|
|
|
paddle::optional<std::tuple<Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_2(PyObject* kwargs);
|
|
paddle::optional<std::tuple<Tensor*, Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_3(PyObject* kwargs);
|
|
paddle::optional<std::tuple<Tensor*, Tensor*, Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_4(PyObject* kwargs);
|
|
paddle::optional<std::tuple<Tensor*, Tensor*, Tensor*, Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_5(PyObject* kwargs);
|
|
paddle::optional<
|
|
std::tuple<Tensor*, Tensor*, Tensor*, Tensor*, Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_6(PyObject* kwargs);
|
|
paddle::optional<
|
|
std::tuple<Tensor*, Tensor*, Tensor*, Tensor*, Tensor*, Tensor*, Tensor*>>
|
|
GetPredefinedOutTupleTensorFromKwargs_7(PyObject* kwargs);
|
|
|
|
void Check_PIR_not_support_out(PyObject* kwargs);
|
|
|
|
std::unordered_map<std::string, std::string> ParseStringDict(PyObject* py_dict);
|
|
|
|
std::unordered_map<std::string, void*> ParsePythonOpAttrs(PyObject* py_dict);
|
|
/*----------------------for arg parse-----------------------------*/
|
|
Tensor& GetTensorFromArgsOrKWArgs(const std::string& op_type,
|
|
const std::string& arg_name,
|
|
PyObject* args,
|
|
ssize_t arg_idx,
|
|
PyObject* kwargs,
|
|
const std::vector<std::string>& keywords,
|
|
const int nargs,
|
|
int* remaining_kwargs,
|
|
bool dispensable = false);
|
|
} // namespace pybind
|
|
} // namespace paddle
|