Skip to content

Commit 6388e1e

Browse files
pcaspersdamienbarker
authored andcommitted
Merge remote-tracking branch 'origin/master' into QPR-12487
1 parent 412f18f commit 6388e1e

8 files changed

Lines changed: 567 additions & 226 deletions

File tree

OREAnalytics/orea/app/oreapp.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,8 +1477,9 @@ void OREAppInputParameters::loadParameters() {
14771477
setWriteScenarios(true);
14781478

14791479
tmp = params_->get("simulation", "xvaCgBumpSensis", false);
1480-
if (tmp != "")
1481-
setXvaCgBumpSensis(parseBool(tmp));
1480+
if (tmp != "")
1481+
setXvaCgBumpSensis(parseBool(tmp));
1482+
14821483
}
14831484

14841485
/**********************

OREData/ored/scripting/computationgraphbuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ class ASTRunner : public AcyclicVisitor,
12051205
// if observation date is in the future, the answer is always zero
12061206
std::size_t node;
12071207
if (obs > model_->referenceDate()) {
1208-
value.push(RandomVariable(model_->size(), 0));
1208+
value.push(RandomVariable(model_->size(), 0.0));
12091209
node = cg_const(g_, 0.0);
12101210
} else {
12111211
// otherwise check whether a fixing is present in the historical time series

OREData/ored/scripting/scriptengine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ class ASTRunner : public AcyclicVisitor,
918918
std::string und = QuantLib::ext::get<IndexVec>(underlying).value;
919919
// if observation date is in the future, the answer is always zero
920920
if (obs > model_->referenceDate())
921-
value.push(RandomVariable(model_->size(), 0));
921+
value.push(RandomVariable(model_->size(), 0.0));
922922
else {
923923
// otherwise check whether a fixing is present in the historical time series
924924
TimeSeries<Real> series = IndexManager::instance().getHistory(IndexInfo(und).index()->name());

QuantExt/qle/math/openclenvironment.cpp

Lines changed: 496 additions & 213 deletions
Large diffs are not rendered by default.

QuantExt/qle/math/randomvariable.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,22 +407,28 @@ RandomVariable::RandomVariable(const Filter& f, const Real valueTrue, const Real
407407
time_ = time;
408408
}
409409

410-
RandomVariable::RandomVariable(const QuantLib::Array& array, const Real time) {
411-
n_ = array.size();
410+
RandomVariable::RandomVariable(const Size n, const Real* const data, const Real time) {
411+
n_ = n;
412412
deterministic_ = false;
413413
time_ = time;
414414
if (n_ != 0) {
415415
resumeDataStats();
416416
data_ = new double[n_];
417417
// std::memcpy(data_, array.begin(), n_ * sizeof(double));
418-
std::copy(array.begin(), array.end(), data_);
418+
std::copy(data, data + n_, data_);
419419
stopDataStats(n_);
420420
} else {
421421
data_ = nullptr;
422422
}
423423
constantData_ = 0.0;
424424
}
425425

426+
RandomVariable::RandomVariable(const std::vector<Real>& data, const Real time)
427+
: RandomVariable(data.size(), &data[0], time) {}
428+
429+
RandomVariable::RandomVariable(const QuantLib::Array& data, const Real time)
430+
: RandomVariable(data.size(), data.begin(), time) {}
431+
426432
void RandomVariable::copyToMatrixCol(QuantLib::Matrix& m, const Size j) const {
427433
if (deterministic_)
428434
std::fill(m.column_begin(j), std::next(m.column_end(j), n_), constantData_);

QuantExt/qle/math/randomvariable.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,10 @@ struct RandomVariable {
161161
explicit RandomVariable(const Size n, const Real value = 0.0, const Real time = Null<Real>());
162162
explicit RandomVariable(const Filter& f, const Real valueTrue = 1.0, const Real valueFalse = 0.0,
163163
const Real time = Null<Real>());
164+
explicit RandomVariable(const Size n, const Real* const data, const Real time = Null<Real>());
165+
explicit RandomVariable(const std::vector<double>& data, const Real time = Null<Real>());
164166
// interop with ql classes
165-
explicit RandomVariable(const QuantLib::Array& array, const Real time = Null<Real>());
167+
explicit RandomVariable(const QuantLib::Array& data, const Real time = Null<Real>());
166168
void copyToMatrixCol(QuantLib::Matrix&, const Size j) const;
167169
void copyToArray(QuantLib::Array& array) const;
168170
// modifiers

QuantExt/qle/pricingengines/mcmultilegbaseengine.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,11 +888,11 @@ void McMultiLegBaseEngine::calculate() const {
888888
regressorModel_, regressionVarianceCutoff_);
889889
regModelContinuationValue[counter].train(polynomOrder_, polynomType_, pathValueOption, pathValuesRef,
890890
simulationTimes,
891-
exerciseValue > RandomVariable(calibrationSamples_, 0));
891+
exerciseValue > RandomVariable(calibrationSamples_, 0.0));
892892
auto continuationValue = regModelContinuationValue[counter].apply(model_->stateProcess()->initialValues(),
893893
pathValuesRef, simulationTimes);
894894
pathValueOption = conditionalResult(exerciseValue > continuationValue &&
895-
exerciseValue > RandomVariable(calibrationSamples_, 0),
895+
exerciseValue > RandomVariable(calibrationSamples_, 0.0),
896896
pathValueUndExInto, pathValueOption);
897897
regModelOption[counter] = RegressionModel(
898898
*t, cashflowInfo, [&cfStatus](std::size_t i) { return cfStatus[i] == CfStatus::done; }, **model_,

QuantExt/test/computeenvironment.cpp

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,11 +305,11 @@ BOOST_AUTO_TEST_CASE(testReplayFlowError) {
305305
}
306306
}
307307

308-
BOOST_AUTO_TEST_CASE(testRngGenerationTmp) {
308+
BOOST_AUTO_TEST_CASE(testRngGenerationMt19937) {
309309
ComputeEnvironmentFixture fixture;
310310
const std::size_t n = 1500;
311311
for (auto const& d : ComputeEnvironment::instance().getAvailableDevices()) {
312-
BOOST_TEST_MESSAGE("testing rng generation on device '" << d << "'.");
312+
BOOST_TEST_MESSAGE("testing rng generation mt19937 against QL on device '" << d << "'.");
313313
ComputeEnvironment::instance().selectContext(d);
314314
auto& c = ComputeEnvironment::instance().context();
315315
ComputeContext::Settings settings;
@@ -318,12 +318,12 @@ BOOST_AUTO_TEST_CASE(testRngGenerationTmp) {
318318
BOOST_TEST_MESSAGE("using double precision = " << std::boolalpha << settings.useDoublePrecision);
319319
c.initiateCalculation(n, 0, 0, settings);
320320
auto vs = c.createInputVariates(1, 1);
321+
auto vs2 = c.createInputVariates(1, 1);
321322
for (auto const& d : vs) {
322323
for (auto const& r : d) {
323324
c.declareOutputVariable(r);
324325
}
325326
}
326-
auto vs2 = c.createInputVariates(1, 1);
327327
for (auto const& d : vs2) {
328328
for (auto const& r : d) {
329329
c.declareOutputVariable(r);
@@ -357,6 +357,55 @@ BOOST_AUTO_TEST_CASE(testRngGenerationTmp) {
357357
BOOST_CHECK(true);
358358
}
359359

360+
BOOST_AUTO_TEST_CASE(testConditionalExpectation) {
361+
ComputeEnvironmentFixture fixture;
362+
const std::size_t n = 100;
363+
for (auto const& d : ComputeEnvironment::instance().getAvailableDevices()) {
364+
BOOST_TEST_MESSAGE("testing conditional expectation on device '" << d << "'.");
365+
ComputeEnvironment::instance().selectContext(d);
366+
auto& c = ComputeEnvironment::instance().context();
367+
ComputeContext::Settings settings;
368+
settings.useDoublePrecision = c.supportsDoublePrecision();
369+
BOOST_TEST_MESSAGE("using double precision = " << std::boolalpha << settings.useDoublePrecision);
370+
371+
c.initiateCalculation(n, 0, 0, settings);
372+
373+
auto one = c.createInputVariable(1.0);
374+
auto vs = c.createInputVariates(1, 2);
375+
auto ce = c.applyOperation(RandomVariableOpCode::ConditionalExpectation, {vs[0][0], one, vs[0][1]});
376+
377+
for (auto const& d : vs) {
378+
for (auto const& r : d) {
379+
c.declareOutputVariable(r);
380+
}
381+
}
382+
c.declareOutputVariable(ce);
383+
384+
std::vector<std::vector<double>> output(3, std::vector<double>(n));
385+
c.finalizeCalculation(output);
386+
387+
RandomVariable y(output[0]);
388+
RandomVariable x(output[1]);
389+
RandomVariable z = conditionalExpectation(
390+
y, {&x}, multiPathBasisSystem(1, settings.regressionOrder, QuantLib::LsmBasisSystem::Monomial, x.size()));
391+
392+
double tol = settings.useDoublePrecision ? 1E-12 : 1E-4;
393+
Size noErrors = 0, errorThreshold = 10;
394+
395+
for (Size i = 0; i < n; ++i) {
396+
Real err = std::abs(output[2][i] - z[i]);
397+
if (std::abs(z[i]) > 1E-10)
398+
err /= std::abs(z[i]);
399+
if (err > tol && noErrors < errorThreshold) {
400+
BOOST_ERROR("gpu value (" << output[2][i] << ") at i=" << i << " does not match reference cpu value ("
401+
<< z[i] << "), error " << err << ", tol " << tol);
402+
noErrors++;
403+
}
404+
}
405+
}
406+
BOOST_CHECK(true);
407+
}
408+
360409
BOOST_AUTO_TEST_SUITE_END()
361410

362411
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)