Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

parallel_Reduces memory access problem

deependu
Beginner
398 Views

hi all,

I am trying to figure out for last 2 days why this code is not working. The code is giving me memory access error.

The code is as follows:-

#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_reduce.h"
#include "tbb/blocked_range.h"
#include
#include
#include

using namespace tbb;
using namespace std;



class Parallel_StringFinder{

vector edgeList;
vector nodeList;
set::iterator it;
bool flag1,flag2,toInsert;

public:

vector finalNodesList;
vector tempGroup;
void operator()(const blocked_range& r ){

string stringTemp;
string edgeToInsert;

for(size_t I = r.begin(); I< r.end();++I)
{
int begin = r.begin();
int end = r.end();

edgeToInsert = edgeList.at(I);
toInsert = false;
for (it=Main::finalEdge.begin(); it!=Main::finalEdge.end(); it++)
{
stringTemp = *it;

if(stringTemp.size()!=edgeToInsert.size())
{
flag1 = true;
continue;
}
else
{
flag2 = true;
flag1=false;
toInsert = Main::checkStrings(stringTemp,edgeToInsert);
if((toInsert)==0)
break;
}

}
if(toInsert){
finalNodesList.push_back(edgeToInsert);
cout<<"................Node inserted-->"<< }
if(flag1&&!flag2){
finalNodesList.push_back(edgeToInsert);
cout<<"................Node inserted-->"<< }

}

}
Parallel_StringFinder(vector _edgeList,vector _nodeList,bool _flag1,bool _flag2,bool _toInsert):edgeList(_edgeList),nodeList(_nodeList),flag1(_flag1),flag2(_flag2),toInsert(_toInsert)
{


}

Parallel_StringFinder(Parallel_StringFinder& stringFinder,split)
{

cout<<"I am in split";
this->edgeList = stringFinder.edgeList;
this->nodeList = stringFinder.nodeList;
this->flag1 = stringFinder.flag1;
this->flag2 = stringFinder.flag2;
this->toInsert = stringFinder.toInsert;

}

void join(const Parallel_StringFinder& stringFinder)
{
cout<<"I am in join";
for(int i=0;i finalNodesList.push_back(stringFinder.finalNodesList.at(i));

}


};

I am invoking it as :-

Parallel_StringFinder pf(edgeList,temporaryNodeList,0,0,0);
size_t range = Main::finalEdge.size();

parallel_reduce(blocked_range(0,range),pf,auto_partitioner());

This code exit with memory access exception.Please guide me.

thanks

With regards

Deependus

0 Kudos
6 Replies
Dmitry_Vyukov
Valued Contributor I
398 Views
Quoting - deependu

hi all,

I am trying to figure out for last 2 days why this code is not working. The code is giving me memory access error.

The code is as follows:-


Please, provide minimal compilable example. There are some omitted functions like Main::checkStrings(). It will be easier to track down the issue if we will be able to compile and run the code to see where and when exception occurs.

0 Kudos
Dmitry_Vyukov
Valued Contributor I
398 Views
Quoting - deependu

hi all,

I am trying to figure out for last 2 days why this code is not working. The code is giving me memory access error.

The code is as follows:-


Also I notice that you are excessively and unnecessary copy containers (vectors and strings). This can't be a cause for exception, but can substantially degrade performance.

For example, you can not copy string here:

for (it=Main::finalEdge.begin(); it!=Main::finalEdge.end(); it++)
{
std::string const& stringTemp = *it;


And not copy vectors here:

Parallel_StringFinder(vector const& _edgeList,vector const& _nodeList,bool _flag1,bool _flag2,bool _toInsert):edgeList(_edgeList),nodeList(_nodeList),flag1(_flag1),flag2(_flag2),toInsert(_toInsert)
{
}


And there are other similar places.

0 Kudos
deependu
Beginner
398 Views
Quoting - Dmitriy V'jukov


Also I notice that you are excessively and unnecessary copy containers (vectors and strings). This can't be a cause for exception, but can substantially degrade performance.

For example, you can not copy string here:

for (it=Main::finalEdge.begin(); it!=Main::finalEdge.end(); it++)
{
std::string const& stringTemp = *it;


And not copy vectors here:

Parallel_StringFinder(vector const& _edgeList,vector const& _nodeList,bool _flag1,bool _flag2,bool _toInsert):edgeList(_edgeList),nodeList(_nodeList),flag1(_flag1),flag2(_flag2),toInsert(_toInsert)
{
}


And there are other similar places.

Hello Sir,
Thanks for replying,

First let me explain you , What the code is intended to do ?

I have got two vectors, nodeList and nodesToInsert .And I want to insert the nodes from nodesToInsert
to the finalNodeList vector.

checkNodeForInsertion() is a dummy function which here is just returning true. In actual system it consist of
logic which is working fine.

The final outcome of the program is to have all the nodes in finalNodesList vector.

The working code is as follows:-

#include "tbb/task_scheduler_init.h"
#include "tbb/parallel_reduce.h"
#include "tbb/blocked_range.h"
#include
#include
#include
using namespace tbb;
using namespace std;



class Parallel_StringFinder{

vector edgeList;
vector nodesToInsert;

public:
vector finalNodesList;

void operator()(const blocked_range& r ){
string stringTemp;
string edgeToInsert;
bool flag1=false,flag2=false,toInsert=false;

for(size_t I = r.begin(); I< r.end();++I)
{

edgeToInsert = nodesToInsert.at(I);

toInsert = false;
for (int it=0; it!=edgeList.size(); it++)
{
stringTemp = edgeList.at(it);

if(stringTemp.size()!=edgeToInsert.size())
{
flag1 = true;
continue;
}
else
{
flag2 = true;
flag1=false;
toInsert = checkNodeForInsertion(stringTemp,edgeToInsert);
if((toInsert)==0)
break;
}

}
if(toInsert){
finalNodesList.push_back(edgeToInsert);
cout<<"................Node inserted-->"<< }
if(flag1&&!flag2){
finalNodesList.push_back(edgeToInsert);
cout<<"................Node inserted-->"<< }

}

}
Parallel_StringFinder(vector _edgeList,vector _nodesToInsert,vector _finalNodeList):edgeList(_edgeList),nodesToInsert(_nodesToInsert),finalNodesList(_finalNodeList)
{}

Parallel_StringFinder(Parallel_StringFinder& stringFinder,split)
{
cout<<<"I am in split"< this->edgeList = stringFinder.edgeList;
this->nodesToInsert = stringFinder.nodesToInsert;
}

void join(const Parallel_StringFinder& stringFinder)
{
cout<<<"I am in join"< for(int i=0;i finalNodesList.push_back(stringFinder.finalNodesList.at(i));
}

bool checkNodeForInsertion(string temp1,string temp2)
{
return true;
}

};


int main()
{

task_scheduler_init init;
vector edgeList;

edgeList.push_back("GHQR");
edgeList.push_back("QRMN");
edgeList.push_back("KLMN");
edgeList.push_back("MNYZ");
edgeList.push_back("ABYZ");
edgeList.push_back("ABCD");
edgeList.push_back("CDYZ");

vector nodesToInsert;
nodesToInsert.push_back("KLMNABCD");
nodesToInsert.push_back("GHQRKLMN");


Parallel_StringFinder pf(edgeList,nodesToInsert,edgeList);


parallel_reduce(blocked_range(0,edgeList.size()),pf,auto_partitioner());
vector finalNodeList = pf.finalNodesList;

for(int i=0;i cout<
int i;
cout<<"Enter some value continue..."
cin>>i;


}



How the code is now behaving:-

When the code runs, it

Sometimes run fine.

But most of the times it gives me error

"Unhandled exception at 0x7c81eb33 in IntelCompetition.exe: Microsoft C++ exception: tbb::captured_exception at memory location 0x0012f930.."

and lands up in the file task.h at following code snippet

static void spawn_root_and_wait( task& root ) {
__TBB_ASSERT( root.is_owned_by_current_thread(), "root not owned by current thread" );
this line---> root.prefix().owner->spawn_root_and_wait( root, root.prefix().next );
}

Please let me know if you need more infomation.

Thanks

With regards

Deependu

0 Kudos
deependu
Beginner
398 Views

One more question,

Please let me know also whether the implementition is thread safe or not. Because the function checkNodeForInsertion() in actualy program checks whether the node, which is going to be inserted is, already in the finalNodeList vector or not.

Because, here many threads or tasks will be accessing the vector finalNodeList to insert as well as to check the avalibality of node before inserting it into the vector.

Thus, do we need to make some changes in the vector to make it thread safe or it is implict in TBB.

Please give someguidline also in that case how to do that.

Thanks

With regards

Deependu

0 Kudos
robert-reed
Valued Contributor II
399 Views
Quoting - deependu
Please let me know also whether the implementition is thread safe or not. Because the function checkNodeForInsertion() in actualy program checks whether the node, which is going to be inserted is, already in the finalNodeList vector or not.

Because, here many threads or tasks will be accessing the vector finalNodeList to insert as well as to check the avalibality of node before inserting it into the vector.

Thus, do we need to make some changes in the vector to make it thread safe or it is implict in TBB.

Deependu

I took a look at your code and found several things that look suspect to me. To start off, this example constructs a parallel_reduce over a range from 0 to edgeList.size(), but the range as used in the functor body indexes nodesToInsert, not edgeList. If edgeList is bigger than nodesToInsert, at least one of the workers will try to reference elements off the end ofnodesToInsert.

I wont try to comment on the rest of the functor body, but it looks like the intent is to try to select some nodes in nodesToInsert that pass some criteria based on comparison with the nodes in edgeList. The logic escapes me and toInsert is treated both as a bool and an int, so I doubt it will compile.

One more problematic area: it looks like the intent in the reduction operation is to have the functor select which nodesToInsert meet the criteria and copy them over to the local finalNodesList and then have the join operation merge the local finalNodesList objects. However, the splitting constructor does not appear to initialize its local copy of finalNodesList, which might also cause some problems.

I wouldnt vouch for the thread-safety of the STL vector calls youre using here, but I didnt see any that were operating on non-local data so I saw no obvious issues; thats not to say there are none.

0 Kudos
Dmitry_Vyukov
Valued Contributor I
399 Views

One more problematic area: it looks like the intent in the reduction operation is to have the functor select which nodesToInsert meet the criteria and copy them over to the local finalNodesList and then have the join operation merge the local finalNodesList objects. However, the splitting constructor does not appear to initialize its local copy of finalNodesList, which might also cause some problems.

I wouldnt vouch for the thread-safety of the STL vector calls youre using here, but I didnt see any that were operating on non-local data so I saw no obvious issues; thats not to say there are none.

The only concurrent access I see is concurrent indexing of 'edgeList' in operator() and copying of 'edgeList' in splitting constructor. However, such concurrent 'const' accesses are usually allowed by standard library implementations.

If something will be changed, it's crucial to remember that operator() and splitting constructor can be executed concurrently.

0 Kudos
Reply