cpu_cuda_black_scholes.jl 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. include("../../src/Compiler/include.jl")
  2. starpu_new_cpu_kernel_file("../build/generated_cpu_black_scholes.c")
  3. starpu_new_cuda_kernel_file("../build/generated_cuda_black_scholes.cu")
  4. @cpu_cuda_kernel function black_scholes(data ::Matrix{Float64}, res ::Matrix{Float64}) ::Void
  5. widthn ::Int64 = width(data)
  6. # data[1,...] -> S
  7. # data[2,...] -> K
  8. # data[3,...] -> r
  9. # data[4,...] -> T
  10. # data[4,...] -> sig
  11. p ::Float64 = 0.2316419
  12. b1 ::Float64 = 0.31938153
  13. b2 ::Float64 = -0.356563782
  14. b3 ::Float64 = 1.781477937
  15. b4 ::Float64 = -1.821255978
  16. b5 ::Float64 = 1.330274428
  17. @indep for i = 1:widthn
  18. d1 ::Float64 = (log(data[1,i] / data[2,i]) + (data[3,i] + pow(data[5,i], 2.0) * 0.5) * data[4,i]) / (data[5,i] * sqrt(data[4,i]))
  19. d2 ::Float64 = (log(data[1,i] / data[2,i]) + (data[3,i] - pow(data[5,i], 2.0) * 0.5) * data[4,i]) / (data[5,i] * sqrt(data[4,i]))
  20. f ::Float64 = 0
  21. ff ::Float64 = 0
  22. s1 ::Float64 = 0
  23. s2 ::Float64 = 0
  24. s3 ::Float64 = 0
  25. s4 ::Float64 = 0
  26. s5 ::Float64 = 0
  27. sz ::Float64 = 0
  28. ######## Compute normcdf of d1
  29. normd1p ::Float64 = 0
  30. normd1n ::Float64 = 0
  31. boold1 ::Int64 = (d1 >= 0) + (d1 <= 0)
  32. if (boold1 >= 2)
  33. normd1p = 0.5
  34. normd1n = 0.5
  35. else
  36. tmp1 ::Float64 = abs(d1)
  37. f = 1 / sqrt(2 * M_PI)
  38. ff = exp(-pow(tmp1, 2.0) / 2) * f
  39. s1 = b1 / (1 + p * tmp1)
  40. s2 = b2 / pow((1 + p * tmp1), 2.0)
  41. s3 = b3 / pow((1 + p * tmp1), 3.0)
  42. s4 = b4 / pow((1 + p * tmp1), 4.0)
  43. s5 = b5 / pow((1 + p * tmp1), 5.0)
  44. sz = ff * (s1 + s2 + s3 + s4 + s5)
  45. if (d1 > 0)
  46. normd1p = 1 - sz # normcdf(d1)
  47. normd1n = sz # normcdf(-d1)
  48. else
  49. normd1p = sz
  50. normd1n = 1 - sz
  51. end
  52. end
  53. ########
  54. ######## Compute normcdf of d2
  55. normd2p ::Float64 = 0
  56. normd2n ::Float64 = 0
  57. boold2 ::Int64 = (d2 >= 0) + (d2 <= 0)
  58. if (boold2 >= 2)
  59. normd2p = 0.5
  60. normd2n = 0.5
  61. else
  62. tmp2 ::Float64 = abs(d2)
  63. f = 1 / sqrt(2 * M_PI)
  64. ff = exp(-pow(tmp2, 2.0) / 2) * f
  65. s1 = b1 / (1 + p * tmp2)
  66. s2 = b2 / pow((1 + p * tmp2), 2.0)
  67. s3 = b3 / pow((1 + p * tmp2), 3.0)
  68. s4 = b4 / pow((1 + p * tmp2), 4.0)
  69. s5 = b5 / pow((1 + p * tmp2), 5.0)
  70. sz = ff * (s1 + s2 + s3 + s4 + s5)
  71. if (d2 > 0)
  72. normd2p = 1 - sz # normcdf(d2)
  73. normd2n = sz # normcdf(-d2)
  74. else
  75. normd2p = sz
  76. normd2n = 1 - sz
  77. end
  78. end
  79. # normd1p = (1 + erf(d1/sqrt(2.0)))/2.0
  80. # normd1n = (1 + erf(-d1/sqrt(2.0)))/2.0
  81. # normd2p = (1 + erf(d2/sqrt(2.0)))/2.0
  82. # normd2n = (1 + erf(-d2/sqrt(2.0)))/2.0
  83. res[1,i] = data[1,i] * (normd1p) - data[2,i]*exp(-data[3,i]*data[4,i]) * (normd2p) # S * N(d1) - r*exp(-r*T) * norm(d2)
  84. res[2,i] = -data[1,i] * (normd1n) + data[2,i]*exp(-data[3,i]*data[4,i]) * (normd2n) # -S * N(-d1) + r*exp(-r*T) * norm(-d2)
  85. end
  86. end
  87. compile_cpu_kernels("../build/generated_cpu_black_scholes.so")
  88. compile_cuda_kernels("../build/generated_cuda_black_scholes.so")
  89. combine_kernel_files("../build/generated_tasks_black_scholes.so", ["../build/generated_cpu_black_scholes.so", "../build/generated_cuda_black_scholes.so"])