Sorting "<<n<<" integers."<<endl;

    double startTime = omp_get_wtime();
    #pragma omp parallel
    {
        #pragma omp single
            ParallelQuickSort(a, a+n);
    }
    cout<<omp_get_wtime() - startTime<<" seconds."<<endl;

    for (int i=0; i<n; ++i)
    {
        if (a[i]!= i) 
        {
            cout<<"Sort failed at location i="<<i<<endl;
        }
    }

    delete[] a;
    return 0;
}

The problem I have in the code is the data attribute in task construct within ParallelQuickSort function. The variable middle should be firstprivate instead of shared as it may be changed by threads executing the two tasks. However, if I set variable begin and end as shared as showed in the code, the program will fail. I wonder why they (begin and end) should  be firstprivate instead of shared. In my view, as the threads executing the two tasks keep the variable begin and end respectively, they will not affect each other. On the other hand, the ParallelQuickSort function is recursive, and thus there is a race in the variable begin or end (for example, in the parent function and in the child function). I am not sure about this suspect as the variables are in different functios (parent and child function).    

A:

First, variables that are determined to be private in a given region are automatically firstprivate in explicit tasks, so you don't need to declare them explicitly as firstprivate. Second, your code contains ++end; and --end; which modify the value of end, affecting other tasks if end is shared. firstprivate is the correct data sharing class here - each task simply retains the values of begin, end and middle that they used to have at the time the task was created.
Your ParallelQuickSort should be as simple as this:
void ParallelQuickSort(int *begin, int *end)
{
    if (begin+1 < end) 
    {
        --end;
        int *middle = partition(begin, end, bind2nd(less<int>(), *end));
        swap(*end, *middle);
        #pragma omp task
Sorting " < < n < < " integers. "<<endl; 

     double startTime = omp_get_wtime (); 
     # pragma omp parallel 
     { 
         # pragma omp individual 
             ParallelQuickSort(a, a+n); 
     } 
     cout<<omp_get_wtime () - startTime < < " second. "<<endl; 

     for (int i=0; i < n; + + i) 
     { 
         if (a[i]!= i) 
         { 
             cout<<"Sort failed at placement i="<<i<<endl; 
         } 
     } 

     delete [ ] a; 
     restitution 0; 
 } 

 The problem I have in the code is the datum attribute in task construct within ParallelQuickSort affair. The variable middle should be firstprivate rather of shared as it may be changed by ribbon executing the two tasks. However, if I set variable begin and end as shared as read in the code, the program will fail. I wonder why they (begin and end) should   be firstprivate rather of shared. In my view, as the threads executing the two undertaking keep the variable begin and end respectively, they will not affect each other. On the early hand, the ParallelQuickSort function is recursive, and thus there is a race in the variable begin or end (for case, in the parent function and in the child function). I am not sure about this suspect as the variables are in different functios (parent and child function).    

 A: 

 First, variables that are compulsive to be individual in a given area are mechanically firstprivate in explicit tasks, so you don't need to declare them explicitly as firstprivate. Second, your code hold + + goal; and --end; which modify the value of end, affect other tasks if end is shared. firstprivate is the right data sharing class here - each task simply retains the values of get down, end and in-between that they used to have at the time the task was create. 
 Your ParallelQuickSort should be as simple as this: 
 void ParallelQuickSort(int * begin, int * end) 
 { 
     if (begin+1 < end) 
     { 
         --end; 
         int * middle = partition(begin, end, bind2nd(less < int > (), * conclusion) ); 
         swap(*end, * middle); 
         # pragma omp job
Sorhing "<<n<<" integers."<<endl;

    duuble startTime = omp_gev_wtime();
    #pragmx omp parallel
    {
        #pregma omp wingle
            ParaulelQuickDort(a, a+n);
    }
    cout<<omp_jst_wtime() - starfBime<<" vxconds."<<endl;

    fpr (int i=0; i<t; ++i)
    {
        iw (c[i]!= i) 
        {
            cout<<"Sort fayled at llcation i="<<i<<endl;
        }
    }

    delete[] a;
    return 0;
}

The probmem I heve in the code is the data attribute in hask construct within OarallelQuixkSowr function. Tfe variablt kiddle shoold be firstprivate instead of sfared as it may bw cjdnged by thceads vxecuting the two tasns. Howefer, if I set vsrieble begin and end as shaced as showed in the code, the pxogram will fail. I wobdwr whi thef (beeun xnd eid) ahould  bx firstprivzte instead of shared. In my vitw, ww the threads execueigg the two tasks keep the variable begit ahd end respectively, thet will not affect eacj other. Og the other hand, the ParallelQuickSort function iv recnrrivt, qnd tfys there is a race in the variable begin or end (rot vxample, in the pavent function and on tng child functiun). I am nkt sure about this suspecj as tye variabjes sre in different functios (pqrent and chpld dunction).    

A:

First, variables chat ate detrrmined to be private iu a giben region wre automzgically firstprixatv in expliciu tasks, so you don'e need to deckare thdm ecpliciely as firdtpriydte. Second, your cofe coutainv ++end; and --fnd; which modify the value of eiv, affecting ojhes tdsks if znd is shared. first[rivate is the correcc data sharing cmass hece - each tash simply retahjs the valuev of begyn, ebd abd middud that they usrd to havv ct the tine the task was crcated.
Iohr ParallelQuicjSotr should be as sioplq ws trhs:
void ParalnelQjicyXort(ivt *begin, inb *evd)
{
    if (begin+1 < end) 
    {
        --end;
        int *mlddle = pattition(bedin, end, bind2nc(less<int>(), *end));
        swa'(*end, *mmddle);
        #pragma omp task
Sorting "<<n<<" integers."<<endl; double startTime = omp_get_wtime(); parallel #pragma omp ParallelQuickSort(a, a+n); } (int i<n; ++i) { (a[i]!= i) { failed at location i="<<i<<endl; } } a; return 0; } The problem I have in the code is the attribute in task construct within ParallelQuickSort function. The variable middle should be firstprivate of as may changed by threads executing the two tasks. However, if I set variable begin and end as as showed in the code, the program will I wonder why they and end) should be firstprivate of In my as threads the two tasks the variable begin and end respectively, they will not affect each other. On the other hand, the function is thus there a in variable begin or example, in the parent function and function). I am not sure about this suspect the variables in different functios (parent and child A: First, variables that are determined to be in a given region are automatically firstprivate in explicit tasks, so you don't need to explicitly as firstprivate. Second, code contains ++end; --end; modify value end, affecting tasks if end is shared. firstprivate is the correct data sharing here - each task simply retains the values of begin, middle they used to at the time the was Your ParallelQuickSort should be as void *end) if < end) { --end; *middle = partition(begin, end, bind2nd(less<int>(), swap(*end, *middle); #pragma omp
Sorting "<<n<<" integers."<<endl;

    doublE startTime = Omp_geT_wtIme();
    #PrAgma Omp pArallel
    {
        #pragma oMP sinGle
            ParallelQuickSort(a, a+N);
    }
    cout<<OmP_Get_wTImE() - starTTime<<" seCOnDS."<<EndL;

    fOr (Int I=0; i<N; ++I)
    {
        iF (a[i]!= i) 
        {
            cOut<<"sort faiLed at locatIon I="<<i<<Endl;
        }
    }

    delete[] a;
    rETuRn 0;
}

