Skip to content

Sole tbb executor#17851

Merged
alalek merged 18 commits intoopencv:masterfrom
anton-potapov:sole_tbb_executor
Nov 30, 2020
Merged

Sole tbb executor#17851
alalek merged 18 commits intoopencv:masterfrom
anton-potapov:sole_tbb_executor

Conversation

@anton-potapov
Copy link
Copy Markdown
Contributor

@anton-potapov anton-potapov commented Jul 15, 2020

This Merge Request adds TBB based executor into GAPI

  • Only the executor itself, which is not yet used
  • The executor uses priority queue based logic for ready to execution tasks

TBB executor description

TBB executor engine operate with graph of tasks represented via cv::gimpl::parallel::tile_node instances.

Dependencies

For every task (tile_node ) there might be a number of input dependencies (i.e. tasks that should be executed before). This number is represented twice in the tile_node structure. They are dependencies and dependency_count. First one describes total number (i.e. input edges in the graph before execution) and does not change during execution, while second one describes current number of unresolved input dependencies. Once dependency_count drops to zero, task is ready for execution as all it's dependencies are satisfied

Dependents

Every task that directly depends on the current one is listed in the tile_node::dependees member. The engine decrees dependency_count of these tasks right after the completion of the current task.

Sync Vs. Async payload

Task's body in enclosed in either task_body or async_task_body members depending on task's nature (and async flag). While in both cases the engine calls passed in function there are two differences:

  • async one accept the callback (from the engine), which should be called when asynchronous activity started by this function completes
  • While for synchronous payloads engine treat the task completed after the function returns, for asynchronous ones task treated completed once the callback is called.

Execution and Priorities

