Bug ID | 983161 |
---|---|
Summary | Segmentation fault on build of quantlib |
Classification | openSUSE |
Product | openSUSE Distribution |
Version | Leap 42.1 |
Hardware | x86-64 |
OS | openSUSE 42.1 |
Status | NEW |
Severity | Normal |
Priority | P5 - None |
Component | Development |
Assignee | bnc-team-screening@forge.provo.novell.com |
Reporter | dickinsw@frontier.com |
QA Contact | qa-bugs@suse.de |
Found By | --- |
Blocker | --- |
I also submitted this bug to the QuantLib group. After a successful build of boost 1_61_0, I could not build QuantLib version 1.8. The build fails while attempting to compile cdo.cpp in the /experimental folder: libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const': cdo.cpp:123:10: internal compiler error: Segmentation fault void CDO::performCalculations() const { Here are the details: make error: Making all in config make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/config' make[1]: Nothing to be done for 'all'. make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/config' Making all in ql make[1]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql' make all-recursive make[2]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql' Making all in cashflows make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/cashflows' Making all in currencies make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies' make[3]: Nothing to be done for 'all'. make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/currencies' Making all in experimental make[3]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental' Making all in amortizingbonds make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/amortizingbonds' Making all in barrieroption make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/barrieroption' Making all in callablebonds make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/callablebonds' Making all in catbonds make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/catbonds' Making all in commodities make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/commodities' Making all in convertiblebonds make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/convertiblebonds' Making all in coupons make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons' make[4]: Nothing to be done for 'all'. make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/coupons' Making all in credit make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit' /bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o Makefile:517: recipe for target 'cdo.lo' failed make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit' Makefile:508: recipe for target 'all-recursive' failed make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental' Makefile:661: recipe for target 'all-recursive' failed make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql' Makefile:494: recipe for target 'all' failed make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql' Makefile:593: recipe for target 'all-recursive' failed make[4]: Entering directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit' /bin/sh ../../../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c -o cdo.lo cdo.cpp libtool: compile: g++ -DHAVE_CONFIG_H -I. -I../../../ql -I../../.. -I../../.. -g -O2 -MT cdo.lo -MD -MP -MF .deps/cdo.Tpo -c cdo.cpp -fPIC -DPIC -o .libs/cdo.o cdo.cpp: In member function 'virtual void QuantLib::CDO::performCalculations() const': cdo.cpp:123:10: internal compiler error: Segmentation fault void CDO::performCalculations() const { ^ Please submit a full bug report, with preprocessed source if appropriate. See <http://bugs.opensuse.org/> for instructions. Makefile:517: recipe for target 'cdo.lo' failed make[4]: *** [cdo.lo] Error 1 make[4]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental/credit' Makefile:508: recipe for target 'all-recursive' failed make[3]: *** [all-recursive] Error 1 make[3]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql/experimental' Makefile:661: recipe for target 'all-recursive' failed make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql' Makefile:494: recipe for target 'all' failed make[1]: *** [all] Error 2 make[1]: Leaving directory '/usr/local/quantlib/QuantLib-1.8/ql' Makefile:593: recipe for target 'all-recursive' failed make: *** [all-recursive] Error 1 gcc version: linux-k07u:/usr/local/quantlib/QuantLib-1.8 # gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/lto-wrapper Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.8 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --enable-linker-build-id --enable-linux-futex --program-suffix=-4.8 --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux Thread model: posix gcc version 4.8.5 (SUSE Linux) OS: linux-k07u:/usr/local/quantlib/QuantLib-1.8 # cat /etc/os-release NAME="openSUSE Leap" VERSION="42.1" VERSION_ID="42.1" PRETTY_NAME="openSUSE Leap 42.1 (x86_64)" ID=opensuse ANSI_COLOR="0;32" CPE_NAME="cpe:/o:opensuse:opensuse:42.1" BUG_REPORT_URL="https://bugs.opensuse.org" HOME_URL="https://opensuse.org/" ID_LIKE="suse" boost version: // Boost version.hpp configuration header file ------------------------------// // (C) Copyright John maddock 1999. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // See http://www.boost.org/libs/config for documentation #ifndef BOOST_VERSION_HPP #define BOOST_VERSION_HPP // // Caution: this is the only Boost header that is guaranteed // to change with every Boost release. Including this header // will cause a recompile every time a new Boost version is // used. // // BOOST_VERSION % 100 is the patch level // BOOST_VERSION / 100 % 1000 is the minor version // BOOST_VERSION / 100000 is the major version #define BOOST_VERSION 106100 // // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION // but as a *string* in the form "x_y[_z]" where x is the major version // number, y is the minor version number, and z is the patch level if not 0. // This is used by <config/auto_link.hpp> to select which library version to link to. #define BOOST_LIB_VERSION "1_61" #endif Affected File(s): cdo.cpp /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2008 Roland Lichters This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email <quantlib-dev@lists.sf.net>. The license is also available online at <http://quantlib.org/license.shtml>. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ #include <ql/experimental/credit/cdo.hpp> #include <ql/event.hpp> using namespace std; namespace QuantLib { CDO::CDO (Real attachment, Real detachment, const vector<Real>& nominals, const vector<Handle<DefaultProbabilityTermStructure> >& basket, const Handle<OneFactorCopula>& copula, bool protectionSeller, const Schedule& premiumSchedule, Rate premiumRate, const DayCounter& dayCounter, Rate recoveryRate, Rate upfrontPremiumRate, const Handle<YieldTermStructure>& yieldTS, Size nBuckets, const Period& integrationStep) : attachment_(attachment), detachment_(detachment), nominals_(nominals), basket_(basket), copula_(copula), protectionSeller_(protectionSeller), premiumSchedule_(premiumSchedule), premiumRate_(premiumRate), dayCounter_(dayCounter), recoveryRate_(recoveryRate), upfrontPremiumRate_(upfrontPremiumRate), yieldTS_(yieldTS), nBuckets_(nBuckets), integrationStep_(integrationStep) { QL_REQUIRE (!basket.empty(), "basket is empty"); QL_REQUIRE (attachment_ >= 0 && attachment_ < detachment_ && detachment_ <= 1, "illegal attachment/detachment point"); registerWith (yieldTS_); registerWith (copula_); for (Size i = 0; i < basket_.size(); i++) registerWith (basket_[i]); QL_REQUIRE (nominals_.size() <= basket_.size(), "nominal vector size too large"); if (nominals_.size() < basket_.size()) { Size n = basket_.size() - nominals_.size(); Real back = nominals_.back(); for (Size i = 0; i < n; i++) nominals_.push_back(back); } QL_REQUIRE (nominals_.size() == basket_.size(), "nominal size " << nominals_.size() << " != basket size " << basket_.size()); nominal_ = 0; for (Size i = 0; i < nominals_.size(); i++) { lgds_.push_back (nominals_[i] * (1.0 - recoveryRate_)); nominal_ += nominals_[i]; lgd_ += lgds_[i]; } xMax_ = detachment_ * nominal_; xMin_ = attachment_ * nominal_; } bool CDO::isExpired () const { return detail::simple_event(premiumSchedule_.dates().back()) .hasOccurred(yieldTS_->referenceDate()); } void CDO::setupExpired() const { Instrument::setupExpired(); } Real CDO::expectedTrancheLoss (Date d) const { if (d <= basket_.front()->referenceDate()) return 0; vector<Real> defProb (basket_.size()); for (Size j = 0; j < basket_.size(); j++) defProb[j] = basket_[j]->defaultProbability (d); LossDistBucketing op (nBuckets_, xMax_); Distribution dist = copula_->integral (op, lgds_, defProb); return dist.trancheExpectedValue (xMin_, xMax_); // The following causes two errors in test against literature values. // FIXME: Investigate accuracy. // return dist.cumulativeExcessProbability (xMin_, xMax_); // TranchePayoff func (xMin_, xMax_); // return (dist.expectedValue (func) // + (xMax_ - xMin_) * (1.0 - dist.cumulatedProbability (xMax_))); } void CDO::performCalculations() const { QL_REQUIRE(!yieldTS_.empty(), "no yield term structure set"); errorEstimate_ = Null<Real>(); NPV_ = 0.0; premiumValue_ = 0; protectionValue_ = 0; error_ = 0; /* Expectations e1 and e2 are portfolio loss given default, i.e. with recovery already "bult in". Multiplication by (1-r) is therefore not necessary, neither in premium nor protection value calculation. */ Real e1 = 0; Date today = yieldTS_->referenceDate(); if (premiumSchedule_[0] > today) e1 = expectedTrancheLoss (premiumSchedule_[0]); for (Size i = 1; i < premiumSchedule_.size(); i++) { Date d2 = premiumSchedule_[i]; if (d2 < today) continue; Date d1 = premiumSchedule_[i-1]; Date d, d0 = d1; do { d = NullCalendar().advance (d0 > today ? d0 : today, integrationStep_); if (d > d2) d = d2; Real e2 = expectedTrancheLoss (d); premiumValue_ += (xMax_ - xMin_ - e2) * premiumRate_ * dayCounter_.yearFraction (d0, d) * yieldTS_->discount (d); if (e2 < e1) { error_ ++; } protectionValue_ -= (e2 - e1) * yieldTS_->discount (d); d0 = d; e1 = e2; } while (d < d2); } if (premiumSchedule_[0] >= today) upfrontPremiumValue_ = (xMax_ - xMin_) * upfrontPremiumRate_ * yieldTS_->discount(premiumSchedule_[0]); else upfrontPremiumValue_ = 0.0; if (!protectionSeller_) { premiumValue_ *= -1; upfrontPremiumValue_ *= -1; protectionValue_ *= -1; } NPV_ = premiumValue_ + protectionValue_ + upfrontPremiumValue_; } Rate CDO::premiumValue () const { calculate(); return premiumValue_; } Rate CDO::protectionValue () const { calculate(); return protectionValue_; } Size CDO::error () const { calculate(); return error_; } Rate CDO::fairPremium () const { calculate(); return - premiumRate_ * protectionValue_ / premiumValue_; } } cdo.hpp: /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Copyright (C) 2008 Roland Lichters This file is part of QuantLib, a free-software/open-source library for financial quantitative analysts and developers - http://quantlib.org/ QuantLib is free software: you can redistribute it and/or modify it under the terms of the QuantLib license. You should have received a copy of the license along with this program; if not, please email <quantlib-dev@lists.sf.net>. The license is also available online at <http://quantlib.org/license.shtml>. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. */ /*! \file cdo.hpp \brief collateralized debt obligation */ #ifndef quantlib_cdo_hpp #define quantlib_cdo_hpp #include <ql/instrument.hpp> #include <ql/termstructures/yieldtermstructure.hpp> #include <ql/termstructures/defaulttermstructure.hpp> #include <ql/experimental/credit/lossdistribution.hpp> #include <ql/experimental/credit/onefactorcopula.hpp> #include <ql/time/schedule.hpp> namespace QuantLib { //! collateralized debt obligation /*! The instrument prices a mezzanine CDO tranche with loss given default between attachment point \f$ D_1\f$ and detachment point \f$ D_2 > D_1 \f$. For purchased protection, the instrument value is given by the difference of the protection value \f$ V_1 \f$ and premium value \f$ V_2 \f$, \f[ V = V_1 - V_2. \f] The protection leg is priced as follows: - Build the probability distribution for volume of defaults \f$ L \f$ (before recovery) or Loss Given Default \f$ LGD = (1-r)\,L \f$ at times/dates \f$ t_i, i=1, ..., N\f$ (premium schedule times with intermediate steps) - Determine the expected value \f$ E_i = E_{t_i}\,\left[Pay(LGD)\right] \f$ of the protection payoff \f$ Pay(LGD) \f$ at each time \f$ t_i\f$ where \f[ Pay(L) = min (D_1, LGD) - min (D_2, LGD) = \left\{ \begin{array}{lcl} \displaystyle 0 &;& LGD < D_1 \\ \displaystyle LGD - D_1 &;& D_1 \leq LGD \leq D_2 \\ \displaystyle D_2 - D_1 &;& LGD > D_2 \end{array} \right. \f] - The protection value is then calculated as \f[ V_1 \:=\: \sum_{i=1}^N (E_i - E_{i-1}) \cdot d_i \f] where \f$ d_i\f$ is the discount factor at time/date \f$ t_i \f$ The premium is paid on the protected notional amount, initially \f$ D_2 - D_1. \f$ This notional amount is reduced by the expected protection payments \f$ E_i \f$ at times \f$ t_i, \f$ so that the premium value is calculated as \f[ V_2 = m \, \cdot \sum_{i=1}^N \,(D_2 - D_1 - E_i) \cdot \Delta_{i-1,i}\,d_i \f] where \f$ m \f$ is the premium rate, \f$ \Delta_{i-1, i}\f$ is the day count fraction between date/time \f$ t_{i-1}\f$ and \f$ t_i.\f$ The construction of the portfolio loss distribution \f$ E_i \f$ is based on the probability bucketing algorithm described in <strong> John Hull and Alan White, "Valuation of a CDO and nth to default CDS without Monte Carlo simulation", Journal of Derivatives 12, 2, 2004 </strong> The pricing algorithm allows for varying notional amounts and default termstructures of the underlyings. \todo Investigate and fix cases \f$ E_{i+1} < E_i. \f$ */ class CDO : public Instrument { public: /*! \param attachment fraction of the LGD where protection starts \param detachment fraction of the LGD where protection ends \param nominals vector of basket nominal amounts \param basket default basket represented by a vector of default term structures that allow computing single name default probabilities depending on time \param copula one-factor copula \param protectionSeller sold protection if set to true, purchased otherwise \param premiumSchedule schedule for premium payments \param premiumRate annual premium rate, e.g. 0.05 for 5% p.a. \param dayCounter day count convention for the premium rate \param recoveryRate recovery rate as a fraction \param upfrontPremiumRate premium as a tranche notional fraction \param yieldTS yield term structure handle \param nBuckets number of distribution buckets \param integrationStep time step for integrating over one premium period; if larger than premium period length, a single step is taken */ CDO (Real attachment, Real detachment, const std::vector<Real>& nominals, const std::vector<Handle<DefaultProbabilityTermStructure> >& basket, const Handle<OneFactorCopula>& copula, bool protectionSeller, const Schedule& premiumSchedule, Rate premiumRate, const DayCounter& dayCounter, Rate recoveryRate, Rate upfrontPremiumRate, const Handle<YieldTermStructure>& yieldTS, Size nBuckets, const Period& integrationStep = Period(10, Years)); Real nominal() { return nominal_; } Real lgd() { return lgd_; } Real attachment () { return attachment_; } Real detachment () { return detachment_; } std::vector<Real> nominals() { return nominals_; } Size size() { return basket_.size(); } bool isExpired () const; Rate fairPremium() const; Rate premiumValue () const; Rate protectionValue () const; Size error () const; private: void setupExpired() const; void performCalculations() const; Real expectedTrancheLoss (Date d) const; Real attachment_; Real detachment_; std::vector<Real> nominals_; std::vector<Handle<DefaultProbabilityTermStructure> > basket_; Handle<OneFactorCopula> copula_; bool protectionSeller_; Schedule premiumSchedule_; Rate premiumRate_; DayCounter dayCounter_; Rate recoveryRate_; Rate upfrontPremiumRate_; Handle<YieldTermStructure> yieldTS_; Size nBuckets_; // number of buckets up to detachment point Period integrationStep_; std::vector<Real> lgds_; Real nominal_; // total basket volume (sum of nominals_) Real lgd_; // maximum loss given default (sum of lgds_) Real xMax_; // tranche detachment point (tranche_ * nominal_) Real xMin_; // tranche attachment point (tranche_ * nominal_) mutable Size error_; mutable Real premiumValue_; mutable Real protectionValue_; mutable Real upfrontPremiumValue_; }; } #endif