summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2023-02-01 12:52:40 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2023-02-01 12:52:40 -0500
commit1db8c8a1fa2ecb90236d1b27dbc9805c448869e2 (patch)
treecc66a35c6ca6c5d3f27305c179f807da90fd611b
parent28c6f1ec8cfcfe8a28e54aa99ddfa441904ceaf7 (diff)
downloadpyisda-1db8c8a1fa2ecb90236d1b27dbc9805c448869e2.tar.gz
take advantage of fam
-rw-r--r--pyisda/credit_index.pyx7
-rw-r--r--pyisda/curve.pxd4
-rw-r--r--pyisda/curve.pyx104
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