Commit 305dd5b7 authored by Jaikrishnan Menon's avatar Jaikrishnan Menon

CPU: Implement scalar-tensor and vector dot product

Also make Eigen format construction explicit
parent 4bc6f486
...@@ -44,7 +44,7 @@ static unordered_map<type_index, string> element_type_names = {{TI(ngraph::eleme ...@@ -44,7 +44,7 @@ static unordered_map<type_index, string> element_type_names = {{TI(ngraph::eleme
}; };
#define EIGEN_VECTOR_FORMAT(x) "{" + to_string(x) + "}" #define EIGEN_VECTOR_FORMAT(x) "fmt::V{" + to_string(x) + "}"
static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape, static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape,
const ngraph::Strides& strides) const ngraph::Strides& strides)
...@@ -54,7 +54,7 @@ static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape, ...@@ -54,7 +54,7 @@ static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape,
{ {
if (!i) if (!i)
{ {
I += "{" + to_string(shape[i]); I += "fmt::M{{" + to_string(shape[i]);
} }
else else
{ {
...@@ -73,7 +73,7 @@ static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape, ...@@ -73,7 +73,7 @@ static std::string EIGEN_MATRIX_FORMAT(const ngraph::Shape& shape,
I += ", " + to_string(strides[i]); I += ", " + to_string(strides[i]);
} }
} }
I += "}"; I += "}}";
return I; return I;
} }
...@@ -102,6 +102,60 @@ void Emitter::EMITTER_DECL(EmitAdd) ...@@ -102,6 +102,60 @@ void Emitter::EMITTER_DECL(EmitAdd)
void Emitter::EMITTER_DECL(EmitDot) void Emitter::EMITTER_DECL(EmitDot)
{ {
auto& arg_nodes = n->get_arguments();
assert(arg_nodes.size() == 2);
auto arg0_tensor_type =
dynamic_pointer_cast<const TensorViewType>(arg_nodes.at(0)->get_value_type());
assert(nullptr != arg0_tensor_type);
auto arg1_tensor_type =
dynamic_pointer_cast<const TensorViewType>(arg_nodes.at(1)->get_value_type());
assert(nullptr != arg1_tensor_type);
auto arg0_shape = arg0_tensor_type->get_shape();
auto arg1_shape = arg1_tensor_type->get_shape();
auto& arg0_element_type = arg0_tensor_type->get_element_type();
if (arg0_shape.empty() || arg1_shape.empty())
{
auto& first = (arg0_shape.empty() ? inputs[0] : inputs[1]);
auto& second = (arg0_shape.empty() ? inputs[1] : inputs[0]);
TU += " {\n";
" auto arg1 = call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] +
">(" + to_string(second.get_index()) + ");\n"
" auto out = call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] +
">(" + to_string(outputs[0].get_index()) + ");\n"
" EigenVector<" + element_type_names[TI(arg0_element_type)] +
">(out, " EIGEN_VECTOR_FORMAT(outputs[0].get_layout<DenseTensorViewLayout>()->get_size()) ") = "
"call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] +
">(" + to_string(first.get_index()) + ")[0] * EigenVector<" +
element_type_names[TI(arg0_element_type)] +
">(arg1, " EIGEN_VECTOR_FORMAT(second.get_layout<DenseTensorViewLayout>()->get_size()) ");\n"
" }\n";
}
else if ((arg0_shape.size() == 1) && (arg1_shape.size() == 1))
{
TU += " {\n"
" auto arg0 = call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] + ">(" +
to_string(inputs[0].get_index()) + ");\n"
" auto arg1 = call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] + ">(" +
to_string(inputs[1].get_index()) + ");\n"
" auto out = call_frame->get_tensor_view_data<" + element_type_names[TI(arg0_element_type)] + ">(" +
to_string(outputs[0].get_index()) + ");\n"
" EigenVector<" + element_type_names[TI(arg0_element_type)] + ">(out, "
EIGEN_VECTOR_FORMAT(outputs[0].get_layout<DenseTensorViewLayout>()->get_size()) ") << \n"
" EigenVector<" + element_type_names[TI(arg0_element_type)] + ">(arg0, "
EIGEN_VECTOR_FORMAT(inputs[0].get_layout<DenseTensorViewLayout>()->get_size()) ").dot("
"EigenVector<" + element_type_names[TI(arg0_element_type)] + ">(arg1, "
EIGEN_VECTOR_FORMAT(inputs[1].get_layout<DenseTensorViewLayout>()->get_size()) "));\n"
" }\n";
}
else
{
throw ngraph_error("Dot product for given tensors unimplemented");
}
} }
void Emitter::EMITTER_DECL(EmitMultiply) void Emitter::EMITTER_DECL(EmitMultiply)
...@@ -210,8 +264,8 @@ void Emitter::EMITTER_DECL(EmitConcat) ...@@ -210,8 +264,8 @@ void Emitter::EMITTER_DECL(EmitConcat)
TU += " {\n" TU += " {\n"
" auto out = call_frame->get_tensor_view_data<" + element_type_names[TI(result_element_type)] + " auto out = call_frame->get_tensor_view_data<" + element_type_names[TI(result_element_type)] +
">(" + to_string(outputs[0].get_index()) + ");\n" ">(" + to_string(outputs[0].get_index()) + ");\n"
" EigenMatrix<" + element_type_names[TI(result_element_type)] + "> out_matrix(out, {" + " EigenMatrix<" + element_type_names[TI(result_element_type)] + "> out_matrix(out, " +
EIGEN_MATRIX_FORMAT(out_layout->get_shape(), out_layout->get_strides()) + "});\n"; EIGEN_MATRIX_FORMAT(out_layout->get_shape(), out_layout->get_strides()) + ");\n";
size_t concat_pos[2]{0, 0}; size_t concat_pos[2]{0, 0};
for (size_t i = 0; i < inputs.size(); i++) for (size_t i = 0; i < inputs.size(); i++)
...@@ -224,8 +278,8 @@ void Emitter::EMITTER_DECL(EmitConcat) ...@@ -224,8 +278,8 @@ void Emitter::EMITTER_DECL(EmitConcat)
to_string(arg_shape.at(1)) + ") << " to_string(arg_shape.at(1)) + ") << "
"EigenMatrix<" + element_type_names[TI(result_element_type)] + ">(call_frame->" "EigenMatrix<" + element_type_names[TI(result_element_type)] + ">(call_frame->"
"get_tensor_view_data<" + element_type_names[TI(result_element_type)] + ">(" + "get_tensor_view_data<" + element_type_names[TI(result_element_type)] + ">(" +
to_string(inputs[i].get_index()) + "), {" + to_string(inputs[i].get_index()) + "), " +
EIGEN_MATRIX_FORMAT(arg_layout->get_shape(), arg_layout->get_strides()) + "});\n"; EIGEN_MATRIX_FORMAT(arg_layout->get_shape(), arg_layout->get_strides()) + ");\n";
concat_pos[axis] += arg_shape.at(axis); concat_pos[axis] += arg_shape.at(axis);
} }
......
...@@ -442,8 +442,7 @@ TEST(cpu, equal) ...@@ -442,8 +442,7 @@ TEST(cpu, equal)
ASSERT_EQ((vector<char>{1, 1, 0, 0, 0, 1, 1, 0}), result->get_vector()); ASSERT_EQ((vector<char>{1, 1, 0, 0, 0, 1, 1, 0}), result->get_vector());
} }
/* TEST(cpu, dot_0_0)
TEST(execute, dot_0_0)
{ {
auto shape = Shape{0}; auto shape = Shape{0};
auto A = make_shared<op::Parameter>(element::Float32::element_type(), shape); auto A = make_shared<op::Parameter>(element::Float32::element_type(), shape);
...@@ -452,7 +451,7 @@ TEST(execute, dot_0_0) ...@@ -452,7 +451,7 @@ TEST(execute, dot_0_0)
auto rt = make_shared<TensorViewType>(element::Float32::element_type(), Shape{}); auto rt = make_shared<TensorViewType>(element::Float32::element_type(), Shape{});
auto f = make_shared<Function>(make_shared<op::Dot>(A, B), rt, op::Parameters{A, B}); auto f = make_shared<Function>(make_shared<op::Dot>(A, B), rt, op::Parameters{A, B});
auto manager = runtime::Manager::get("NGVM"); auto manager = runtime::Manager::get("CPU");
auto external = manager->compile(f); auto external = manager->compile(f);
auto backend = manager->allocate_backend(); auto backend = manager->allocate_backend();
auto cf = backend->make_call_frame(external); auto cf = backend->make_call_frame(external);
...@@ -468,6 +467,7 @@ TEST(execute, dot_0_0) ...@@ -468,6 +467,7 @@ TEST(execute, dot_0_0)
ASSERT_EQ((vector<float>{0}), result->get_vector()); ASSERT_EQ((vector<float>{0}), result->get_vector());
} }
/*
TEST(execute, dot_matrix_2x0_0x2) TEST(execute, dot_matrix_2x0_0x2)
{ {
auto shape_a = Shape{2, 0}; auto shape_a = Shape{2, 0};
......
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