diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2023-01-25 21:47:39 -0500 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2023-01-25 22:41:01 -0500 |
| commit | 846daaf8a1f3090965a2606a7933ad0e6f71aa6e (patch) | |
| tree | fe8b2407a0f518b145e4b929d37dfe121dbac3be | |
| parent | eb1fc3f3c30a7fad72d577cc22171fb1d7865d95 (diff) | |
| download | pyisda-846daaf8a1f3090965a2606a7933ad0e6f71aa6e.tar.gz | |
faster deepcopy
| -rw-r--r-- | pyisda/credit_index.pxd | 5 | ||||
| -rw-r--r-- | pyisda/credit_index.pyx | 121 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 2 | ||||
| -rw-r--r-- | pyisda/legs.pxd | 3 | ||||
| -rw-r--r-- | pyisda/legs.pyx | 19 |
5 files changed, 80 insertions, 70 deletions
diff --git a/pyisda/credit_index.pxd b/pyisda/credit_index.pxd index 2be66ff..1a07a6f 100644 --- a/pyisda/credit_index.pxd +++ b/pyisda/credit_index.pxd @@ -20,4 +20,7 @@ cdef class CreditIndex(CurveList): cdef vector[TDate] _maturities cdef TContingentLeg** contingent_legs cdef TFeeLeg** fee_legs - cdef readonly char* cal_file + cdef readonly char[30] cal_file + + +cdef copy(CurveList orig, CurveList copy) diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index 2bbfe96..57cd48c 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -10,7 +10,8 @@ from cython.parallel cimport prange, parallel cimport cython from .legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake, - JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree) + JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree, + fee_leg_copy) from .curve cimport (SpreadCurve, JpmcdsCopyCurve, tweak_curve, YieldCurve, JpmcdsFreeTCurve, survival_prob, Hash64WithSeed, Hash64, uint64_t, CurveName, @@ -28,18 +29,6 @@ cimport cython ctypedef TFeeLeg* TFeeLeg_ptr ctypedef TContingentLeg* TContingentLeg_ptr -cdef TFeeLeg* copyFeeLeg(TFeeLeg* leg) nogil: - cdef TFeeLeg* new_leg = <TFeeLeg*>malloc(sizeof(TFeeLeg)) - cdef size_t size = leg.nbDates * sizeof(TDate) - memcpy(new_leg, leg, sizeof(TFeeLeg)) - new_leg.accStartDates = <TDate*>malloc(size) - new_leg.accEndDates = <TDate*>malloc(size) - new_leg.payDates = <TDate*>malloc(size) - memcpy(new_leg.accStartDates, leg.accStartDates, size) - memcpy(new_leg.accEndDates, leg.accEndDates, size) - memcpy(new_leg.payDates, leg.payDates, size) - return new_leg - cdef TContingentLeg* copyContingentLeg(TContingentLeg* leg) nogil: cdef TContingentLeg* new_leg = <TContingentLeg*>malloc(sizeof(TContingentLeg)) memcpy(new_leg, leg, sizeof(TContingentLeg)) @@ -48,6 +37,31 @@ cdef TContingentLeg* copyContingentLeg(TContingentLeg* leg) nogil: cdef inline void char_free(char* ptr) nogil: free(ptr) +cdef copy(CurveList orig, CurveList copy): + cdef: + char* buf + char* new_buf + TCurve* curve + int size + CurveName cn + uint16_t offset + copy.base_date = orig.base_date + copy._weights = orig._weights + copy._curves.resize(orig._curves.size()) + copy.defaulted = orig.defaulted + copy.offset_recovery_rates = orig.offset_recovery_rates + for p in orig.names: + buf = orig._curves[p.second].get() + offset = p.first.name - buf + size = offset + p.first.size() + new_buf = <char*>malloc(size) + memcpy(new_buf, buf, size) + curve = <TCurve*>new_buf + curve.fArray = <TRatePt*>(new_buf + sizeof(TCurve)) + cn = CurveName(new_buf + offset) + copy._curves[p.second] = shared_ptr[char](new_buf, char_free) + copy.names[cn] = p.second + @cython.auto_pickle(False) cdef class CurveList: @@ -220,32 +234,9 @@ cdef class CurveList: CurveList.__init__(self, l) self.base_date = temp - # def __deepcopy__(self, memo): - # cdef: - # CurveList copy = CurveList.__new__(CurveList) - # char* buf - # char* new_buf - # TCurve* curve - # int size - # CurveName cn - # uint16_t offset - # copy.base_date = self.base_date - # copy._weights = self._weights - # copy._curves.resize(self._curves.size()) - # copy.defaulted = self.defaulted - # copy.offset_recovery_rates = self.offset_recovery_rates - # for p in self.names: - # buf = self._curves[p.second].get() - # offset = p.first.name - buf - # size = offset + p.first.size() - # new_buf = <char*>malloc(size) - # memcpy(new_buf, buf, size) - # curve = <TCurve*>new_buf - # curve.fArray = <TRatePt*>(new_buf + sizeof(TCurve)) - # cn = CurveName(new_buf + offset) - # copy._curves[p.second] = shared_ptr[char](new_buf, char_free) - # copy.names[cn] = p.second - # return copy + def __deepcopy__(self, memo): + cdef CurveList copy = CurveList.__new__(CurveList) + copy(self, copy) def __reduce__(self): return (self.__class__, (self.curves, TDate_to_pydate(self.base_date))) @@ -286,34 +277,32 @@ cdef class CreditIndex(CurveList): for i in range(self._maturities.size()): JpmcdsFeeLegFree(self.fee_legs[i]) - # def __deepcopy__(self, memo): - # cdef: - # shared_ptr[TCurve] sc - # double* temp - # size_t i = 0 - # TCurve* copy_sc - # CreditIndex copy = CreditIndex.__new__(CreditIndex) - # copy._weights = self._weights - # copy.T = self.T - # copy.base_date = self.base_date - # copy.start_date = self.start_date - # copy._maturities = self._maturities - # for sc in self._curves: - # copy_sc = sc.get() - # copy._curves.push_back(make_shared(JpmcdsCopyCurve(copy_sc))) - # temp = <double*>malloc(copy_sc.fNumItems * sizeof(double)) - # if temp != NULL: - # memcpy(<void*>temp, self.recovery_rates[i].get(), - # copy_sc.fNumItems * sizeof(double)) - # copy.recovery_rates.push_back(shared_ptr[double](temp, double_free)) + def __deepcopy__(self, memo): + cdef: + CreditIndex copy = CreditIndex.__new__(CreditIndex) + size_t i + int n + TContingentLeg* cl + TFeeLeg* fl + copy(self, copy) + copy._start_date = self._start_date + copy._maturities = self._maturities + n = self._maturities.size() + copy.contingent_legs = <TContingentLeg**>malloc(n * sizeof(TContingentLeg*)) + copy.fee_legs = <TFeeLeg**>malloc(n * sizeof(TFeeLeg*)) + for i in range(n): + cl = self.contingent_legs[i] + fl = self.fee_legs[i] + copy.contingent_legs[i] = JpmcdsCdsContingentLegMake(cl.startDate, + cl.endDate, + cl.notional, + cl.protectStart) + copy.fee_legs[i] = <TFeeLeg*>malloc(sizeof(TFeeLeg)) + fee_leg_copy(fl, copy.fee_legs[i]) - # copy.tickers = self.tickers - # copy.contingent_legs = <TContingentLeg**>malloc(sizeof(TContingentLeg*) * self._maturities.size()) - # copy.fee_legs = <TFeeLeg**>malloc(sizeof(TFeeLeg*) * self._maturities.size()) - # for i in range(self._maturities.size()): - # copy.fee_legs[i] = copyFeeLeg(self.fee_legs[i]) - # copy.contingent_legs[i] = copyContingentLeg(self.contingent_legs[i]) - # return copy + strcpy(copy.cal_file, self.cal_file) + memo[id(self)] = copy + return copy def __reduce__(self): return (self.__class__, diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 6e3b452..a3821c2 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -811,8 +811,6 @@ cdef class SpreadCurve(Curve): return JpmcdsForwardZeroPrice(curve, pydate_to_TDate(d1), pydate_to_TDate(d2)) - - def __setstate__(self, bytes state): super().__setstate__(state) cdef char* cursor = self.buf.get() diff --git a/pyisda/legs.pxd b/pyisda/legs.pxd index a9e1ad7..bd35530 100644 --- a/pyisda/legs.pxd +++ b/pyisda/legs.pxd @@ -110,3 +110,6 @@ cdef class ContingentLeg: cdef class FeeLeg: cdef TFeeLeg* _thisptr + + +cdef void fee_leg_copy(TFeeLeg* orig, TFeeLeg* copy) nogil diff --git a/pyisda/legs.pyx b/pyisda/legs.pyx index 12c8bff..a7f6ab2 100644 --- a/pyisda/legs.pyx +++ b/pyisda/legs.pyx @@ -1,4 +1,5 @@ -from libc.stdlib cimport free +from libc.stdlib cimport free, malloc +from libc.string cimport memcpy from .date cimport (pydate_to_TDate, TDate_to_pydate, dcc, JpmcdsStringToStubMethod, MODIFIED) from .date import dcc_tostring @@ -211,3 +212,19 @@ cdef class FeeLeg: def __dealloc__(self): if self._thisptr is not NULL: JpmcdsFeeLegFree(self._thisptr) + + +cdef void fee_leg_copy(const TFeeLeg* orig, TFeeLeg* copy) nogil: + cdef int n = orig.nbDates + copy.nbDates = n + copy.notional = orig.notional + copy.couponRate = orig.couponRate + copy.dcc = orig.dcc + copy.accrualPayConv = orig.accrualPayConv + copy.obsStartOfDay = orig.obsStartOfDay + copy.accStartDates = <TDate*>malloc(n * sizeof(TDate)) + copy.accEndDates = <TDate*>malloc(n * sizeof(TDate)) + copy.payDates = <TDate*>malloc(n * sizeof(TDate)) + memcpy(copy.accStartDates, orig.accStartDates, n * sizeof(TDate)) + memcpy(copy.accEndDates, orig.accEndDates, n * sizeof(TDate)) + memcpy(copy.payDates, orig.payDates, n * sizeof(TDate)) |
