ref_count is too small

ref_count is too small

I encapsulate 4 functions into 4 task derivedclasses respectively and using 1 class to spawn all of them. While it is running there is an assertion said ref_count is too small. Please help me out of this problem.

Here are the 4 task derived classes, each of them call the corresponding function that is implemented in another file.

class PCalculateGA:public tbb::task{

public:

VecDoub & m_tempXValue;

MatDoub & m_ga;

double m_k;

double m_lr;

PCalculateGA(VecDoub & XValue, MatDoub & ga, double k, double lr):

m_tempXValue(XValue),m_ga(ga),m_k(k),m_lr(lr){}

task* execute(){

CalculateGA(m_tempXValue, m_ga, m_k, m_lr);

return NULL;

}

};

class PCalculateGp:public tbb::task{

public:

VecDoub & m_tempXValue;

VecDoub & m_gp;

double m_k;

double m_lr;

PCalculateGp(VecDoub & XValue, VecDoub & gp, double k, double lr):

m_tempXValue(XValue),m_gp(gp),m_k(k),m_lr(lr){}

task* execute(){

CalculateGp(m_tempXValue, m_gp, m_k, m_lr);

return NULL;

}

};

class PCalculateEp:public tbb::task{

public:

VecDoub & m_tempXValue;

VecDoub & m_ep;

double m_k;

double m_lr;

double* m_externalFore;

PCalculateEp(VecDoub & XValue, VecDoub & ep, double k, double lr, double* externalFore):

m_tempXValue(XValue),m_ep(ep),m_k(k),m_lr(lr),m_externalFore(externalFore){}

task* execute(){

CalculateEp(m_tempXValue, m_ep, m_k, m_lr, m_externalFore);

return NULL;

}

};

class PCalculateEA:public tbb::task{

public:

VecDoub & m_tempXValue;

MatDoub & m_ea;

double m_k;

double m_lr;

double* m_externalFore;

PCalculateEA(VecDoub & XValue, MatDoub & ea, double k, double lr, double* externalFore):

m_tempXValue(XValue),m_ea(ea),m_k(k),m_lr(lr),m_externalFore(externalFore){}

task* execute(){

CalculateEA(m_tempXValue, m_ea, m_k, m_lr, m_externalFore);

return NULL;

}

};

The final class that spawn above tasks is

class ParallelCalculation:public tbb::task{

public:

VecDoub & m_tempXValue;

MatDoub & m_ga;

VecDoub & m_gp;

VecDoub & m_ep;

MatDoub & m_ea;

double m_k;

double m_lr;

double* m_externalFore;

ParallelCalculation(VecDoub & XValue,MatDoub & ga, VecDoub & gp, VecDoub & ep, MatDoub & ea, double k,double lrt,double* externalFore):

m_tempXValue(XValue),m_ga(ga),m_gp(gp),m_ep(ep),m_ea(ea),m_k(k),m_lr(lrt),m_externalFore(externalFore){}

task* execute(){

set_ref_count(5);

PCalculateGA& t4 = *new(allocate_child())PCalculateGA(m_tempXValue,m_ga,m_k,m_lr);

PCalculateGp& t3 = *new(allocate_child())PCalculateGp(m_tempXValue,m_gp,m_k,m_lr);

PCalculateEp& t2 = *new(allocate_child())PCalculateEp(m_tempXValue,m_ep,m_k,m_lr,m_externalFore);

PCalculateEA& t1 = *new(allocate_child())PCalculateEA(m_tempXValue,m_ea,m_k,m_lr,m_externalFore);

spawn(t4);

spawn(t3);

spawn(t2);

spawn_and_wait_for_all(t1);

return NULL;

}

};

In the reference, it said the reference count should be set k+1, k is the number of the task. In my case, there are 4 tasks and due to spawn_and_wait_for_all, the ref_count should be set to 5. Am I right?

14 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

Strange... consider parallel_invoke() instead.

I will type the assertion first here

Debug Assertion Failed!

Program:
...Jerry\Desktop\Project\TenSegrityDemo\Debug\TenSegrityDemo.exe
Module: tbb_debug.dll
File: ../../src/tbb/custom_scheduler.h
Line:329

Expression: parent.ref_count() >= (child && child ->parent() == &parent ? 2 :1)
ref_count is too small

And in my program, it used to be

CalculateGA(xValue, ga, kcable, lr);

CalculateGp(xValue, gp, kcable ,lr);

