From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- benchmarks/CUDA/LIB/libor.cu | 387 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 benchmarks/CUDA/LIB/libor.cu (limited to 'benchmarks/CUDA/LIB/libor.cu') diff --git a/benchmarks/CUDA/LIB/libor.cu b/benchmarks/CUDA/LIB/libor.cu new file mode 100644 index 0000000..a245862 --- /dev/null +++ b/benchmarks/CUDA/LIB/libor.cu @@ -0,0 +1,387 @@ + +/* Program to compute swaption portfolio using NVIDIA CUDA */ + +#include +#include + +// parameters for nVidia device execution + +#define BLOCK_SIZE 64 +#define GRID_SIZE 64 + +// parameters for LIBOR calculation + +#define NN 80 +#define NMAT 40 +#define L2_SIZE 3280 //NN*(NMAT+1) +#define NOPT 15 +#define NPATH 4096 + +// constant data for swaption portfolio: stored in device memory, +// initialised by host and read by device threads + +__constant__ int N, Nmat, Nopt, maturities[NOPT]; +__constant__ float delta, swaprates[NOPT], lambda[NN]; + + +/* Monte Carlo LIBOR path calculation */ + +__device__ void path_calc(float *L, float *z) +{ + int i, n; + float sqez, lam, con1, v, vrat; + + for(n=0; n=0; n--) { + v1 = 0.0; + for (i=N-1; i>n; i--) { + v1 += lambda[i-n-1]*L2[i+(n+1)*N]*L_b[i]; + faci = __fdividef(delta,1.0+delta*L2[i+n*N]); + L_b[i] = L_b[i]*__fdividef(L2[i+(n+1)*N],L2[i+n*N]) + + v1*lambda[i-n-1]*faci*faci; + + } + } +} + +/* calculate the portfolio value v, and its sensitivity to L */ +/* hand-coded reverse mode sensitivity */ + +__device__ float portfolio_b(float *L, float *L_b) +{ + int m, n; + float b, s, swapval,v; + float B[NMAT], S[NMAT], B_b[NMAT], S_b[NMAT]; + + b = 1.0; + s = 0.0; + for (m=0; m=0; m--) { + n = m + Nmat; + B_b[m] += delta*S_b[m]; + L_b[n] = -B_b[m]*B[m]*__fdividef(delta,1.0+delta*L[n]); + if (m>0) { + S_b[m-1] += S_b[m]; + B_b[m-1] += __fdividef(B_b[m],1.+delta*L[n]); + } + } + + // apply discount // + + b = 1.0; + for (n=0; n= 1) + break; + } + if (dev == deviceCount) { + fprintf(stderr, "There is no device supporting CUDA.\n"); + exit(EXIT_FAILURE); + } + else + CUDA_SAFE_CALL(cudaSetDevice(dev)); + + CUT_SAFE_CALL( cutCreateTimer(&hTimer) ); + + for (i=0; i>>(d_v); + CUT_CHECK_ERROR("Pathcalc_Portfolio_kernelGPU2() execution failed\n"); + CUDA_SAFE_CALL( cudaThreadSynchronize() ); + + // Read back GPU results and compute average + + CUDA_SAFE_CALL( cudaMemcpy(h_v, d_v, sizeof(float)*NPATH, + cudaMemcpyDeviceToHost) ); + CUT_SAFE_CALL( cutStopTimer(hTimer) ); + gpuTime = cutGetTimerValue(hTimer); + + v = 0.0; + for (i=0; i>>(d_v,d_Lb); + CUT_CHECK_ERROR("Pathcalc_Portfolio_kernelGPU() execution failed\n"); + CUDA_SAFE_CALL( cudaThreadSynchronize() ); + + // Read back GPU results and compute average + + CUDA_SAFE_CALL( cudaMemcpy(h_v, d_v, sizeof(float)*NPATH, + cudaMemcpyDeviceToHost) ); + CUDA_SAFE_CALL( cudaMemcpy(h_Lb, d_Lb, sizeof(float)*NPATH, + cudaMemcpyDeviceToHost) ); + CUT_SAFE_CALL( cutStopTimer(hTimer) ); + gpuTime = cutGetTimerValue(hTimer); + + v = 0.0; + for (i=0; i