chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# Copyright (c) 2023 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.
|
||||
|
||||
|
||||
import paddle
|
||||
from paddle import _C_ops
|
||||
|
||||
__all__ = []
|
||||
|
||||
|
||||
FLOAT_TYPE_DICT = {
|
||||
paddle.float16: "float16",
|
||||
paddle.float32: "float32",
|
||||
paddle.float64: "float64",
|
||||
paddle.bfloat16: "bfloat16",
|
||||
paddle.bool: "bool",
|
||||
}
|
||||
|
||||
PADDLE_TO_NUMBER = {
|
||||
paddle.float16: 0,
|
||||
paddle.float32: 1,
|
||||
paddle.float64: 2,
|
||||
paddle.int32: 3,
|
||||
paddle.int64: 4,
|
||||
paddle.bfloat16: 5,
|
||||
paddle.bool: 6,
|
||||
}
|
||||
|
||||
NUMBER_TO_DTYPE = {
|
||||
0: "float16",
|
||||
1: "float32",
|
||||
2: "float64",
|
||||
3: "int32",
|
||||
4: "int64",
|
||||
5: "bfloat16",
|
||||
6: "bool",
|
||||
}
|
||||
|
||||
|
||||
def is_float_tensor(tensor):
|
||||
"""Is a float tensor"""
|
||||
return tensor.dtype in FLOAT_TYPE_DICT.keys()
|
||||
|
||||
|
||||
def get_tensor_dtype(dtype):
|
||||
assert dtype in FLOAT_TYPE_DICT.keys()
|
||||
return FLOAT_TYPE_DICT[dtype]
|
||||
|
||||
|
||||
def paddle_2_number(dtype):
|
||||
assert dtype in PADDLE_TO_NUMBER.keys()
|
||||
return PADDLE_TO_NUMBER[dtype]
|
||||
|
||||
|
||||
def number_2_dtype(number):
|
||||
assert number in NUMBER_TO_DTYPE.keys()
|
||||
return NUMBER_TO_DTYPE[number]
|
||||
|
||||
|
||||
def get_tensor_bytes(tensor):
|
||||
"""Get the bytes a tensor occupied."""
|
||||
elem_size = None
|
||||
if tensor.dtype == paddle.float32:
|
||||
elem_size = 4
|
||||
elif tensor.dtype == paddle.float64:
|
||||
elem_size = 8
|
||||
elif tensor.dtype == paddle.int64:
|
||||
elem_size = 8
|
||||
elif tensor.dtype == paddle.int32:
|
||||
elem_size = 4
|
||||
elif tensor.dtype == paddle.float16:
|
||||
elem_size = 2
|
||||
elif tensor.dtype == paddle.int8:
|
||||
elem_size = 1
|
||||
else:
|
||||
raise ValueError(f"unknown data type: {tensor.dtype}")
|
||||
return tensor.numel() * elem_size
|
||||
|
||||
|
||||
def _all_gather(tensor, group=None, use_calc_stream=True):
|
||||
"""
|
||||
The main difference with paddle.distributed.all_gather:
|
||||
no need to pass in tensor_list, the returned tensor is spliced
|
||||
"""
|
||||
if group is not None and not group.is_member():
|
||||
return
|
||||
ring_id = 0 if group is None else group.id
|
||||
nranks = (
|
||||
paddle.distributed.collective._get_global_group().nranks
|
||||
if group is None
|
||||
else group.nranks
|
||||
)
|
||||
return _C_ops.all_gather(
|
||||
tensor,
|
||||
ring_id,
|
||||
nranks,
|
||||
)
|
||||
|
||||
|
||||
def tuple_to_dict_helper(input_tensor):
|
||||
# recv tuple -> fwd input dict
|
||||
use_dict = False
|
||||
if isinstance(input_tensor, tuple):
|
||||
use_dict = hasattr(input_tensor[0], "key")
|
||||
else: # single tensor
|
||||
use_dict = hasattr(input_tensor, "key")
|
||||
if use_dict:
|
||||
input_tensor = convert_tensor_tuple_to_dict(input_tensor)
|
||||
return input_tensor, use_dict
|
||||
|
||||
|
||||
def dict_to_tuple_helper(output_tensor):
|
||||
if isinstance(output_tensor, dict):
|
||||
output_tensor_tuple = convert_tensor_dict_to_tuple(
|
||||
output_tensor_dict=output_tensor
|
||||
)
|
||||
else: # single tensor or tensor tuple
|
||||
output_tensor_tuple = output_tensor
|
||||
return output_tensor_tuple
|
||||
|
||||
|
||||
def convert_tensor_dict_to_tuple(output_tensor_dict):
|
||||
output_tensor = []
|
||||
for key, tensor in output_tensor_dict.items():
|
||||
if isinstance(tensor, (list, tuple)):
|
||||
for idx, t in enumerate(tensor):
|
||||
t.key = key + " " + str(idx)
|
||||
output_tensor.append(t)
|
||||
else: # single tensor
|
||||
tensor.key = key
|
||||
output_tensor.append(tensor)
|
||||
|
||||
return tuple(output_tensor)
|
||||
|
||||
|
||||
def convert_tensor_tuple_to_dict(input_tensor_tuple):
|
||||
input_tensor_dict = {}
|
||||
for tensor in input_tensor_tuple:
|
||||
key = tensor.key
|
||||
if " " in key:
|
||||
real_key, _ = key.split(" ")
|
||||
if real_key in input_tensor_dict.keys():
|
||||
input_tensor_dict[real_key].append(tensor)
|
||||
else:
|
||||
input_tensor_dict[real_key] = [tensor]
|
||||
else:
|
||||
input_tensor_dict[key] = tensor
|
||||
delattr(tensor, "key")
|
||||
return input_tensor_dict
|
||||
Reference in New Issue
Block a user