CalculateEp(xValue, ep, kcable, lr,externalFore);

CalculateEA(xValue, ea, kcable, lr,externalFore);

And the tbb version is like

ParallelCalculation& a = *new(task::allocate_root())ParallelCalculation(xValue,ga,gp,ep,ea,kcable,lr,externalFore);

a.spawn_and_wait_for_all(a);/* is this place right? in the example it should be task::spawn_and_wait_for_all
(a), but compiler will not get through and say task::spawn_and_wait_for_all' : illegal call of non-static member function*/

I have not write anything about scheduler initiation and commented out any other tbb program so I am sure there is no side effect from outside of this function.

Have you tried to run the same program with the bodies emptied out? Maybe something is writing where it shouldn't (just a wild guess)...

Quoting xinyuhou...
Module: tbb_debug.dll
File: ../../src/tbb/custom_scheduler.h
Line:329

Expression: parent.ref_count() >= (child && child ->parent() == &parent ? 2 : 1) ref_count is too small

[SergeyK] I saw that piece of code. Please see my comments below.

And in my program, it used to be

CalculateGA(xValue, ga, kcable, lr);
CalculateGp(xValue, gp, kcable ,lr);
CalculateEp(xValue, ep, kcable, lr,externalFore);
CalculateEA(xValue, ea, kcable, lr,externalFore);
...

[SergeyK]Unfortunately, it doesn't helpsince it is hard to reproduce your problem without a simple test-case.

Here are a couple of comments:

1. Try to debug and step into the 'parent.ref_count()' method in order to see what exactly happens there at run-time (!)

2. If you decide to debug you need to do the following:

- open 'tbb.vcproj'
- change aconfiguration to Debug ( I assume that you useWin32 Platform )
- set a host application in: 'Configuration Properties' -> 'Debugging' -> 'Command' ->a path to your test application
compiled in Debug configuration
- set a breakpointon the line 329 ( or 328 ) in 'custom_scheduler.h'
- press F10 to start debugging

3. Ialsorecommend to step into the'child->parent()' method

4. Take into account thatthe assert is only displayed in Debug configuration but its is not clear for me if this is a warning or indication of some
problem with implementation of your codes

5. What is your TBB version?

Best regards,
Sergey

em sounds really complicated. But still I will try to follow it. Many thanks!

Jerry

Guess I know where is wrong. I set a breakpoint at a.spawn_and_wait_for_all(a); and stepped into it. Found void spawn_and_wait_for_all( task& child ) was called instead of static void spawn_root_and_wait( task& root ). Like I said in the example it was task::spawn_and_wait_for_all which I guess it would call the later one since task:: indicates this is a static function. But when I use task::spawn_and_wait_for_all(a) compiler give me an error saying task::spawn_and_wait_for_all' : illegal call of non-static member function. Apparently there is a static function corresponding to the that call but the compiler just stupidly can not match it -_-||

Regards

Jerry

OMG How careless I am! It should be task::spawn_root_and_wait(a); I was typing to task::spawn_and_wait_for_all(a); No doubt it always calls void spawn_and_wait_for_all( task& child )

Best Regards

Jerry

Quoting xinyuhouem sounds really complicated. But still I will try to follow it. Many thanks!

Jerry

Did you follow my instructions for debugging of 'tbb_debug.dll'? Did you have any issues or problems?

I need your feedback because I plan to make apost called "Tips for debugging IntelTBB library". Thanks in advance.

Best regards,
Sergey

What is the status now? I don't quite understand #11 and #12...

If the problem is not yet solved after all, consider splitting up the spawn_and_wait_for_all() into spawn() and wait_for_all(), tracing ref_count() after each spawn() (it should have decreased by at most the number of preceding spawn() calls), and again in a loop until it reaches 1 just before wait_for_all(). If that doesn't reveal anything, merge spawn_and_wait_for_all() again and do the loop until ref_count() reaches 2. Or the other way around of course.

Quoting Raf SchietekatWhat is the status now? I don't quite understand #11 and #12...
I understood that Jerry found a typing "error"in his sources. He used a different spawn-like method...

I don't see it. Oh well, never mind.

Quoting Raf SchietekatI don't see it...

Please take a look at Post #11:

...Found void spawn_and_wait_for_all( task& child ) was called instead of static void spawn_root_and_wait( task& root )...

Ah, for spawning the ParallelCalculation instance (I now presume)... OK, got it. :-)

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui