SPECX Coding Practice

Examples
Code Test Promise
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"
#include "Random/SpPhiloxGenerator.hpp"


#include "mcglobal.hpp"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"

#include "Task/SpTask.hpp"
#include "Legacy/SpRuntime.hpp"
#include "Utils/SpTimer.hpp"
#include "Utils/small_vector.hpp"
#include "Utils/SpBufferDataView.hpp"
#include "Utils/SpArrayView.hpp"
#include "Utils/SpHeapBuffer.hpp"


#include "UTester.hpp"
#include "utestUtils.hpp"



#include <algorithm>
#include <iostream>
#include <vector>
#include <string>



using namespace std;

template <typename C> void print(const string& s, const C& c) {
    cout << s;
    for (const auto& e : c) { cout << e << " "; }
    cout << endl;
}

void fillVector(vector<int>& v)
{
    // A local static variable.
    static int nextValue = 1;

    // The lambda expression that appears in the following call to
    // the generate function modifies and uses the local static
    // variable nextValue.
    generate(v.begin(), v.end(), [] { return nextValue++; });
    //WARNING: this isn't thread-safe and is shown for illustration only
}


int gen()
{
    static int i = 0;
    return ++i;
}

class MyFunction001
{
public:
    // The required constructor for this example.
    explicit MyFunction001(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    MyFunction001& operator=(const MyFunction001&);

    int& m_evenCount; // the number of even variables in the vector.
};




int main(int argc, char **argv)
{

    int NumThreads = SpUtils::DefaultNumThreads();

    const int NbLoops = 3;
    const int NbInnerLoops = 2;
    static_assert(NbInnerLoops <= NbLoops, "Nb inner loops cannot be greater than Nb Loops");

    const int NbDomains = 5;
    const int NbParticlesPerDomain = 10;
    const double BoxWidth = 1;
    const double displacement = 0.00001;

    const int NbReplicas = 5;
    std::array<double,NbReplicas> betas;
    std::array<double,NbReplicas> temperatures;

    const double MinTemperature = 0.5;
    const double MaxTemperature = 1.5;

    for(int idxReplica = 0 ; idxReplica < NbReplicas ; ++idxReplica){
        betas[idxReplica] = 1;
        temperatures[idxReplica] = MinTemperature + double(idxReplica)*(MaxTemperature-MinTemperature)/double(NbReplicas-1);
    }

    std::array<size_t,NbReplicas> cptGeneratedSeq = {0};

    ///////////////////////////////////////////////////////////////////////////
    /// With a possible failure move
    ///////////////////////////////////////////////////////////////////////////

    const bool runSeqMove = false;
    const bool runTaskMove = false;
    const bool runSpecMove = false;

    std::array<double,NbReplicas> energySeq = {0};

    const int MaxIterationToMove = 5;
    const double collisionLimit = 0.00001;


    if (1==1)
    {

        cout<<"===================================\n";

        NumThreads=2;
        SpRuntime My_Runtime3(NumThreads); 

        //SpRuntime<SpSpeculativeModel::SP_MODEL_2> My_Runtime3;
        //cout<<":"<<My_Runtime3.getValue()<<"\n";

        My_Runtime3.setSpeculationTest(
            [](const int /*inNbReadyTasks*/,
            const SpProbability& /*inProbability*/) -> bool
            {
                // Always speculate
                //usleep(50000);
                return true;
            } 
        );

        int val = 0;
        std::promise<int> promise3;
        //la promesse que doit remplir le thread annexe

         My_Runtime3.task(SpRead(val)
            , 
            [&promise3](const int& /*valParam*/)
            {
                usleep(100);
                promise3.get_future().get();
                //Retourne un objet future qui a le même état asynchrone associé que cet objet promise.
            }
        ).setTaskName("First task");

       
        
        for(int idx = 0; idx < 1; idx++) {
          My_Runtime3.task(SpWrite(val), 
              [](int& valParam)  
              {
                cout<<"CTRL Val in certain task="<<valParam<<"\n";
                usleep(500);
              }
          ).setTaskName("Certain task -- " + std::to_string(idx));
        }

        
        
        const int nbUncertainTasks = 6;

        for(int idx = 0 ; idx < nbUncertainTasks ; ++idx){
            My_Runtime3.task(SpPotentialWrite(val), 
               [](int& valParam) -> bool
                {
                   cout<<"CTRL Val in uncertain task="<<valParam<<"\n";
                   usleep(1000);
                   return true;
                }
            ).setTaskName("Uncertain task -- " + std::to_string(idx));
        }
        

        /*
        for(int idx = 2; idx < 4; idx++) {
          My_Runtime3.task(SpWrite(val), 
              [](int& valParam)  
              {
                usleep(1500);
              }
           ).setTaskName("Certain task -- " + std::to_string(idx));
        }
        */
        
        My_Runtime3.task(SpWrite(val), 
              []([[maybe_unused]] int& valParam)
              {
                usleep(2000);
              }
        ).setTaskName("Last-task");

        promise3.set_value(0);
        //L'opération se comporte comme si set_value , set_exception , 
        //set_value_at_thread_exit et set_exception_at_thread_exit acquéraient 
        //un seul mutex associé à l'objet de promesse lors de la mise à jour de 
        //l'objet de promesse.
    
        //Une exception est levée s'il n'y a pas d'état partagé ou si 
        //l'état partagé stocke déjà une valeur ou une exception.
        //Les appels à cette fonction n'introduisent pas de courses de 
        //données avec les appels à get_future (ils n'ont donc pas besoin 
        //de se synchroniser les uns avec les autres).



        My_Runtime3.waitAllTasks();

        My_Runtime3.generateDot("RuntimePromise.dot",true);
        My_Runtime3.generateTrace("RuntimePromose.svg");


    }


}



 
#pragma GCC diagnostic pop
Code Test Race
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"
#include "Random/SpPhiloxGenerator.hpp"


#include "mcglobal.hpp"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"

#include "Task/SpTask.hpp"
#include "Legacy/SpRuntime.hpp"
#include "Utils/SpTimer.hpp"
#include "Utils/small_vector.hpp"
#include "Utils/SpBufferDataView.hpp"
#include "Utils/SpArrayView.hpp"
#include "Utils/SpHeapBuffer.hpp"


#include "UTester.hpp"
#include "utestUtils.hpp"



#include <algorithm>
#include <iostream>
#include <vector>
#include <string>



using namespace std;

template <typename C> void print(const string& s, const C& c) {
    cout << s;
    for (const auto& e : c) { cout << e << " "; }
    cout << endl;
}

void fillVector(vector<int>& v)
{
    // A local static variable.
    static int nextValue = 1;

    // The lambda expression that appears in the following call to
    // the generate function modifies and uses the local static
    // variable nextValue.
    generate(v.begin(), v.end(), [] { return nextValue++; });
    //WARNING: this isn't thread-safe and is shown for illustration only
}


int gen()
{
    static int i = 0;
    return ++i;
}

class MyFunction001
{
public:
    // The required constructor for this example.
    explicit MyFunction001(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    MyFunction001& operator=(const MyFunction001&);

    int& m_evenCount; // the number of even variables in the vector.
};




int main(int argc, char **argv)
{

    int NumThreads = SpUtils::DefaultNumThreads();

    const int NbLoops = 3;
    const int NbInnerLoops = 2;
    static_assert(NbInnerLoops <= NbLoops, "Nb inner loops cannot be greater than Nb Loops");

    const int NbDomains = 5;
    const int NbParticlesPerDomain = 10;
    const double BoxWidth = 1;
    const double displacement = 0.00001;

    const int NbReplicas = 5;
    std::array<double,NbReplicas> betas;
    std::array<double,NbReplicas> temperatures;

    const double MinTemperature = 0.5;
    const double MaxTemperature = 1.5;

    for(int idxReplica = 0 ; idxReplica < NbReplicas ; ++idxReplica){
        betas[idxReplica] = 1;
        temperatures[idxReplica] = MinTemperature + double(idxReplica)*(MaxTemperature-MinTemperature)/double(NbReplicas-1);
    }

    std::array<size_t,NbReplicas> cptGeneratedSeq = {0};

    ///////////////////////////////////////////////////////////////////////////
    /// With a possible failure move
    ///////////////////////////////////////////////////////////////////////////

    const bool runSeqMove = false;
    const bool runTaskMove = false;
    const bool runSpecMove = false;

    std::array<double,NbReplicas> energySeq = {0};

    const int MaxIterationToMove = 5;
    const double collisionLimit = 0.00001;


    std::array<unsigned int,3> SleepTimes{0, 500,1000};

    for (const int& value : SleepTimes) { cout << value << "  "; }; cout << "\n";



    //Small Horse Race

    string ch0 = "Small Horse Race";
    string chNb = to_string(4);
    ch0=ch0+chNb;

    NumThreads = SpUtils::DefaultNumThreads();
    std::cout<<"Nb Thread="<<NumThreads<<"\n";
    NumThreads = 2;
    std::cout<<"Nb Thread="<<NumThreads<<"\n";

    SpTimer T0;

    for(auto SleepTime : SleepTimes){
        
        SpRuntime My_Runtime(NumThreads); 

        My_Runtime.setSpeculationTest(
            [](const int, const SpProbability&) -> bool
            {
                return true;
            });

        const int arraySize = 6;
        //int val[arraySize] = {0};
        int val[arraySize];

        for (int i=0; i<arraySize; ++i)
        {
            val[i]=0;
        }

        cout<<"Array : ";
        for (const int& value : val) { cout << value << "  "; }; cout << "\n";


        UTestRaceChecker counterAccess;
        string ChInfo,ChInfoPlus;
        ChInfo = "Runtime Array Process";

        My_Runtime.task(SpReadArray(val,SpArrayView(arraySize)), 
        [](SpArrayAccessor<const int>& /*valParam*/){}).setTaskName("Small Horse Race");
 
            for(int idx = 0 ; idx < arraySize ; ++idx){
                ChInfoPlus = ChInfo+to_string(idx);

                My_Runtime.task(SpWrite(val[idx]),
                                      SpReadArray(val,SpArrayView(arraySize).removeItem(idx)),
                                      [SleepTime,idx,&counterAccess]
                                      (int& valParam, const SpArrayAccessor<const int>& valArray) -> bool {
                    {
                        counterAccess.lock();
                        counterAccess.addWrite(&valParam);
                        for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
                            counterAccess.addRead(&valArray.getAt(idxTest));
                        }
                        counterAccess.unlock();
                    }

                    string ChNumidx=to_string(idx);

                    cout<<"TimeSleep="<<SleepTime<<" Idx="<<idx;
                    cout<<" valParam1="<<valParam;

                    if (1==1) {
                         if(idx == 1){
                            valParam += 2;
                        }
                        if(idx == 3){
                            valParam += 1;
                        }
                        if(idx == 5){
                            valParam += 10;
                        }
                    }
                    cout<<" valParam2="<<valParam<<"\n";

                    usleep(SleepTime);

                    {
                        counterAccess.lock();
                        counterAccess.releaseWrite(&valParam);
                        for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
                            counterAccess.releaseRead(&valArray.getAt(idxTest));
                        }
                        counterAccess.unlock();
                    }

                    return (idx == 3 || idx == 5);
                }).setTaskName(ChInfoPlus); //END runtime;
            }
            My_Runtime.waitAllTasks();
            My_Runtime.stopAllThreads();

            My_Runtime.generateDot("TestRaceThread.dot",true);

            My_Runtime.generateTrace("TestRaceThread.svg");

        cout<<"Array : ";
        for (const int& value : val) { cout << value << "  "; }; cout << "\n";
        

    }//END FOR


    T0.stop();
    cout<<"Delta Time="<<T0.getElapsed()<<"\n";

    SpPhiloxGenerator<double> randGen(0);


}



 
#pragma GCC diagnostic pop
Code Test Vector Buffer
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"
#include "Random/SpPhiloxGenerator.hpp"


#include "mcglobal.hpp"



#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"

#include "Task/SpTask.hpp"
#include "Legacy/SpRuntime.hpp"
#include "Utils/SpTimer.hpp"
#include "Utils/small_vector.hpp"
#include "Utils/SpBufferDataView.hpp"
#include "Utils/SpArrayView.hpp"
#include "Utils/SpHeapBuffer.hpp"


#include "UTester.hpp"
#include "utestUtils.hpp"



#include <algorithm>
#include <iostream>
#include <vector>
#include <string>



using namespace std;

template <typename C> void print(const string& s, const C& c) {
    cout << s;
    for (const auto& e : c) { cout << e << " "; }
    cout << endl;
}

void fillVector(vector<int>& v)
{
    // A local static variable.
    static int nextValue = 1;

    // The lambda expression that appears in the following call to
    // the generate function modifies and uses the local static
    // variable nextValue.
    generate(v.begin(), v.end(), [] { return nextValue++; });
    //WARNING: this isn't thread-safe and is shown for illustration only
}


int gen()
{
    static int i = 0;
    return ++i;
}

class MyFunction001
{
public:
    // The required constructor for this example.
    explicit MyFunction001(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    MyFunction001& operator=(const MyFunction001&);

    int& m_evenCount; // the number of even variables in the vector.
};




int main(int argc, char **argv)
{

    int NumThreads = SpUtils::DefaultNumThreads();

    const int NbLoops = 3;
    const int NbInnerLoops = 2;
    static_assert(NbInnerLoops <= NbLoops, "Nb inner loops cannot be greater than Nb Loops");

    const int NbDomains = 5;
    const int NbParticlesPerDomain = 10;
    const double BoxWidth = 1;
    const double displacement = 0.00001;

    const int NbReplicas = 5;
    std::array<double,NbReplicas> betas;
    std::array<double,NbReplicas> temperatures;

    const double MinTemperature = 0.5;
    const double MaxTemperature = 1.5;

    for(int idxReplica = 0 ; idxReplica < NbReplicas ; ++idxReplica){
        betas[idxReplica] = 1;
        temperatures[idxReplica] = MinTemperature + double(idxReplica)*(MaxTemperature-MinTemperature)/double(NbReplicas-1);
    }

    std::array<size_t,NbReplicas> cptGeneratedSeq = {0};

    ///////////////////////////////////////////////////////////////////////////
    /// With a possible failure move
    ///////////////////////////////////////////////////////////////////////////

    const bool runSeqMove = false;
    const bool runTaskMove = false;
    const bool runSpecMove = false;

    std::array<double,NbReplicas> energySeq = {0};

    const int MaxIterationToMove = 5;
    const double collisionLimit = 0.00001;


    if (1==1)
    {
        const int initVal = 1;
        int writeVal = 0;

        NumThreads=6;
        SpRuntime My_Runtime2(NumThreads); 

        small_vector<int> vs;
        std::cout << "std::allocator<int>:"                         << '\n'
            << "  sizeof (vs):     " << sizeof (vs)           << '\n'
            << "  Maximum size:    " << vs.max_size ()        << "\n\n";

        SpHeapBuffer<small_vector<int>> heapBuffer;

        int valueN=0;
        int valueM=0;

        for(int idx = 0 ; idx < 6 ; ++idx){
            auto vectorBuffer = heapBuffer.getNewBuffer();

            
            //On écrit dans 6 buffers
            My_Runtime2.task(SpWrite(vectorBuffer.getDataDep()),
            [&](SpDataBuffer<small_vector<int>> ) mutable
            {
                valueN=idx;  
                usleep(1000);
            }
            ).setTaskName("Write Vector Buffer");
            
            valueM=valueN;
            //Puis on lit 2 fois
            for(int idxSub = 0 ; idxSub < 2 ; ++idxSub){
                My_Runtime2.task(SpRead(vectorBuffer.getDataDep()),
                    [=](const SpDataBuffer<small_vector<int>>)
                    {
                        
                        cout<<"idx="<<idx<<" idSub="<<idxSub<<" valueN="<<valueN<<" valueM="<<valueM<<"\n";
                        usleep(2000);
                       
                    }
                    ).setTaskName("Read Vector Buffer");;
            }    
        }
        My_Runtime2.waitAllTasks();
        My_Runtime2.stopAllThreads();
        My_Runtime2.generateDot("RuntimeVectorBuffer.dot",true);
        My_Runtime2.generateTrace("RuntimeVectorBuffer.svg");
    }




}



 
#pragma GCC diagnostic pop
Code Draft Tests
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"






#include "Data/SpDataAccessMode.hpp"
#include "Utils/SpUtils.hpp"
#include "Random/SpPhiloxGenerator.hpp"


#include "mcglobal.hpp"


#include "Task/SpTask.hpp"
#include "Legacy/SpRuntime.hpp"
#include "Utils/SpTimer.hpp"
#include "Utils/small_vector.hpp"
#include "Utils/SpBufferDataView.hpp"
#include "Utils/SpArrayView.hpp"
#include "Utils/SpHeapBuffer.hpp"


#include "UTester.hpp"
#include "utestUtils.hpp"



#include <algorithm>
#include <iostream>
#include <vector>
#include <string>



using namespace std;

template <typename C> void print(const string& s, const C& c) {
    cout << s;
    for (const auto& e : c) { cout << e << " "; }
    cout << endl;
}

void fillVector(vector<int>& v)
{
    // A local static variable.
    static int nextValue = 1;

    // The lambda expression that appears in the following call to
    // the generate function modifies and uses the local static
    // variable nextValue.
    generate(v.begin(), v.end(), [] { return nextValue++; });
    //WARNING: this isn't thread-safe and is shown for illustration only
}


int gen()
{
    static int i = 0;
    return ++i;
}

class MyFunction001
{
public:
    // The required constructor for this example.
    explicit MyFunction001(int& evenCount)
        : m_evenCount(evenCount) { }

    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n) const {
        cout << n;

        if (n % 2 == 0) {
            cout << " is even " << endl;
            ++m_evenCount;
        } else {
            cout << " is odd " << endl;
        }
    }

private:
    // Default assignment operator to silence warning C4512.
    MyFunction001& operator=(const MyFunction001&);

    int& m_evenCount; // the number of even variables in the vector.
};




int main(int argc, char **argv)
{

    int NumThreads = SpUtils::DefaultNumThreads();

    const int NbLoops = 3;
    const int NbInnerLoops = 2;
    static_assert(NbInnerLoops <= NbLoops, "Nb inner loops cannot be greater than Nb Loops");

    const int NbDomains = 5;
    const int NbParticlesPerDomain = 10;
    const double BoxWidth = 1;
    const double displacement = 0.00001;

    const int NbReplicas = 5;
    std::array<double,NbReplicas> betas;
    std::array<double,NbReplicas> temperatures;

    const double MinTemperature = 0.5;
    const double MaxTemperature = 1.5;

    for(int idxReplica = 0 ; idxReplica < NbReplicas ; ++idxReplica){
        betas[idxReplica] = 1;
        temperatures[idxReplica] = MinTemperature + double(idxReplica)*(MaxTemperature-MinTemperature)/double(NbReplicas-1);
    }

    std::array<size_t,NbReplicas> cptGeneratedSeq = {0};

    ///////////////////////////////////////////////////////////////////////////
    /// With a possible failure move
    ///////////////////////////////////////////////////////////////////////////

    const bool runSeqMove = false;
    const bool runTaskMove = false;
    const bool runSpecMove = false;

    std::array<double,NbReplicas> energySeq = {0};

    const int MaxIterationToMove = 5;
    const double collisionLimit = 0.00001;



    SpRuntime runtime(NumThreads); 
    std::cout<<"Nb Thread="<<NumThreads<<"\n";
    SpTimer timer;


    int v=1; 
    int r=0;

    std::cout<<"v="<<v<<" r="<<r<<"\n";

    runtime.task(SpRead(v),SpWrite(r),
    [] (const int &,int r1) {
        r1=10;
    } ).setTaskName("First Runtime");

    runtime.task(SpRead(v),
    [] (const int &) {
        
    } ).setTaskName("Second Runtime");

    std::cout<<"v="<<v<<" r="<<r<<"\n";

    //=============================================
    int p;
    auto Area=[=] (int a,int b)->int
    {
        return p*a*b;
    };
    p=10;
    std::cout<<"Result1="<<Area(2,3)<<"\n";

    //=============================================
    int p2=100;
    auto Area2=[&] (int a,int b)
     {
        p2=50;
        return p2*a*b;
    };
    std::cout<<"Result2="<<Area2(2,3)<<"\n";

    //=============================================

    
    auto Area3=[] (int a,int b)
     {
        return a*b;
    };

    std::cout<<"Result3="<<Area3(2,3)<<"\n";

    //=============================================
    int v1;
    int g=3;
    auto Area4=[&,g] (int a,int b)
     {
        return v1+a*b;
    };
    v1=1;
    std::cout<<"Result3="<<Area3(2,3)<<"\n";


    int x = 1;
    auto valueLambda = [=]() { std::cout << x << std::endl; };
    auto refLambda = [&]() { std::cout << x << std::endl; };
    x = 13;
    valueLambda();
    refLambda();


    //=============================================
    int m = 0;
    int n = 0;
    [&, n] (int a) mutable { m = ++n + a; }(4);
    std::cout <<"m="<<m << std::endl <<"n="<< n << std::endl;

    m = 0;
    n = 0;
    auto Fonc1=[&,n] (int a) mutable { m = n++ + a; n=20; };
    Fonc1(6);
    std::cout <<"m="<<m << std::endl <<"n="<< n << std::endl;


    //m = 0;
    //n = 0;
    //auto Fonc2=[&,n] (int a) { m = n++ + a; n=20; }; // Error no mutable
    //Fonc2(6);
    //std::cout <<"m="<<m << std::endl <<"n="<< n << std::endl;



    const int elementCount = 9;

    // Create a vector object with each element set to 1.
    vector<int> vvv0 {1,2,3,4,5,6,7,8,9,10,11};
    cout << "v0: "<< vvv0.data() << endl;
    for (const int& value : vvv0) { cout << value << "  "; }
    cout << "\n";

    cout <<vvv0[4]<<"\n";
    cout <<vvv0.at(4)<<"\n"; //Better to used give exception if up range 

    cout << "\n";

    vector<int> vvv1(10);
    for (const int& value : vvv1) { cout << value << "  "; }
    cout << "\n";
  
    // using std::generate
    std::generate(vvv1.begin(), vvv1.end(), gen);
    for (const int& value : vvv1) { cout << value << "  "; }
    cout << "\n";
    vector<int>::iterator i1;
    for (i1 = vvv1.begin(); i1 != vvv1.end(); ++i1) {
        cout << *i1 << " ";
    }
    cout << "\n";




    cout << "\n";
    vector<int> vvv(elementCount, 1);


    cout << "v: "<< vvv.data() << endl;
    for (const int& value : vvv) { cout << value << "  "; }
    cout << "\n";


    // These variables hold the previous two elements of the vector.
    int xx = 1;
    int yy = 1;

    // Sets each element in the vector to the sum of the
    // previous two elements.
    generate_n(vvv.begin() + 2,
        elementCount - 2,
        [=]() mutable throw() -> int { // lambda is the 3rd parameter
        // Generate current value.
        int n = xx + yy;
        // Update previous two values.
        xx = yy;
        yy = n;
        return n;
    });
    print("vector v after call to generate_n() with lambda: ", vvv);

    // Print the local variables x and y.
    // The values of x and y hold their initial values because
    // they are captured by value.
    cout << "x: " << xx << " y: " << yy << endl;

    // Fill the vector with a sequence of numbers
    fillVector(vvv);
    print("vector v after 1st call to fillVector(): ", vvv);
    // Fill the vector with the next sequence of numbers
    fillVector(vvv);
    print("vector v after 2nd call to fillVector(): ", vvv);


    cout << endl;


    //Assign the lambda expression that adds two numbers to an auto variable.
    auto f1 = [](int x, int y) { return x + y; };

    cout << f1(2, 3) << endl;

    // Assign the same lambda expression to a function object.
    function<int(int, int)> f2 = [](int x, int y) { return x + y; };

    cout << f2(3, 4) << endl;

    cout << endl;

    /*int yw = 32;
    auto answer = [yw]() constexpr
    {
        int xw = 10;
        return yw + xw;
    };

    constexpr int Increment(int n)
    {
        return [n] { return n + 1; }();
    }
    */



   // Create a vector object that contains 9 elements.
    vector<int> vn;
    for (int i = 1; i < 10; ++i) {
        vn.push_back(i);
    }

    // Count the number of even numbers in the vector by
    // using the for_each function and a function object.
    int evenCount = 0;
    for_each(vn.begin(), vn.end(), MyFunction001(evenCount));

    // Print the count of even numbers to the console.
    cout << "There are " << evenCount
        << " even numbers in the vector." << endl;

    cout << endl;

    const int NbTab=10;
    double Tab[NbTab]={0};
    for (int i=0; i<NbTab; ++i)
    {
        Tab[i]=0.01*double(i);
    }
    UTestRaceChecker counterAccess;


    runtime.task(SpReadArray(Tab,SpArrayView(NbTab)), 
        [](SpArrayAccessor<const double>& ){}
    ).setTaskName("Runtime read Array");


    for (const double& value : Tab) { cout << value << "  "; }; cout << "\n";



    for(int idx = 0 ; idx < NbTab ; ++idx){
                runtime.task(SpWrite(Tab[idx]),
                             SpReadArray(Tab,SpArrayView(NbTab).removeItem(idx)),
                                     
                [idx](double& valParam, const SpArrayAccessor<const double>& valArray) -> bool
                {
                    {
                       
                            if(idx == 3){
                                valParam += 1;
                            }
                            if(idx == 5){
                                valParam += 10;
                            }
                            usleep(1000);

                            cout<<"valParam="<<valParam<<"\n";


                        return (idx == 3 || idx == 5); 
                    } 
                }
                ).setTaskName("Runtime Array Process"); //END runtime
            } //END FOR


    for (const double& value : Tab) { cout << value << "  "; }; cout << "\n";

    //specx part




    runtime.waitAllTasks();

    runtime.stopAllThreads();

    timer.stop();

    runtime.generateDot("Test.dot",true);

    runtime.generateTrace("Test.svg");
  

    //std::array<unsigned int,2> SleepTimes{0, 500};

    std::array<unsigned int,3> SleepTimes{0, 500,1000};

    for (const int& value : SleepTimes) { cout << value << "  "; }; cout << "\n";



    //Small Horse Race

    string ch0 = "Small Horse Race";
    string chNb = to_string(4);
    ch0=ch0+chNb;

    NumThreads = SpUtils::DefaultNumThreads();
    std::cout<<"Nb Thread="<<NumThreads<<"\n";
    NumThreads = 2;
    std::cout<<"Nb Thread="<<NumThreads<<"\n";

    SpTimer T0;

    for(auto SleepTime : SleepTimes){
        
        SpRuntime My_Runtime(NumThreads); 

        My_Runtime.setSpeculationTest(
            [](const int, const SpProbability&) -> bool
            {
                return true;
            });

        const int arraySize = 6;
        //int val[arraySize] = {0};
        int val[arraySize];

        for (int i=0; i<arraySize; ++i)
        {
            val[i]=0;
        }

        cout<<"Array : ";
        for (const int& value : val) { cout << value << "  "; }; cout << "\n";


        UTestRaceChecker counterAccess;
        string ChInfo,ChInfoPlus;
        ChInfo = "Runtime Array Process";

        My_Runtime.task(SpReadArray(val,SpArrayView(arraySize)), 
        [](SpArrayAccessor<const int>& /*valParam*/){}).setTaskName("Small Horse Race");
 
            for(int idx = 0 ; idx < arraySize ; ++idx){
                ChInfoPlus = ChInfo+to_string(idx);

                My_Runtime.task(SpWrite(val[idx]),
                                      SpReadArray(val,SpArrayView(arraySize).removeItem(idx)),
                                      [SleepTime,idx,&counterAccess]
                                      (int& valParam, const SpArrayAccessor<const int>& valArray) -> bool {
                    {
                        counterAccess.lock();
                        counterAccess.addWrite(&valParam);
                        for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
                            counterAccess.addRead(&valArray.getAt(idxTest));
                        }
                        counterAccess.unlock();
                    }

                    string ChNumidx=to_string(idx);

                    cout<<"TimeSleep="<<SleepTime<<" Idx="<<idx;
                    cout<<" valParam1="<<valParam;

                    if (1==1) {
                         if(idx == 1){
                            valParam += 2;
                        }
                        if(idx == 3){
                            valParam += 1;
                        }
                        if(idx == 5){
                            valParam += 10;
                        }
                    }
                    cout<<" valParam2="<<valParam<<"\n";

                    usleep(SleepTime);

                    {
                        counterAccess.lock();
                        counterAccess.releaseWrite(&valParam);
                        for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
                            counterAccess.releaseRead(&valArray.getAt(idxTest));
                        }
                        counterAccess.unlock();
                    }

                    return (idx == 3 || idx == 5);
                }).setTaskName(ChInfoPlus); //END runtime;
            }
            My_Runtime.waitAllTasks();
            My_Runtime.stopAllThreads();

            My_Runtime.generateDot("TestRaceThread.dot",true);

            My_Runtime.generateTrace("TestRaceThread.svg");

        cout<<"Array : ";
        for (const int& value : val) { cout << value << "  "; }; cout << "\n";
        

    }//END FOR


    T0.stop();
    cout<<"Delta Time="<<T0.getElapsed()<<"\n";

    SpPhiloxGenerator<double> randGen(0);

    //cout<<"Value SpPhiloGenerator="<<randGen<<"\n";


    //**********************************************************

    if (1==1)
    {
        const int initVal = 1;
        int writeVal = 0;

        NumThreads=6;
        SpRuntime My_Runtime2(NumThreads); 

        small_vector<int> vs;
        std::cout << "std::allocator<int>:"                         << '\n'
            << "  sizeof (vs):     " << sizeof (vs)           << '\n'
            << "  Maximum size:    " << vs.max_size ()        << "\n\n";

        SpHeapBuffer<small_vector<int>> heapBuffer;

        int valueN=0;
        int valueM=0;

        for(int idx = 0 ; idx < 6 ; ++idx){
            auto vectorBuffer = heapBuffer.getNewBuffer();

            
            //On écrit dans 6 buffers
            My_Runtime2.task(SpWrite(vectorBuffer.getDataDep()),
            [&](SpDataBuffer<small_vector<int>> ) mutable
            {
                valueN=idx;  
                usleep(1000);
            }
            ).setTaskName("Write Vector Buffer");
            
            valueM=valueN;
            //Puis on lit 2 fois
            for(int idxSub = 0 ; idxSub < 2 ; ++idxSub){
                My_Runtime2.task(SpRead(vectorBuffer.getDataDep()),
                    [=](const SpDataBuffer<small_vector<int>>)
                    {
                        
                        cout<<"idx="<<idx<<" idSub="<<idxSub<<" valueN="<<valueN<<" valueM="<<valueM<<"\n";
                        usleep(2000);
                       
                    }
                    ).setTaskName("Read Vector Buffer");;
            }    
        }
        My_Runtime2.waitAllTasks();
        My_Runtime2.stopAllThreads();
        My_Runtime2.generateDot("Runtime2.dot",true);
        My_Runtime2.generateTrace("Runtime2.svg");
    }


  //**********************************************************

    if (1==1)
    {

        cout<<"===================================\n";

        NumThreads=2;
        SpRuntime My_Runtime3(NumThreads); 

        //SpRuntime<SpSpeculativeModel::SP_MODEL_2> My_Runtime3;
        //cout<<":"<<My_Runtime3.getValue()<<"\n";

        My_Runtime3.setSpeculationTest(
            [](const int /*inNbReadyTasks*/,
            const SpProbability& /*inProbability*/) -> bool
            {
                // Always speculate
                //usleep(50000);
                return true;
            } 
        );

        int val = 0;
        std::promise<int> promise3;
        //la promesse que doit remplir le thread annexe

         My_Runtime3.task(SpRead(val)
            , 
            [&promise3](const int& /*valParam*/)
            {
                usleep(100);
                promise3.get_future().get();
                //Retourne un objet future qui a le même état asynchrone associé que cet objet promise.
            }
        ).setTaskName("First task");

       
        
        for(int idx = 0; idx < 1; idx++) {
          My_Runtime3.task(SpWrite(val), 
              [](int& valParam)  
              {
                cout<<"CTRL Val in certain task="<<valParam<<"\n";
                usleep(500);
              }
          ).setTaskName("Certain task -- " + std::to_string(idx));
        }

        
        
        const int nbUncertainTasks = 6;

        for(int idx = 0 ; idx < nbUncertainTasks ; ++idx){
            My_Runtime3.task(SpPotentialWrite(val), 
               [](int& valParam) -> bool
                {
                   cout<<"CTRL Val in uncertain task="<<valParam<<"\n";
                   usleep(1000);
                   return true;
                }
            ).setTaskName("Uncertain task -- " + std::to_string(idx));
        }
        

        /*
        for(int idx = 2; idx < 4; idx++) {
          My_Runtime3.task(SpWrite(val), 
              [](int& valParam)  
              {
                usleep(1500);
              }
           ).setTaskName("Certain task -- " + std::to_string(idx));
        }
        */
        
        My_Runtime3.task(SpWrite(val), 
              []([[maybe_unused]] int& valParam)
              {
                usleep(2000);
              }
        ).setTaskName("Last-task");

        promise3.set_value(0);
        //L'opération se comporte comme si set_value , set_exception , 
        //set_value_at_thread_exit et set_exception_at_thread_exit acquéraient 
        //un seul mutex associé à l'objet de promesse lors de la mise à jour de 
        //l'objet de promesse.
    
        //Une exception est levée s'il n'y a pas d'état partagé ou si 
        //l'état partagé stocke déjà une valeur ou une exception.
        //Les appels à cette fonction n'introduisent pas de courses de 
        //données avec les appels à get_future (ils n'ont donc pas besoin 
        //de se synchroniser les uns avec les autres).



        My_Runtime3.waitAllTasks();

        My_Runtime3.generateDot("Runtime3.dot",true);
        My_Runtime3.generateTrace("Runtime3.svg");


    }



    if (1==1)
    {

        SpDebug::Controller.isEnable();

        cout<<"===================================\n";
            const int NbThreads = 2;
            SpRuntime My_Runtime4(NbThreads);

            int readVal = 0;
            std::promise<int> promise0;
            std::promise<int> promise1;
            std::promise<int> promise2;

            My_Runtime4.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                   promise0.get_future().get();
                   usleep(2000);
                }).setTaskName("Promise0");

            My_Runtime4.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                    promise1.get_future().get();
                    usleep(2000);
                }).setTaskName("Promise1");

            My_Runtime4.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                    promise2.get_future().get();
                    usleep(2000);
                }).setTaskName("Promise2");

            My_Runtime4.waitRemain(3);

            promise0.set_value(0);

            //My_Runtime4

            My_Runtime4.waitRemain(2);

            promise1.set_value(0);

            My_Runtime4.waitRemain(1);

            promise2.set_value(0);

            My_Runtime4.waitAllTasks();

            My_Runtime4.generateDot("Runtime4.dot",true);
            My_Runtime4.generateTrace("Runtime4.svg");
        }

    if (1==1)
    {



    


        {

        
        const int NbTasks = 10;
        const int NbThreads = 10;

        std::promise<int> promises[NbTasks];
        //Fix Taches Pronises
        SpRuntime My_Runtime5(NbThreads);

        std::cout<<"Nb Thread="<<My_Runtime5.getNbThreads()<<"\n";
        std::cout<<"Nb CPU Workers="<<My_Runtime5.getNbCpuWorkers()<<"\n";

            int readVal = 0;

            for(int idxTask = 0 ; idxTask < NbTasks ; ++idxTask){
                My_Runtime5.task(SpRead(readVal),
                    [&,idxTask](const int& /*readVal*/)
                    {
                        promises[idxTask].get_future().get();
                        usleep(1000);
                        //usleep(100*NbTasks);
                    });
            }

            for(int idxTask = NbTasks ; idxTask < 2*NbTasks ; ++idxTask){
                My_Runtime5.waitRemain(idxTask); //mutexFinishedTasks
                
            }


            //for(int idxTask = 0 ; idxTask < NbTasks ; ++idxTask){
            //    My_Runtime5.waitRemain(idxTask); //mutexFinishedTasks
            //}

            
            for(int idxTaskPromise = 0 ; idxTaskPromise < NbTasks ; ++idxTaskPromise)
            {
                promises[idxTaskPromise].set_value(0);
                //Une exception est levée s'il n'y a pas d'état partagé ou si 
                //l'état partagé stocke déjà une valeur ou une exception.

                //usleep(2000);
                for(int idxTask = NbTasks-idxTaskPromise-1 ; idxTask < 2*NbTasks ; ++idxTask)
                {
                    My_Runtime5.waitRemain(idxTask);
                }
            }
            

            My_Runtime5.waitAllTasks();

            My_Runtime5.generateDot("Runtime5.dot",true);
            My_Runtime5.generateTrace("Runtime5.svg");
        }


            const int NbThreads = 10;
            SpRuntime My_Runtime6(NbThreads);

            int readVal = 0;
            std::promise<int> promise0;
            std::promise<int> promise1;


            My_Runtime6.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                   promise0.get_future().get();
                   usleep(2000);
                }).setTaskName("Promise0");

            My_Runtime6.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                    promise1.get_future().get();
                    usleep(2000);
                }).setTaskName("Promise1");

 
            My_Runtime6.waitRemain(3);

            promise0.set_value(0);
            My_Runtime6.waitRemain(2);

            promise1.set_value(0);



            My_Runtime6.waitAllTasks();

            My_Runtime6.generateDot("Runtime6.dot",true);
            My_Runtime6.generateTrace("Runtime6.svg");

    }


    if (1==0)
    {

        cout<<"===================================\n";



            const int NbThreads = 2;
            SpRuntime My_Runtime5(NbThreads);

            int readVal = 0;
            

            My_Runtime5.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                   
                   usleep(2000);
                }).setTaskName("Promise0");

            My_Runtime5.task(SpRead(readVal),
                [&](const int& /*readVal*/)
                {
                    
                    usleep(2000);
                }).setTaskName("Promise1");


            My_Runtime5.waitRemain(2);

            My_Runtime5.waitAllTasks();

            My_Runtime5.generateDot("Runtime5.dot",true);
            My_Runtime5.generateTrace("Runtime5.svg");
        }


   if (1==1)
    {        
        const int NBB=500;
        const int NbTasks = NBB;
        const int NbThreads = NBB;

        
        double Tab[NbTasks]={0};
        for (int i=0; i<NbTasks; ++i)
        {
            Tab[i]=0.01*double(i);
        }
        UTestRaceChecker counterAccess;

        std::promise<int> promises[NbTasks];
        //Fix Taches Pronises
        SpRuntime My_Runtime7(NbThreads);

        std::cout<<"Nb Thread="<<My_Runtime7.getNbThreads()<<"\n";
        std::cout<<"Nb CPU Workers="<<My_Runtime7.getNbCpuWorkers()<<"\n";

            int readVal = 0;

            for(int idxTask = 0 ; idxTask < NbTasks ; ++idxTask){
                My_Runtime7.task(
                    SpRead(readVal),
                    SpReadArray(Tab,SpArrayView(NbTab))
                    ,
                    [&,idxTask](
                        const int& /*readVal*/,
                        SpArrayAccessor<const double>&)
                    {
                        promises[idxTask].get_future().get();
                        usleep(1000);
                        
                    }).setTaskName("Runtime Array Process"+to_string(idxTask));

                
                
                
            }

            for (const double& value : Tab) { cout << value << "  "; }; cout << "\n";


            //for(int idxTask = 0 ; idxTask < NbTasks ; ++idxTask)

            //My_Runtime7.task(SpWrite(Tab[0]),
            //    [](double& valParam)
            //    {
            //    }
            //    );


/*
            for(int idx = 0 ; idx < NbTasks ; ++idx){
                My_Runtime7.task(SpWrite(Tab[idx]),
                             SpReadArray(Tab,SpArrayView(NbTasks).removeItem(idx)),
                                     
                [idx](double& valParam, const SpArrayAccessor<const double>& valArray) -> bool
                {
                    {
                            if(idx == 3){
                                valParam += 1;
                            }
                            if(idx == 5){
                                valParam += 10;
                            }
                            usleep(1000);
                            cout<<"valParam="<<valParam<<"\n";
                        return (idx == 3 || idx == 5); 
                    } 
                }
                ).setTaskName("Runtime Array Process"); //END runtime
            } //END FOR
*/
            

            for(int idxTask = NbTasks ; idxTask < 2*NbTasks ; ++idxTask){
                
                
                My_Runtime7.waitRemain(idxTask); //mutexFinishedTasks
                
            }


            //for(int idxTask = 0 ; idxTask < NbTasks ; ++idxTask){
            //    My_Runtime5.waitRemain(idxTask); //mutexFinishedTasks
            //}

            
            for(int idxTaskPromise = 0 ; idxTaskPromise < NbTasks ; ++idxTaskPromise)
            {
                promises[idxTaskPromise].set_value(0);

                

                //Une exception est levée s'il n'y a pas d'état partagé ou si 
                //l'état partagé stocke déjà une valeur ou une exception.

                //usleep(2000);
                for(int idxTask = NbTasks-idxTaskPromise-1 ; idxTask < 2*NbTasks ; ++idxTask)
                {
                    My_Runtime7.waitRemain(idxTask);
                }
            }

            for (const double& value : Tab) { cout << value << "  "; }; cout << "\n";
            

            My_Runtime7.waitAllTasks();

            My_Runtime7.generateDot("Runtime7.dot",true);
            My_Runtime7.generateTrace("Runtime7.svg");
        }



if (1==1)
    {
         
    }


}



 
#pragma GCC diagnostic pop

…​