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 20b15aabb3Stbbdev 2151c0b2f7Stbbdev #include "conformance_flowgraph.h" 2251c0b2f7Stbbdev 23*de0109beSIlya Mishin using input_msg = conformance::message</*default_ctor*/true, /*copy_ctor*/true, /*copy_assign*/false>; 24*de0109beSIlya Mishin using output_msg = conformance::message</*default_ctor*/false, /*copy_ctor*/true, /*copy_assign*/false>; 25*de0109beSIlya Mishin 2651c0b2f7Stbbdev //! \file conformance_function_node.cpp 2751c0b2f7Stbbdev //! \brief Test for [flow_graph.function_node] specification 2851c0b2f7Stbbdev 2951c0b2f7Stbbdev /* 30*de0109beSIlya Mishin Test node deduction guides 3151c0b2f7Stbbdev */ 3251c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 33*de0109beSIlya Mishin 34*de0109beSIlya Mishin int function_body_f(const int&) { return 1; } 35*de0109beSIlya Mishin 36*de0109beSIlya Mishin template <typename Body> 37*de0109beSIlya Mishin void test_deduction_guides_common(Body body) { 38*de0109beSIlya Mishin using namespace tbb::flow; 3951c0b2f7Stbbdev graph g; 4051c0b2f7Stbbdev 4151c0b2f7Stbbdev function_node f1(g, unlimited, body); 42*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f1), function_node<int, int>>); 43*de0109beSIlya Mishin 44*de0109beSIlya Mishin function_node f2(g, unlimited, body, rejecting()); 45*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f2), function_node<int, int, rejecting>>); 46*de0109beSIlya Mishin 47*de0109beSIlya Mishin function_node f3(g, unlimited, body, node_priority_t(5)); 48*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f3), function_node<int, int>>); 49*de0109beSIlya Mishin 50*de0109beSIlya Mishin function_node f4(g, unlimited, body, rejecting(), node_priority_t(5)); 51*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f4), function_node<int, int, rejecting>>); 52*de0109beSIlya Mishin 53*de0109beSIlya Mishin #if __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 54*de0109beSIlya Mishin function_node f5(follows(f2), unlimited, body); 55*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f5), function_node<int, int>>); 56*de0109beSIlya Mishin 57*de0109beSIlya Mishin function_node f6(follows(f5), unlimited, body, rejecting()); 58*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f6), function_node<int, int, rejecting>>); 59*de0109beSIlya Mishin 60*de0109beSIlya Mishin function_node f7(follows(f6), unlimited, body, node_priority_t(5)); 61*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f7), function_node<int, int>>); 62*de0109beSIlya Mishin 63*de0109beSIlya Mishin function_node f8(follows(f7), unlimited, body, rejecting(), node_priority_t(5)); 64*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f8), function_node<int, int, rejecting>>); 65*de0109beSIlya Mishin #endif // __TBB_PREVIEW_FLOW_GRAPH_NODE_SET 66*de0109beSIlya Mishin 67*de0109beSIlya Mishin function_node f9(f1); 68*de0109beSIlya Mishin static_assert(std::is_same_v<decltype(f9), function_node<int, int>>); 6951c0b2f7Stbbdev } 70*de0109beSIlya Mishin 71*de0109beSIlya Mishin void test_deduction_guides() { 72*de0109beSIlya Mishin test_deduction_guides_common([](const int&)->int { return 1; }); 73*de0109beSIlya Mishin test_deduction_guides_common([](const int&) mutable ->int { return 1; }); 74*de0109beSIlya Mishin test_deduction_guides_common(function_body_f); 75*de0109beSIlya Mishin } 76*de0109beSIlya Mishin 7751c0b2f7Stbbdev #endif 7851c0b2f7Stbbdev 79*de0109beSIlya Mishin //! Test calling function body 80*de0109beSIlya Mishin //! \brief \ref interface \ref requirement 81*de0109beSIlya Mishin TEST_CASE("Test function_node body") { 82*de0109beSIlya Mishin conformance::test_body_exec<oneapi::tbb::flow::function_node<input_msg, output_msg>, input_msg, output_msg>(oneapi::tbb::flow::unlimited); 8351c0b2f7Stbbdev } 8451c0b2f7Stbbdev 85*de0109beSIlya Mishin //! Test function_node constructors 86*de0109beSIlya Mishin //! \brief \ref requirement 87*de0109beSIlya Mishin TEST_CASE("function_node constructors"){ 8849e08aacStbbdev using namespace oneapi::tbb::flow; 8951c0b2f7Stbbdev graph g; 9051c0b2f7Stbbdev 91*de0109beSIlya Mishin conformance::counting_functor<int> fun; 9251c0b2f7Stbbdev 93*de0109beSIlya Mishin function_node<int, int> fn1(g, unlimited, fun); 94*de0109beSIlya Mishin function_node<int, int> fn2(g, unlimited, fun, oneapi::tbb::flow::node_priority_t(1)); 95*de0109beSIlya Mishin 96*de0109beSIlya Mishin function_node<int, int, lightweight> lw_node1(g, serial, fun, lightweight()); 97*de0109beSIlya Mishin function_node<int, int, lightweight> lw_node2(g, serial, fun, lightweight(), oneapi::tbb::flow::node_priority_t(1)); 9851c0b2f7Stbbdev } 9951c0b2f7Stbbdev 100*de0109beSIlya Mishin //! 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. 101*de0109beSIlya Mishin //! The predecessors and successors of src are not copied. 102*de0109beSIlya Mishin //! \brief \ref requirement 103*de0109beSIlya Mishin TEST_CASE("function_node copy constructor"){ 104*de0109beSIlya Mishin conformance::test_copy_ctor<oneapi::tbb::flow::function_node<int, int>>(); 10551c0b2f7Stbbdev } 10651c0b2f7Stbbdev 107*de0109beSIlya Mishin //! Test node reject the incoming message if the concurrency limit achieved. 10851c0b2f7Stbbdev //! \brief \ref interface 10951c0b2f7Stbbdev TEST_CASE("function_node with rejecting policy"){ 110*de0109beSIlya Mishin conformance::test_rejecting<oneapi::tbb::flow::function_node<int, int, oneapi::tbb::flow::rejecting>>(); 11151c0b2f7Stbbdev } 11251c0b2f7Stbbdev 11351c0b2f7Stbbdev //! Test body copying and copy_body logic 114*de0109beSIlya Mishin //! Test the body object passed to a node is copied 11551c0b2f7Stbbdev //! \brief \ref interface 11651c0b2f7Stbbdev TEST_CASE("function_node and body copying"){ 117*de0109beSIlya Mishin conformance::test_copy_body_function<oneapi::tbb::flow::function_node<int, int>, conformance::copy_counting_object<int>>(oneapi::tbb::flow::unlimited); 11851c0b2f7Stbbdev } 11951c0b2f7Stbbdev 120*de0109beSIlya Mishin //! Test function_node is a graph_node, receiver<Input>, and sender<Output> 12151c0b2f7Stbbdev //! \brief \ref interface 12251c0b2f7Stbbdev TEST_CASE("function_node superclasses"){ 123*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::function_node<int, int>, int, int>(); 124*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::function_node<void*, float>, void*, float>(); 125*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::function_node<input_msg, output_msg>, input_msg, output_msg>(); 12651c0b2f7Stbbdev } 12751c0b2f7Stbbdev 128*de0109beSIlya Mishin //! Test node not buffered unsuccessful message, and try_get after rejection should not succeed. 12951c0b2f7Stbbdev //! \brief \ref requirement 13051c0b2f7Stbbdev TEST_CASE("function_node buffering"){ 131*de0109beSIlya Mishin conformance::dummy_functor<int> fun; 132*de0109beSIlya Mishin conformance::test_buffering<oneapi::tbb::flow::function_node<input_msg, int, oneapi::tbb::flow::rejecting>, input_msg>(oneapi::tbb::flow::unlimited, fun); 133*de0109beSIlya Mishin conformance::test_buffering<oneapi::tbb::flow::function_node<input_msg, int, oneapi::tbb::flow::queueing>, input_msg>(oneapi::tbb::flow::unlimited, fun); 13451c0b2f7Stbbdev } 13551c0b2f7Stbbdev 136*de0109beSIlya Mishin //! Test node broadcast messages to successors 13751c0b2f7Stbbdev //! \brief \ref requirement 13851c0b2f7Stbbdev TEST_CASE("function_node broadcast"){ 139*de0109beSIlya Mishin conformance::counting_functor<int> fun(conformance::expected); 140*de0109beSIlya Mishin conformance::test_forwarding<oneapi::tbb::flow::function_node<input_msg, int>, input_msg, int>(1, oneapi::tbb::flow::unlimited, fun); 14151c0b2f7Stbbdev } 14251c0b2f7Stbbdev 14351c0b2f7Stbbdev //! Test deduction guides 14451c0b2f7Stbbdev //! \brief \ref interface \ref requirement 14551c0b2f7Stbbdev TEST_CASE("Deduction guides"){ 14651c0b2f7Stbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT 14751c0b2f7Stbbdev test_deduction_guides(); 14851c0b2f7Stbbdev #endif 14951c0b2f7Stbbdev } 15051c0b2f7Stbbdev 15151c0b2f7Stbbdev //! Test priorities work in single-threaded configuration 15251c0b2f7Stbbdev //! \brief \ref requirement 15351c0b2f7Stbbdev TEST_CASE("function_node priority support"){ 154*de0109beSIlya Mishin conformance::test_priority<oneapi::tbb::flow::function_node<input_msg, int>, input_msg>(oneapi::tbb::flow::unlimited); 15551c0b2f7Stbbdev } 15651c0b2f7Stbbdev 157*de0109beSIlya Mishin //! Test function_node has a user-settable concurrency limit. It can be set to one of predefined values. 158*de0109beSIlya Mishin //! The user can also provide a value of type std::size_t to limit concurrency. 159*de0109beSIlya Mishin //! Test that not more than limited threads works in parallel. 16051c0b2f7Stbbdev //! \brief \ref requirement 16151c0b2f7Stbbdev TEST_CASE("concurrency follows set limits"){ 162*de0109beSIlya Mishin conformance::test_concurrency<oneapi::tbb::flow::function_node<int, int>>(); 16351c0b2f7Stbbdev } 16451c0b2f7Stbbdev 165*de0109beSIlya Mishin //! Test node Input class meet the DefaultConstructible and CopyConstructible requirements and Output class meet the CopyConstructible requirements. 16651c0b2f7Stbbdev //! \brief \ref interface \ref requirement 167*de0109beSIlya Mishin TEST_CASE("Test function_node Output and Input class") { 168*de0109beSIlya Mishin using Body = conformance::copy_counting_object<int>; 169*de0109beSIlya Mishin conformance::test_output_input_class<oneapi::tbb::flow::function_node<Body, Body>, Body>(); 17051c0b2f7Stbbdev } 171