未验证 提交 fb66355e 编写于 作者: W wangchaochaohu 提交者: GitHub

[cherry-pick]add support for place string representation #30264

cherry-pick #28769, add support for place string representation 
上级 e59524f8
...@@ -47,11 +47,12 @@ class CreateDoubleBufferReaderOp : public framework::OperatorBase { ...@@ -47,11 +47,12 @@ class CreateDoubleBufferReaderOp : public framework::OperatorBase {
platform::Place place; platform::Place place;
if (place_str == "AUTO") { if (place_str == "AUTO") {
place = dev_place; place = dev_place;
} else if (place_str == "CPU") { } else if (place_str == "CPUPLACE") {
place = platform::CPUPlace(); place = platform::CPUPlace();
} else { } else {
place_str = place_str.substr(0, place_str.length() - 1);
std::istringstream sin(place_str); std::istringstream sin(place_str);
sin.seekg(std::string("CUDA:").size(), std::ios::beg); sin.seekg(std::string("CUDAPLACE(").size(), std::ios::beg);
size_t num; size_t num;
sin >> num; sin >> num;
place = platform::CUDAPlace(static_cast<int>(num)); place = platform::CUDAPlace(static_cast<int>(num));
...@@ -78,9 +79,9 @@ class CreateDoubleBufferReaderOpMaker : public DecoratedReaderMakerBase { ...@@ -78,9 +79,9 @@ class CreateDoubleBufferReaderOpMaker : public DecoratedReaderMakerBase {
std::unordered_set<std::string> enum_range; std::unordered_set<std::string> enum_range;
constexpr size_t kMaxCUDADevs = 128; constexpr size_t kMaxCUDADevs = 128;
for (size_t i = 0; i < kMaxCUDADevs; ++i) { for (size_t i = 0; i < kMaxCUDADevs; ++i) {
enum_range.insert(string::Sprintf("CUDA:%d", i)); enum_range.insert(string::Sprintf("CUDAPLACE(%d)", i));
} }
enum_range.insert("CPU"); enum_range.insert("CPUPLACE");
enum_range.insert("AUTO"); enum_range.insert("AUTO");
AddAttr<std::string>("place", "The double buffer place") AddAttr<std::string>("place", "The double buffer place")
.SetDefault("AUTO") .SetDefault("AUTO")
......
...@@ -20,6 +20,8 @@ from .. import compat as cpt ...@@ -20,6 +20,8 @@ from .. import compat as cpt
from . import framework from . import framework
from .framework import cuda_places, cpu_places, xpu_places from .framework import cuda_places, cpu_places, xpu_places
from .framework import _get_paddle_place, _get_paddle_place_list
from .framework import cuda_places, cpu_places, xpu_places
from . import core from . import core
__all__ = ['CompiledProgram', 'ExecutionStrategy', 'BuildStrategy'] __all__ = ['CompiledProgram', 'ExecutionStrategy', 'BuildStrategy']
...@@ -202,7 +204,7 @@ class CompiledProgram(object): ...@@ -202,7 +204,7 @@ class CompiledProgram(object):
Tensors to other devices when it is first executed, the CompiledProgram Tensors to other devices when it is first executed, the CompiledProgram
specified by share_vars_from must be run before the current CompiledProgram. specified by share_vars_from must be run before the current CompiledProgram.
The default is None. The default is None.
places(list(CUDAPlace)|list(CPUPlace)|None): This parameter specifies the device places(list(CUDAPlace)|list(CPUPlace)|list(str)|None): This parameter specifies the device
on which the model is running. If you want to run on GPU0 and GPU1, places are on which the model is running. If you want to run on GPU0 and GPU1, places are
[fluid.CUDAPlace(0), fluid.CUDAPlace(1)]; if you want to run with 2 CPUs, places are [fluid.CUDAPlace(0), fluid.CUDAPlace(1)]; if you want to run with 2 CPUs, places are
[fluid.CPUPlace()] * 2. If the parameter is not set, i.e. the parameter is None, [fluid.CPUPlace()] * 2. If the parameter is not set, i.e. the parameter is None,
...@@ -213,7 +215,8 @@ class CompiledProgram(object): ...@@ -213,7 +215,8 @@ class CompiledProgram(object):
CPU number is obtained from the environment variable CPU_NUM. For example, CPU number is obtained from the environment variable CPU_NUM. For example,
export CPU_NUM=4, if the environment variable is not set, the executor will export CPU_NUM=4, if the environment variable is not set, the executor will
add the variable to the environment variable and set its value to 1. add the variable to the environment variable and set its value to 1.
The default is None. The default is None. If ``places`` is the list of string, the string in the list
can be ``cpu``, ``gpu:x``, where ``x`` is the index of the GPUs.
Returns: Returns:
CompiledProgram CompiledProgram
...@@ -282,7 +285,10 @@ class CompiledProgram(object): ...@@ -282,7 +285,10 @@ class CompiledProgram(object):
self._exec_strategy = exec_strategy self._exec_strategy = exec_strategy
self._loss_name = loss_name self._loss_name = loss_name
self._share_vars_from = share_vars_from self._share_vars_from = share_vars_from
self._places = places if isinstance(places, (list, tuple)):
self._places = _get_paddle_place_list(places)
else:
self._places = _get_paddle_place(places)
if _has_backward_op(self._graph): if _has_backward_op(self._graph):
assert self._loss_name is not None, "The loss name of CompiledProgram is None. The loss name should be set if CompiledProgram contains backward part." assert self._loss_name is not None, "The loss name of CompiledProgram is None. The loss name should be set if CompiledProgram contains backward part."
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
import numpy as np import numpy as np
from .... import core from .... import core
from ....framework import IrGraph from ....framework import IrGraph
from ....framework import _get_paddle_place
__all__ = ['Quant2Int8MkldnnPass'] __all__ = ['Quant2Int8MkldnnPass']
...@@ -43,7 +44,7 @@ class Quant2Int8MkldnnPass(object): ...@@ -43,7 +44,7 @@ class Quant2Int8MkldnnPass(object):
_core=None, _core=None,
_debug=False): _debug=False):
self._scope = _scope self._scope = _scope
self._place = _place self._place = _get_paddle_place(_place)
self._core = _core self._core = _core
self._debug = _debug self._debug = _debug
self._fake_quantize_types = [ self._fake_quantize_types = [
......
...@@ -16,6 +16,7 @@ import numpy as np ...@@ -16,6 +16,7 @@ import numpy as np
from .... import core from .... import core
from ....framework import IrGraph from ....framework import IrGraph
from ....framework import IrNode from ....framework import IrNode
from ....framework import _get_paddle_place
__all__ = ['QuantInt8MkldnnPass'] __all__ = ['QuantInt8MkldnnPass']
...@@ -40,7 +41,8 @@ class QuantInt8MkldnnPass(object): ...@@ -40,7 +41,8 @@ class QuantInt8MkldnnPass(object):
r""" r"""
Args: Args:
scope(fluid.Scope): scope is used to initialize the new parameters. scope(fluid.Scope): scope is used to initialize the new parameters.
place(fluid.CPUPlace): place is used to initialize the new parameters. place(fluid.CPUPlace|str): place is used to initialize the new parameters.
When it is string, it can be only 'cpu'.
Examples: Examples:
...@@ -60,7 +62,7 @@ class QuantInt8MkldnnPass(object): ...@@ -60,7 +62,7 @@ class QuantInt8MkldnnPass(object):
""" """
self._scope = _scope self._scope = _scope
self._place = _place self._place = _get_paddle_place(_place)
self._quantize_type = [ self._quantize_type = [
'fake_quantize_moving_average_abs_max', 'fake_quantize_moving_average_abs_max',
......
...@@ -25,6 +25,7 @@ from ....framework import Program, program_guard, default_startup_program ...@@ -25,6 +25,7 @@ from ....framework import Program, program_guard, default_startup_program
from ....data import data from ....data import data
from ....layers import mean from ....layers import mean
from ....executor import scope_guard from ....executor import scope_guard
from ....framework import _get_paddle_place
__all__ = [ __all__ = [
'QuantizationTransformPass', 'QuantizationFreezePass', 'ConvertToInt8Pass', 'QuantizationTransformPass', 'QuantizationFreezePass', 'ConvertToInt8Pass',
...@@ -246,8 +247,9 @@ class QuantizationTransformPass(object): ...@@ -246,8 +247,9 @@ class QuantizationTransformPass(object):
scope(fluid.Scope): When activation use 'range_abs_max' as the quantize scope(fluid.Scope): When activation use 'range_abs_max' as the quantize
type, this pass will create some new parameters. The scope is used to type, this pass will create some new parameters. The scope is used to
initialize these new parameters. initialize these new parameters.
place(fluid.CPUPlace|fluid.CUDAPlace): place is used to initialize new place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to initialize new
parameters described above. parameters described above. If it's string, It can be ``cpu``, and ``gpu:x``,
where ``x`` is the index of the GPUs.
weight_bits(int): quantization bit number for weights, weight_bits(int): quantization bit number for weights,
the bias is not quantized. the bias is not quantized.
activation_bits(int): quantization bit number for activation. activation_bits(int): quantization bit number for activation.
...@@ -315,7 +317,7 @@ class QuantizationTransformPass(object): ...@@ -315,7 +317,7 @@ class QuantizationTransformPass(object):
transform_pass.apply(graph) transform_pass.apply(graph)
""" """
self._scope = scope self._scope = scope
self._place = place self._place = _get_paddle_place(place)
self._weight_bits = weight_bits self._weight_bits = weight_bits
self._activation_bits = activation_bits self._activation_bits = activation_bits
self._skip_pattern = skip_pattern self._skip_pattern = skip_pattern
...@@ -1057,7 +1059,8 @@ class QuantizationFreezePass(object): ...@@ -1057,7 +1059,8 @@ class QuantizationFreezePass(object):
Args: Args:
scope(fluid.Scope): scope is used to get the weight tensor values. scope(fluid.Scope): scope is used to get the weight tensor values.
place(fluid.CPUPlace|fluid.CUDAPlace): place is used to restore the weight tensors. place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to restore the weight tensors.
If it's string, It can be ``cpu``, and ``gpu:x``, where ``x`` is the index of the GPUs.
weight_bits(int): quantization bit number for weights. weight_bits(int): quantization bit number for weights.
activation_bits(int): quantization bit number for activation. activation_bits(int): quantization bit number for activation.
weight_quantize_type(str): quantization type for weights, support 'abs_max' and weight_quantize_type(str): quantization type for weights, support 'abs_max' and
...@@ -1071,7 +1074,7 @@ class QuantizationFreezePass(object): ...@@ -1071,7 +1074,7 @@ class QuantizationFreezePass(object):
assert place is not None, \ assert place is not None, \
'The place cannot be set None.' 'The place cannot be set None.'
self._scope = scope self._scope = scope
self._place = place self._place = _get_paddle_place(place)
self._weight_bits = weight_bits self._weight_bits = weight_bits
self._activation_bits = activation_bits self._activation_bits = activation_bits
self._weight_quantize_type = weight_quantize_type self._weight_quantize_type = weight_quantize_type
...@@ -1365,8 +1368,9 @@ class ConvertToInt8Pass(object): ...@@ -1365,8 +1368,9 @@ class ConvertToInt8Pass(object):
Args: Args:
scope(fluid.Scope): scope is used to get the weight tensor values. scope(fluid.Scope): scope is used to get the weight tensor values.
place(fluid.CPUPlace|fluid.CUDAPlace): place is used to restore the place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to restore the
8bits weight tensors. 8bits weight tensors. If it's string, It can be ``cpu``, and ``gpu:x``,
where ``x`` is the index of the GPUs.
quantizable_op_type(list[str]): This input param will be removed latter. The pass quantizable_op_type(list[str]): This input param will be removed latter. The pass
will process all quantized op, so it is not necessary to set the input param. will process all quantized op, so it is not necessary to set the input param.
""" """
...@@ -1375,7 +1379,7 @@ class ConvertToInt8Pass(object): ...@@ -1375,7 +1379,7 @@ class ConvertToInt8Pass(object):
assert place is not None, \ assert place is not None, \
'The place cannot be set None.' 'The place cannot be set None.'
self._scope = scope self._scope = scope
self._place = place self._place = _get_paddle_place(place)
def apply(self, graph): def apply(self, graph):
""" """
...@@ -1495,11 +1499,13 @@ class OutScaleForTrainingPass(object): ...@@ -1495,11 +1499,13 @@ class OutScaleForTrainingPass(object):
Args: Args:
scope(fluid.Scope): The scope is used to initialize these new parameters. scope(fluid.Scope): The scope is used to initialize these new parameters.
place(fluid.CPUPlace|fluid.CUDAPlace): The place is used to initialize new parameters. place(fluid.CPUPlace|fluid.CUDAPlace|str): The place is used to initialize new parameters.
If it's string, It can be ``cpu``, and ``gpu:x``, where ``x`` is the
index of the GPUs.
moving_rate(float): The decay coefficient of moving average. The default value is 0.9. moving_rate(float): The decay coefficient of moving average. The default value is 0.9.
""" """
self._scope = scope self._scope = scope
self._place = place self._place = _get_paddle_place(place)
self._moving_rate = moving_rate self._moving_rate = moving_rate
self._is_test = None self._is_test = None
self._teller_set = _out_scale_op_list self._teller_set = _out_scale_op_list
...@@ -1688,8 +1694,9 @@ class AddQuantDequantPass(object): ...@@ -1688,8 +1694,9 @@ class AddQuantDequantPass(object):
Args: Args:
scope(fluid.Scope): The scope is used to initialize these new parameters. scope(fluid.Scope): The scope is used to initialize these new parameters.
place(fluid.CPUPlace|fluid.CUDAPlace): place is used to initialize new place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to initialize new
parameters described above. parameters described above. If ``place`` is string, it can be It can be ``cpu``
or ``gpu:x``, where ``x`` is the index of the GPUs.
moving_rate(float, optional): the param for 'quant_dequant_moving_average_abs_max' moving_rate(float, optional): the param for 'quant_dequant_moving_average_abs_max'
quantization. Default is 0.9. quantization. Default is 0.9.
quant_bits(int, optional): quantization bit number for activation. Default is 8. quant_bits(int, optional): quantization bit number for activation. Default is 8.
...@@ -1705,7 +1712,7 @@ class AddQuantDequantPass(object): ...@@ -1705,7 +1712,7 @@ class AddQuantDequantPass(object):
quantizable_op_type. quantizable_op_type.
""" """
self._scope = scope self._scope = scope
self._place = place self._place = _get_paddle_place(place)
self._moving_rate = moving_rate self._moving_rate = moving_rate
self._quant_bits = quant_bits self._quant_bits = quant_bits
self._is_test = None self._is_test = None
......
...@@ -25,6 +25,7 @@ from .tracer import Tracer ...@@ -25,6 +25,7 @@ from .tracer import Tracer
import logging import logging
from ..data_feeder import convert_dtype from ..data_feeder import convert_dtype
import warnings import warnings
from ..framework import _get_paddle_place
__all__ = [ __all__ = [
'no_grad', 'no_grad_', 'grad', 'guard', 'enable_dygraph', 'disable_dygraph', 'no_grad', 'no_grad_', 'grad', 'guard', 'enable_dygraph', 'disable_dygraph',
...@@ -128,8 +129,9 @@ def enable_dygraph(place=None): ...@@ -128,8 +129,9 @@ def enable_dygraph(place=None):
This API turn OFF static graph mode. You can turn ON static graph mode by `enable_static <./disable_dygraph_en.html>`_ . This API turn OFF static graph mode. You can turn ON static graph mode by `enable_static <./disable_dygraph_en.html>`_ .
Parameters: Parameters:
place(paddle.CPUPlace|paddle.CUDAPlace, optional): Place to run dynamic graph. Default: None. Which means that the running place will be place(paddle.CPUPlace|paddle.CUDAPlace|str, optional): Place to run dynamic graph. Default: None. Which means that the running place will be
determined according to the way of paddle compilation. determined according to the way of paddle compilation. If ``place`` is string, It can be ``cpu``, and ``gpu:x``, where ``x`` is the
index of the GPUs.
return: return:
None None
...@@ -149,7 +151,8 @@ def enable_dygraph(place=None): ...@@ -149,7 +151,8 @@ def enable_dygraph(place=None):
""" """
global _functional_dygraph_context_manager global _functional_dygraph_context_manager
if _functional_dygraph_context_manager is None: if _functional_dygraph_context_manager is None:
_functional_dygraph_context_manager = guard(place=place) _functional_dygraph_context_manager = guard(
place=_get_paddle_place(place))
_functional_dygraph_context_manager.__enter__() _functional_dygraph_context_manager.__enter__()
# call disable_dygraph when Python exit # call disable_dygraph when Python exit
...@@ -343,8 +346,10 @@ def guard(place=None): ...@@ -343,8 +346,10 @@ def guard(place=None):
This context will create a dygraph context for dygraph to run, using python ``with`` statement. This context will create a dygraph context for dygraph to run, using python ``with`` statement.
Parameters: Parameters:
place(fluid.CPUPlace or fluid.CUDAPlace, optional): Place to execute dygraph. place(fluid.CPUPlace| fluid.CUDAPlace|str, optional): Place to execute dygraph.
If None, the running place will be determined according to the way of paddle compilation. Default: None If None, the running place will be determined according to the way of paddle compilation.
If ``place`` is string, It can be ``cpu``, ``gpu:x`` and ``xpu:x``, where ``x`` is the
index of the GPUs or XPUs. Default: None
return: return:
None None
...@@ -371,7 +376,7 @@ def guard(place=None): ...@@ -371,7 +376,7 @@ def guard(place=None):
VarBase = core.VarBase VarBase = core.VarBase
if place is not None: if place is not None:
expected_place = place expected_place = _get_paddle_place(place)
else: else:
expected_place = framework._current_expected_place() expected_place = framework._current_expected_place()
tracer._expected_place = expected_place tracer._expected_place = expected_place
......
...@@ -480,11 +480,13 @@ class Executor(object): ...@@ -480,11 +480,13 @@ class Executor(object):
and single/multiple-CPU running. and single/multiple-CPU running.
Args: Args:
place(paddle.CPUPlace()|paddle.CUDAPlace(n)|None): This parameter represents place(paddle.CPUPlace()|paddle.CUDAPlace(n)|str|None): This parameter represents
which device the executor runs on. When this parameter is None, PaddlePaddle which device the executor runs on. When this parameter is None, PaddlePaddle
will set the default device according to its installation version. If Paddle will set the default device according to its installation version. If Paddle
is CPU version, the default device would be set to `CPUPlace()` . If Paddle is is CPU version, the default device would be set to `CPUPlace()` . If Paddle is
GPU version, the default device would be set to `CUDAPlace(0)` . Default is None. GPU version, the default device would be set to `CUDAPlace(0)` . Default is None.
If ``place`` is string, it can be ``cpu``, and ``gpu:x``, where ``x``
is the index of the GPUs.
Returns: Returns:
Executor Executor
...@@ -550,7 +552,7 @@ class Executor(object): ...@@ -550,7 +552,7 @@ class Executor(object):
expected_place = framework._current_expected_place() expected_place = framework._current_expected_place()
self.place = expected_place self.place = expected_place
else: else:
self.place = place self.place = framework._get_paddle_place(place)
self.program_caches = dict() self.program_caches = dict()
self.ctx_caches = dict() self.ctx_caches = dict()
self.scope_caches = dict() self.scope_caches = dict()
......
...@@ -5801,3 +5801,64 @@ def get_flags(flags): ...@@ -5801,3 +5801,64 @@ def get_flags(flags):
else: else:
raise TypeError('Flags in get_flags should be a list, tuple or string.') raise TypeError('Flags in get_flags should be a list, tuple or string.')
return flags_value return flags_value
def _get_paddle_place(place):
"convert the string to paddle Place"
if place is None:
return place
if isinstance(place, (core.Place, core.XPUPlace, core.CPUPlace,
core.CUDAPinnedPlace, core.CUDAPlace)):
return place
if not isinstance(place, str):
raise ValueError(
"place only support string which is 'Place' and so on.")
place = place.lower()
if (place == "cpu"):
return core.CPUPlace()
if (place == "device"):
return core.Place()
avaliable_gpu_place = re.match(r'gpu:\d+', place)
if place == "gpu_pinned" or place == "gpu" or avaliable_gpu_place:
if not core.is_compiled_with_cuda():
raise ValueError(
"The device should not be {}, since PaddlePaddle is " \
"not compiled with CUDA".format(avaliable_gpu_place))
if place == "gpu_pinned":
return core.CUDAPinnedPlace()
elif place == "gpu":
return core.CUDAPlace(0)
else:
place_info_list = place.split(':', 1)
device_id = place_info_list[1]
device_id = int(device_id)
return core.CUDAPlace(device_id)
avaliable_xpu_place = re.match(r'xpu:\d+', place)
if avaliable_xpu_place:
if not core.is_compiled_with_xpu():
raise ValueError(
"The device should not be {}, since PaddlePaddle is " \
"not compiled with XPU".format(avaliable_xpu_place))
place_info_list = place.split(':', 1)
device_id = place_info_list[1]
device_id = int(device_id)
return core.XPUPlace(device_id)
raise ValueError(
"paddle support CPUPlace, CUDAPlace,CUDAPinnedPlace and XPUPlace, Please check your Place Input"
)
def _get_paddle_place_list(places):
if not isinstance(places, (list, tuple)):
raise TypeError("places must to be List or Tuple")
ret = []
for p in places:
p = _get_paddle_place(p)
ret.append(p)
return ret
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
"""This is definition of generator class, which is for managing the state of the algorithm that produces pseudo random numbers.""" """This is definition of generator class, which is for managing the state of the algorithm that produces pseudo random numbers."""
from . import core from . import core
from .framework import _get_paddle_place
__all__ = ['Generator'] __all__ = ['Generator']
...@@ -26,14 +27,15 @@ class Generator(core.Generator): ...@@ -26,14 +27,15 @@ class Generator(core.Generator):
Create a generator object which manages the random number generation. ( Experimental Feature ) Create a generator object which manages the random number generation. ( Experimental Feature )
Parameters: Parameters:
place(CPUPlace|CUDAPinnedPlace|CUDAPlace, optional): The place to allocate Tensor. Can be place(CPUPlace|CUDAPinnedPlace|CUDAPlace|str,optional): The place to allocate Tensor. Can be
CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. If ``place`` is
string, it can be ``cpu`` and ``gpu:x``, where ``x`` is the index of the GPUs.
Returns: Returns:
Generator: A generator object. Generator: A generator object.
""" """
self.place = place self.place = _get_paddle_place(place)
if not place: if not place:
place = core.CPUPlace() place = core.CPUPlace()
if isinstance(place, core.CPUPlace): if isinstance(place, core.CPUPlace):
......
...@@ -32,6 +32,7 @@ from ..unique_name import generate as unique_name ...@@ -32,6 +32,7 @@ from ..unique_name import generate as unique_name
import logging import logging
from ..data_feeder import check_dtype, check_type from ..data_feeder import check_dtype, check_type
from paddle.fluid.framework import static_only from paddle.fluid.framework import static_only
from ..framework import _get_paddle_place
__all__ = [ __all__ = [
'data', 'read_file', 'double_buffer', 'py_reader', 'data', 'read_file', 'double_buffer', 'py_reader',
...@@ -842,7 +843,8 @@ def double_buffer(reader, place=None, name=None): ...@@ -842,7 +843,8 @@ def double_buffer(reader, place=None, name=None):
Args: Args:
reader (Variable): The Reader Variable need to be wrapped. reader (Variable): The Reader Variable need to be wrapped.
place (Place, optional): The place of target data, such as CPU, GPU, and if use GPU, it's necessary to point out which card is involved. Default is the sample place of executor perform. place (Place|str, optional): The place of target data, such as CPU, GPU, and if use GPU, it's necessary to point out which card is involved. Default is the sample place of executor perform.
if ``place`` is string, It can be ``cpu``, ``gpu:x``, where ``x`` is the ndex of the GPUs.
name (str, optional): Variable name. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default is None. name (str, optional): Variable name. Normally there is no need for user to set this property. For more information, please refer to :ref:`api_guide_Name`. Default is None.
Returns: Returns:
...@@ -861,7 +863,8 @@ def double_buffer(reader, place=None, name=None): ...@@ -861,7 +863,8 @@ def double_buffer(reader, place=None, name=None):
""" """
attrs = dict() attrs = dict()
if place is not None: if place is not None:
attrs['place'] = str(place).upper() attrs['place'] = str(_get_paddle_place(place)).upper()
return __create_unshared_decorated_reader__( return __create_unshared_decorated_reader__(
'create_double_buffer_reader', reader, attrs, name=name) 'create_double_buffer_reader', reader, attrs, name=name)
......
...@@ -27,6 +27,7 @@ from .dataloader.dataloader_iter import _DataLoaderIterSingleProcess, _DataLoade ...@@ -27,6 +27,7 @@ from .dataloader.dataloader_iter import _DataLoaderIterSingleProcess, _DataLoade
from .dataloader.batch_sampler import _InfiniteIterableSampler from .dataloader.batch_sampler import _InfiniteIterableSampler
from .layers.io import monkey_patch_reader_methods, _copy_reader_var_, double_buffer from .layers.io import monkey_patch_reader_methods, _copy_reader_var_, double_buffer
from .unique_name import UniqueNameGenerator from .unique_name import UniqueNameGenerator
from .framework import _get_paddle_place, _get_paddle_place_list
import logging import logging
import warnings import warnings
...@@ -186,10 +187,12 @@ class DataLoader(object): ...@@ -186,10 +187,12 @@ class DataLoader(object):
The Tensors should be created by :code:`paddle.static.data()`. The Tensors should be created by :code:`paddle.static.data()`.
:attr:`feed_list` must be set if :attr:`return_list` is :attr:`feed_list` must be set if :attr:`return_list` is
False. Default None. False. Default None.
places(list(Place)|tuple(Place)|optional): a list of Place, places(list(Place)|tuple(Place)|list(str)|optional): a list of Place,
to put data onto, :attr:`places` can be None, if to put data onto, :attr:`places` can be None, if
:attr:`places` is None, default place(CPUPlace or CUDAPlace(0)) :attr:`places` is None, default place(CPUPlace or CUDAPlace(0))
will be used. Default None. will be used. Default None. If ``places`` is list of string,
the string in the list can be ``cpu``, ``gpu:x`` and ``gpu_pinned``,
where ``x`` is the index of the GPUs.
return_list (bool): whether the return value on each device is return_list (bool): whether the return value on each device is
presented as a list. If :attr:`return_list=False`, the return presented as a list. If :attr:`return_list=False`, the return
value on each device would be a dict of str -> Tensor, where value on each device would be a dict of str -> Tensor, where
...@@ -335,6 +338,10 @@ class DataLoader(object): ...@@ -335,6 +338,10 @@ class DataLoader(object):
if places is None: if places is None:
places = _current_expected_place() places = _current_expected_place()
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
self.places = _convert_places(places) self.places = _convert_places(places)
assert num_workers >= 0, "num_workers should be a non-negative value" assert num_workers >= 0, "num_workers should be a non-negative value"
...@@ -752,8 +759,9 @@ class DataLoader(object): ...@@ -752,8 +759,9 @@ class DataLoader(object):
Args: Args:
dataset (InMemoryDataset|QueueDataset): the dataset object. dataset (InMemoryDataset|QueueDataset): the dataset object.
places (list(CUDAPlace)|list(CPUPlace)): places where the result places (list(CUDAPlace)|list(CPUPlace)|list(str)): places where the result
data should be converted. data should be converted. If places is list of string, the string in the list
can be ``cpu``, ``gpu:x`` and ``gpu_pinned``, where x is the index of the GPUs.
drop_last (bool): whether to drop the last batch whose sample drop_last (bool): whether to drop the last batch whose sample
number is less than batch size. If drop_last = True, they number is less than batch size. If drop_last = True, they
would be dropped. If drop_last = False, they would be kept. would be dropped. If drop_last = False, they would be kept.
...@@ -1030,6 +1038,10 @@ class DygraphGeneratorLoader(DataLoaderBase): ...@@ -1030,6 +1038,10 @@ class DygraphGeneratorLoader(DataLoaderBase):
drop_last=True, drop_last=True,
places=None): places=None):
assert batch_size > 0, "batch_size must be larger than 0" assert batch_size > 0, "batch_size must be larger than 0"
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
self.set_sample_list_generator( self.set_sample_list_generator(
paddle.batch( paddle.batch(
reader, batch_size=batch_size, drop_last=drop_last), reader, batch_size=batch_size, drop_last=drop_last),
...@@ -1037,6 +1049,11 @@ class DygraphGeneratorLoader(DataLoaderBase): ...@@ -1037,6 +1049,11 @@ class DygraphGeneratorLoader(DataLoaderBase):
return self return self
def set_sample_list_generator(self, reader, places=None): def set_sample_list_generator(self, reader, places=None):
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
def __batch_reader_impl__(): def __batch_reader_impl__():
for batch in reader(): for batch in reader():
slots = [] slots = []
...@@ -1052,6 +1069,10 @@ class DygraphGeneratorLoader(DataLoaderBase): ...@@ -1052,6 +1069,10 @@ class DygraphGeneratorLoader(DataLoaderBase):
return self return self
def set_batch_generator(self, reader, places=None): def set_batch_generator(self, reader, places=None):
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
self._batch_reader = reader self._batch_reader = reader
if places is None: if places is None:
places = _current_expected_place() places = _current_expected_place()
...@@ -1275,6 +1296,10 @@ class GeneratorLoader(DataLoaderBase): ...@@ -1275,6 +1296,10 @@ class GeneratorLoader(DataLoaderBase):
drop_last=True, drop_last=True,
places=None): places=None):
assert batch_size > 0, "batch_size must be larger than 0" assert batch_size > 0, "batch_size must be larger than 0"
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
has_lod = False has_lod = False
for f in self._feed_list: for f in self._feed_list:
if f.lod_level != 0: if f.lod_level != 0:
...@@ -1297,6 +1322,10 @@ class GeneratorLoader(DataLoaderBase): ...@@ -1297,6 +1322,10 @@ class GeneratorLoader(DataLoaderBase):
return self return self
def set_sample_list_generator(self, reader, places=None): def set_sample_list_generator(self, reader, places=None):
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
with program_guard(Program(), Program()): with program_guard(Program(), Program()):
feeder = DataFeeder( feeder = DataFeeder(
feed_list=self._feed_list, place=core.CPUPlace()) feed_list=self._feed_list, place=core.CPUPlace())
...@@ -1310,6 +1339,10 @@ class GeneratorLoader(DataLoaderBase): ...@@ -1310,6 +1339,10 @@ class GeneratorLoader(DataLoaderBase):
return self return self
def set_batch_generator(self, reader, places=None): def set_batch_generator(self, reader, places=None):
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
self._tensor_reader = reader self._tensor_reader = reader
if self._iterable: if self._iterable:
assert places is not None, "Places cannot be None when DataLoader is iterable" assert places is not None, "Places cannot be None when DataLoader is iterable"
...@@ -1784,6 +1817,10 @@ class DatasetLoader(DataLoaderBase): ...@@ -1784,6 +1817,10 @@ class DatasetLoader(DataLoaderBase):
DatasetBase), "dataset must be type of DatasetBase" DatasetBase), "dataset must be type of DatasetBase"
assert not in_dygraph_mode( assert not in_dygraph_mode(
), "DatasetLoader is not supported in dygraph mode yet" ), "DatasetLoader is not supported in dygraph mode yet"
if isinstance(places, (list, tuple)):
places = _get_paddle_place_list(places)
else:
places = _get_paddle_place(places)
thread_num = len(places) thread_num = len(places)
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
import paddle.fluid as fluid import paddle.fluid as fluid
import unittest import unittest
import numpy as np import numpy as np
import paddle
class TestPyReaderErrorMsg(unittest.TestCase): class TestPyReaderErrorMsg(unittest.TestCase):
...@@ -35,5 +36,19 @@ class TestPyReaderErrorMsg(unittest.TestCase): ...@@ -35,5 +36,19 @@ class TestPyReaderErrorMsg(unittest.TestCase):
]) ])
class TestDoubleBufferAPI(unittest.TestCase):
def test_double_buffer(self):
paddle.enable_static()
if fluid.core.is_compiled_with_cuda():
reader = fluid.layers.py_reader(
capacity=64,
shapes=[(-1, 1, 28, 28), (-1, 1)],
dtypes=['float32', 'int64'],
use_double_buffer=False)
reader = fluid.layers.double_buffer(
reader, place=fluid.core.CUDAPlace(0))
image, label = fluid.layers.read_file(reader)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -149,9 +149,12 @@ class TestVarBase(unittest.TestCase): ...@@ -149,9 +149,12 @@ class TestVarBase(unittest.TestCase):
paddle.to_tensor([[1], [2, 3]], place=1) paddle.to_tensor([[1], [2, 3]], place=1)
_test_place(core.CPUPlace()) _test_place(core.CPUPlace())
_test_place("cpu")
if core.is_compiled_with_cuda(): if core.is_compiled_with_cuda():
_test_place(core.CUDAPinnedPlace()) _test_place(core.CUDAPinnedPlace())
_test_place("gpu_pinned")
_test_place(core.CUDAPlace(0)) _test_place(core.CUDAPlace(0))
_test_place("gpu:0")
def test_to_variable(self): def test_to_variable(self):
with fluid.dygraph.guard(): with fluid.dygraph.guard():
......
...@@ -31,7 +31,7 @@ import paddle ...@@ -31,7 +31,7 @@ import paddle
from paddle import fluid from paddle import fluid
from paddle.fluid import core from paddle.fluid import core
from paddle.fluid.framework import in_dygraph_mode, Variable, ParamBase, _current_expected_place from paddle.fluid.framework import in_dygraph_mode, Variable, ParamBase, _current_expected_place
from paddle.fluid.framework import in_dygraph_mode, Variable from paddle.fluid.framework import in_dygraph_mode, Variable, _get_paddle_place
from paddle.fluid.framework import _current_expected_place as _get_device from paddle.fluid.framework import _current_expected_place as _get_device
from paddle.fluid.executor import global_scope from paddle.fluid.executor import global_scope
from paddle.fluid.io import is_belong_to_optimizer from paddle.fluid.io import is_belong_to_optimizer
...@@ -167,6 +167,7 @@ def prepare_distributed_context(place=None): ...@@ -167,6 +167,7 @@ def prepare_distributed_context(place=None):
place = fluid.CUDAPlace(ParallelEnv().dev_id) if ParallelEnv().nranks > 1 \ place = fluid.CUDAPlace(ParallelEnv().dev_id) if ParallelEnv().nranks > 1 \
else fluid.CUDAPlace(0) else fluid.CUDAPlace(0)
place = _get_paddle_place(place)
strategy = fluid.dygraph.parallel.ParallelStrategy() strategy = fluid.dygraph.parallel.ParallelStrategy()
strategy.nranks = ParallelEnv().nranks strategy.nranks = ParallelEnv().nranks
strategy.local_rank = ParallelEnv().local_rank strategy.local_rank = ParallelEnv().local_rank
......
...@@ -18,7 +18,7 @@ import numpy as np ...@@ -18,7 +18,7 @@ import numpy as np
from ..fluid.layers import tensor from ..fluid.layers import tensor
from ..fluid.framework import Variable from ..fluid.framework import Variable
from ..fluid.framework import unique_name from ..fluid.framework import unique_name
from ..fluid.framework import _current_expected_place from ..fluid.framework import _current_expected_place, _get_paddle_place
from ..fluid.framework import dygraph_only from ..fluid.framework import dygraph_only
from ..fluid.initializer import Constant from ..fluid.initializer import Constant
from ..fluid.layers import core from ..fluid.layers import core
...@@ -26,7 +26,6 @@ from ..fluid.layer_helper import LayerHelper ...@@ -26,7 +26,6 @@ from ..fluid.layer_helper import LayerHelper
from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtype, convert_dtype from ..fluid.data_feeder import check_variable_and_dtype, check_type, check_dtype, convert_dtype
from ..fluid.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varbase_creator, device_guard, OpProtoHolder from ..fluid.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varbase_creator, device_guard, OpProtoHolder
from paddle.common_ops_import import * from paddle.common_ops_import import *
# TODO: define functions to get create a tensor # TODO: define functions to get create a tensor
from ..fluid.layers import linspace #DEFINE_ALIAS from ..fluid.layers import linspace #DEFINE_ALIAS
import paddle import paddle
...@@ -70,8 +69,9 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): ...@@ -70,8 +69,9 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True):
'float32' , 'float64' , 'int8' , 'int16' , 'int32' , 'int64' , 'uint8', 'float32' , 'float64' , 'int8' , 'int16' , 'int32' , 'int64' , 'uint8',
'complex64' , 'complex128'. Default: None, infers dtype from ``data`` 'complex64' , 'complex128'. Default: None, infers dtype from ``data``
except for python float number which gets dtype from ``get_default_type`` . except for python float number which gets dtype from ``get_default_type`` .
place(CPUPlace|CUDAPinnedPlace|CUDAPlace, optional): The place to allocate Tensor. Can be place(CPUPlace|CUDAPinnedPlace|CUDAPlace|str, optional): The place to allocate Tensor. Can be
CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. If ``place`` is
string, It can be ``cpu``, ``gpu:x`` and ``gpu_pinned``, where ``x`` is the index of the GPUs.
stop_gradient(bool, optional): Whether to block the gradient propagation of Autograd. Default: True. stop_gradient(bool, optional): Whether to block the gradient propagation of Autograd. Default: True.
Returns: Returns:
...@@ -81,7 +81,7 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): ...@@ -81,7 +81,7 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True):
TypeError: If the data type of ``data`` is not scalar, list, tuple, numpy.ndarray, paddle.Tensor TypeError: If the data type of ``data`` is not scalar, list, tuple, numpy.ndarray, paddle.Tensor
ValueError: If ``data`` is tuple|list, it can't contain nested tuple|list with different lengths , such as: [[1, 2], [3, 4, 5]] ValueError: If ``data`` is tuple|list, it can't contain nested tuple|list with different lengths , such as: [[1, 2], [3, 4, 5]]
TypeError: If ``dtype`` is not bool, float16, float32, float64, int8, int16, int32, int64, uint8, complex64, complex128 TypeError: If ``dtype`` is not bool, float16, float32, float64, int8, int16, int32, int64, uint8, complex64, complex128
ValueError: If ``place`` is not paddle.CPUPlace, paddle.CUDAPinnedPlace, paddle.CUDAPlace ValueError: If ``place`` is not paddle.CPUPlace, paddle.CUDAPinnedPlace, paddle.CUDAPlace or specified pattern string.
Examples: Examples:
...@@ -119,10 +119,12 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): ...@@ -119,10 +119,12 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True):
# [(3+2j), (4+0j)]]) # [(3+2j), (4+0j)]])
""" """
place = _get_paddle_place(place)
if place is None: if place is None:
place = _current_expected_place() place = _current_expected_place()
elif not isinstance(place, (core.Place, core.CPUPlace, core.CUDAPinnedPlace, elif not isinstance(
core.CUDAPlace)): place,
(core.Place, core.CPUPlace, core.CUDAPinnedPlace, core.CUDAPlace)):
raise ValueError( raise ValueError(
"'place' must be any of paddle.Place, paddle.CPUPlace, paddle.CUDAPinnedPlace, paddle.CUDAPlace" "'place' must be any of paddle.Place, paddle.CPUPlace, paddle.CUDAPinnedPlace, paddle.CUDAPlace"
) )
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册