Skip to content

Commit

Permalink
get linux build running for lattice pricer examples (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
andyD123 authored Jan 6, 2024
1 parent b6335ba commit f94cdae
Showing 1 changed file with 87 additions and 116 deletions.
203 changes: 87 additions & 116 deletions scratch/scratch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@

#include "../Vectorisation/VecX/dr3.h"

#include <algorithm>

#include <random>
#include <numeric>
#include <iterator>
#include <iostream>
#include <vector>
#include <chrono>
#include <iomanip>
#include <iomanip>
#include <functional>
#include <utility>



//using namespace DRC::VecD2D;
Expand All @@ -24,80 +22,63 @@ using namespace DRC::VecD4D;



void doAdd()
void doAddWithoutCancellation()
{



using BINNED_ACCUMULATOR = BinsT<VecXX::INS>;
using FLOAT = InstructionTraits<VecXX::INS>::FloatType;
FLOAT oneThird = static_cast<FLOAT>(1.0 / 3.0);


std::cout << "create empty bin, value 0.0 \n";
BINNED_ACCUMULATOR bin;


std::cout << "add one third to it , value =";

bin += oneThird;
std::cout << std::setprecision(8) << bin.hsum();
std::cout << std::setprecision(8) << bin.hsum() << "\n";

std::cout << "add one hundred thousand to it , value =";
bin += 100000.0f;

auto t = bin.hsum();

std::cout << std::setprecision(8)<< "\n" << t << "\n" << std::endl;
std::cout << std::setprecision(8)<< t << std::endl;

std::cout << "dd minus one hundred thousand to it , value =";
bin += -100000.0f;
t=bin.hsum();

std::cout << std::setprecision(8) << "\n" << t << "\n" << std::endl;

//////////////////////////
FLOAT bigThird = oneThird * 1.e20f;

BINNED_ACCUMULATOR bigbin;
std::cout << std::setprecision(8) << t << std::endl;


bigbin += bigThird;
std::cout << std::setprecision(8) << bigbin.hsum();

bigbin += 100000.0f *1.e20f;

t = bigbin.hsum();

std::cout << std::setprecision(8) << "\n" << t << "\n" << std::endl;

bigbin += -100000.0f* 1.e20f;
t = bigbin.hsum();

std::cout << std::setprecision(8) << "\n" << t << "\n" << std::endl;
std::cout << "no cancellation! \n \n \n";


}

/*
example summation using std reduction, and for loop
Example summation using std reduction, and for loop
then pairwise_reduce and reduce with Kahan summation
and finally using binned summation.
generally for large sums we get the same rounding error for the for loop and
std accumulation
with pairwise _reduce and kahan, we tend to last digit level precision.
Generally for large sums, we get the same rounding error for the for loop and
std accumulation/ reduce
However when we add pairs of large +ve and -ve numbers which cancel each other
they destroy accuracy of intermediate sums. This is achieved by running
using BIG_CANCELLATION = true.
However, with pairwise reduce and kahan accumulation, we tend to last digit level precision.
the cancelation flag does not change the theoretical value of the sum.
and the sums should return the same result as when CANCELLATION =false.
Unfortunately, when we add pairs of large +ve and -ve numbers which cancel each other
they destroy accuracy of intermediate sums. In the code we turn this on by
setting BIG_CANCELLATION = true.
Binned arithmetic can achieve this sort of stability under the right circumstances.
The cancellation flag does not change the theoretical value of the sum,
the sums should return the same result as when CANCELLATION =false.
However, we find that only the binned arithmetic scheme can achieve this
sort of stability with this example.
The input is randomly permuted and re calculated. The ideal result is that we get the same
answer irrespective of the ordering.
The input data set is randomly permuted and the sum re calculated. The ideal result is that we get the same
answer irrespective of the ordering. The actual results differ to varying degrees.
This can happen with pairwise and kahan summation if we have no significan cancellation.
Both pairwise and kahan summation can significantly reduce rounding errors, however
binned summation tends to work much better if we have significant cancellation.
For loops and std::accumulate /reduce are generally less accurate.
*/

Expand All @@ -114,122 +95,112 @@ void setCancelInput(double& dbl)

int main()
{

doAdd();
//simple binned sum example
doAddWithoutCancellation();

long SZ = 10000 * 1024 ;

long SZ = 10000 * 1024 ; // size of data set to be summed
using FLOAT = InstructionTraits<VecXX::INS>::FloatType;
FLOAT initVal = static_cast<FLOAT>(1.0 / 3.0);

VecXX data(initVal, SZ);

double scale = 1.0;// us power of 2 eg 1.0 / 1024.0 * 1.0 / 1024.0 * 1.0 / 1024.0;
data *= scale;


bool USE_BIG_CANCELLATION = false;
//bool USE_BIG_CANCELLATION = true;
bool USE_BIG_CANCELLATION = false;

int i = 0;
for( int C = 0; C < 2;C++) // iterate using cancellation data set
{
if (C >0) { USE_BIG_CANCELLATION = true;}

int i = 0;


auto mixed = data;
long count = 0;
for (auto& x : mixed)
{

//make data members slightly different and add
//cancelling values if required
for (auto &x: mixed) {
count++;
x += count * 0.0001f;
FLOAT a;
setCancelInput(a);
FLOAT b = -a;

if (!USE_BIG_CANCELLATION)
{
if (!USE_BIG_CANCELLATION) {
a = 0.0;
b = 0.0;
}
if ((count > 17) && (count % 17 == 0))

if ((count > 17) && (count % 17 == 0)) //every 17'th element set up cancellation
{
auto c = mixed[count] + mixed[count - 1] + mixed[count - 2];
mixed[count] = c;
mixed[count - 1] = b;
mixed[count - 2] = a;
}

ignore(x);
}

std::vector<FLOAT> scaledVec = mixed;

for(int kkk = 0; kkk < 100; kkk++)
//std::vector<FLOAT> scaledVec = mixed; //for debug observation
// run ten permutations of data set and do summation
for (int kkk = 0; kkk < 10; kkk++)
{
std::random_device rd;
std::mt19937 g(rd());

std::random_device rd;
std::mt19937 g(rd());


std::shuffle(mixed.begin(), mixed.end(), g);
std::vector<FLOAT> obs= mixed;
std::shuffle(mixed.begin(), mixed.end(), g);
// std::vector<FLOAT> obs= mixed;


auto std_acc = std::accumulate(mixed.begin(), mixed.end(), static_cast<FLOAT>(0.0));
auto std_acc = std::accumulate(mixed.begin(), mixed.end(), static_cast<FLOAT>(0.0));
auto std_reduce = std::reduce(mixed.begin(), mixed.end(), static_cast<FLOAT>(0.0));

auto sumIt = [](auto x, auto y) { return x + y; };
auto sumPairwiseDr3 = ApplyAccumulate2UR_X_pairwise(mixed, sumIt);

auto sumIt = [](auto x, auto y) {return x + y; };
auto sumPairwiseDr3 = ApplyAccumulate2UR_X_pairwise(mixed, sumIt);
auto DRCubedAccum = ApplyAccumulate2UR_X(mixed, sumIt);


auto DRCubedAccum = ApplyAccumulate2UR_X(mixed, sumIt);
FLOAT trad_for_loop = 0.0f;
for (auto x: mixed) {
trad_for_loop += x;
}

FLOAT trad_for_loop = 0.0f;
for (auto x : mixed)
{
trad_for_loop += x;
}
//correcting summation lambda
auto NULL_Vec = VecXX::INS(0.0);
auto KhanAddV = [c = NULL_Vec](auto sum, auto rhs) mutable {
auto y = rhs - c;
auto t = sum + y;
c = (t - sum);
c = c - y;
sum = t;
return t;
};


auto sumKahan = reduce(mixed, KhanAddV);

auto NULL_Vec = VecXX::INS(0.0);

auto KhanAddV = [c = NULL_Vec](auto sum, auto rhs) mutable
{
auto y = rhs - c;
auto t = sum + y;
c = (t - sum);
c = c - y;
sum = t;
return t;
};
NULL_Vec = VecXX::INS(0.0);
auto sumPairwiseWithKahan = ApplyAccumulate2UR_X_pairwise(mixed, KhanAddV);

// reduce with binned accumulator
using BINNED_ACCUMULATOR = BinsT<VecXX::INS>;
BINNED_ACCUMULATOR Bin(0.0);

auto sumKahan = reduce(mixed, KhanAddV);
auto binned_Sum = reduceWithAccumulator(Bin, mixed, BinnedAdd);

NULL_Vec = VecXX::INS(0.0);
std::cout << "\nUsing Significant Cancellation Data = " << std::boolalpha << USE_BIG_CANCELLATION << " \n";
std::cout << "shuffled version " << ++i << "\n" << std::setprecision(16)
<< trad_for_loop << "\t for loop sum \n"
<< std_acc << "\t std::accumulate sum \n"
<< std_reduce << "\t std::reduce \n"
<< DRCubedAccum << "\t accumulate DR3 \n"
<< sumPairwiseDr3 << "\t sum pairwise \n"
<< sumKahan << "\t sum Kahan acc \n"
<< sumPairwiseWithKahan << " \t pairwise_sum using Kahan acc \n"
<< binned_Sum << "\t binned sum acc \n \n \n \n";

auto sumPairwiseWithKahan = ApplyAccumulate2UR_X_pairwise(mixed, KhanAddV);


// reduce with binned accumulator
using BINNED_ACCUMULATOR = BinsT<VecXX::INS>;
BINNED_ACCUMULATOR Bin(0.0);

auto binned_Sum = reduceWithAccumulator(Bin, mixed, BinnedAdd);


std::cout << ++i << "\n" << std::setprecision(16)
<< trad_for_loop << "\t for loop sum trad = \n"
<< std_acc << "\t std::accumulate sum trad = \n"
<< DRCubedAccum << "\t accumulate DR3 = \n"
<< sumPairwiseDr3 << "\t sum pairwise = \n"
<< sumKahan << " ,\t Kahan acc ,\n"
<< sumPairwiseWithKahan << " ,\t pairwise_sum using Kahan acc ,\n"
<< binned_Sum << "\t \t binned sum acc, \n \n \n \n";

}

}
}
}

0 comments on commit f94cdae

Please sign in to comment.