1 /* 2 Copyright (c) 2020-2021 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #if __INTEL_COMPILER && _MSC_VER 18 #pragma warning(disable : 2586) // decorated name length exceeded, name was truncated 19 #endif 20 21 #define CONFORMANCE_MULTIFUNCTION_NODE 22 23 #include "conformance_flowgraph.h" 24 25 //! \file conformance_multifunction_node.cpp 26 //! \brief Test for [flow_graph.function_node] specification 27 28 using input_msg = conformance::message</*default_ctor*/true, /*copy_ctor*/true, /*copy_assign*/false>; 29 using output_msg = conformance::message</*default_ctor*/false, /*copy_ctor*/false, /*copy_assign*/false>; 30 31 /* 32 Test function_node is a graph_node, receiver<Input>, and sender<Output> 33 */ 34 template<typename I, typename O> 35 void test_inheritance(){ 36 using namespace oneapi::tbb::flow; 37 38 CHECK_MESSAGE((std::is_base_of<graph_node, multifunction_node<I, O>>::value), "multifunction_node should be derived from graph_node"); 39 CHECK_MESSAGE((std::is_base_of<receiver<I>, multifunction_node<I, O>>::value), "multifunction_node should be derived from receiver<Input>"); 40 } 41 42 //! Test node reject the incoming message if the concurrency limit achieved. 43 //! \brief \ref interface 44 TEST_CASE("multifunction_node with rejecting policy"){ 45 conformance::test_rejecting<oneapi::tbb::flow::multifunction_node<int, std::tuple<int>, oneapi::tbb::flow::rejecting>>(); 46 } 47 48 //! Test nodes for execution with priority in single-threaded configuration 49 //! \brief \ref interface 50 TEST_CASE("multifunction_node priority"){ 51 conformance::test_priority<oneapi::tbb::flow::multifunction_node<input_msg, std::tuple<int>>, input_msg>(oneapi::tbb::flow::unlimited); 52 } 53 54 //! Test function_node has a user-settable concurrency limit. It can be set to one of predefined values. 55 //! The user can also provide a value of type std::size_t to limit concurrency. 56 //! Test that not more than limited threads works in parallel. 57 //! \brief \ref interface 58 TEST_CASE("multifunction_node concurrency"){ 59 conformance::test_concurrency<oneapi::tbb::flow::multifunction_node<int, std::tuple<int>>>(); 60 } 61 62 //! Test all node constructors 63 //! \brief \ref interface 64 TEST_CASE("multifunction_node constructors"){ 65 using namespace oneapi::tbb::flow; 66 graph g; 67 68 conformance::counting_functor<int> fun; 69 70 multifunction_node<int, std::tuple<int>> fn1(g, unlimited, fun); 71 multifunction_node<int, std::tuple<int>> fn2(g, unlimited, fun, oneapi::tbb::flow::node_priority_t(1)); 72 73 multifunction_node<int, std::tuple<int>, lightweight> lw_node1(g, serial, fun, lightweight()); 74 multifunction_node<int, std::tuple<int>, lightweight> lw_node2(g, serial, fun, lightweight(), oneapi::tbb::flow::node_priority_t(1)); 75 } 76 77 //! The node that is constructed has a reference to the same graph object as src, has a copy of the initial body used by src, and has the same concurrency threshold as src. 78 //! The predecessors and successors of src are not copied. 79 //! \brief \ref interface 80 TEST_CASE("multifunction_node copy constructor"){ 81 conformance::test_copy_ctor<oneapi::tbb::flow::multifunction_node<int, std::tuple<int>>>(); 82 } 83 84 //! Test node not buffered unsuccessful message, and try_get after rejection should not succeed. 85 //! \brief \ref requirement 86 TEST_CASE("multifunction_node buffering"){ 87 conformance::dummy_functor<int> fun; 88 conformance::test_buffering<oneapi::tbb::flow::multifunction_node<input_msg, std::tuple<int>, 89 oneapi::tbb::flow::rejecting>, input_msg>(oneapi::tbb::flow::unlimited, fun); 90 } 91 92 //! Test multifunction_node broadcasting 93 //! \brief \ref requirement 94 TEST_CASE("multifunction_node broadcast"){ 95 conformance::counting_functor<int> fun(conformance::expected); 96 conformance::test_forwarding<oneapi::tbb::flow::multifunction_node<input_msg, std::tuple<int>>, input_msg, int>(1, oneapi::tbb::flow::unlimited, fun); 97 } 98 99 //! Test the body object passed to a node is copied 100 //! \brief \ref interface 101 TEST_CASE("multifunction_node copy body"){ 102 conformance::test_copy_body_function<oneapi::tbb::flow::multifunction_node<int, std::tuple<int>>, conformance::copy_counting_object<int>>(oneapi::tbb::flow::unlimited); 103 } 104 105 //! Test execution of node body 106 //! Test node can do try_put call 107 //! \brief \ref interface \ref requirement 108 TEST_CASE("multifunction_node body") { 109 conformance::test_body_exec<oneapi::tbb::flow::multifunction_node<input_msg, std::tuple<output_msg>, oneapi::tbb::flow::rejecting>, input_msg, output_msg>(oneapi::tbb::flow::unlimited); 110 } 111 112 //! Test multifunction_node output_ports() returns a tuple of output ports. 113 //! \brief \ref interface \ref requirement 114 TEST_CASE("multifunction_node output_ports") { 115 using namespace oneapi::tbb::flow; 116 graph g; 117 conformance::dummy_functor<int> fun; 118 oneapi::tbb::flow::multifunction_node <int, std::tuple<int>> node(g, unlimited, fun); 119 120 CHECK_MESSAGE((std::is_same<oneapi::tbb::flow::multifunction_node<int, std::tuple<int>>::output_ports_type&, 121 decltype(node.output_ports())>::value), "multifunction_node output_ports should returns a tuple of output ports"); 122 } 123 124 //! Test inheritance relations 125 //! \brief \ref interface 126 TEST_CASE("multifunction_node superclasses"){ 127 test_inheritance<int, std::tuple<int>>(); 128 test_inheritance<void*, std::tuple<float>>(); 129 test_inheritance<input_msg, std::tuple<output_msg>>(); 130 } 131 132 //! Test node Input class meet the DefaultConstructible and CopyConstructible requirements and Output class meet the CopyConstructible requirements. 133 //! \brief \ref interface \ref requirement 134 TEST_CASE("Test function_node Output and Input class") { 135 using Body = conformance::copy_counting_object<int>; 136 conformance::test_output_input_class<oneapi::tbb::flow::multifunction_node<Body, std::tuple<Body>>, Body>(); 137 } 138