Skip to content

Commit

Permalink
[Cherry-Pick] Support vector<double> as type of op attribute and op s…
Browse files Browse the repository at this point in the history
…et_value suppport vector<double> as value (#30126)
  • Loading branch information
liym27 committed Jan 11, 2021
1 parent afbc636 commit cf10e7a
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 10 deletions.
29 changes: 29 additions & 0 deletions paddle/fluid/framework/attribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,35 @@ struct ExtractAttribute<float> {
const std::string& attr_name_;
};

template <>
struct ExtractAttribute<std::vector<double>> {
explicit ExtractAttribute(const std::string& attr_name)
: attr_name_(attr_name) {}

std::vector<double>* operator()(Attribute& attr) const {
if (attr.type() == typeid(std::vector<int>)) { // NOLINT
std::vector<int> val = BOOST_GET_CONST(std::vector<int>, attr);
std::vector<double> vec(val.begin(), val.end());
attr = vec;
} else if (attr.type() == typeid(std::vector<float>)) { // NOLINT
std::vector<float> val = BOOST_GET_CONST(std::vector<float>, attr);
std::vector<double> vec(val.begin(), val.end());
attr = vec;
}
std::vector<double>* attr_value = nullptr;
try {
attr_value = &boost::get<std::vector<double>>(attr);
} catch (boost::bad_get& bad_get) {
PADDLE_THROW(platform::errors::InvalidArgument(
"Cannot get attribute (%s) by type std::vector<double>, its type is "
"%s.",
attr_name_, paddle::platform::demangle(attr.type().name())));
}
return attr_value;
}

const std::string& attr_name_;
};
template <typename T>
inline proto::AttrType AttrTypeID() {
Attribute tmp = T();
Expand Down
2 changes: 2 additions & 0 deletions paddle/fluid/framework/framework.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ enum AttrType {
LONG = 9;
BLOCKS = 10;
LONGS = 11;
FLOAT64S = 12;
}

// OpDesc describes an instance of a C++ framework::OperatorBase
Expand All @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions paddle/fluid/framework/op_desc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,10 @@ struct SetAttrDescVisitor : public boost::static_visitor<void> {
VectorToRepeated(v, attr_->mutable_longs());
}

void operator()(const std::vector<double> &v) const {
VectorToRepeated(v, attr_->mutable_float64s());
}

void operator()(boost::blank) const {
PADDLE_THROW(platform::errors::Unavailable(
"Unsupported calling method of SetAttrDescVisitor object for "
Expand Down
9 changes: 4 additions & 5 deletions paddle/fluid/framework/type_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ using VariableNameMap = std::map<std::string, std::vector<std::string>>;
using VariableValueMap = std::map<std::string, std::vector<Variable*>>;

// The order should be as same as framework.proto
using Attribute =
boost::variant<boost::blank, int, float, std::string, std::vector<int>,
std::vector<float>, std::vector<std::string>, bool,
std::vector<bool>, BlockDesc*, int64_t,
std::vector<BlockDesc*>, std::vector<int64_t>>;
using Attribute = boost::variant<
boost::blank, int, float, std::string, std::vector<int>, std::vector<float>,
std::vector<std::string>, bool, std::vector<bool>, BlockDesc*, int64_t,
std::vector<BlockDesc*>, std::vector<int64_t>, std::vector<double>>;

using AttributeMap = std::unordered_map<std::string, Attribute>;

Expand Down
2 changes: 2 additions & 0 deletions paddle/fluid/operators/set_value_op.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class SetValueMaker : public framework::OpProtoAndCheckerMaker {
.SetDefault({});
AddAttr<std::vector<int64_t>>("int64_values", "store the int64 values")
.SetDefault({});
AddAttr<std::vector<double>>("fp64_values", "store the float64 values")
.SetDefault({});

AddAttr<std::vector<int64_t>>("shape", "(vector<int64_t>) Shape of values.")
.SetDefault({});
Expand Down
4 changes: 4 additions & 0 deletions paddle/fluid/operators/set_value_op.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down
7 changes: 5 additions & 2 deletions python/paddle/fluid/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1893,9 +1893,10 @@ def __setitem__(self, item, value):
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):
Expand All @@ -1906,14 +1907,16 @@ def __setitem__(self, item, value):
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]
elif dtype == core.VarDesc.VarType.INT64:
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 "
Expand Down
46 changes: 43 additions & 3 deletions python/paddle/fluid/tests/unittests/test_set_value_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _get_answer(self):


# 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):
Expand Down Expand Up @@ -165,6 +165,26 @@ def set_dtype(self):
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):
Expand All @@ -185,7 +205,7 @@ def set_dtype(self):
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):
Expand Down Expand Up @@ -246,6 +266,26 @@ def set_dtype(self):
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):
Expand Down Expand Up @@ -451,7 +491,7 @@ def _dtype_error(self):
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):
Expand Down

1 comment on commit cf10e7a

@paddle-bot-old
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Congratulation! Your pull request passed all required CI. You could ask reviewer(s) to approve and merge. 🎉

Please sign in to comment.