@@ -251,6 +251,200 @@ BOOST_AUTO_TEST_CASE(testReplayFlowError) {
251251 }
252252}
253253
254+ // The code below replicates the behavior of one iteration of one of our static backtests
255+ // when executed on our GPGPU Framework.
256+ namespace {
257+ double externalAverage (const std::vector<double >& v) {
258+ boost::accumulators::accumulator_set<double , boost::accumulators::stats<boost::accumulators::tag::mean>> acc;
259+ for (auto const & x : v) {
260+ acc (x);
261+ }
262+ return boost::accumulators::mean (acc);
263+ }
264+ struct S0 {
265+ std::size_t randomVariableOpCode;
266+ std::vector<std::size_t > args;
267+ std::vector<bool > vb;
268+ };
269+ void runBacktest (const std::string &d, const std::size_t id, const std::vector<S0>& s0, double expected) {
270+ BOOST_TEST_MESSAGE (" testing backtest iteration on device '" << d << " '." );
271+
272+ ComputeEnvironmentFixture fixture;
273+ ComputeEnvironment::instance ().selectContext (d);
274+
275+ const std::size_t n = 10000 ;
276+ std::size_t externalCalculationId_ = 0 ;
277+ std::size_t cgVersion_ = 1 ;
278+ bool newExternalCalc = false ;
279+ std::tie (externalCalculationId_, newExternalCalc) =
280+ ComputeEnvironment::instance ().context ().initiateCalculation (n, externalCalculationId_, cgVersion_);
281+ constexpr double max = std::numeric_limits<float >::max ();
282+
283+ std::vector<double > v0 = {
284+ -56340 , -39240 , -37560 , -37380 , -35460 , -30960 , -26220 , -26160 , -24920 , -24060 , -22820 ,
285+ -22680 , -20640 , -18780 , -18540 , -17480 , -16680 , -15960 , -15380 , -15120 , -14100 , -13380 ,
286+ -13140 , -13080 , -13020 , -12460 , -11120 , -10640 , -10320 , -9480 , -9400 , -9020 , -8920 ,
287+ -8760 , -8740 , -8540 , -7560 , -7300 , -7260 , -6820 , -6320 , -5560 , -5320 , -4820 ,
288+ -4700 , -4460 , -4380 , -3160 , -2 , -1 , -0.0939 , -0.0654 , -0.0623 , -0.0516 , -0.0437 ,
289+ -0.0378 , -0.0278 , -0.0266 , -0.0235 , -0.0223 , -0.0219 , -0.0158 , 0 , 0.003 , 0.0075 , 0.5 ,
290+ 0.8434 , 0.8719 , 0.875 , 0.8857 , 0.8936 , 0.8995 , 0.9095 , 0.9107 , 0.9138 , 0.915 , 0.9154 ,
291+ 0.9215 , 0.9373 , 0.9403 , 0.9448 , 1 , 2 , 3 , 15 , 30 , 600 , 1200 ,
292+ 1500 , 2100 , 3000 , 30000 , 187460 , 200000 , 400000 , max, 0.0242777 , 0.000589407 , 0.99513 ,
293+ 0.998575 , -0.172332 , 0.998575 };
294+
295+ for (const auto & x : v0)
296+ ComputeEnvironment::instance ().context ().createInputVariable (x);
297+
298+ std::vector<std::vector<std::size_t >> rv = {{11 }};
299+ auto gen = ComputeEnvironment::instance ().context ().createInputVariates (rv.size (), rv.front ().size (), 42 );
300+
301+ for (const auto & s : s0) {
302+ ComputeEnvironment::instance ().context ().applyOperation (s.randomVariableOpCode , s.args );
303+ int i = 0 ;
304+ for (const auto & b : s.vb ) {
305+ if (b)
306+ ComputeEnvironment::instance ().context ().freeVariable (s.args [i]);
307+ i++;
308+ }
309+ }
310+ ComputeEnvironment::instance ().context ().declareOutputVariable (id);
311+
312+ std::vector<std::vector<double >> externalOutput_ = std::vector<std::vector<double >>(1 , std::vector<double >(n));
313+ std::vector<double *> externalOutputPtr_ = std::vector<double *>(1 , &externalOutput_.front ()[0 ]);
314+ std::size_t regressionOrder = 2 ;
315+ ComputeEnvironment::instance ().context ().finalizeCalculation (externalOutputPtr_, {regressionOrder});
316+ auto baseNpv_ = externalAverage (externalOutput_[0 ]);
317+ BOOST_CHECK_CLOSE (baseNpv_, expected, 1E-3 );
318+ }
319+ } // namespace
320+
321+ BOOST_AUTO_TEST_CASE (testBacktest) {
322+
323+ // Replicate one iteration of the static backtest, execute it on the GPU
324+ std::string d0 = " BasicCpu/Default/Default" ;
325+ const std::size_t id0 = 78 ;
326+ std::vector<S0> s0 = {
327+ {5 , {99 , 98 }, {false , false }},
328+ {4 , {65 , 97 }, {true , false }},
329+ {15 , {103 }, {true }},
330+ {3 , {65 }, {true }},
331+ {2 , {103 , 104 }, {true , true }},
332+ {13 , {100 }, {false }},
333+ {4 , {96 , 102 }, {false , true }},
334+ {1 , {100 , 103 }, {false , true }},
335+ {1 , {105 , 65 }, {true , true }},
336+ {13 , {103 }, {true }},
337+ {8 , {65 , 62 }, {false , false }},
338+ {8 , {65 , 78 }, {false , false }},
339+ {2 , {81 , 105 }, {false , true }},
340+ {4 , {103 , 106 }, {true , true }},
341+ {2 , {65 , 78 }, {false , false }},
342+ {4 , {94 , 106 }, {true , true }},
343+ {4 , {105 , 103 }, {false , true }},
344+ {2 , {81 , 105 }, {false , true }},
345+ {8 , {65 , 78 }, {false , false }},
346+ {8 , {65 , 95 }, {false , true }},
347+ {2 , {81 , 94 }, {false , true }},
348+ {4 , {105 , 95 }, {true , true }},
349+ {2 , {65 , 78 }, {true , true }},
350+ {4 , {93 , 95 }, {true , true }},
351+ {1 , {106 , 78 }, {false , true }},
352+ {4 , {94 , 95 }, {false , true }},
353+ {2 , {81 , 94 }, {false , true }},
354+ {4 , {95 , 106 }, {true , true }},
355+ {1 , {78 , 94 }, {true , true }},
356+ {9 , {106 , 62 }, {false , true }},
357+ {1 , {89 , 106 }, {false , false }},
358+ {4 , {94 , 62 }, {false , true }},
359+ {2 , {81 , 94 }, {false , false }},
360+ {4 , {62 , 89 }, {true , true }},
361+ {1 , {78 , 95 }, {true , true }},
362+ {4 , {94 , 83 }, {false , true }},
363+ {2 , {81 , 94 }, {false , true }},
364+ {4 , {83 , 82 }, {true , true }},
365+ {1 , {95 , 94 }, {true , true }},
366+ {9 , {89 , 91 }, {true , true }},
367+ {2 , {81 , 94 }, {false , false }},
368+ {2 , {81 , 94 }, {false , false }},
369+ {5 , {81 , 101 }, {false , false }},
370+ {5 , {81 , 95 }, {false , true }},
371+ {4 , {106 , 83 }, {false , false }},
372+ {4 , {94 , 95 }, {false , true }},
373+ {2 , {81 , 94 }, {false , false }},
374+ {2 , {81 , 94 }, {false , true }},
375+ {4 , {106 , 83 }, {true , true }},
376+ {1 , {78 , 94 }, {false , true }},
377+ {4 , {62 , 83 }, {false , true }},
378+ {2 , {81 , 62 }, {true , true }},
379+ {4 , {83 , 78 }, {true , true }},
380+ {1 , {94 , 62 }, {true , true }},
381+ };
382+ runBacktest (d0, id0, s0, -39400 );
383+
384+ // Uncomment the code below to replicate one iteration of the backtest on the GPUs
385+ // std::string d1 = "OpenCL/Intel(R) OpenCL Graphics/Intel(R) Iris(R) Xe Graphics";
386+ // std::string d2 = "OpenCL/NVIDIA CUDA/NVIDIA GeForce RTX 3050 Ti Laptop GPU";
387+ // const std::size_t id1 = 111;
388+ // std::vector<S0> s1 = {
389+ // {5, {99, 98}, {false, false}},
390+ // {4, {65, 97}, {true, false}},
391+ // {15, {103}, {true}},
392+ // {3, {105}, {true}},
393+ // {2, {103, 104}, {true, true}},
394+ // {13, {100}, {false}},
395+ // {4, {96, 102}, {false, true}},
396+ // {1, {100, 103}, {false, true}},
397+ // {1, {102, 105}, {true, true}},
398+ // {13, {103}, {true}},
399+ // {8, {105, 62}, {false, false}},
400+ // {8, {105, 78}, {false, false}},
401+ // {2, {81, 102}, {false, true}},
402+ // {4, {103, 106}, {true, true}},
403+ // {2, {105, 78}, {false, false}},
404+ // {4, {94, 106}, {true, true}},
405+ // {4, {102, 103}, {false, true}},
406+ // {2, {81, 102}, {false, true}},
407+ // {8, {105, 78}, {false, false}},
408+ // {8, {105, 95}, {false, true}},
409+ // {2, {81, 107}, {false, true}},
410+ // {4, {102, 108}, {true, true}},
411+ // {2, {105, 78}, {true, true}},
412+ // {4, {93, 108}, {true, true}},
413+ // {1, {106, 105}, {false, true}},
414+ // {4, {107, 108}, {false, true}},
415+ // {2, {81, 107}, {false, true}},
416+ // {4, {108, 106}, {true, true}},
417+ // {1, {105, 107}, {true, true}},
418+ // {9, {106, 62}, {false, true}},
419+ // {1, {89, 106}, {false, false}},
420+ // {4, {107, 105}, {false, true}},
421+ // {2, {81, 107}, {false, false}},
422+ // {4, {105, 89}, {true, true}},
423+ // {1, {108, 102}, {true, true}},
424+ // {4, {107, 83}, {false, true}},
425+ // {2, {81, 107}, {false, true}},
426+ // {4, {108, 82}, {true, true}},
427+ // {1, {102, 107}, {true, true}},
428+ // {9, {105, 91}, {true, true}},
429+ // {2, {81, 107}, {false, false}},
430+ // {2, {81, 107}, {false, false}},
431+ // {5, {81, 101}, {false, false}},
432+ // {5, {81, 109}, {false, true}},
433+ // {4, {106, 110}, {false, false}},
434+ // {4, {107, 109}, {false, true}},
435+ // {2, {81, 107}, {false, false}},
436+ // {2, {81, 107}, {false, true}},
437+ // {4, {106, 110}, {true, true}},
438+ // {1, {111, 107}, {false, true}},
439+ // {4, {112, 110}, {false, true}},
440+ // {2, {81, 112}, {true, true}},
441+ // {4, {110, 111}, {true, true}},
442+ // {1, {107, 112}, {true, true}},
443+ // };
444+ // runBacktest(d1, id1, s1, -39438);
445+ // runBacktest(d2, id1, s1, -39438);
446+ }
447+
254448BOOST_AUTO_TEST_SUITE_END ()
255449
256450BOOST_AUTO_TEST_SUITE_END()
0 commit comments