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


You are receiving this mail because: