151c0b2f7Stbbdev /* 2b15aabb3Stbbdev Copyright (c) 2020-2021 Intel Corporation 351c0b2f7Stbbdev 451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License"); 551c0b2f7Stbbdev you may not use this file except in compliance with the License. 651c0b2f7Stbbdev You may obtain a copy of the License at 751c0b2f7Stbbdev 851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0 951c0b2f7Stbbdev 1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software 1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS, 1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1351c0b2f7Stbbdev See the License for the specific language governing permissions and 1451c0b2f7Stbbdev limitations under the License. 1551c0b2f7Stbbdev */ 1651c0b2f7Stbbdev 17b15aabb3Stbbdev #if __INTEL_COMPILER && _MSC_VER 18b15aabb3Stbbdev #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated 19b15aabb3Stbbdev #endif 2051c0b2f7Stbbdev 21*de0109beSIlya Mishin #include "conformance_flowgraph.h" 2251c0b2f7Stbbdev 2351c0b2f7Stbbdev //! \file conformance_indexer_node.cpp 2451c0b2f7Stbbdev //! \brief Test for [flow_graph.indexer_node] specification 2551c0b2f7Stbbdev 26*de0109beSIlya Mishin using input_msg = conformance::message</*default_ctor*/false, /*copy_ctor*/true, /*copy_assign*/false>; 27*de0109beSIlya Mishin using my_indexer_type = oneapi::tbb::flow::indexer_node<int, float, input_msg>; 28*de0109beSIlya Mishin using my_output_type = my_indexer_type::output_type; 2951c0b2f7Stbbdev 30*de0109beSIlya Mishin //! Test node broadcast messages to successors 3151c0b2f7Stbbdev //! \brief \ref requirement 3251c0b2f7Stbbdev TEST_CASE("indexer_node broadcasts"){ 33*de0109beSIlya Mishin oneapi::tbb::flow::graph g; 34*de0109beSIlya Mishin 35*de0109beSIlya Mishin my_indexer_type testing_node(g); 36*de0109beSIlya Mishin std::vector<conformance::test_push_receiver<my_output_type>*> receiver_nodes; 37*de0109beSIlya Mishin 38*de0109beSIlya Mishin for(std::size_t i = 0; i < 3; ++i) { 39*de0109beSIlya Mishin receiver_nodes.emplace_back(new conformance::test_push_receiver<my_output_type>(g)); 40*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(testing_node, *receiver_nodes.back()); 41*de0109beSIlya Mishin } 42*de0109beSIlya Mishin 43*de0109beSIlya Mishin oneapi::tbb::flow::input_port<0>(testing_node).try_put(6); 44*de0109beSIlya Mishin oneapi::tbb::flow::input_port<1>(testing_node).try_put(1.5); 45*de0109beSIlya Mishin oneapi::tbb::flow::input_port<2>(testing_node).try_put(input_msg(1)); 46*de0109beSIlya Mishin g.wait_for_all(); 47*de0109beSIlya Mishin 48*de0109beSIlya Mishin for(auto receiver: receiver_nodes) { 49*de0109beSIlya Mishin auto values = conformance::get_values(*receiver); 50*de0109beSIlya Mishin CHECK_MESSAGE((values.size() == 3), std::string("Descendant of the node must receive 3 messages.")); 51*de0109beSIlya Mishin for(auto& value : values){ 52*de0109beSIlya Mishin if(value.is_a<int>()){ 53*de0109beSIlya Mishin CHECK_MESSAGE((value.cast_to<int>() == 6), "Value passed is the actual one received."); 54*de0109beSIlya Mishin } else if(value.is_a<float>()){ 55*de0109beSIlya Mishin CHECK_MESSAGE((value.cast_to<float>() == 1.5), "Value passed is the actual one received."); 56*de0109beSIlya Mishin } else { 57*de0109beSIlya Mishin CHECK_MESSAGE((value.cast_to<input_msg>() == 1), "Value passed is the actual one received."); 58*de0109beSIlya Mishin } 59*de0109beSIlya Mishin } 60*de0109beSIlya Mishin delete receiver; 61*de0109beSIlya Mishin } 6251c0b2f7Stbbdev } 6351c0b2f7Stbbdev 6451c0b2f7Stbbdev //! Test inheritance relations 6551c0b2f7Stbbdev //! \brief \ref interface 6651c0b2f7Stbbdev TEST_CASE("indexer_node superclasses"){ 67*de0109beSIlya Mishin CHECK_MESSAGE((std::is_base_of<oneapi::tbb::flow::graph_node, my_indexer_type>::value), "indexer_node should be derived from graph_node"); 6851c0b2f7Stbbdev } 6951c0b2f7Stbbdev 70*de0109beSIlya Mishin //! Test node not buffered unsuccessful message, and try_get after rejection should not succeed. 7151c0b2f7Stbbdev //! \brief \ref requirement 72*de0109beSIlya Mishin TEST_CASE("indexer_node buffering") { 73*de0109beSIlya Mishin oneapi::tbb::flow::graph g; 7451c0b2f7Stbbdev 75*de0109beSIlya Mishin my_indexer_type testing_node(g); 7651c0b2f7Stbbdev 77*de0109beSIlya Mishin oneapi::tbb::flow::limiter_node<my_output_type> rejecter(g,0); 78*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(testing_node, rejecter); 7951c0b2f7Stbbdev 80*de0109beSIlya Mishin oneapi::tbb::flow::input_port<0>(testing_node).try_put(6); 81*de0109beSIlya Mishin oneapi::tbb::flow::input_port<1>(testing_node).try_put(1.5); 82*de0109beSIlya Mishin oneapi::tbb::flow::input_port<2>(testing_node).try_put(input_msg(1)); 8351c0b2f7Stbbdev 84*de0109beSIlya Mishin my_output_type tmp; 85*de0109beSIlya Mishin CHECK_MESSAGE((testing_node.try_get(tmp) == false), "Value should be discarded after rejection"); 8651c0b2f7Stbbdev g.wait_for_all(); 8751c0b2f7Stbbdev } 8851c0b2f7Stbbdev 89*de0109beSIlya Mishin //! Test indexer behaviour 9051c0b2f7Stbbdev //! \brief \ref requirement 91*de0109beSIlya Mishin TEST_CASE("indexer_node behaviour") { 92*de0109beSIlya Mishin oneapi::tbb::flow::graph g; 93*de0109beSIlya Mishin oneapi::tbb::flow::function_node<int, int> f1( g, oneapi::tbb::flow::unlimited, __anon3412adbc0102(const int &i) 9451c0b2f7Stbbdev [](const int &i) { return 2*i; } ); 95*de0109beSIlya Mishin oneapi::tbb::flow::function_node<float, float> f2( g, oneapi::tbb::flow::unlimited, __anon3412adbc0202(const float &f) 9651c0b2f7Stbbdev [](const float &f) { return f/2; } ); 97*de0109beSIlya Mishin oneapi::tbb::flow::continue_node<input_msg> c1( g, __anon3412adbc0302(oneapi::tbb::flow::continue_msg) 98*de0109beSIlya Mishin [](oneapi::tbb::flow::continue_msg) { return input_msg(5); } ); 9951c0b2f7Stbbdev 100*de0109beSIlya Mishin my_indexer_type testing_node(g); 10151c0b2f7Stbbdev 102*de0109beSIlya Mishin oneapi::tbb::flow::function_node<my_output_type> 103*de0109beSIlya Mishin f3( g, oneapi::tbb::flow::unlimited, __anon3412adbc0402( const my_output_type &v ) 104*de0109beSIlya Mishin []( const my_output_type &v ) { 10551c0b2f7Stbbdev if (v.tag() == 0) { 106*de0109beSIlya Mishin CHECK_MESSAGE((v.is_a<int>()), "Expected to int" ); 107*de0109beSIlya Mishin CHECK_MESSAGE((oneapi::tbb::flow::cast_to<int>(v) == 6), "Expected to receive 6" ); 108*de0109beSIlya Mishin } else if (v.tag() == 1) { 109*de0109beSIlya Mishin CHECK_MESSAGE((v.is_a<float>()), "Expected to float" ); 110*de0109beSIlya Mishin CHECK_MESSAGE((oneapi::tbb::flow::cast_to<float>(v) == 1.5), "Expected to receive 1.5" ); 11151c0b2f7Stbbdev } else { 112*de0109beSIlya Mishin CHECK_MESSAGE((v.is_a<input_msg>()), "Expected to float" ); 113*de0109beSIlya Mishin CHECK_MESSAGE((oneapi::tbb::flow::cast_to<input_msg>(v) == 5), "Expected to receive input_msg(5)" ); 11451c0b2f7Stbbdev } 11551c0b2f7Stbbdev } 11651c0b2f7Stbbdev ); 117*de0109beSIlya Mishin 118*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(f1, oneapi::tbb::flow::input_port<0>(testing_node)); 119*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(f2, oneapi::tbb::flow::input_port<1>(testing_node)); 120*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(c1, oneapi::tbb::flow::input_port<2>(testing_node)); 121*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(testing_node, f3); 12251c0b2f7Stbbdev 12351c0b2f7Stbbdev f1.try_put(3); 12451c0b2f7Stbbdev f2.try_put(3); 125*de0109beSIlya Mishin c1.try_put(oneapi::tbb::flow::continue_msg()); 12651c0b2f7Stbbdev g.wait_for_all(); 12751c0b2f7Stbbdev } 128*de0109beSIlya Mishin 129*de0109beSIlya Mishin //! The node that is constructed has a reference to the same graph object as src. 130*de0109beSIlya Mishin //! The list of predecessors, messages in the input ports, and successors are not copied. 131*de0109beSIlya Mishin //! \brief \ref interface 132*de0109beSIlya Mishin TEST_CASE("indexer_node copy constructor"){ 133*de0109beSIlya Mishin oneapi::tbb::flow::graph g; 134*de0109beSIlya Mishin oneapi::tbb::flow::continue_node<int> node0( g, __anon3412adbc0502(oneapi::tbb::flow::continue_msg) 135*de0109beSIlya Mishin [](oneapi::tbb::flow::continue_msg) { return 1; } ); 136*de0109beSIlya Mishin 137*de0109beSIlya Mishin my_indexer_type node1(g); 138*de0109beSIlya Mishin conformance::test_push_receiver<my_output_type> node2(g); 139*de0109beSIlya Mishin conformance::test_push_receiver<my_output_type> node3(g); 140*de0109beSIlya Mishin 141*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(node0, oneapi::tbb::flow::input_port<0>(node1)); 142*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(node1, node2); 143*de0109beSIlya Mishin 144*de0109beSIlya Mishin my_indexer_type node_copy(node1); 145*de0109beSIlya Mishin 146*de0109beSIlya Mishin oneapi::tbb::flow::make_edge(node_copy, node3); 147*de0109beSIlya Mishin 148*de0109beSIlya Mishin oneapi::tbb::flow::input_port<0>(node_copy).try_put(1); 149*de0109beSIlya Mishin g.wait_for_all(); 150*de0109beSIlya Mishin 151*de0109beSIlya Mishin CHECK_MESSAGE((conformance::get_values(node2).size() == 0 && conformance::get_values(node3).size() == 1), "Copied node doesn`t copy successor"); 152*de0109beSIlya Mishin 153*de0109beSIlya Mishin node0.try_put(oneapi::tbb::flow::continue_msg()); 154*de0109beSIlya Mishin g.wait_for_all(); 155*de0109beSIlya Mishin 156*de0109beSIlya Mishin CHECK_MESSAGE((conformance::get_values(node2).size() == 1 && conformance::get_values(node3).size() == 0), "Copied node doesn`t copy predecessor"); 157*de0109beSIlya Mishin } 158*de0109beSIlya Mishin 159*de0109beSIlya Mishin //! Test indexer_node output_type 160*de0109beSIlya Mishin //! \brief \ref interface \ref requirement 161*de0109beSIlya Mishin TEST_CASE("indexer_node output_type") { 162*de0109beSIlya Mishin CHECK_MESSAGE((conformance::check_output_type<my_output_type, oneapi::tbb::flow::tagged_msg<size_t, int, float, input_msg>>()), "indexer_node output_type should returns a tagged_msg"); 163*de0109beSIlya Mishin } 164