diff --git a/paddle/fluid/operators/reader/create_double_buffer_reader_op.cc b/paddle/fluid/operators/reader/create_double_buffer_reader_op.cc index 15971af58c6841050e008b486a1487ea8df891ec..44db3f3a33563d0e5531a631f21b69fd508533ba 100644 --- a/paddle/fluid/operators/reader/create_double_buffer_reader_op.cc +++ b/paddle/fluid/operators/reader/create_double_buffer_reader_op.cc @@ -47,11 +47,12 @@ class CreateDoubleBufferReaderOp : public framework::OperatorBase { platform::Place place; if (place_str == "AUTO") { place = dev_place; - } else if (place_str == "CPU") { + } else if (place_str == "CPUPLACE") { place = platform::CPUPlace(); } else { + place_str = place_str.substr(0, place_str.length() - 1); 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; sin >> num; place = platform::CUDAPlace(static_cast(num)); @@ -78,9 +79,9 @@ class CreateDoubleBufferReaderOpMaker : public DecoratedReaderMakerBase { std::unordered_set enum_range; constexpr size_t kMaxCUDADevs = 128; 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"); AddAttr("place", "The double buffer place") .SetDefault("AUTO") diff --git a/python/paddle/fluid/compiler.py b/python/paddle/fluid/compiler.py index a07378a6f58f72b66e67b5e7cc2db9e9515be888..cf4a0ee56e5145efeff078d81403f793314acab7 100644 --- a/python/paddle/fluid/compiler.py +++ b/python/paddle/fluid/compiler.py @@ -20,6 +20,8 @@ from .. import compat as cpt from . import framework 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 __all__ = ['CompiledProgram', 'ExecutionStrategy', 'BuildStrategy'] @@ -202,7 +204,7 @@ class CompiledProgram(object): Tensors to other devices when it is first executed, the CompiledProgram specified by share_vars_from must be run before the current CompiledProgram. 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 [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, @@ -213,7 +215,8 @@ class CompiledProgram(object): 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 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: CompiledProgram @@ -282,7 +285,10 @@ class CompiledProgram(object): self._exec_strategy = exec_strategy self._loss_name = loss_name 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): 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." diff --git a/python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py b/python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py index 7e1db69703c8a804cf3fc4c87750c9f6dad8cee8..0f44d7240e2ac91d31974329e25d121d2da81753 100644 --- a/python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py +++ b/python/paddle/fluid/contrib/slim/quantization/quant2_int8_mkldnn_pass.py @@ -15,6 +15,7 @@ import numpy as np from .... import core from ....framework import IrGraph +from ....framework import _get_paddle_place __all__ = ['Quant2Int8MkldnnPass'] @@ -43,7 +44,7 @@ class Quant2Int8MkldnnPass(object): _core=None, _debug=False): self._scope = _scope - self._place = _place + self._place = _get_paddle_place(_place) self._core = _core self._debug = _debug self._fake_quantize_types = [ diff --git a/python/paddle/fluid/contrib/slim/quantization/quant_int8_mkldnn_pass.py b/python/paddle/fluid/contrib/slim/quantization/quant_int8_mkldnn_pass.py index d31dc35d143dec009936edeaa02fcb7975cbfc71..2ed06a48c29f72e7c684610ad3bcbcdbd8306873 100644 --- a/python/paddle/fluid/contrib/slim/quantization/quant_int8_mkldnn_pass.py +++ b/python/paddle/fluid/contrib/slim/quantization/quant_int8_mkldnn_pass.py @@ -16,6 +16,7 @@ import numpy as np from .... import core from ....framework import IrGraph from ....framework import IrNode +from ....framework import _get_paddle_place __all__ = ['QuantInt8MkldnnPass'] @@ -40,7 +41,8 @@ class QuantInt8MkldnnPass(object): r""" Args: 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: @@ -60,7 +62,7 @@ class QuantInt8MkldnnPass(object): """ self._scope = _scope - self._place = _place + self._place = _get_paddle_place(_place) self._quantize_type = [ 'fake_quantize_moving_average_abs_max', diff --git a/python/paddle/fluid/contrib/slim/quantization/quantization_pass.py b/python/paddle/fluid/contrib/slim/quantization/quantization_pass.py index 219025269fe97b9ebaf332886f67f9ad8cf3c6ad..0017c29cbda24ea28537e55ccb54f4f1f194c662 100644 --- a/python/paddle/fluid/contrib/slim/quantization/quantization_pass.py +++ b/python/paddle/fluid/contrib/slim/quantization/quantization_pass.py @@ -25,6 +25,7 @@ from ....framework import Program, program_guard, default_startup_program from ....data import data from ....layers import mean from ....executor import scope_guard +from ....framework import _get_paddle_place __all__ = [ 'QuantizationTransformPass', 'QuantizationFreezePass', 'ConvertToInt8Pass', @@ -246,8 +247,9 @@ class QuantizationTransformPass(object): 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 initialize these new parameters. - place(fluid.CPUPlace|fluid.CUDAPlace): place is used to initialize new - parameters described above. + place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to initialize new + 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, the bias is not quantized. activation_bits(int): quantization bit number for activation. @@ -315,7 +317,7 @@ class QuantizationTransformPass(object): transform_pass.apply(graph) """ self._scope = scope - self._place = place + self._place = _get_paddle_place(place) self._weight_bits = weight_bits self._activation_bits = activation_bits self._skip_pattern = skip_pattern @@ -1057,7 +1059,8 @@ class QuantizationFreezePass(object): Args: 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. activation_bits(int): quantization bit number for activation. weight_quantize_type(str): quantization type for weights, support 'abs_max' and @@ -1071,7 +1074,7 @@ class QuantizationFreezePass(object): assert place is not None, \ 'The place cannot be set None.' self._scope = scope - self._place = place + self._place = _get_paddle_place(place) self._weight_bits = weight_bits self._activation_bits = activation_bits self._weight_quantize_type = weight_quantize_type @@ -1365,8 +1368,9 @@ class ConvertToInt8Pass(object): Args: scope(fluid.Scope): scope is used to get the weight tensor values. - place(fluid.CPUPlace|fluid.CUDAPlace): place is used to restore the - 8bits weight tensors. + place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to restore the + 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 will process all quantized op, so it is not necessary to set the input param. """ @@ -1375,7 +1379,7 @@ class ConvertToInt8Pass(object): assert place is not None, \ 'The place cannot be set None.' self._scope = scope - self._place = place + self._place = _get_paddle_place(place) def apply(self, graph): """ @@ -1495,11 +1499,13 @@ class OutScaleForTrainingPass(object): Args: 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. """ self._scope = scope - self._place = place + self._place = _get_paddle_place(place) self._moving_rate = moving_rate self._is_test = None self._teller_set = _out_scale_op_list @@ -1688,8 +1694,9 @@ class AddQuantDequantPass(object): Args: scope(fluid.Scope): The scope is used to initialize these new parameters. - place(fluid.CPUPlace|fluid.CUDAPlace): place is used to initialize new - parameters described above. + place(fluid.CPUPlace|fluid.CUDAPlace|str): place is used to initialize new + 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' quantization. Default is 0.9. quant_bits(int, optional): quantization bit number for activation. Default is 8. @@ -1705,7 +1712,7 @@ class AddQuantDequantPass(object): quantizable_op_type. """ self._scope = scope - self._place = place + self._place = _get_paddle_place(place) self._moving_rate = moving_rate self._quant_bits = quant_bits self._is_test = None diff --git a/python/paddle/fluid/dygraph/base.py b/python/paddle/fluid/dygraph/base.py index b63941206ecd592f55a4ff865c70be625e0e379a..11c836c9166a9dd612b996b490d4a775fb8309e0 100644 --- a/python/paddle/fluid/dygraph/base.py +++ b/python/paddle/fluid/dygraph/base.py @@ -25,6 +25,7 @@ from .tracer import Tracer import logging from ..data_feeder import convert_dtype import warnings +from ..framework import _get_paddle_place __all__ = [ 'no_grad', 'no_grad_', 'grad', 'guard', 'enable_dygraph', 'disable_dygraph', @@ -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>`_ . Parameters: - place(paddle.CPUPlace|paddle.CUDAPlace, optional): Place to run dynamic graph. Default: None. Which means that the running place will be - determined according to the way of paddle compilation. + 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. If ``place`` is string, It can be ``cpu``, and ``gpu:x``, where ``x`` is the + index of the GPUs. return: None @@ -149,7 +151,8 @@ def enable_dygraph(place=None): """ global _functional_dygraph_context_manager 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__() # call disable_dygraph when Python exit @@ -343,8 +346,10 @@ def guard(place=None): This context will create a dygraph context for dygraph to run, using python ``with`` statement. Parameters: - place(fluid.CPUPlace or fluid.CUDAPlace, optional): Place to execute dygraph. - If None, the running place will be determined according to the way of paddle compilation. Default: None + 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. + 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: None @@ -371,7 +376,7 @@ def guard(place=None): VarBase = core.VarBase if place is not None: - expected_place = place + expected_place = _get_paddle_place(place) else: expected_place = framework._current_expected_place() tracer._expected_place = expected_place diff --git a/python/paddle/fluid/executor.py b/python/paddle/fluid/executor.py index 9b17d61c33c22eca308acfe7fceb4b2687c0651a..9b0b04a6ea7164501ff5af6caace2bd4a6315cf4 100644 --- a/python/paddle/fluid/executor.py +++ b/python/paddle/fluid/executor.py @@ -480,11 +480,13 @@ class Executor(object): and single/multiple-CPU running. 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 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 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: Executor @@ -550,7 +552,7 @@ class Executor(object): expected_place = framework._current_expected_place() self.place = expected_place else: - self.place = place + self.place = framework._get_paddle_place(place) self.program_caches = dict() self.ctx_caches = dict() self.scope_caches = dict() diff --git a/python/paddle/fluid/framework.py b/python/paddle/fluid/framework.py index ac2fa5c0bd27732532859458f92c4d47fceed38c..c1e048b769416ef4e6d7442c9e6636a0882544c4 100644 --- a/python/paddle/fluid/framework.py +++ b/python/paddle/fluid/framework.py @@ -5801,3 +5801,64 @@ def get_flags(flags): else: raise TypeError('Flags in get_flags should be a list, tuple or string.') 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 diff --git a/python/paddle/fluid/generator.py b/python/paddle/fluid/generator.py index 98924f801413bcd822a0d9a6fd61adcc4d00fddc..7ce2d6a4bf3d92aff83e3f0e5b6979d01c5a204f 100644 --- a/python/paddle/fluid/generator.py +++ b/python/paddle/fluid/generator.py @@ -14,6 +14,7 @@ """This is definition of generator class, which is for managing the state of the algorithm that produces pseudo random numbers.""" from . import core +from .framework import _get_paddle_place __all__ = ['Generator'] @@ -26,14 +27,15 @@ class Generator(core.Generator): Create a generator object which manages the random number generation. ( Experimental Feature ) Parameters: - place(CPUPlace|CUDAPinnedPlace|CUDAPlace, optional): The place to allocate Tensor. Can be - CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. + place(CPUPlace|CUDAPinnedPlace|CUDAPlace|str,optional): The place to allocate Tensor. Can be + 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: Generator: A generator object. """ - self.place = place + self.place = _get_paddle_place(place) if not place: place = core.CPUPlace() if isinstance(place, core.CPUPlace): diff --git a/python/paddle/fluid/layers/io.py b/python/paddle/fluid/layers/io.py index 6b98dea42903e1392febd14b739b49cec7bc8c14..8e52f01a88bd719535df12af551279b0fbfe517e 100644 --- a/python/paddle/fluid/layers/io.py +++ b/python/paddle/fluid/layers/io.py @@ -32,6 +32,7 @@ from ..unique_name import generate as unique_name import logging from ..data_feeder import check_dtype, check_type from paddle.fluid.framework import static_only +from ..framework import _get_paddle_place __all__ = [ 'data', 'read_file', 'double_buffer', 'py_reader', @@ -842,7 +843,8 @@ def double_buffer(reader, place=None, name=None): Args: 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. Returns: @@ -861,7 +863,8 @@ def double_buffer(reader, place=None, name=None): """ attrs = dict() if place is not None: - attrs['place'] = str(place).upper() + attrs['place'] = str(_get_paddle_place(place)).upper() + return __create_unshared_decorated_reader__( 'create_double_buffer_reader', reader, attrs, name=name) diff --git a/python/paddle/fluid/reader.py b/python/paddle/fluid/reader.py index 84ccba98e60408baa5465051e971622ba62d2be6..a9f9c3486227ade635ae4a9d10bda14d5c8aa059 100644 --- a/python/paddle/fluid/reader.py +++ b/python/paddle/fluid/reader.py @@ -27,6 +27,7 @@ from .dataloader.dataloader_iter import _DataLoaderIterSingleProcess, _DataLoade from .dataloader.batch_sampler import _InfiniteIterableSampler from .layers.io import monkey_patch_reader_methods, _copy_reader_var_, double_buffer from .unique_name import UniqueNameGenerator +from .framework import _get_paddle_place, _get_paddle_place_list import logging import warnings @@ -186,10 +187,12 @@ class DataLoader(object): The Tensors should be created by :code:`paddle.static.data()`. :attr:`feed_list` must be set if :attr:`return_list` is 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 :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 presented as a list. If :attr:`return_list=False`, the return value on each device would be a dict of str -> Tensor, where @@ -335,6 +338,10 @@ class DataLoader(object): if places is None: 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) assert num_workers >= 0, "num_workers should be a non-negative value" @@ -752,8 +759,9 @@ class DataLoader(object): Args: dataset (InMemoryDataset|QueueDataset): the dataset object. - places (list(CUDAPlace)|list(CPUPlace)): places where the result - data should be converted. + places (list(CUDAPlace)|list(CPUPlace)|list(str)): places where the result + 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 number is less than batch size. If drop_last = True, they would be dropped. If drop_last = False, they would be kept. @@ -1030,6 +1038,10 @@ class DygraphGeneratorLoader(DataLoaderBase): drop_last=True, places=None): 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( paddle.batch( reader, batch_size=batch_size, drop_last=drop_last), @@ -1037,6 +1049,11 @@ class DygraphGeneratorLoader(DataLoaderBase): return self 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__(): for batch in reader(): slots = [] @@ -1052,6 +1069,10 @@ class DygraphGeneratorLoader(DataLoaderBase): return self 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 if places is None: places = _current_expected_place() @@ -1275,6 +1296,10 @@ class GeneratorLoader(DataLoaderBase): drop_last=True, places=None): 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 for f in self._feed_list: if f.lod_level != 0: @@ -1297,6 +1322,10 @@ class GeneratorLoader(DataLoaderBase): return self 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()): feeder = DataFeeder( feed_list=self._feed_list, place=core.CPUPlace()) @@ -1310,6 +1339,10 @@ class GeneratorLoader(DataLoaderBase): return self 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 if self._iterable: assert places is not None, "Places cannot be None when DataLoader is iterable" @@ -1784,6 +1817,10 @@ class DatasetLoader(DataLoaderBase): DatasetBase), "dataset must be type of DatasetBase" assert not in_dygraph_mode( ), "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) diff --git a/python/paddle/fluid/tests/unittests/test_py_reader_error_msg.py b/python/paddle/fluid/tests/unittests/test_py_reader_error_msg.py index 4c45908c5c369c57b954ace890af3e215f97a21a..f4fa419b91dde2a02f68db6948f77e853a2ecb90 100644 --- a/python/paddle/fluid/tests/unittests/test_py_reader_error_msg.py +++ b/python/paddle/fluid/tests/unittests/test_py_reader_error_msg.py @@ -15,6 +15,7 @@ import paddle.fluid as fluid import unittest import numpy as np +import paddle 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__': unittest.main() diff --git a/python/paddle/fluid/tests/unittests/test_var_base.py b/python/paddle/fluid/tests/unittests/test_var_base.py index 653127319a1e1363dd1201a6492655e5ef7d50a5..58ac8aab2db2c212013df6b758305bb37e1280bb 100644 --- a/python/paddle/fluid/tests/unittests/test_var_base.py +++ b/python/paddle/fluid/tests/unittests/test_var_base.py @@ -149,9 +149,12 @@ class TestVarBase(unittest.TestCase): paddle.to_tensor([[1], [2, 3]], place=1) _test_place(core.CPUPlace()) + _test_place("cpu") if core.is_compiled_with_cuda(): _test_place(core.CUDAPinnedPlace()) + _test_place("gpu_pinned") _test_place(core.CUDAPlace(0)) + _test_place("gpu:0") def test_to_variable(self): with fluid.dygraph.guard(): diff --git a/python/paddle/hapi/model.py b/python/paddle/hapi/model.py index 7c731c4002939095d465672d3e36c4bffcec618d..99e8acd2b0b934d2fd666472a8a6fa79c29277f6 100644 --- a/python/paddle/hapi/model.py +++ b/python/paddle/hapi/model.py @@ -31,7 +31,7 @@ import paddle from paddle import fluid 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 +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.executor import global_scope from paddle.fluid.io import is_belong_to_optimizer @@ -167,6 +167,7 @@ def prepare_distributed_context(place=None): place = fluid.CUDAPlace(ParallelEnv().dev_id) if ParallelEnv().nranks > 1 \ else fluid.CUDAPlace(0) + place = _get_paddle_place(place) strategy = fluid.dygraph.parallel.ParallelStrategy() strategy.nranks = ParallelEnv().nranks strategy.local_rank = ParallelEnv().local_rank diff --git a/python/paddle/tensor/creation.py b/python/paddle/tensor/creation.py index d1c203d84ccc4b7cc25e51f087e005bc8ba13802..fd5ca15840076022870af033a5d23a37fd49995d 100644 --- a/python/paddle/tensor/creation.py +++ b/python/paddle/tensor/creation.py @@ -18,7 +18,7 @@ import numpy as np from ..fluid.layers import tensor from ..fluid.framework import Variable 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.initializer import Constant from ..fluid.layers import core @@ -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.framework import convert_np_dtype_to_dtype_, in_dygraph_mode, _varbase_creator, device_guard, OpProtoHolder from paddle.common_ops_import import * - # TODO: define functions to get create a tensor from ..fluid.layers import linspace #DEFINE_ALIAS import paddle @@ -70,8 +69,9 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): 'float32' , 'float64' , 'int8' , 'int16' , 'int32' , 'int64' , 'uint8', 'complex64' , 'complex128'. Default: None, infers dtype from ``data`` except for python float number which gets dtype from ``get_default_type`` . - place(CPUPlace|CUDAPinnedPlace|CUDAPlace, optional): The place to allocate Tensor. Can be - CPUPlace, CUDAPinnedPlace, CUDAPlace. Default: None, means global place. + place(CPUPlace|CUDAPinnedPlace|CUDAPlace|str, optional): The place to allocate Tensor. Can be + 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. Returns: @@ -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 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 - 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: @@ -119,10 +119,12 @@ def to_tensor(data, dtype=None, place=None, stop_gradient=True): # [(3+2j), (4+0j)]]) """ + place = _get_paddle_place(place) if place is None: place = _current_expected_place() - elif not isinstance(place, (core.Place, core.CPUPlace, core.CUDAPinnedPlace, - core.CUDAPlace)): + elif not isinstance( + place, + (core.Place, core.CPUPlace, core.CUDAPinnedPlace, core.CUDAPlace)): raise ValueError( "'place' must be any of paddle.Place, paddle.CPUPlace, paddle.CUDAPinnedPlace, paddle.CUDAPlace" )