Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions examples/simple/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2021-2023 Lawrence Livermore National Security, LLC and other
# AMSLib Project Developers
#
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required(VERSION 3.24)
cmake_policy(SET CMP0104 NEW)

# Define the project
project(AMSExamples LANGUAGES CXX)


option(WITH_AMS_EXAMPLE_CUDA "Option to enable CUDA" Off)
option(WITH_AMS_EXAMPLE_HIP "Option to enable HIP" Off)
option(WITH_AMS_DOWNLOAD_DATA "Download benchmark datasets at configure time" OFF)

if(WITH_AMS_EXAMPLE_CUDA AND WITH_AMS_EXAMPLE_HIP)
message(FATAL_ERROR
"WITH_AMS_EXAMPLE_CUDA=${WITH_AMS_EXAMPLE_CUDA} and "
"WITH_AMS_EXAMPLE_HIP=${WITH_AMS_EXAMPLE_HIP} are mutually exclusive."
)
endif()


set(AMS_INPUT_DIR "${CMAKE_BINARY_DIR}/inputs")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if (WITH_AMS_EXAMPLE_CUDA)
message(STATUS "HERE")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
enable_language(CUDA)
find_package(CUDAToolkit)
elseif (WITH_AMS_EXAMPLE_HIP)
enable_language(HIP)
find_package(hip REQUIRED)
endif()

if (WITH_AMS_DOWNLOAD_DATA)
enable_testing()
add_subdirectory(inputs)
endif()


add_subdirectory(blackscholes)
88 changes: 88 additions & 0 deletions examples/simple/blackscholes/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

add_executable(blck_cpu driver.cpp cpu_compute.cpp)

if (WITH_AMS_EXAMPLE_HIP)
add_executable(blck_hip driver.cpp gpu_compute.cpp)
set_source_files_properties(gpu_compute.cpp PROPERTIES LANGUAGE HIP)
target_link_libraries(blck_hip PRIVATE hip::device hip::host)
target_include_directories(blck_hip
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
target_compile_definitions(blck_hip PRIVATE AMS_EXAMPLE_ENABLE_HIP)
elseif(WITH_AMS_EXAMPLE_CUDA)
add_executable(blck_cuda driver.cpp gpu_compute.cpp)
set_source_files_properties(gpu_compute.cpp PROPERTIES LANGUAGE CUDA)
target_link_libraries(blck_cuda PRIVATE CUDA::cudart)
target_include_directories(blck_cuda
PRIVATE
${PROJECT_SOURCE_DIR}/include
)
target_compile_definitions(blck_cuda PRIVATE AMS_EXAMPLE_ENABLE_CUDA)
endif()


target_include_directories(blck_cpu
PRIVATE
${PROJECT_SOURCE_DIR}/include
)


if (WITH_AMS_DOWNLOAD_DATA)
set(BS_ZST "${AMS_INPUT_DIR}/blackscholes_input.bin.zst")
set(BS_BIN "${AMS_INPUT_DIR}/blackscholes_input.bin")

ams_download_dataset(
NAME blackscholes_input_zst
URL "https://zenodo.org/records/17992861/files/random_input.bin.zst?download=1"
SHA256 "b895a9e5206ed60e5fd63529ceeb5e63d823149de4559f578fcab58cb2908ee4"
OUT_FILE "${BS_ZST}"
)

# Always define the build-time decompression target (it will run when needed)
ams_add_zstd_decompress_target(
NAME inputs_blackscholes
ZST_FILE "${BS_ZST}"
OUT_FILE "${BS_BIN}"
)

add_dependencies(blck_cpu inputs_blackscholes)
add_test(
NAME BLACKSCHOLES::CPU
COMMAND blck_cpu
${BS_BIN}
)
set_tests_properties(BLACKSCHOLES::CPU
PROPERTIES
LABELS "benchmark;blackscholes;cpu;no-ams"
TIMEOUT 600
)

if (WITH_AMS_EXAMPLE_HIP)
add_dependencies(blck_hip inputs_blackscholes)
add_test(
NAME BLACKSCHOLES::CPU
COMMAND blck_hip
${BS_BIN}
)
set_tests_properties(BLACKSCHOLES::GPU
PROPERTIES
LABELS "benchmark;blackscholes;gpu;no-ams"
TIMEOUT 600
)
elseif(WITH_AMS_EXAMPLE_CUDA)
add_dependencies(blck_cpu inputs_blackscholes)
add_test(
NAME BLACKSCHOLES::GPU
COMMAND blck_cuda
${BS_BIN}
)
set_tests_properties(BLACKSCHOLES::CPU
PROPERTIES
LABELS "benchmark;blackscholes;gpu;no-ams"
TIMEOUT 600
)
endif()


endif()
12 changes: 12 additions & 0 deletions examples/simple/blackscholes/constants.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#define fptype double

const fptype inv_sqrt_2xPI = 0.39894228040143270286f;
const fptype zero = 0.0;
const fptype half = 0.5;
const fptype const1 = 0.2316419;
const fptype one = 1.0;
const fptype const2 = 0.319381530;
const fptype const3 = 0.356563782;
const fptype const4 = 1.781477937;
const fptype const5 = 1.821255978;
const fptype const6 = 1.330274429;
179 changes: 179 additions & 0 deletions examples/simple/blackscholes/cpu_compute.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#include <cmath>

#include "constants.hpp"

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Cumulative Normal Distribution Function
// See Hull, Section 11.8, P.243-244
//

fptype CNDF(fptype InputX)
{
int sign;

fptype OutputX;
fptype xInput;
fptype xNPrimeofX;
fptype expValues;
fptype xK2;
fptype xK2_2, xK2_3;
fptype xK2_4, xK2_5;
fptype xLocal, xLocal_1;
fptype xLocal_2, xLocal_3;
fptype temp;

// Check for negative value of InputX
if (InputX < zero) {
InputX = -InputX;
sign = 1;
} else
sign = 0;

xInput = InputX;

// Compute NPrimeX term common to both four & six decimal accuracy calcs
temp = -half * InputX * InputX;

expValues = exp(temp);

xNPrimeofX = expValues;
xNPrimeofX = xNPrimeofX * inv_sqrt_2xPI;

xK2 = const1 * xInput;
xK2 = one + xK2;
xK2 = one / xK2;
xK2_2 = xK2 * xK2;
xK2_3 = xK2_2 * xK2;
xK2_4 = xK2_3 * xK2;
xK2_5 = xK2_4 * xK2;

xLocal_1 = xK2 * const2;
xLocal_2 = xK2_2 * (-const3);
xLocal_3 = xK2_3 * const4;
xLocal_2 = xLocal_2 + xLocal_3;
xLocal_3 = xK2_4 * (-const5);
xLocal_2 = xLocal_2 + xLocal_3;
xLocal_3 = xK2_5 * const6;
xLocal_2 = xLocal_2 + xLocal_3;

xLocal_1 = xLocal_2 + xLocal_1;
xLocal = xLocal_1 * xNPrimeofX;
xLocal = one - xLocal;

OutputX = xLocal;

if (sign) {
OutputX = one - OutputX;
}

return OutputX;
}

fptype BlkSchlsEqEuroNoDiv(fptype sptprice,
fptype strike,
fptype rate,
fptype volatility,
fptype time,
int otype,
float timet)
{
fptype OptionPrice;

// local private working variables for the calculation
fptype xStockPrice;
fptype xStrikePrice;
fptype xRiskFreeRate;
fptype xVolatility;

fptype xTime;
fptype xSqrtTime;

fptype logValues;
fptype xLogTerm;
fptype xD1;
fptype xD2;
fptype xPowerTerm;
fptype xDen;
fptype d1;
fptype d2;
fptype FutureValueX;
fptype NofXd1;
fptype NofXd2;
fptype NegNofXd1;
fptype NegNofXd2;
fptype temp;

xStockPrice = sptprice;

Check warning on line 109 in examples/simple/blackscholes/cpu_compute.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

examples/simple/blackscholes/cpu_compute.cpp:109:3 [clang-analyzer-deadcode.DeadStores]

Value stored to 'xStockPrice' is never read
xStrikePrice = strike;

Check warning on line 110 in examples/simple/blackscholes/cpu_compute.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

examples/simple/blackscholes/cpu_compute.cpp:110:3 [clang-analyzer-deadcode.DeadStores]

Value stored to 'xStrikePrice' is never read
xRiskFreeRate = rate;
xVolatility = volatility;

xTime = time;
xSqrtTime = sqrt(xTime);

temp = sptprice / strike;

Check warning on line 117 in examples/simple/blackscholes/cpu_compute.cpp

View workflow job for this annotation

GitHub Actions / cpp-linter

examples/simple/blackscholes/cpu_compute.cpp:117:3 [clang-analyzer-deadcode.DeadStores]

Value stored to 'temp' is never read

logValues = log(sptprice / strike);

xLogTerm = logValues;


xPowerTerm = xVolatility * xVolatility;
xPowerTerm = xPowerTerm * half;

xD1 = xRiskFreeRate + xPowerTerm;
xD1 = xD1 * xTime;
xD1 = xD1 + xLogTerm;

xDen = xVolatility * xSqrtTime;
xD1 = xD1 / xDen;
xD2 = xD1 - xDen;

d1 = xD1;
d2 = xD2;

//@APPROX LABEL("CNDF_1") IN(d1) OUT(NofXd1) APPROX_TECH(MEMO_IN|MEMO_OUT)
NofXd1 = CNDF(d1);

//@APPROX LABEL("CNDF_2") IN(d2) OUT(NofXd2) APPROX_TECH(MEMO_IN|MEMO_OUT)
NofXd2 = CNDF(d2);

temp = -(rate * time);

FutureValueX = (exp(temp));

FutureValueX *= strike;

if (otype == 0) {
OptionPrice = (sptprice * NofXd1) - (FutureValueX * NofXd2);
} else {
NegNofXd1 = (one - NofXd1);
NegNofXd2 = (one - NofXd2);
OptionPrice = (FutureValueX * NegNofXd2) - (sptprice * NegNofXd1);
}

return OptionPrice;
}


int compute(fptype *sptprice,
fptype *strike,
fptype *rate,
fptype *volatility,
fptype *otime,
int *otype,
fptype *prices,
size_t numOptions)
{
int i, j, k;
fptype priceDelta;
for (i = 0; i < numOptions; i++) {
prices[i] = BlkSchlsEqEuroNoDiv(
sptprice[i], strike[i], rate[i], volatility[i], otime[i], otype[i], 0);
}

return 0;
}
Loading
Loading