Once all input dependencies for the task are satisfied (i.e. it's dependency_count drops to zero) it is treated as ready for execution and is put into the "ready" queue. The queue (tbb::concurrent_priority_queue) sorts all task according to their priorities.

Some TBB tasking Likbez

TBB uses tbb::task derivatives to describe a piece of work. They can be linked together into a tree describing tasks dependencies. Every TBB task has a refcount field describing unsatisfied dependencies. Once it drops to zero task is ready for execution (i.e. can be spawned). Dependency tasks are called child tasks (i.e. parent depends on it's childs). Every child task on creation increases it's parent's refcount. After child task is executed TBB task scheduler automatically decrease parent's refcount. Root of tasks tree is used only to call it's tbb::task::wait_for_all method to wait for the CPU work to complete. wait_for_all waits for root refcount value to become 1 as a sign that all work is done.

Mapping to TBB

The executor engine creates a root task (derived from tbb::task) - a root of the task's tree. Once new tile_node item is pushed to the ready queue, new child task of root's is created (Effectively increasing root dependency count). Every child task body does the following :

  1. Pops ready for execution tile_node instance from the priority queue
  2. Execute it's body
  3. Decrease dependency_count for every dependent tile_node instance (via tile_node::dependees member)
  4. Per every tile_node with dependency_count dropped to zero, spawn extra (tbb) child task.

Asynchronicity work and TBB active waiting

While waiting for the root task, TBB does not put to sleep the calling thread. Instead, it keeps searching for spawned (or enqueued) TBB tasks to do, assuming it somehow related with the root task.

However, in case of async work (like GPU or non TBB CPU work) there may be no such (tbb) tasks to do. In this case calling thread wasting CPU time, constantly searching for tasks or spin waiting. To overcome drawback, more elaborated scheme then plain calling to tbb::task::wait_for_all is needed.

The scheme

Master thread (i.e. one that enters cv::gimpl::parallel::execute) after graph execution ignition does the following loop:

  • if there are ready to go TBB tasks, call root->wait_for_all() effectively participating in those tasks execution
    (wait_for_all() will return once all (soawned) childes of root complete)
  • if no such tasks exist, but there active async tasks, then wait on the conditional variable until :
    • there is new TBB work to do (i.e. new tasks are spawned)
    • last async task completes (and it's callback is called)

In order to track number of active asynchronous tasks count filed of exec_ctx::async_tasks is used.

Graph re-execution

The engine allows correct re-execution of already completed (tile_node based) graph instance. To allow it dependency_count of every executed tile_node is reset back to dependencies immediately after execution.

Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

  • I agree to contribute to the project under OpenCV (BSD) License.
  • To the best of my knowledge, the proposed patch is not based on a code under GPL or other license that is incompatible with OpenCV
  • The PR is proposed to proper branch
  • There is reference to original bug report and related work
  • There is accuracy test, performance test and test data in opencv_extra repository, if applicable
    Patch to opencv_extra has the same branch name.
  • The feature is well documented and sample code can be built with the project CMake
force_builders=ARMv7,Custom
build_image:Custom=centos:7
buildworker:Custom=linux-1
build_gapi_standalone:Custom=ade-0.1.1f

build_gapi_standalone:Linux x64=ade-0.1.1f
build_gapi_standalone:Win64=ade-0.1.1f
build_gapi_standalone:Mac=ade-0.1.1f
build_gapi_standalone:Linux x64 Debug=ade-0.1.1f

@dmatveev
Copy link
Copy Markdown
Contributor

@anton-potapov please invite other reviewers from the team first

@asmorkalov
Copy link
Copy Markdown
Contributor

@anton-potapov your turn

@asmorkalov asmorkalov mentioned this pull request Jul 29, 2020
6 tasks
#include <type_traits>
#include <memory>

#ifdef OPENCV_WITH_ITT
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This macro is not propagated to other modules except opencv_core

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm.... So what is the right way to check for ITT here then ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alalek ping

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The right way is reusing OpenCV's trace.hpp functionality for profiling purposes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a FIXME


#define ITT_AUTO_TRACE_GUARD_IMPL_(LINE, h) ITT_NAMED_TRACE_GUARD(itt_trace_guard_##LINE , h)
#define ITT_AUTO_TRACE_GUARD_IMPL(LINE, h) ITT_AUTO_TRACE_GUARD_IMPL_(LINE, h)
#define ITT_AUTO_TRACE_GUARD(h) ITT_AUTO_TRACE_GUARD_IMPL(__LINE__ , h)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful with definition macros with ITT_ prefixes.
Consider using of GAPI_ITT_ prefix or similar instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed prefix to GAPI_ITT

return (use_tbb_scheduler_bypass::yes == reuse_current_task) ? (recycle_as_continuation(), this) : nullptr;
}
~functor_task(){
assert_graph_is_running(parent());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be careful with exceptions in destructors.

Details: https://en.cppreference.com/w/cpp/error/uncaught_exception

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the warning, but this intentionally is not a exception, but and assert either CV_ one or a hand-crafted one

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to be enabled in debug only

if ((active_async_tasks == 0) || (wake_master == wake_tbb_master::yes) )//was the last or there is the new TBB tasks to execute
{
ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
//Wile decrement of async_tasks_t::count is atomic it might be done after waiting thread checked it value but _before_ it actually start waiting on the condition variable.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

broken indentation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+a too long line

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in while

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


# Executor
src/executor/gexecutor.cpp
src/executor/gapi_tbb_executor.cpp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything here is gapi, so I'd recommend renaming it to gtbbexecutor

Comment on lines +179 to +187
if(HAVE_TBB)
if(TARGET opencv_test_gapi)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AND ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

//
// Copyright (C) 2020 Intel Corporation

#ifndef OPENCV_GAPI_GAPI_ITT_HPP
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ITT be part of the /executor? maybe move it to backends/common?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a FIXME


#define ITT_AUTO_TRACE_GUARD_IMPL_(LINE, h) ITT_NAMED_TRACE_GUARD(itt_trace_guard_##LINE , h)
#define ITT_AUTO_TRACE_GUARD_IMPL(LINE, h) ITT_AUTO_TRACE_GUARD_IMPL_(LINE, h)
#define ITT_AUTO_TRACE_GUARD(h) ITT_AUTO_TRACE_GUARD_IMPL(__LINE__ , h)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

}
} //namespace util

namespace gimpl { namespace parallel {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though it has nothing with parallelism, right? :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right :)

added a FIXME


}}} // namespace cv::gimpl::parallel

void cv::gimpl::parallel::execute(tbb::concurrent_priority_queue<tile_node* , tile_node_indirect_priority_comparator> & q)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally we don't have lines long like this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Comment on lines +122 to +123
//Specify tbb::task_group_context::concurrent_wait in the traits to ask TBB scheduler not to change ref_count of the task we wait on (root) when wait is complete.
//As the traits is last argument explicitly specify (default) value for first argument
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And especially like this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if ((active_async_tasks == 0) || (wake_master == wake_tbb_master::yes) )//was the last or there is the new TBB tasks to execute
{
ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
//Wile decrement of async_tasks_t::count is atomic it might be done after waiting thread checked it value but _before_ it actually start waiting on the condition variable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+a too long line

Copy link
Copy Markdown
Contributor

@AsyaPronina AsyaPronina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation is very cool, thanks a lot for this!!

Comments are decorative, part of comments are just questions to understand code idea more deeply.

The main comment about code style - unaligned spaces, could you please align all indents in expressions, functions signatures and other statements? I haven't caught all unaligned spaces in comments because started to write feedback for them quite late..

The second comment about code style which is also was caught by Dmitry Matveev is too long comments and too long signatures/statements. Could you please break long comments, signatures and statements to multiple lines?

The third proposal is just about code documentation - may be we can split code by phases or highlight logical entities with comments? For example, highlight discussed logical entities with "Creating G-API static graph" (it is actually phase in the test, but still), "Creating TBB dynamic graph", "Main execution entry point for the each TBB task", "Execution of real tile node's body", "Spawning tasks for dynamic TBB graph", and so on?

if ((active_async_tasks == 0) || (wake_master == wake_tbb_master::yes) )//was the last or there is the new TBB tasks to execute
{
ITT_AUTO_TRACE_GUARD(ittTbbUnlockMasterThread);
//Wile decrement of async_tasks_t::count is atomic it might be done after waiting thread checked it value but _before_ it actually start waiting on the condition variable.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in while

@dmatveev
Copy link
Copy Markdown
Contributor

dmatveev commented Oct 5, 2020

@anton-potapov anton-potapov force-pushed the sole_tbb_executor branch 2 times, most recently from a97e530 to a02c2fc Compare October 13, 2020 09:38
 - the sole executor
 - unit tests for it
 - no usage in the GAPI at the momnet
 - introduced new overload of execute to explicitly accept tbb::arena
   argument
 - added more basic tests
 - moved arena creation code into tests
 -
 - fixed compie errors & warnings
 - split all-in-one execute() function into logicaly independant parts
 - used util::variant in in the tile_node
 - moved copy_through_move to separate header
 - rearranged details staff in proper namespaces
 - moved all implementation into detail namespace
 - fixed build error with TBB 4.4.
 - fixed build warnings
 - aligned strings width
 - fixed spaces in expressions
 - fixed english grammar
 - minor improvements
 - added more comments
 - minor improvements
 - changed ITT_ prefix for macroses to GAPI_ITT
 - no more "unused" warning for GAPI_DbgAssert
 - changed local assert macro to man onto GAPI_DbgAssert
 - file renamings
 - changed local assert macro to man onto GAPI_DbgAsse
 - test file renamed
 - add more comments
Copy link
Copy Markdown
Contributor

@OrestChura OrestChura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I have some little suggestions, mostly typo-corrections

 - minor clenups and cosmetic changes
 - minor clenups and cosmetic changes
 - changed spaces and curly braces alignment
 - minor cleanups
@anton-potapov
Copy link
Copy Markdown
Contributor Author

@alalek could you please merge it ?

Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some performance test to check benefits?

Approve from G-API team (@dmatveev @rgarnov ) is required for merge.
I'm not able to check in detail G-API code internals (or it will took enormous amount of time which I don't have).

// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018 Intel Corporation
// Copyright (C) 2020 Intel Corporation
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2018-2020 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed


#ifdef NDEBUG
# define GAPI_DbgAssert(expr)
# define GAPI_DbgAssert(expr) cv::util::suppress_unused_warning(expr)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, expression is still should be computed by compiler (and then dead code is eliminated - but not all).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As suppress_unused_warning(expr) is the function call, it's actual argument i.e. expr is calculated, then however it's value is discarded as bound to unnamed function argument.

The suppress_unused_warning defined as:

template<typename T> void suppress_unused_warning( const T& ) {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All functions and methods are not "pure" in C++ standard ("pure" is GCC extension).
So some non-inline .type() calls will be evaluated if they are part of this expr.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the classic C assert() implementation from assert.h / cassert headers (it is "dbg" assert in OpenCV):
https://en.cppreference.com/w/cpp/error/assert

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having the assert implemented like this does not prevent "unused" warnings (and that is why it was not enough to use CV_DbgAssert as is and I had to re-invent it. )

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that sizeof() is the solution here. As it is silence the warning and does not evaluate it's argument

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that sizeof() is the solution here.

But not for lambdas :) - fixed to use constexpr and bool operations short-circuit evaluation


enum class is_tbb_work_present {
no,
yes
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By coding style constants / enums should be upper case.
NO is a macro on some platforms (Apple).

Consider using bool type instead. Enum doesn't look as necessary here.

Copy link
Copy Markdown
Contributor Author

@anton-potapov anton-potapov Nov 27, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using meaningful names instead of faceless true / false , so bool is not an option :)

will rename to UPPERCASE

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed

@anton-potapov
Copy link
Copy Markdown
Contributor Author

anton-potapov commented Nov 27, 2020

Is there some performance test to check benefits?

Not yet, as it is first part of the puzzle- the executor itself. Actual usage/integration is to come up

Copy link
Copy Markdown
Contributor

@OrestChura OrestChura left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks!

Copy link
Copy Markdown
Contributor

@dmatveev dmatveev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK with the TBB part, not very certain about macro changes, though

# define GAPI_DbgAssert CV_DbgAssert
#else
# define GAPI_DbgAssert(expr) cv::util::suppress_unused_warning(expr)
#endif
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So what's the reason for all these changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason is - compiler warnings on release builds on unused variables in asserts

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, this unused variable is still going to be evaluated. Why we need that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that actually evaluate the expression is the only reliable way to actually "use" variables it made of (and there fore silence those warnings).

And yes compiling optimization of dead code removal is crucial here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"unused"

problem is in caller code. Not in assertion macro.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just replace to C-like assert() and you will receive the same "unused" warning in release builds.

Workaround for such cases:

-auto result = t->decrement_ref_count();
+auto result = t->decrement_ref_count(); (void)result;
 ASSERT(result >= 1);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, almost every problem can be workarounded :) ... but why if there is a proper solution to it ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there is a proper solution

