Commit 85fb5761 authored by Robert Kimball's avatar Robert Kimball

fix generation of ParameterizedConstants that are copied directly to output

parent 886eb1ec
......@@ -20,9 +20,10 @@ using namespace descriptor;
PrimaryTensorView::PrimaryTensorView(const std::shared_ptr<const TensorViewType>& tensor_view_type,
const std::string& name,
bool is_output,
bool is_input)
bool is_input,
bool is_constant)
: TensorView(tensor_view_type)
, m_tensor(tensor_view_type->get_element_type(), this, name, is_output, is_input)
, m_tensor(tensor_view_type->get_element_type(), this, name, is_output, is_input, is_constant)
{
// Set the name in the parent TensorView.
// This can't be done until after the m_tensor is constructed.
......
......@@ -43,7 +43,8 @@ namespace ngraph
PrimaryTensorView(const std::shared_ptr<const TensorViewType>& tensor_view_type,
const std::string& name,
bool is_output,
bool is_input);
bool is_input,
bool is_constant);
virtual const Tensor& get_tensor() const override;
virtual Tensor& get_tensor() override;
......
......@@ -23,12 +23,14 @@ Tensor::Tensor(const element::Type& element_type,
PrimaryTensorView* primary_tensor_view,
const std::string& name,
bool is_output,
bool is_input)
bool is_input,
bool is_constant)
: m_element_type(element_type)
, m_primary_tensor_view(primary_tensor_view)
, m_is_output{is_output}
, m_is_input{is_input}
, m_is_persistent{false}
, m_is_constant{is_constant}
, m_name{name}
, m_next_view_id{0}
{
......
......@@ -47,7 +47,8 @@ private:
PrimaryTensorView* tensor_view,
const std::string& name,
bool is_output,
bool is_input);
bool is_input,
bool is_constant);
std::string get_next_view_name();
......@@ -55,6 +56,7 @@ public:
bool is_output() const { return m_is_output; }
bool is_input() const { return m_is_input; }
bool is_persistent() const { return m_is_persistent; }
bool is_constant() const { return m_is_constant; }
const std::string& get_name() const { return m_name; }
size_t size() const;
void set_pool_offset(size_t);
......@@ -68,6 +70,7 @@ protected:
bool m_is_output;
bool m_is_input;
bool m_is_persistent;
bool m_is_constant;
std::string m_name;
size_t m_next_view_id;
size_t m_size;
......
......@@ -70,7 +70,8 @@ void Node::set_value_type_checked(const shared_ptr<const ValueType>& value_type)
tvt,
ngraph::descriptor::Tensor::make_tensor_name(this, i),
is_output(),
is_parameter());
is_parameter(),
is_constant());
m_outputs.emplace_back(this, i, tensor_view_descriptor);
i++;
}
......@@ -124,6 +125,11 @@ void Node::set_is_output()
}
}
bool Node::is_constant() const
{
return false;
}
std::string Node::get_node_id() const
{
stringstream ss;
......
......@@ -89,6 +89,7 @@ namespace ngraph
bool is_parameter() const;
bool is_output() const;
void set_is_output();
virtual bool is_constant() const;
size_t get_instance_id() const { return m_instance_id; }
friend std::ostream& operator<<(std::ostream&, const Node&);
......
......@@ -40,6 +40,8 @@ namespace ngraph
{
set_value_type_checked(type);
}
virtual bool is_constant() const override { return true; }
};
/// \brief Class for constants whose element types are known at C++ compile-time.
......
......@@ -125,8 +125,7 @@ bool pass::Liveness::run_on_call_graph(list<shared_ptr<Node>>& ops)
bool pass::Liveness::is_temporary(const Tensor& tensor)
{
return tensor.is_persistent() == false && tensor.is_input() == false &&
tensor.is_output() == false;
// && tensor.is_constant() == false
tensor.is_output() == false && tensor.is_constant() == false;
// && tensor.is_compile_only() == false;
}
......
This diff is collapsed.
......@@ -103,6 +103,39 @@ namespace ngraph
std::string emit_vector(const TensorViewInfo&, const std::string& name = "");
std::string emit_array1d(const TensorViewInfo&, const std::string& name = "");
std::string emit_matrix(const TensorViewInfo&, const std::string& name = "");
template <typename T>
void EmitParameterizedConstant(const std::string& type,
const ngraph::Node* n,
const std::vector<T>& value,
const TensorViewInfo& tv)
{
TU << "// " << n->get_name() << " EmitParameterizedConstant_" << type << "\n";
if (tv.get_tensor().is_output())
{
// Special case where constant is stored directly in the output
for (size_t i = 0; i < value.size(); i++)
{
TU << tv.get_tensor().get_name() << "[" << i << "] = static_cast<"
<< type << ">(" << value[i] << ");\n";
}
}
else
{
TU << "// this should be const but eigen hates const :(\n";
TU << type << " " << tv.get_tensor().get_name() << "[] = {\n";
for (size_t i = 0; i < value.size(); i++)
{
if (i != 0)
{
TU << ",\n";
}
TU << " " << value[i];
}
TU << "\n};";
}
TU << "\n";
}
};
}
}
......
......@@ -25,7 +25,11 @@ using namespace std;
runtime::cpu::CPUTensorView::CPUTensorView(const ngraph::element::Type& element_type,
const Shape& shape)
: runtime::TensorView(std::make_shared<ngraph::descriptor::PrimaryTensorView>(
std::make_shared<ngraph::TensorViewType>(element_type, shape), "external", true, true))
std::make_shared<ngraph::TensorViewType>(element_type, shape),
"external",
true,
true,
false))
, m_allocated_buffer_pool(nullptr)
, m_aligned_buffer_pool(nullptr)
......
......@@ -41,7 +41,8 @@ namespace ngraph
std::make_shared<ngraph::TensorViewType>(ET::element_type(), shape),
"external",
true,
true))
true,
false))
{
m_descriptor->set_tensor_view_layout(
std::make_shared<ngraph::descriptor::layout::DenseTensorViewLayout>(
......
......@@ -1065,7 +1065,27 @@ TEST(${BACKEND_NAME}, subtract)
ASSERT_EQ((vector<float>{1, 2, 4, 8}), result->get_vector<float>());
}
TEST(${BACKEND_NAME}, scalar_constant)
TEST(${BACKEND_NAME}, scalar_parameterized_constant_bool)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::Bool>(shape, {true});
auto A = make_shared<op::ParameterizedConstant<element::Bool>>(shape, t);
auto rt = make_shared<TensorViewType>(element::Bool::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::Bool::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<char>{true}), result->get_vector<char>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_float)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::Float32>(shape, {-3.0f});
......@@ -1085,6 +1105,126 @@ TEST(${BACKEND_NAME}, scalar_constant)
ASSERT_EQ((vector<float>{-3.0f}), result->get_vector<float>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_int8)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::Int8>(shape, {-3});
auto A = make_shared<op::ParameterizedConstant<element::Int8>>(shape, t);
auto rt = make_shared<TensorViewType>(element::Int8::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::Int8::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<int8_t>{-3}), result->get_vector<int8_t>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_int32)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::Int32>(shape, {-3});
auto A = make_shared<op::ParameterizedConstant<element::Int32>>(shape, t);
auto rt = make_shared<TensorViewType>(element::Int32::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::Int32::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<int32_t>{-3}), result->get_vector<int32_t>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_int64)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::Int64>(shape, {-3});
auto A = make_shared<op::ParameterizedConstant<element::Int64>>(shape, t);
auto rt = make_shared<TensorViewType>(element::Int64::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::Int64::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<int64_t>{-3}), result->get_vector<int64_t>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_uint8)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::UInt8>(shape, {3});
auto A = make_shared<op::ParameterizedConstant<element::UInt8>>(shape, t);
auto rt = make_shared<TensorViewType>(element::UInt8::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::UInt8::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<uint8_t>{3}), result->get_vector<uint8_t>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_uint32)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::UInt32>(shape, {3});
auto A = make_shared<op::ParameterizedConstant<element::UInt32>>(shape, t);
auto rt = make_shared<TensorViewType>(element::UInt32::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::UInt32::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<uint32_t>{3}), result->get_vector<uint32_t>());
}
TEST(${BACKEND_NAME}, scalar_parameterized_constant_uint64)
{
auto shape = Shape{};
auto t = runtime::make_tensor<element::UInt64>(shape, {3});
auto A = make_shared<op::ParameterizedConstant<element::UInt64>>(shape, t);
auto rt = make_shared<TensorViewType>(element::UInt64::element_type(), shape);
auto f = make_shared<Function>(A, rt, op::Parameters{});
auto manager = runtime::Manager::get("${BACKEND_NAME}");
auto external = manager->compile(f);
auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external);
// Create some tensors for input/output
auto result = backend->make_primary_tensor_view(element::UInt64::element_type(), shape);
(*cf)({}, {result});
ASSERT_EQ((vector<uint64_t>{3}), result->get_vector<uint64_t>());
}
TEST(${BACKEND_NAME}, tensor_constant)
{
auto shape = Shape{2, 2, 2};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment