LCOV - code coverage report
Current view: top level - UTests - testPotentialTasks.cpp (source / functions) Hit Total Coverage
Test: Coverage example Lines: 100 102 98.0 %
Date: 2021-12-02 17:21:05 Functions: 14 14 100.0 %

          Line data    Source code
       1             : ///////////////////////////////////////////////////////////////////////////
       2             : // Spetabaru - Berenger Bramas MPCDF - 2017
       3             : // Under LGPL Licence, please you must read the LICENCE file.
       4             : ///////////////////////////////////////////////////////////////////////////
       5             : 
       6             : #include "UTester.hpp"
       7             : #include "utestUtils.hpp"
       8             : 
       9             : #include "Data/SpDataAccessMode.hpp"
      10             : #include "Utils/SpUtils.hpp"
      11             : #include "Utils/SpArrayView.hpp"
      12             : #include "Utils/SpArrayAccessor.hpp"
      13             : 
      14             : #include "Task/SpTask.hpp"
      15             : #include "Legacy/SpRuntime.hpp"
      16             : 
      17             : class TestPotentialTask : public UTester< TestPotentialTask > {
      18             :     using Parent = UTester< TestPotentialTask >;
      19             :     
      20             :     template <SpSpeculativeModel Spm>
      21           3 :     void TestBasic(){
      22           6 :         SpRuntime<Spm> runtime;
      23             : 
      24           3 :         runtime.setSpeculationTest([](const int /*inNbReadyTasks*/, const SpProbability& /*inProbability*/) -> bool{
      25           0 :             return true;
      26             :         });
      27             : 
      28           3 :         int val = 0;
      29           3 :         std::promise<int> promise1;
      30             : 
      31         134 :         runtime.task(SpRead(val), [](const int& /*valParam*/){
      32             :         });
      33             :         // val is 0
      34             : 
      35           9 :         runtime.task(SpRead(val), [&promise1](const int& /*valParam*/){
      36           3 :             promise1.get_future().get();
      37             :         });
      38             :         // val is 0
      39             : 
      40          48 :         runtime.task(SpPotentialWrite(val), [](int& /*valParam*/) -> bool {
      41           3 :             std::cout << "Maybe task will return false" << std::endl;
      42           3 :             std::cout.flush();
      43           3 :             return false;
      44             :         });
      45             :         // val is 0
      46             : 
      47           3 :         std::atomic_int counterFirstSpec(0);
      48             : 
      49         330 :         runtime.task(SpWrite(val), [&val,&counterFirstSpec](int& valParam){
      50           3 :             std::cout << "Speculative task, valParam is " << valParam << " at " << &valParam << std::endl;
      51           3 :             std::cout << "Speculative task, val is " << val << " at " << &val << std::endl;
      52           3 :             valParam += 1;
      53           3 :             std::cout << "Speculative task, valParam is " << valParam << " at " << &valParam << std::endl;
      54           3 :             std::cout << "Speculative task, val is " << val << " at " << &val << std::endl;
      55           3 :             std::cout.flush();
      56           3 :             counterFirstSpec += 1;
      57             :         });
      58             :         // val is 1
      59             : 
      60             : 
      61           6 :         runtime.task(SpPotentialWrite(val), [](int& valParam) -> bool {
      62             :             // valParam should be 1
      63           3 :             std::cout << "Maybe task 2, valParam is " << valParam << " at " << &valParam << std::endl;
      64           3 :             std::cout.flush();
      65           3 :             valParam += 2;
      66           3 :             std::cout << "Maybe task 2, return true with valParam is " << valParam << " at " << &valParam << std::endl;
      67           3 :             return true;
      68             :         });
      69             :         // val is 3
      70             : 
      71           3 :         std::atomic_int counterSecondSpec(0);
      72             : 
      73          45 :         runtime.task(SpWrite(val), [&val,&counterSecondSpec](int& valParam){
      74           6 :             std::cout << "Speculative last write, valParam is " << valParam << " at " << &valParam << std::endl;
      75           6 :             std::cout << "Speculative last write, val is " << val << " at " << &val << std::endl;
      76           6 :             valParam *= 2;
      77           6 :             std::cout << "Speculative last write, valParam is " << valParam << " at " << &valParam << std::endl;
      78           6 :             std::cout << "Speculative last write, val is " << val << " at " << &val << std::endl;
      79           6 :             std::cout.flush();
      80           6 :             counterSecondSpec += 1;
      81             :         });
      82             :         // val is 6
      83             : 
      84           3 :         promise1.set_value(0);
      85             : 
      86           3 :         runtime.waitAllTasks();
      87           3 :         runtime.stopAllThreads();
      88             : 
      89           3 :         runtime.generateDot("/tmp/test.dot");
      90           3 :         runtime.generateTrace("/tmp/test.svg");
      91             : 
      92           6 :         UASSERTEEQUAL(counterFirstSpec.load(), 1);
      93           6 :         UASSERTEEQUAL(counterSecondSpec.load(), 2);
      94           3 :         UASSERTEEQUAL(val, 6);
      95           3 :     }
      96             : 
      97             :     template <SpSpeculativeModel Spm>
      98           3 :     void TestBasicLoop(){
      99           3 :         std::array<unsigned int,2> SleepTimes{0, 500000};
     100           9 :         for(auto SleepTime : SleepTimes){
     101          12 :             SpRuntime<Spm> runtime;
     102             : 
     103           6 :             runtime.setSpeculationTest([](const int /*inNbReadyTasks*/, const SpProbability& /*inProbability*/) -> bool{
     104           0 :                 return true;
     105             :             });
     106             : 
     107           6 :             const int arraySize = 6;
     108           6 :             int val[arraySize] = {0};
     109             : 
     110          12 :             UTestRaceChecker counterAccess;
     111             : 
     112           6 :             std::promise<int> promise1;
     113             : 
     114          18 :             runtime.task(SpReadArray(val,SpArrayView(arraySize)), [&promise1](SpArrayAccessor<const int>& /*valParam*/){
     115           6 :                 promise1.get_future().get();
     116             :             });
     117             :             // val is 0
     118             : 
     119          42 :             for(int idx = 0 ; idx < arraySize ; ++idx){
     120          72 :                 runtime.task(SpPotentialWrite(val[idx]),
     121             :                                       SpReadArray(val,SpArrayView(arraySize).removeItem(idx)),
     122             :                                       [SleepTime,idx,&counterAccess]
     123          44 :                                       (int& valParam, const SpArrayAccessor<const int>& valArray) -> bool {
     124             :                     {
     125          44 :                         counterAccess.lock();
     126          44 :                         counterAccess.addWrite(&valParam);
     127          44 :                         assert(valArray.getSize() == 5);
     128         264 :                         for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
     129         220 :                             counterAccess.addRead(&valArray.getAt(idxTest));
     130             :                         }
     131          44 :                         counterAccess.unlock();
     132             :                     }
     133             : 
     134          44 :                     if(idx == 3){
     135           6 :                         valParam += 1;
     136             :                     }
     137          44 :                     if(idx == 5){
     138          10 :                         valParam += 10;
     139             :                     }
     140          44 :                     usleep(SleepTime);
     141             : 
     142             :                     {
     143          44 :                         counterAccess.lock();
     144          44 :                         counterAccess.releaseWrite(&valParam);
     145         264 :                         for(int idxTest = 0 ; idxTest < valArray.getSize() ; ++idxTest){
     146         220 :                             counterAccess.releaseRead(&valArray.getAt(idxTest));
     147             :                         }
     148          44 :                         counterAccess.unlock();
     149             :                     }
     150             : 
     151          44 :                     return idx == 3 || idx == 5;
     152         696 :                 }).setTaskName("Task iteration " + std::to_string(idx));
     153             :             }
     154             : 
     155           6 :             promise1.set_value(0);
     156             : 
     157           6 :             runtime.waitAllTasks();
     158           6 :             runtime.stopAllThreads();
     159             : 
     160           6 :             UASSERTEEQUAL(val[3], 1);
     161           6 :             UASSERTEEQUAL(val[5], 10);
     162             : 
     163             : 
     164           6 :             runtime.generateDot("/tmp/test" + std::to_string(SleepTime) + ".dot");
     165           6 :             runtime.generateTrace("/tmp/test" + std::to_string(SleepTime) + ".svg");
     166             :         }
     167           3 :     }
     168             :     
     169           1 :     void TestBasic1() { TestBasic<SpSpeculativeModel::SP_MODEL_1>(); }
     170           1 :     void TestBasicLoop1() { TestBasicLoop<SpSpeculativeModel::SP_MODEL_1>(); }
     171           1 :     void TestBasic2() { TestBasic<SpSpeculativeModel::SP_MODEL_2>(); }
     172           1 :     void TestBasicLoop2() { TestBasicLoop<SpSpeculativeModel::SP_MODEL_2>(); }
     173           1 :     void TestBasic3() { TestBasic<SpSpeculativeModel::SP_MODEL_3>(); }
     174           1 :     void TestBasicLoop3() { TestBasicLoop<SpSpeculativeModel::SP_MODEL_3>(); }
     175             : 
     176           1 :     void SetTests() {
     177           1 :         Parent::AddTest(&TestPotentialTask::TestBasic1, "Basic test for vec type");
     178           1 :         Parent::AddTest(&TestPotentialTask::TestBasicLoop1, "Basic test for vec type");
     179           1 :         Parent::AddTest(&TestPotentialTask::TestBasic2, "Basic test for vec type");
     180           1 :         Parent::AddTest(&TestPotentialTask::TestBasicLoop2, "Basic test for vec type");
     181           1 :         Parent::AddTest(&TestPotentialTask::TestBasic3, "Basic test for vec type");
     182           1 :         Parent::AddTest(&TestPotentialTask::TestBasicLoop3, "Basic test for vec type");
     183           1 :     }
     184             : };
     185             : 
     186             : // You must do this
     187           1 : TestClass(TestPotentialTask)
     188             : 
     189             : 

Generated by: LCOV version 1.14