/* * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "NodeExecution.h" #include "locomotiv/NodeData.h" #include "NodeDataImpl.h" #include "NodeDomain.h" #include #include #include #include #include #include using nncc::core::ADT::tensor::Shape; using nncc::core::ADT::tensor::LexicalLayout; using nncc::core::ADT::tensor::make_buffer; using nncc::core::ADT::tensor::IndexEnumerator; /* test case generated from the following: x = tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], shape=[1, 3, 3, 2], dtype=tf.float32) y = tf.constant([18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], shape=[1, 3, 3, 2], dtype=tf.float32) out = tf.math.maximum(x, y) with tf.Session() as sess: print(sess.run(out)) */ TEST(NodeExecution_EltwiseMax, f32) { float x_val[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; float y_val[] = {18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; float out_val[] = {18, 17, 16, 15, 14, 13, 12, 11, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18}; // make EltwiseMax(Pull, Pull) auto g = loco::make_graph(); Shape input_shape{1, 3, 3, 2}; // NHWC auto inp_lhs = g->nodes()->create(); { inp_lhs->dtype(loco::DataType::FLOAT32); inp_lhs->shape({1, 3, 3, 2}); } auto inp_rhs = g->nodes()->create(); { inp_rhs->dtype(loco::DataType::FLOAT32); inp_rhs->shape({1, 3, 3, 2}); } auto eltwise_max = g->nodes()->create(); { eltwise_max->lhs(inp_lhs); eltwise_max->rhs(inp_rhs); } // Make and assign data to two pull nodes auto inp_lhs_buf = make_buffer(input_shape); { int n = 0; for (IndexEnumerator e{inp_lhs_buf.shape()}; e.valid(); e.advance()) { inp_lhs_buf.at(e.current()) = x_val[n++]; } } auto inp_rhs_buf = make_buffer(input_shape); { int n = 0; for (IndexEnumerator e{inp_rhs_buf.shape()}; e.valid(); e.advance()) { inp_rhs_buf.at(e.current()) = y_val[n++]; } } auto inp_lhs_data = locomotiv::make_data(inp_lhs_buf); locomotiv::annot_data(inp_lhs, std::move(inp_lhs_data)); locomotiv::annot_domain(inp_lhs, loco::Domain::Tensor); auto inp_rhs_data = locomotiv::make_data(inp_rhs_buf); locomotiv::annot_data(inp_rhs, std::move(inp_rhs_data)); locomotiv::annot_domain(inp_rhs, loco::Domain::Tensor); // run the network locomotiv::NodeExecution::get().run(eltwise_max); // get result auto eltwise_max_data = locomotiv::annot_data(eltwise_max); // comparing the result ASSERT_NE(eltwise_max_data, nullptr); ASSERT_EQ(loco::DataType::FLOAT32, eltwise_max_data->dtype()); ASSERT_EQ(Shape({1, 3, 3, 2}), *(eltwise_max_data->shape())); uint32_t n = 0; for (IndexEnumerator e{*(eltwise_max_data->shape())}; e.valid(); e.advance()) { ASSERT_FLOAT_EQ(out_val[n++], eltwise_max_data->as_f32_bufptr()->at(e.current())); } ASSERT_EQ(loco::Domain::Tensor, locomotiv::annot_domain(eltwise_max)); }