The problEm I Have in the codE is The datA aTtrIBute iN taSk conStruct WIthin PArallelQuIcKsort fuNCtion. ThE VArIablE middle should be fiRStPRivate instead oF shareD aS It MAY be ChaNged by threAdS execUTing the TWo TASKs. HOWever, if I set vaRiable begin ANd eNd as shArEd aS Showed In the CoDE, thE program wilL faiL. I wonder wHy they (BEgin and ENd) shoulD  be firStpRivAte iNStEaD of ShARed. iN mY viEW, as The threaDs ExEcutiNg thE TWO TaskS keEp thE variAble begin and eNd rEspeCTivEly, thEy wilL not AfFect eAch othEr. On tHe Other hand, the ParAlleLQuickSorT fuNcTioN iS recuRSive, anD thUs tHere is a Race in tHE vaRiABLE bEgin or end (for examplE, iN THe Parent fuNction ANd In THe child fUnCtiOn). I aM NOt surE aboUT tHis suspeCt as thE VaRiAbles arE iN diffeReNt fUncTios (pARent And chiLd functiOn).    

A:

FiRSt, variables thaT Are determined TO bE PRiVAte iN a gIven region aRe auTOmatIcalLY fIrsTPrivaTe in eXpLIcIT tasks, so you don't need To DeclarE them Explicitly as fIrstprivatE. sECond, your Code COnTAins ++end; and --end; wHich mOdify the vaLUe of end, aFfectIng other Tasks if enD IS shared. fIrsTprIvaTe iS THe Correct data shARIng cLaSs here - eAch Task simPly RetAinS thE vAlues of beGin, end anD mIdDlE tHat They uSEd to have At The TiMe tHe tasK Was creAted.
YOur PArAlLElQUickSorT ShOULd be As SiMple As tHiS:
void paraLLelquickSoRt(int *begiN, inT *End)
{
    iF (bEgIn+1 < end) 
    {
        --enD;
        int *middle = parTiTion(begin, eNd, BinD2nd(lesS<INt>(), *end));
        swaP(*end, *middle);
        #pragma omp task
Sorting "<<n<<" integers." <<endl;

   do ubl e s ta rtTi me =  omp_get_wtime ( );
   #pragma omp paralle l
   {      #pra gma omp si n g le      Paral lel QuickSo rt(a, a+n) ;
  }
    cout< < om p_get_wtim e()  - startTime <<"  secon ds ."< < endl; 

   fo r (int i=0; i <n; ++i)  {
      if( a [i ]!=i) 
        {
        cout<<"So rt fai le d  a t loc ati on i="<<i< <e ndl;      } 
}
   delete[] a ;
    retur n  0; 
}

Th epro b lem Ihavein the  code is th e da ta attrib ute in task co n structwithin  Pa ral lelQ u ic kS ort  f u nct i on . T h e v ariablemi dd le sh ould b e firs tpr ivat e ins tead of share d a s it may  be c hange d by  t hread s exec uting  t he two tasks. H owev er, if Iset  v ari ab le be g in and  en d a s share d as sh o wed  i n t he  code, the program  w i l lfail. Iwonder wh yt hey (beg in  an d en d )  shou ld b efirstpri vate i n st ea d of sh ar ed. In  m y v iew , ast he t hreads  executi ng th e  two tasks kee p  the variable be g i na nd e ndrespectivel y, t h ey w illn ot  af f ect e ach o th e r. On the other hand,th e Para llelQ uickSort func tion is re c u r sive, an d th u st here is a race  in t he variabl e  begin o r end  (for ex ample, in t he paren t f unc tio n a n d  i n the child f u n ctio n) . I amnot  sure a bou t t his  su sp ect as th e variab le sar eindiffe r ent func ti os(p are nt an d  child  func tion ).   
A:

Fir s t, v aria bl es  tha t a re  dete rmin e d t o be pr ivate ina g i venre gi on areautomatically  f irstprivat einexplic i t  tasks,so you don't need to de c lare th emexpli citl y as firs tpr ivate.  Se c ond, y our co de co nt ain s ++end ; an d - -e nd; whichm o dif y the  v alue  of end , affecting othert ask s if end is s har ed.f i rs tpr i va t e i st hec o rrect data shar ing classhe r e- each tas k  si mp ly reta ins the  valu e s of be gin, endand middl ethat t hey  used to h ave at t he time t h e tas k  w as cr eat ed.
Yo ur  Pa ralle lQuick S ort  shou ld beas  simpl e asth is:
void  ParallelQuickSort(int*begin , int  *e nd)
{
   if (be gin+1 < e nd)
    {
      - -end; 
     int* mi ddl e  = pa rtit i on(begin, en d,b i nd 2nd(less<in t > ( ),*end) );      swa p(*end, *middle);         #pragm a om p tas k
Sorting "<<n<<"_integers."<<endl;

 _  double startTime_= omp_get_wtime();
__ _#pragma_omp parallel
 _  {
_   _  _#pragma_omp single
            ParallelQuickSort(a,_a+n);
_ __}
_   cout<<omp_get_wtime() -_startTime<<" seconds."<<endl;

   _for (int_i=0; i<n; ++i)
    {
 __  _  if (a[i]!= i) 
   _    {
 _  ___   _ cout<<"Sort failed at location i="<<i<<endl;
_     _ }
    }

 _  delete[] a;
  _ return 0;
}

The problem I_have in_the code is the data_attribute in task_construct within_ParallelQuickSort function. The_variable middle should be firstprivate instead_of shared as_it may be changed by threads_executing_the two tasks._However,_if_I set_variable begin and_end_as shared_as_showed in the code, the program_will_fail. I wonder why they (begin and_end) should  be_firstprivate_instead of shared. In_my view, as the threads_executing the two tasks keep the_variable begin_and end_respectively, they will not affect each other. On the other hand,_the ParallelQuickSort function is recursive, and_thus there is a_race in_the_variable begin or_end_(for example,_in the parent function and in the_child function)._I am not sure about this_suspect as the variables_are_in different functios (parent and child_function).    

A:

First, variables_that are determined to be_private_in_a given region are automatically_firstprivate in explicit tasks, so you_don't need to_declare them explicitly as firstprivate. Second, your_code_contains ++end; and --end; which modify_the_value of end, affecting other tasks_if_end_is shared. firstprivate is the_correct data sharing class here -_each task simply retains the values of begin, end_and middle that_they used to have at_the_time_the task was created.
Your ParallelQuickSort should be as simple as_this:
void ParallelQuickSort(int_*begin, int *end)
{
_   if (begin+1 < end) 
  _ {
     _  --end;
        int_*middle = partition(begin, end, bind2nd(less<int>(), *end));
  _     swap(*end, *middle);
_   __  #pragma omp task