It still evaluates expression.
More complex and common cases looks like ASSERT(node->isValid());. Compiler's DCE can't remove that completely.


Assertion macro must not evaluate passed expression (should be empty) in case of "noop".
Do not confuse developers with new specific behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last version of the patch does not evaluate the expression (and not cause "unused" warning)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, it is a tricky way, but looks like it works.

@anton-potapov anton-potapov force-pushed the sole_tbb_executor branch 2 times, most recently from 63da882 to 35cf42a Compare November 27, 2020 21:07
// First participate in execution of TBB graph till there are no more ready tasks.
ctx.root->wait_for_all();

if (!async_work_done()) { // Wait on the conditional variable iff there is active async work
Copy link
Copy Markdown
Contributor

@AsyaPronina AsyaPronina Nov 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iff -> if

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@AsyaPronina AsyaPronina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the efforts!

{
namespace util
{
//This is a tool to move initialize captures of a lambda in C++11
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check gasync.cpp for similar stuff. We really don't want to have duplicated code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you do not mind, I will unify them in a separate PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <opencv2/gapi/util/copy_through_move.hpp>
#include "logger.hpp" // GAPI_LOG

#include <tbb/task.h>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW,

note: ‘#pragma message: TBB Warning: tbb/task.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.’

TBB (ver 2020.3 interface 11103)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I know this

# define GAPI_DbgAssert CV_DbgAssert
#else
# define GAPI_DbgAssert(expr) cv::util::suppress_unused_warning(expr)
#endif
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, it is a tricky way, but looks like it works.

#endif

#include <opencv2/gapi/util/compiler_hints.hpp>
#include <iostream>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iostream

Do we really need that here? (consider using <ostream> if std::ostream is required only without cout/cerr)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch - will change

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed

 - minor cleanups
@anton-potapov
Copy link
Copy Markdown
Contributor Author

Great!

@alalek alalek mentioned this pull request Apr 9, 2021
a-sajjad72 pushed a commit to a-sajjad72/opencv that referenced this pull request Mar 30, 2023
* TBB executor for GAPI

 - the sole executor
 - unit tests for it
 - no usage in the GAPI at the momnet

* TBB executor for GAPI

 - introduced new overload of execute to explicitly accept tbb::arena
   argument
 - added more basic tests
 - moved arena creation code into tests
 -

* TBB executor for GAPI

 - fixed compie errors & warnings

* TBB executor for GAPI

 - split all-in-one execute() function into logicaly independant parts

* TBB executor for GAPI

 - used util::variant in in the tile_node

* TBB executor for GAPI

 - moved copy_through_move to separate header
 - rearranged details staff in proper namespaces
 - moved all implementation into detail namespace

* TBB executor for GAPI

 - fixed build error with TBB 4.4.
 - fixed build warnings

* TBB executor for GAPI

 - aligned strings width
 - fixed spaces in expressions
 - fixed english grammar
 - minor improvements

* TBB executor for GAPI

 - added more comments
 - minor improvements

* TBB executor for GAPI

 - changed ITT_ prefix for macroses to GAPI_ITT

* TBB executor for GAPI

 - no more "unused" warning for GAPI_DbgAssert
 - changed local assert macro to man onto GAPI_DbgAssert

* TBB executor for GAPI

 - file renamings
 - changed local assert macro to man onto GAPI_DbgAsse

* TBB executor for GAPI

 - test file renamed
 - add more comments

* TBB executor for GAPI

 - minor clenups and cosmetic changes

* TBB executor for GAPI

 - minor clenups and cosmetic changes

* TBB executor for GAPI

 - changed spaces and curly braces alignment

* TBB executor for GAPI

 - minor cleanups

* TBB executor for GAPI

 - minor cleanups
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants