Skip to content

Commit 5f173c7

Browse files
[API Compatibility] Support TensorList parameter API sinking C++ (#76138)
* Add support for tensor list sink c++ and add the Get TensorListFromArgsOrKWArgs function * fix unittest
1 parent 12737a6 commit 5f173c7

File tree

9 files changed

+276
-274
lines changed

9 files changed

+276
-274
lines changed

paddle/fluid/eager/auto_code_generator/generator/python_c_gen.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ def FindParsingFunctionFromAttributeType(atype):
9292
' auto& {} = {}("{}", "{}", args, {}, {});\n'
9393
)
9494
PARSE_PYTHON_C_TENSORS_FROM_ARGS_OR_KWARGS_TEMPLATE = ' auto& {} = GetTensorFromArgsOrKWArgs("{}", "{}", args, {}, kwargs,{},nargs,&remaining_kwargs,{});\n'
95+
PARSE_PYTHON_C_TENSORS_LIST_FROM_ARGS_OR_KWARGS_TEMPLATE = ' auto {} = GetTensorListFromArgsOrKWArgs("{}", "{}", args, {}, kwargs,{},nargs,&remaining_kwargs,{});\n'
9596
PARSE_PYTHON_C_OPTIONAL_TENSORS_FROM_ARGS_OR_KWARGS_TEMPLATE = ' auto {} = GetOptionalTensorFromArgsOrKWArgs("{}", "{}", args, {}, kwargs,{},nargs,&remaining_kwargs,{});\n'
9697
CONVERT_TO_DISTTENSOR_AND_PARSE_PYTHON_C_TENSORS_TEMPLATE = (
9798
' {} = {}("{}", "{}", args, {}, {}, mesh);\n'
@@ -451,16 +452,27 @@ def _get_keywords(name, alias_map):
451452
)
452453
)
453454
else:
454-
get_eager_tensor_str += (
455-
PARSE_PYTHON_C_TENSORS_TEMPLATE.format(
455+
if not need_parse_python_api_args:
456+
get_eager_tensor_str += (
457+
PARSE_PYTHON_C_TENSORS_TEMPLATE.format(
458+
name,
459+
"GetTensorListFromArgs",
460+
forward_api_name,
461+
name,
462+
pos,
463+
"false",
464+
)
465+
)
466+
else:
467+
keywords = _get_keywords(name, args_alias_map)
468+
get_eager_tensor_str += PARSE_PYTHON_C_TENSORS_LIST_FROM_ARGS_OR_KWARGS_TEMPLATE.format(
456469
name,
457-
"GetTensorListFromArgs",
458470
forward_api_name,
459471
name,
460472
pos,
473+
keywords,
461474
"false",
462475
)
463-
)
464476
else:
465477
if is_optional:
466478
if need_parse_python_api_args:

paddle/fluid/pybind/eager_utils.cc

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1521,41 +1521,13 @@ static paddle::Tensor& GetTensorFromPyObject(const std::string& op_type,
15211521
}
15221522
}
15231523

