diff options
| author | Guillaume Horel <guillaume.horel@gmail.com> | 2023-02-01 12:52:40 -0500 |
|---|---|---|
| committer | Guillaume Horel <guillaume.horel@gmail.com> | 2023-02-01 12:52:40 -0500 |
| commit | 1db8c8a1fa2ecb90236d1b27dbc9805c448869e2 (patch) | |
| tree | cc66a35c6ca6c5d3f27305c179f807da90fd611b | |
| parent | 28c6f1ec8cfcfe8a28e54aa99ddfa441904ceaf7 (diff) | |
| download | pyisda-1db8c8a1fa2ecb90236d1b27dbc9805c448869e2.tar.gz | |
take advantage of fam
| -rw-r--r-- | pyisda/credit_index.pyx | 7 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 4 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 104 |
3 files changed, 43 insertions, 72 deletions
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx index cfc0b2e..5797f45 100644 --- a/pyisda/credit_index.pyx +++ b/pyisda/credit_index.pyx @@ -53,7 +53,6 @@ cdef CurveList_copy(CurveList orig, CurveList copy): 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 @@ -611,7 +610,6 @@ cdef class CreditIndex(CurveList): memcpy(new_buf, buf, buf_size) sc_orig = <TCurve*>buf sc_copy = <TCurve*>new_buf - sc_copy.fArray = <TRatePt*>(new_buf + sizeof(TCurve)) tweak_curve(sc_orig, sc_copy, epsilon, mask) self._curves[i].reset(new_buf, char_free) self.names[CurveName(new_buf + offset)] = i @@ -812,7 +810,6 @@ cdef unsigned long fill_mask(const TDate maturity, const vector[TDate]& maturiti TDate prev_maturity = 0 TDate next_maturity = maturity size_t i - TRatePt* it = sc.fArray unsigned long mask = 0 for i in range(maturities.size()): @@ -824,10 +821,10 @@ cdef unsigned long fill_mask(const TDate maturity, const vector[TDate]& maturiti if i > 0: prev_maturity = maturities[i-1] i = 0 - while it[i].fDate < prev_maturity: + while sc.fArray[i].fDate < prev_maturity: i += 1 i += 1 - while it[i].fDate < maturity: + while sc.fArray[i].fDate < maturity: mask |= 1 << i i += 1 mask |= 1 << i diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 5d597b3..696a05d 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -30,11 +30,11 @@ cdef extern from "isda/zerocurve.h" nogil: char* holidayFile) cdef extern from "isda/bastypes.h": ctypedef struct TCurve: - TRatePt* fArray int fNumItems int fDayCountConv TDate fBaseDate double fBasis + TRatePt* fArray # TRatePt[] in C (flexible array member) ctypedef struct TRatePt: TDate fDate @@ -298,7 +298,7 @@ cdef class SpreadCurve(Curve): cdef inline double* recovery_rates_ptr(self) nogil cdef inline char* name(self) nogil -cdef fArray_to_list(TRatePt* fArray, int fNumItems) +cdef fArray_to_list(const TRatePt* fArray, int fNumItems) cdef void tweak_curve(const TCurve* sc, TCurve* sc_tweaked, double epsilon, unsigned long mask) nogil diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 182b7a7..b2b9747 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -74,16 +74,16 @@ cdef class Curve(object): bytes r int dst_capacity, compressed_size char* dst - int size = self.buf_size - sizeof(TRatePt*) + int size = self.buf_size if compressed: dst_capacity = LZ4_compressBound(size) dst = <char*>malloc(dst_capacity) - compressed_size = LZ4_compress_default(self.buf.get() + sizeof(TRatePt*), dst, size, dst_capacity) + compressed_size = LZ4_compress_default(self.buf.get(), dst, size, dst_capacity) r = dst[:compressed_size] free(dst) else: - r = self.buf.get()[sizeof(TRatePt*):self.buf_size] + r = self.buf.get()[:self.buf_size] return r def __getstate__(self): @@ -102,7 +102,7 @@ cdef class Curve(object): with nogil: while True: curve = <char*>realloc(curve, decomp_size) - state_size = LZ4_decompress_safe(src, curve + sizeof(TRatePt*), size, decomp_size) + state_size = LZ4_decompress_safe(src, curve, size, decomp_size) if state_size < 0: retry += 1 if retry == 2: @@ -112,8 +112,7 @@ cdef class Curve(object): decomp_size *= 2 else: break - self.buf_size = state_size + sizeof(TRatePt*) - (<TCurve*>curve).fArray = <TRatePt*>(curve + sizeof(TCurve)) + self.buf_size = state_size self.buf.reset(curve, char_free) @classmethod @@ -141,7 +140,7 @@ cdef class Curve(object): if compressed: while True: curve = <char*>realloc(curve, decomp_size) - state_size = LZ4_decompress_safe(src, curve + sizeof(TRatePt*), size, decomp_size) + state_size = LZ4_decompress_safe(src, curve, size, decomp_size) if state_size < 0: retry += 1 if retry == 2: @@ -152,18 +151,17 @@ cdef class Curve(object): else: break else: - curve = <char*>malloc(size + sizeof(TRatePt*)) - memcpy(curve + sizeof(TRatePt*), src, size) + curve = <char*>malloc(size) + memcpy(curve, src, size) state_size = size - (<TCurve*>curve).fArray = <TRatePt*>(curve + sizeof(TCurve)) - instance.buf_size = state_size + sizeof(TRatePt*) + instance.buf_size = state_size instance.buf.reset(curve, char_free) return instance def __hash__(self): cdef: - size_t curve_size = self.buf_size - sizeof(TRatePt*) - cdef uint64_t r = Hash64((self.buf.get() + sizeof(TRatePt*)), curve_size) + size_t curve_size = self.buf_size + cdef uint64_t r = Hash64(self.buf.get(), curve_size) return r def inspect(self): @@ -188,23 +186,22 @@ cdef class Curve(object): cdef np.ndarray[np.float64_t,ndim=1] h = np.PyArray_EMPTY(1, &n, np.NPY_DOUBLE, 0) cdef np.ndarray[np.int64_t,ndim=1] d = np.PyArray_EMPTY(1, &n, np.NPY_INT64, 0) cdef size_t i - cdef TRatePt* it = curve.fArray cdef double t1, h1, t2, h2 t1 = 0 h1 = 0 cdef int base_date = curve.fBaseDate if forward: for i in range(n): - h2 = it[i].fRate - t2 = (it[i].fDate - base_date)/365. + h2 = curve.fArray[i].fRate + t2 = (curve.fArray[i].fDate - base_date)/365. h[i] = (h2 * t2 - h1 * t1) / (t2 - t1) - d[i] = it[i].fDate - 134774 + d[i] = curve.fArray[i].fDate - 134774 h1 = h2 t1 = t2 else: for i in range(n): - h[i] = it[i].fRate - d[i] = it[i].fDate - 134774 + h[i] = curve.fArray[i].fRate + d[i] = curve.fArray[i].fDate - 134774 if isinstance(self, YieldCurve): name = 'forward_rates' elif isinstance(self, SpreadCurve): @@ -216,9 +213,9 @@ cdef class Curve(object): def __iter__(self): cdef: size_t i = 0 - TRatePt* it = self.get_TCurve().fArray - for i in range(self.get_TCurve().fNumItems): - yield (TDate_to_pydate(it[i].fDate), it[i].fRate) + const TCurve* c = self.get_TCurve() + for i in range(c.fNumItems): + yield (TDate_to_pydate(c.fArray[i].fDate), c.fArray[i].fRate) def __len__(self): return self.get_TCurve().fNumItems @@ -227,7 +224,6 @@ cdef class Curve(object): cdef Curve sc = type(self).__new__(type(self)) cdef char* curve = <char*>malloc(self.buf_size) memcpy(curve, self.buf.get(), self.buf_size) - (<TCurve*>curve).fArray = <TRatePt*>(curve + sizeof(TCurve)) sc.buf_size = self.buf_size sc.buf.reset(curve, char_free) memo[id(self)] = sc @@ -310,7 +306,7 @@ cdef class Curve(object): const TCurve* curve = self.get_TCurve() return JpmcdsZeroRate(curve, pydate_to_TDate(d)) -cdef fArray_to_list(TRatePt* fArray, int fNumItems): +cdef fArray_to_list(const TRatePt* fArray, int fNumItems): cdef size_t i cdef list l = [] for i in range(fNumItems): @@ -412,12 +408,8 @@ cdef class YieldCurve(Curve): free(dates) raise ValueError("Curve didn't build") else: - # we copy curve into a continuous buffer self.buf_size = sizeof(TCurve) + curve.fNumItems * sizeof(TRatePt) - buf = <char*>malloc(self.buf_size) - memcpy(buf, curve, sizeof(TCurve)) - (<TCurve*>buf).fArray = <TRatePt*>(buf + sizeof(TCurve)) - memcpy(buf + sizeof(TCurve), curve.fArray, curve.fNumItems * sizeof(TRatePt)) + buf = <char*>curve self.buf.reset(buf, char_free) free(dates) @@ -427,11 +419,9 @@ cdef class YieldCurve(Curve): """ build a yield curve from a list of discount factors """ cdef YieldCurve yc = YieldCurve.__new__(YieldCurve) yc.buf_size = sizeof(TCurve) + len(dates) * sizeof(TRatePt) - cdef char* buf = <char*>malloc(yc.buf_size) - cdef TCurve* curve = <TCurve*>buf + cdef TCurve* curve = <TCurve*>malloc(yc.buf_size) curve.fBaseDate = pydate_to_TDate(base_date) curve.fNumItems = len(dates) - curve.fArray = <TRatePt*>(buf + sizeof(TCurve)) curve.fBasis = <double>basis curve.fDayCountConv = dcc(day_count_conv) @@ -441,7 +431,7 @@ cdef class YieldCurve(Curve): JpmcdsDiscountToRateYearFrac(dfs[i], <double>(curve.fArray[i].fDate-curve.fBaseDate)/365., <double>basis, &curve.fArray[i].fRate) - yc.buf.reset(buf, char_free) + yc.buf.reset(<char*>curve, char_free) return yc @classmethod @@ -449,11 +439,10 @@ cdef class YieldCurve(Curve): """ build a yield curve from a list of discount factors """ cdef YieldCurve yc = YieldCurve.__new__(YieldCurve) yc.buf_size = sizeof(TCurve) + len(dates) * sizeof(TRatePt) - cdef char* buf = <char*>malloc(yc.buf_size) - cdef TCurve* curve = <TCurve*>buf + cdef TCurve* curve = <TCurve*>malloc(yc.buf_size) + curve.fBaseDate = pydate_to_TDate(base_date) curve.fNumItems = len(dates) - curve.fArray = <TRatePt*>(buf + sizeof(TCurve)) curve.fBasis = <double>basis curve.fDayCountConv = dcc(day_count_conv) @@ -461,34 +450,26 @@ cdef class YieldCurve(Curve): for i, d in enumerate(dates): curve.fArray[i].fDate = pydate_to_TDate(d) curve.fArray[i].fRate = rates[i] - yc.buf.reset(buf, char_free) + yc.buf.reset(<char*>curve, char_free) return yc def bump(self, epsilon): cdef: YieldCurve yc = YieldCurve.__new__(YieldCurve) - char* buf = <char*>malloc(self.buf_size) - const TCurve* curve = self.get_TCurve() - TCurve* new_curve = <TCurve*>buf - TRatePt *ptr1, *ptr2 - int N = curve.fNumItems + const TCurve* c1 = self.get_TCurve() + TCurve* c2 = <TCurve*>malloc(self.buf_size) int i yc.buf_size = self.buf_size - new_curve.fNumItems = N - new_curve.fBaseDate = curve.fBaseDate - new_curve.fBasis = curve.fBasis - new_curve.fArray = <TRatePt*>(buf + sizeof(TCurve)) - new_curve.fDayCountConv = curve.fDayCountConv - ptr1 = curve.fArray - ptr2 = new_curve.fArray - for i in range(N): - ptr2.fDate = ptr1.fDate - ptr2.fRate = ptr1.fRate + epsilon - preinc(ptr1) - preinc(ptr2) + c2.fNumItems = c1.fNumItems + c2.fBaseDate = c1.fBaseDate + c2.fBasis = c1.fBasis + c2.fDayCountConv = c1.fDayCountConv + for i in range(c1.fNumItems): + c2.fArray[i].fDate = c1.fArray[i].fDate + c2.fArray[i].fRate = c1.fArray[i].fRate + epsilon - yc.buf.reset(buf, char_free) + yc.buf.reset(<char*>c2, char_free) return yc def discount_factor(self, d2, d1=None): @@ -547,13 +528,11 @@ cdef class YieldCurve(Curve): while curve.fArray[i].fDate < forward_date_c: i += 1 yc.buf_size = sizeof(TCurve) + (n - i) * sizeof(TRatePt) - yc.buf.reset(<char*>malloc(yc.buf_size), char_free) - cdef TCurve* forward_curve = <TCurve*>yc.buf.get() + cdef TCurve* forward_curve = <TCurve*>malloc(yc.buf_size) forward_curve.fNumItems = n - i forward_curve.fDayCountConv = curve.fDayCountConv forward_curve.fBaseDate = forward_date_c forward_curve.fBasis = 1.0 - forward_curve.fArray = <TRatePt*>(yc.buf.get() + sizeof(TCurve)) cdef double df cdef TRatePt* arr = forward_curve.fArray while i < n: @@ -564,6 +543,7 @@ cdef class YieldCurve(Curve): <double>1, &arr.fRate) i += 1 preinc(arr) + yc.buf.reset(<char*>forward_curve, char_free) return yc @cython.cdivision(True) @@ -735,10 +715,7 @@ cdef class SpreadCurve(Curve): else: self.buf_size = buf_size(curve.fNumItems, ticker_len) buf = <char*>malloc(self.buf_size) - memcpy(buf, curve, sizeof(TCurve)) - memcpy(buf + sizeof(TCurve), curve.fArray, curve.fNumItems * sizeof(TRatePt)) - (<TCurve*>buf).fArray = <TRatePt*>(buf + sizeof(TCurve)) - free(curve.fArray) + memcpy(buf, curve, sizeof(TCurve) + curve.fNumItems * sizeof(TRatePt)) free(curve) curve = <TCurve*>buf else: @@ -750,7 +727,6 @@ cdef class SpreadCurve(Curve): buf = <char*>malloc(self.buf_size) curve = <TCurve*>buf curve.fNumItems = n_dates - curve.fArray = <TRatePt*>(buf + sizeof(TCurve)) curve.fBaseDate = today_c curve.fBasis = <double>CONTINUOUS curve.fDayCountConv = ACT_360 @@ -826,7 +802,6 @@ cdef class SpreadCurve(Curve): cdef char* buf = <char*>malloc(self.buf_size) cdef int n = self.get_TCurve().fNumItems memcpy(buf, self.buf.get(), self.buf_size) - (<TCurve*>buf).fArray = <TRatePt*>(buf + sizeof(TCurve)) sc.buf_size = self.buf_size sc.buf.reset(buf, char_free) sc.offset_recovery_rates = sizeof(TCurve) + n * sizeof(TRatePt) @@ -1039,7 +1014,6 @@ cdef void _fill_curve(const TCurve* sc, const TDate* end_dates, int n_dates, cha TDate base_date = sc.fBaseDate double t TCurve* curve = <TCurve*>buf - curve.fArray = <TRatePt*>(buf + sizeof(TCurve)) curve.fNumItems = n_dates curve.fBaseDate = base_date curve.fBasis = <double>CONTINUOUS |
