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 :