1524-
// For Intermediate State Dygraph,
1525-
// we use an uninitialized Tensor to represent dispensable Tensor
1526-
paddle::Tensor& GetTensorFromArgs(const std::string& op_type,
1527-
const std::string& arg_name,
1528-
PyObject* args,
1529-
ssize_t arg_idx,
1530-
bool dispensable) {
1531-
PyObject* obj = PyTuple_GET_ITEM(args, arg_idx);
1532-
return GetTensorFromPyObject(op_type, arg_name, obj, arg_idx, dispensable);
1533-
}
1534-
1535-
paddle::Tensor& GetTensorFromArgsOrKWArgs(
1536-
const std::string& op_type,
1537-
const std::string& arg_name,
1538-
PyObject* args,
1539-
ssize_t arg_idx,
1540-
PyObject* kwargs,
1541-
const std::vector<std::string>& keywords,
1542-
const int nargs,
1543-
int* remaining_kwargs,
1544-
bool dispensable) {
1545-
PyObject* obj = GetItemFromArgsOrKWArgs(
1546-
args, arg_idx, kwargs, keywords, nargs, remaining_kwargs);
1547-
return GetTensorFromPyObject(op_type, arg_name, obj, arg_idx, dispensable);
1548-
}
1549-
1550-
std::vector<paddle::Tensor> GetTensorListFromArgs(
1524+
std::vector<paddle::Tensor> GetTensorListFromPyObject_(
15511525
const std::string& op_type,
15521526
const std::string& arg_name,
1553-
PyObject* args,
1527+
PyObject* list,
15541528
ssize_t arg_idx,
15551529
bool dispensable,
15561530
const phi::distributed::ProcessMesh* mesh) {
1557-
PyObject* list = PyTuple_GET_ITEM(args, arg_idx);
1558-
15591531
if (list == nullptr) {
15601532
if (!dispensable) {
15611533
PADDLE_THROW(common::errors::InvalidArgument(
@@ -1671,6 +1643,61 @@ std::vector<paddle::Tensor> GetTensorListFromArgs(
16711643
return result;
16721644
}
16731645

1646+
// For Intermediate State Dygraph,
1647+
// we use an uninitialized Tensor to represent dispensable Tensor
1648+
paddle::Tensor& GetTensorFromArgs(const std::string& op_type,
1649+
const std::string& arg_name,
1650+
PyObject* args,
1651+
ssize_t arg_idx,
1652+
bool dispensable) {
1653+
PyObject* obj = PyTuple_GET_ITEM(args, arg_idx);
1654+
return GetTensorFromPyObject(op_type, arg_name, obj, arg_idx, dispensable);
1655+
}
1656+
1657+
paddle::Tensor& GetTensorFromArgsOrKWArgs(
1658+
const std::string& op_type,
1659+
const std::string& arg_name,
1660+
PyObject* args,
1661+
ssize_t arg_idx,
1662+
PyObject* kwargs,
1663+
const std::vector<std::string>& keywords,
1664+
const int nargs,
1665+
int* remaining_kwargs,
1666+
bool dispensable) {
1667+
PyObject* obj = GetItemFromArgsOrKWArgs(
1668+
args, arg_idx, kwargs, keywords, nargs, remaining_kwargs);
1669+
return GetTensorFromPyObject(op_type, arg_name, obj, arg_idx, dispensable);
1670+
}
1671+
1672+
std::vector<paddle::Tensor> GetTensorListFromArgs(
1673+
const std::string& op_type,
1674+
const std::string& arg_name,
1675+
PyObject* args,
1676+
ssize_t arg_idx,
1677+
bool dispensable,
1678+
const phi::distributed::ProcessMesh* mesh) {
1679+
PyObject* list = PyTuple_GET_ITEM(args, arg_idx);
1680+
return GetTensorListFromPyObject_(
1681+
op_type, arg_name, list, arg_idx, dispensable, mesh);
1682+
}
1683+
1684+
std::vector<paddle::Tensor> GetTensorListFromArgsOrKWArgs(
1685+
const std::string& op_type,
1686+
const std::string& arg_name,
1687+
PyObject* args,
1688+
ssize_t arg_idx,
1689+
PyObject* kwargs,
1690+
const std::vector<std::string>& keywords,
1691+
const int nargs,
1692+
int* remaining_kwargs,
1693+
bool dispensable,
1694+
const phi::distributed::ProcessMesh* mesh) {
1695+
PyObject* list = GetItemFromArgsOrKWArgs(
1696+
args, arg_idx, kwargs, keywords, nargs, remaining_kwargs);
1697+
return GetTensorListFromPyObject_(
1698+
op_type, arg_name, list, arg_idx, dispensable, mesh);
1699+
}
1700+
16741701
paddle::optional<std::vector<paddle::Tensor>> GetOptionalTensorListFromArgs(
16751702
const std::string& op_type,
16761703
const std::string& arg_name,

paddle/fluid/pybind/eager_utils.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,18 @@ std::vector<paddle::Tensor> GetTensorListFromArgs(
444444
bool dispensable = false,
445445
const phi::distributed::ProcessMesh* mesh = nullptr);
446446

447+
std::vector<paddle::Tensor> GetTensorListFromArgsOrKWArgs(
448+
const std::string& op_type,
449+
const std::string& arg_name,
450+
PyObject* args,
451+
ssize_t arg_idx,
452+
PyObject* kwargs,
453+
const std::vector<std::string>& keywords,
454+
const int nargs,
455+
int* remaining_kwargs,
456+
bool dispensable,
457+
const phi::distributed::ProcessMesh* mesh = nullptr);
458+
447459
paddle::Tensor* GetTensorPtrFromArgs(const std::string& op_type,
448460
const std::string& arg_name,
449461
PyObject* args,

paddle/phi/ops/yaml/python_api_info.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
x : [input]
185185
args_mapper :
186186
func : GeluMapper
187+
187188
- op : sum
188189
name : [paddle.sum, paddle.Tensor.sum]
189190
args_alias:
@@ -192,3 +193,15 @@
192193
func : SumPreProcess(x, axis)
193194
args_mapper :
194195
func : ArgSumMapper
196+
197+
- op : index_put
198+
name : [paddle.index_put,paddle.Tensor.index_put]
199+
args_alias :
200+
value : [values]
201+
use_default_mapping : True
202+
203+
- op : index_put_
204+
name : [paddle.index_put_,paddle.Tensor.index_put_]
205+
args_alias :
206+
value : [values]
207+
use_default_mapping : True

python/paddle/_paddle_docs.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,75 @@ def sum(
11161116
""",
11171117
)
11181118

1119+
add_doc_and_signature(
1120+
"index_put",
1121+
"""
1122+
Puts values from the tensor values into the tensor x using the indices specified in indices (which is a tuple of Tensors).
1123+
The expression paddle.index_put_(x, indices, values) is equivalent to tensor[indices] = values. Returns x.
1124+
If accumulate is True, the elements in values are added to x. If accumulate is False, the behavior is undefined if indices contain duplicate elements.
1125+
1126+
Args:
1127+
x (Tensor) : The Source Tensor. Supported data types are int32, int64, float16, float32, float64, bool.
1128+
indices (list[Tensor]|tuple[Tensor]): The tuple of Tensor containing the indices to index.
1129+
The data type of ``tensor in indices`` must be int32, int64 or bool.
1130+
value (Tensor): The tensor used to be assigned to x.
1131+
accumulate (bool, optional): Whether the elements in values are added to x. Default: False.
1132+
name(str|None, optional): For details, please refer to :ref:`api_guide_Name`. Generally, no setting is required. Default: None.
1133+
1134+
Returns:
1135+
Tensor, same dimension and dtype with x.
1136+
1137+
Examples:
1138+
.. code-block:: python
1139+
1140+
>>> import paddle
1141+
1142+
>>> x = paddle.zeros([3, 3])
1143+
>>> value = paddle.ones([3])
1144+
>>> ix1 = paddle.to_tensor([0,1,2])
1145+
>>> ix2 = paddle.to_tensor([1,2,1])
1146+
>>> indices=(ix1,ix2)
1147+
1148+
>>> out = paddle.index_put(x,indices,value)
1149+
>>> print(x)
1150+
Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
1151+
[[0., 0., 0.],
1152+
[0., 0., 0.],
1153+
[0., 0., 0.]])
1154+
>>> print(out)
1155+
Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
1156+
[[0., 1., 0.],
1157+
[0., 0., 1.],
1158+
[0., 1., 0.]])
1159+
""",
1160+
"""
1161+
def index_put(
1162+
x: Tensor,
1163+
indices: Sequence[Tensor],
1164+
value: Tensor,
1165+
accumulate: bool = False,
1166+
name: str | None = None,
1167+
) -> Tensor
1168+
""",
1169+
)
1170+
1171+
add_doc_and_signature(
1172+
"index_put_",
1173+
"""
1174+
Inplace version of ``index_put`` API, the output Tensor will be inplaced with input ``x``.
1175+
Please refer to :ref:`api_paddle_index_put`.
1176+
""",
1177+
"""
1178+
def index_put_(
1179+
x: Tensor,
1180+
indices: Sequence[Tensor],
1181+
value: Tensor,
1182+
accumulate: bool = False,
1183+
name: str | None = None,
1184+
) -> Tensor
1185+
""",
1186+
)
1187+
11191188
# liuyi
11201189
add_doc_and_signature(
11211190
"any",

python/paddle/tensor/manipulation.py

Lines changed: 1 addition & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
import paddle
2626
from paddle import _C_ops
27-
from paddle._C_ops import roll # noqa: F401
27+
from paddle._C_ops import index_put, index_put_, roll # noqa: F401
2828
from paddle.tensor import fill_constant
2929
from paddle.utils.decorator_utils import (
3030
ParamAliasDecorator,
@@ -7682,99 +7682,6 @@ def index_add_(
76827682
return _C_ops.index_add_(x, index, value, axis)
76837683

76847684

7685-
@inplace_apis_in_dygraph_only
7686-
def index_put_(
7687-
x: Tensor,
7688-
indices: Sequence[Tensor],
7689-
value: Tensor,
7690-
accumulate: bool = False,
7691-
name: str | None = None,
7692-
) -> Tensor:
7693-
"""
7694-
Inplace version of ``index_put`` API, the output Tensor will be inplaced with input ``x``.
7695-
Please refer to :ref:`api_paddle_index_put`.
7696-
"""
7697-
return _C_ops.index_put_(x, indices, value, accumulate)
7698-
7699-
7700-
def index_put(
7701-
x: Tensor,
7702-
indices: Sequence[Tensor],
7703-
value: Tensor,
7704-
accumulate: bool = False,
7705-
name: str | None = None,
7706-
) -> Tensor:
7707-
"""
7708-
Puts values from the tensor values into the tensor x using the indices specified in indices (which is a tuple of Tensors).
7709-
The expression paddle.index_put_(x, indices, values) is equivalent to tensor[indices] = values. Returns x.
7710-
If accumulate is True, the elements in values are added to x. If accumulate is False, the behavior is undefined if indices contain duplicate elements.
7711-
7712-
Args:
7713-
x (Tensor) : The Source Tensor. Supported data types are int32, int64, float16, float32, float64, bool.
7714-
indices (list[Tensor]|tuple[Tensor]): The tuple of Tensor containing the indices to index.
7715-
The data type of ``tensor in indices`` must be int32, int64 or bool.
7716-
value (Tensor): The tensor used to be assigned to x.
7717-
accumulate (bool, optional): Whether the elements in values are added to x. Default: False.
7718-
name(str|None, optional): For details, please refer to :ref:`api_guide_Name`. Generally, no setting is required. Default: None.
7719-
7720-
Returns:
7721-
Tensor, same dimension and dtype with x.
7722-
7723-
Examples:
7724-
.. code-block:: python
7725-
7726-
>>> import paddle
7727-
7728-
>>> x = paddle.zeros([3, 3])
7729-
>>> value = paddle.ones([3])
7730-
>>> ix1 = paddle.to_tensor([0,1,2])
7731-
>>> ix2 = paddle.to_tensor([1,2,1])
7732-
>>> indices=(ix1,ix2)
7733-
7734-
>>> out = paddle.index_put(x,indices,value)
7735-
>>> print(x)
7736-
Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
7737-
[[0., 0., 0.],
7738-
[0., 0., 0.],
7739-
[0., 0., 0.]])
7740-
>>> print(out)
7741-
Tensor(shape=[3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
7742-
[[0., 1., 0.],
7743-
[0., 0., 1.],
7744-
[0., 1., 0.]])
7745-
"""
7746-
if in_dynamic_or_pir_mode():
7747-
return _C_ops.index_put(x, indices, value, accumulate)
7748-
7749-
helper = LayerHelper("index_put", **locals())
7750-
check_variable_and_dtype(
7751-
x,
7752-
'x',
7753-
['float16', 'float32', 'float64', 'int32', 'int64', 'bool'],
7754-
'paddle.tensor.manipulation.index_put',
7755-
)
7756-
check_variable_and_dtype(
7757-
value,
7758-
'value',
7759-
['float16', 'float32', 'float64', 'int32', 'int64', 'bool'],
7760-
'paddle.tensor.manipulation.index_put',
7761-
)
7762-
7763-
out = helper.create_variable_for_type_inference(x.dtype)
7764-
7765-
helper.append_op(
7766-
type='index_put',
7767-
inputs={
7768-
'x': x,
7769-
'indices': indices,
7770-
'value': value,
7771-
},
7772-
outputs={'out': out},
7773-
attrs={'accumulate': accumulate},
7774-
)
7775-
return out
7776-
7777-
77787685
def unflatten(
77797686
x: Tensor, axis: int, shape: ShapeLike, name: str | None = None
77807687
) -> Tensor:

0 commit comments

Comments
 (0)