package x10;
//import java.util.Random;
public class CUDABlackScholes {
static void doBlackScholes(//float optionYears[],
//float stockPrice[],
//float optionStrike[],
//float callResult[],
//float putResult[],
//float R,
//float V,
int opt_N
) {
int blocks = 480;
int threads = 128;
Conc.finish_begin();
doBlackScholes_mainLoop(/*optionYears,stockPrice,optionStrike,callResult,putResult,R,V,*/opt_N,blocks,threads);
Conc.finish_end();
}
static void doBlackScholes_mainLoop(//float optionYears[],
//float stockPrice[],
//float optionStrike[],
//float callResult[],
//float putResult[],
//float R,
//float V,
int opt_N,
int blocks,
int threads) {
Conc.async_begin();
doBlackScholes_mainLoop_1(/*optionYears,stockPrice,optionStrike,callResult,putResult,R,V,*/opt_N,blocks,threads);
Conc.async_end();
}
static void doBlackScholes_mainLoop_1(//float optionYears[],
//float stockPrice[],
//float optionStrike[],
//float callResult[],
//float putResult[],
//float R,
//float V,
int opt_N,
int blocks,
int threads) {
for (int block=0; block<blocks; block++) {
for (int thread=0; thread<threads; thread++) {
Conc.async_begin();
doBlackScholes_innerLoop(/*optionYears,stockPrice,optionStrike,callResult,putResult,R,V,*/opt_N,blocks,threads,block,thread);
Conc.async_end();
}
}
}
static void doBlackScholes_innerLoop(//float optionYears[],
//float stockPrice[],
//float optionStrike[],
//float callResult[],
//float putResult[],
//float R,
//float V,
int opt_N,
int blocks,
int threads,
int block,
int thread) {
//int tid = block * threads + thread;
//int tids = blocks * threads;
//for (int opt=tid; opt<opt_N; opt+=tids) {
//float A1 = 0.31938153f;
//float A2 = -0.356563782f;
//float A3 = 1.781477937f;
//float A4 = -1.821255978f;
//float A5 = 1.330274429f;
//float RSQRT2PI = 0.39894228040143267793994605993438f;
//float T = optionYears[opt];
//float S = stockPrice[opt];
//float X = optionStrike[opt];
//float sqrtT = (float) Math.sqrt(T);
//float d1 = ((float) Math.log(S/X) + (R + 0.5f * V * V) * T) / (V * sqrtT);
//float d2 = d1 - V * sqrtT;
//float K1 = 1.0f / (1.0f + 0.2316419f * Math.abs(d1));
//float K2 = 1.0f / (1.0f + 0.2316419f * Math.abs(d2));
//float CNDD1 = RSQRT2PI * (float) Math.exp(- 0.5f * d1 * d1) *
// (K1 * (A1 + K1 * (A2 + K1 * (A3 + K1 * (A4 + K1 * A5)))));
//float CNDD2 = RSQRT2PI * (float) Math.exp(- 0.5f * d2 * d2) *
// (K2 * (A1 + K2 * (A2 + K2 * (A3 + K2 * (A4 + K2 * A5)))));
//if (d1 > 0) CNDD1 = 1.0f - CNDD1;
//if (d2 > 0) CNDD2 = 1.0f - CNDD2;
//float expRT = (float) Math.exp(- R * T);
//callResult[opt] = S * CNDD1 - X * expRT * CNDD2;
//putResult[opt] = X * expRT * (1.0f - CNDD2) - S * (1.0f - CNDD1);
//}
}
public static void main(String args[]) {
// Problem parameters
int OPT_N = 4000000;
int NUM_ITERATIONS = args.length;//512;
//float RISKFREE = 0.02f;
//float VOLATILITY = 0.30f;
//Random rand = new Random();
//float h_CallResultCPU[] = {};
//float h_PutResultCPU[] = {};
//float h_CallResultGPU[] = {};
//float h_PutResultGPU[] = {};
//float h_StockPrice[] = {};
//float h_OptionStrike[] = {};
//float h_OptionYears[] = {};
//float d_CallResult[] = {};
//float d_PutResult[] = {};
//float d_StockPrice[] = {};
//float d_OptionStrike[] = {};
//float d_OptionYears[] = {};
// array initializing (is OPT_N the length?)
//for(int i=0; i<OPT_N; i++) {
// h_CallResultCPU[i] = 0;
// h_PutResultCPU[i] = -1;
// h_CallResultGPU[i] = 0;
// h_PutResultGPU[i] = 0;
// h_StockPrice[i] = rand.nextFloat();
// h_OptionStrike[i] = rand.nextFloat();
// h_OptionYears[i] = rand.nextFloat();
// d_CallResult[i] = 0;
// d_PutResult[i] = 0;
// d_StockPrice[i] = h_StockPrice[i];
// d_OptionStrike[i] = h_OptionStrike[i];
// d_OptionYears[i] = h_OptionYears[i];
//}
for (int i=0; i<NUM_ITERATIONS; i++) {
doBlackScholes(/*d_OptionYears,d_StockPrice,d_OptionStrike,d_CallResult,d_PutResult,RISKFREE,VOLATILITY*/OPT_N);
}
// here, for simplicity, two calls in a finish have been replaced by two finish calls
Conc.finish_begin();
copyArray(/*d_CallResult,h_CallResultGPU,*/0,OPT_N);
Conc.finish_end();
Conc.finish_begin();
copyArray(/*d_PutResult,h_PutResultGPU,*/0,OPT_N);
Conc.finish_end();
doBlackScholes(/*h_OptionYears,h_StockPrice,h_OptionStrike,h_CallResultCPU,h_PutResultCPU,RISKFREE,VOLATILITY*/OPT_N);
//float sum_delta = 0.0f;
//float sum_ref = 0.0f;
//float max_delta = 0.0f;
//for (int i=0; i<OPT_N; i++) {
//float ref_val = h_CallResultCPU[i];
// float delta = Math.abs(ref_val - h_CallResultGPU[i]);
// if (delta > max_delta) max_delta = delta;
// sum_delta += delta;
// sum_ref += Math.abs(ref_val);
//}
//float L1norm = sum_delta / sum_ref;
}
public static void copyArray(//float source[],
//float target[],
int from,
int to) {
//for (int i=from; i<to; i++) target[i] = source[i];
}
}