diff --git a/paddle/fluid/framework/attribute.h b/paddle/fluid/framework/attribute.h index e516ae1efdfc6a3fe5157dd65078c3bc67a8d005..8a56b6dd1820ef825aa591aec4e8fd3f95ffde97 100644 --- a/paddle/fluid/framework/attribute.h +++ b/paddle/fluid/framework/attribute.h @@ -165,6 +165,35 @@ struct ExtractAttribute { const std::string& attr_name_; }; +template <> +struct ExtractAttribute> { + explicit ExtractAttribute(const std::string& attr_name) + : attr_name_(attr_name) {} + + std::vector* operator()(Attribute& attr) const { + if (attr.type() == typeid(std::vector)) { // NOLINT + std::vector val = BOOST_GET_CONST(std::vector, attr); + std::vector vec(val.begin(), val.end()); + attr = vec; + } else if (attr.type() == typeid(std::vector)) { // NOLINT + std::vector val = BOOST_GET_CONST(std::vector, attr); + std::vector vec(val.begin(), val.end()); + attr = vec; + } + std::vector* attr_value = nullptr; + try { + attr_value = &boost::get>(attr); + } catch (boost::bad_get& bad_get) { + PADDLE_THROW(platform::errors::InvalidArgument( + "Cannot get attribute (%s) by type std::vector, its type is " + "%s.", + attr_name_, paddle::platform::demangle(attr.type().name()))); + } + return attr_value; + } + + const std::string& attr_name_; +}; template inline proto::AttrType AttrTypeID() { Attribute tmp = T(); diff --git a/paddle/fluid/framework/framework.proto b/paddle/fluid/framework/framework.proto index baaecb55d06ee31a3c4d043942fd34bd4c486df5..ff999d829cb3cde00467c53e2d711387e86f95d6 100644 --- a/paddle/fluid/framework/framework.proto +++ b/paddle/fluid/framework/framework.proto @@ -35,6 +35,7 @@ enum AttrType { LONG = 9; BLOCKS = 10; LONGS = 11; + FLOAT64S = 12; } // OpDesc describes an instance of a C++ framework::OperatorBase @@ -56,6 +57,7 @@ message OpDesc { optional int64 l = 13; repeated int32 blocks_idx = 14; repeated int64 longs = 15; + repeated double float64s = 16; }; message Var { diff --git a/paddle/fluid/framework/op_desc.cc b/paddle/fluid/framework/op_desc.cc index bccc92e5c4352927f309f3605bb3c8d8dd823bb5..bb9f7fe1daf9d8aabb9a0787ba51c47c91e8c311 100644 --- a/paddle/fluid/framework/op_desc.cc +++ b/paddle/fluid/framework/op_desc.cc @@ -714,6 +714,10 @@ struct SetAttrDescVisitor : public boost::static_visitor { VectorToRepeated(v, attr_->mutable_longs()); } + void operator()(const std::vector &v) const { + VectorToRepeated(v, attr_->mutable_float64s()); + } + void operator()(boost::blank) const { PADDLE_THROW(platform::errors::Unavailable( "Unsupported calling method of SetAttrDescVisitor object for " diff --git a/paddle/fluid/framework/type_defs.h b/paddle/fluid/framework/type_defs.h index 0ff2b2fd732c0a72b173e95eca9323cfa0c38753..4d2f07fa494d5313483d9f1b27847ea6ad10592e 100644 --- a/paddle/fluid/framework/type_defs.h +++ b/paddle/fluid/framework/type_defs.h @@ -38,11 +38,10 @@ using VariableNameMap = std::map>; using VariableValueMap = std::map>; // The order should be as same as framework.proto -using Attribute = - boost::variant, - std::vector, std::vector, bool, - std::vector, BlockDesc*, int64_t, - std::vector, std::vector>; +using Attribute = boost::variant< + boost::blank, int, float, std::string, std::vector, std::vector, + std::vector, bool, std::vector, BlockDesc*, int64_t, + std::vector, std::vector, std::vector>; using AttributeMap = std::unordered_map; diff --git a/paddle/fluid/operators/set_value_op.cc b/paddle/fluid/operators/set_value_op.cc index a928668a221c91d44d8a49ec39dbc4ebbf84cb3f..1d8bfc99854c20ed121247854faa7e67d1920b73 100644 --- a/paddle/fluid/operators/set_value_op.cc +++ b/paddle/fluid/operators/set_value_op.cc @@ -79,6 +79,8 @@ class SetValueMaker : public framework::OpProtoAndCheckerMaker { .SetDefault({}); AddAttr>("int64_values", "store the int64 values") .SetDefault({}); + AddAttr>("fp64_values", "store the float64 values") + .SetDefault({}); AddAttr>("shape", "(vector) Shape of values.") .SetDefault({}); diff --git a/paddle/fluid/operators/set_value_op.h b/paddle/fluid/operators/set_value_op.h index 1f08e81bf0ac5d12338b8de1e8c40b1e44146986..a400dae3e0a707e66a3ed11024407c3548cf5155 100644 --- a/paddle/fluid/operators/set_value_op.h +++ b/paddle/fluid/operators/set_value_op.h @@ -43,9 +43,13 @@ inline std::string GetValueName(framework::proto::VarType::Type data_type) { case framework::proto::VarType::FP32: value_name = "fp32_values"; break; + case framework::proto::VarType::FP64: + value_name = "fp64_values"; + break; case framework::proto::VarType::BOOL: value_name = "bool_values"; break; + default: PADDLE_THROW(platform::errors::Unimplemented( "Unsupported data type(code %d) for SetValue operator, only " diff --git a/python/paddle/fluid/framework.py b/python/paddle/fluid/framework.py index b423d330f76571afeb86b08e417dd3825ec43321..1ee522f54e692c2c03486c346f6ec58aa2698d1a 100644 --- a/python/paddle/fluid/framework.py +++ b/python/paddle/fluid/framework.py @@ -1893,9 +1893,10 @@ class Variable(object): dtype = self.dtype attrs['dtype'] = dtype + from .data_feeder import convert_dtype # 2.1 value is an integer of float if isinstance(value, (int, float)): - value = np.array([value]) + value = np.array([value]).astype(convert_dtype(dtype)) # 2.2 value is a np.ndarray if isinstance(value, np.ndarray): @@ -1906,6 +1907,9 @@ class Variable(object): elif dtype == core.VarDesc.VarType.FP32: value_name = "fp32_values" values = [float(v) for v in value.flat] + elif dtype == core.VarDesc.VarType.FP64: + value_name = "fp64_values" + values = [float(v) for v in value.flat] elif dtype == core.VarDesc.VarType.INT32: value_name = "int32_values" values = [int(v) for v in value.flat] @@ -1913,7 +1917,6 @@ class Variable(object): value_name = "int64_values" values = [int(v) for v in value.flat] else: - from .data_feeder import convert_dtype raise TypeError( "When assign a numpy.ndarray, integer or float to a paddle.Tensor, " "the data type of the paddle.Tensor must be bool, float32, int32 or int64, but " diff --git a/python/paddle/fluid/tests/unittests/test_set_value_op.py b/python/paddle/fluid/tests/unittests/test_set_value_op.py index cc5bf01b62cce082463071063f5e7763e9230a13..aca685a410251c4158b0c1964c023ece3b92748c 100644 --- a/python/paddle/fluid/tests/unittests/test_set_value_op.py +++ b/python/paddle/fluid/tests/unittests/test_set_value_op.py @@ -102,7 +102,7 @@ class TestSetValueItemSlice4(TestSetValueApi): # 2. Test different type of value: int, float, numpy.ndarray, Tensor -# 2.1 value is int32, int64, float32, bool +# 2.1 value is int32, int64, float32, float64, bool def create_test_value_int32(parent): @@ -165,6 +165,26 @@ create_test_value_fp32(TestSetValueItemSlice3) create_test_value_fp32(TestSetValueItemSlice4) +def create_test_value_fp64(parent): + class TestValueInt(parent): + def set_value(self): + self.value = 2.0**127 # float32:[-2^128, 2^128) + + def set_dtype(self): + self.dtype = "float64" + + cls_name = "{0}_{1}".format(parent.__name__, "ValueFp64") + TestValueInt.__name__ = cls_name + globals()[cls_name] = TestValueInt + + +create_test_value_fp64(TestSetValueItemInt) +create_test_value_fp64(TestSetValueItemSlice) +create_test_value_fp64(TestSetValueItemSlice2) +create_test_value_fp64(TestSetValueItemSlice3) +create_test_value_fp64(TestSetValueItemSlice4) + + def create_test_value_bool(parent): class TestValueInt(parent): def set_value(self): @@ -185,7 +205,7 @@ create_test_value_bool(TestSetValueItemSlice3) create_test_value_bool(TestSetValueItemSlice4) -# 2.2 value is numpy.array (int32, int64, float32, bool) +# 2.2 value is numpy.array (int32, int64, float32, float64, bool) def create_test_value_numpy_int32(parent): class TestValueInt(parent): def set_value(self): @@ -246,6 +266,26 @@ create_test_value_numpy_fp32(TestSetValueItemSlice3) create_test_value_numpy_fp32(TestSetValueItemSlice4) +def create_test_value_numpy_fp64(parent): + class TestValueInt(parent): + def set_value(self): + self.value = np.array([2**127]).astype("float64") + + def set_dtype(self): + self.dtype = "float64" + + cls_name = "{0}_{1}".format(parent.__name__, "ValueNumpyFp64") + TestValueInt.__name__ = cls_name + globals()[cls_name] = TestValueInt + + +create_test_value_numpy_fp64(TestSetValueItemInt) +create_test_value_numpy_fp64(TestSetValueItemSlice) +create_test_value_numpy_fp64(TestSetValueItemSlice2) +create_test_value_numpy_fp64(TestSetValueItemSlice3) +create_test_value_numpy_fp64(TestSetValueItemSlice4) + + def create_test_value_numpy_bool(parent): class TestValueInt(parent): def set_value(self): @@ -451,7 +491,7 @@ class TestError(TestSetValueBase): TypeError, "When assign a numpy.ndarray, integer or float to a paddle.Tensor, " ): - y = paddle.ones(shape=self.shape, dtype="float64") + y = paddle.ones(shape=self.shape, dtype="float16") y[0] = 1 def _step_error(self):