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 2151c0b2f7Stbbdev #include "conformance_flowgraph.h" 2251c0b2f7Stbbdev 2351c0b2f7Stbbdev //! \file conformance_async_node.cpp 2451c0b2f7Stbbdev //! \brief Test for [flow_graph.async_node] specification 2551c0b2f7Stbbdev 26*de0109beSIlya Mishin using input_msg = conformance::message</*default_ctor*/true, /*copy_ctor*/true, /*copy_assign*/false>; 27*de0109beSIlya Mishin using output_msg = conformance::message</*default_ctor*/false, /*copy_ctor*/false, /*copy_assign*/false>; 2851c0b2f7Stbbdev 29*de0109beSIlya Mishin //! Test async_node constructors 3051c0b2f7Stbbdev //! \brief \ref requirement 31*de0109beSIlya Mishin TEST_CASE("async_node constructors"){ 32*de0109beSIlya Mishin using namespace oneapi::tbb::flow; 33*de0109beSIlya Mishin graph g; 3451c0b2f7Stbbdev 35*de0109beSIlya Mishin conformance::dummy_functor<int> fun; 36*de0109beSIlya Mishin 37*de0109beSIlya Mishin async_node<int, int> fn1(g, unlimited, fun); 38*de0109beSIlya Mishin async_node<int, int> fn2(g, unlimited, fun, oneapi::tbb::flow::node_priority_t(1)); 39*de0109beSIlya Mishin 40*de0109beSIlya Mishin async_node<int, int, lightweight> lw_node1(g, serial, fun, lightweight()); 41*de0109beSIlya Mishin async_node<int, int, lightweight> lw_node2(g, serial, fun, lightweight(), oneapi::tbb::flow::node_priority_t(1)); 4251c0b2f7Stbbdev } 4351c0b2f7Stbbdev 44*de0109beSIlya Mishin //! Test buffering property 45*de0109beSIlya Mishin //! \brief \ref requirement 46*de0109beSIlya Mishin TEST_CASE("async_node buffering") { 47*de0109beSIlya Mishin conformance::dummy_functor<int> fun; 48*de0109beSIlya Mishin conformance::test_buffering<oneapi::tbb::flow::async_node<input_msg, int>, input_msg>(oneapi::tbb::flow::unlimited, fun); 4951c0b2f7Stbbdev } 5051c0b2f7Stbbdev 51*de0109beSIlya Mishin //! Test priorities work in single-threaded configuration 52*de0109beSIlya Mishin //! \brief \ref requirement 53*de0109beSIlya Mishin TEST_CASE("async_node priority support"){ 54*de0109beSIlya Mishin conformance::test_priority<oneapi::tbb::flow::async_node<input_msg, int>, input_msg>(oneapi::tbb::flow::unlimited); 55*de0109beSIlya Mishin } 56*de0109beSIlya Mishin 57*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. 58*de0109beSIlya Mishin //! The predecessors and successors of src are not copied. 59*de0109beSIlya Mishin //! \brief \ref requirement 60*de0109beSIlya Mishin TEST_CASE("async_node copy constructor"){ 61*de0109beSIlya Mishin conformance::test_copy_ctor<oneapi::tbb::flow::async_node<int, int>>(); 6251c0b2f7Stbbdev } 6351c0b2f7Stbbdev 6451c0b2f7Stbbdev //! Test calling async body 6551c0b2f7Stbbdev //! \brief \ref interface \ref requirement 6651c0b2f7Stbbdev TEST_CASE("Test async_node body") { 67*de0109beSIlya Mishin conformance::test_body_exec<oneapi::tbb::flow::async_node<input_msg, output_msg>, input_msg, output_msg>(oneapi::tbb::flow::unlimited); 6851c0b2f7Stbbdev } 6951c0b2f7Stbbdev 7051c0b2f7Stbbdev //! Test async_node inheritance relations 7151c0b2f7Stbbdev //! \brief \ref interface 7251c0b2f7Stbbdev TEST_CASE("async_node superclasses"){ 73*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::async_node<int, int>, int, int>(); 74*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::async_node<void*, float>, void*, float>(); 75*de0109beSIlya Mishin conformance::test_inheritance<oneapi::tbb::flow::async_node<input_msg, output_msg>, input_msg, output_msg>(); 76*de0109beSIlya Mishin } 77*de0109beSIlya Mishin 78*de0109beSIlya Mishin //! Test node broadcast messages to successors 79*de0109beSIlya Mishin //! \brief \ref requirement 80*de0109beSIlya Mishin TEST_CASE("async_node broadcast"){ 81*de0109beSIlya Mishin conformance::counting_functor<int> fun(conformance::expected); 82*de0109beSIlya Mishin conformance::test_forwarding<oneapi::tbb::flow::async_node<input_msg, int>, input_msg, int>(1, oneapi::tbb::flow::unlimited, fun); 83*de0109beSIlya Mishin } 84*de0109beSIlya Mishin 85*de0109beSIlya Mishin //! Test async_node has a user-settable concurrency limit. It can be set to one of predefined values. 86*de0109beSIlya Mishin //! The user can also provide a value of type std::size_t to limit concurrency. 87*de0109beSIlya Mishin //! Test that not more than limited threads works in parallel. 88*de0109beSIlya Mishin //! \brief \ref requirement 89*de0109beSIlya Mishin TEST_CASE("concurrency follows set limits"){ 90*de0109beSIlya Mishin conformance::test_concurrency<oneapi::tbb::flow::async_node<int, int>>(); 91*de0109beSIlya Mishin } 92*de0109beSIlya Mishin 93*de0109beSIlya Mishin //! Test body copying and copy_body logic 94*de0109beSIlya Mishin //! Test the body object passed to a node is copied 95*de0109beSIlya Mishin //! \brief \ref interface 96*de0109beSIlya Mishin TEST_CASE("async_node body copying"){ 97*de0109beSIlya Mishin conformance::test_copy_body_function<oneapi::tbb::flow::async_node<int, int>, conformance::copy_counting_object<int>>(oneapi::tbb::flow::unlimited); 98*de0109beSIlya Mishin } 99*de0109beSIlya Mishin 100*de0109beSIlya Mishin //! Test node reject the incoming message if the concurrency limit achieved. 101*de0109beSIlya Mishin //! \brief \ref interface 102*de0109beSIlya Mishin TEST_CASE("async_node with rejecting policy"){ 103*de0109beSIlya Mishin conformance::test_rejecting<oneapi::tbb::flow::async_node<int, int, oneapi::tbb::flow::rejecting>>(); 104*de0109beSIlya Mishin } 105*de0109beSIlya Mishin 106*de0109beSIlya Mishin //! Test node Input class meet the DefaultConstructible and CopyConstructible requirements and Output class meet the CopyConstructible requirements. 107*de0109beSIlya Mishin //! \brief \ref interface \ref requirement 108*de0109beSIlya Mishin TEST_CASE("Test async_node Output and Input class") { 109*de0109beSIlya Mishin using Body = conformance::copy_counting_object<int>; 110*de0109beSIlya Mishin conformance::test_output_input_class<oneapi::tbb::flow::async_node<Body, Body>, Body>(); 111*de0109beSIlya Mishin } 112*de0109beSIlya Mishin 113*de0109beSIlya Mishin //! Test the body of assync_node typically submits the messages to an external activity for processing outside of the graph. 114*de0109beSIlya Mishin //! \brief \ref interface 115*de0109beSIlya Mishin TEST_CASE("async_node with rejecting policy"){ 116*de0109beSIlya Mishin using async_node_type = tbb::flow::async_node<int, int>; 117*de0109beSIlya Mishin using gateway_type = async_node_type::gateway_type; 118*de0109beSIlya Mishin 119*de0109beSIlya Mishin oneapi::tbb::flow::graph g; 120*de0109beSIlya Mishin std::atomic<bool> flag{false}; 121*de0109beSIlya Mishin std::thread thr; 122*de0109beSIlya Mishin async_node_type testing_node{ 123*de0109beSIlya Mishin g, tbb::flow::unlimited, 124*de0109beSIlya Mishin [&](const int& input, gateway_type& gateway) { 125*de0109beSIlya Mishin gateway.reserve_wait(); 126*de0109beSIlya Mishin thr = std::thread{[&]{ 127*de0109beSIlya Mishin flag = true; 128*de0109beSIlya Mishin gateway.try_put(input); 129*de0109beSIlya Mishin gateway.release_wait(); 130*de0109beSIlya Mishin }}; 131*de0109beSIlya Mishin } 132*de0109beSIlya Mishin }; 133*de0109beSIlya Mishin 134*de0109beSIlya Mishin testing_node.try_put(1); 135*de0109beSIlya Mishin g.wait_for_all(); 136*de0109beSIlya Mishin CHECK_MESSAGE((flag.load()), "The body of assync_node must submits the messages to an external activity for processing outside of the graph"); 137*de0109beSIlya Mishin thr.join(); 13851c0b2f7Stbbdev } 139