summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2017-11-20 17:37:06 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2017-11-20 17:44:01 -0500
commita0bd01cbd6cf7d360207f357139ef0b4928cc155 (patch)
tree8773cf6df2501c8220a0f443acc43296728af7ce
parent7620847811e085b46cdfa74b4a9d755be2c5317a (diff)
downloadpyisda-a0bd01cbd6cf7d360207f357139ef0b4928cc155.tar.gz
give up on memoryview
-rw-r--r--pyisda/credit_index.pxd4
-rw-r--r--pyisda/curve.pxd6
-rw-r--r--pyisda/curve.pyx41
3 files changed, 37 insertions, 14 deletions
diff --git a/pyisda/credit_index.pxd b/pyisda/credit_index.pxd
index e52a33d..961130d 100644
--- a/pyisda/credit_index.pxd
+++ b/pyisda/credit_index.pxd
@@ -1,6 +1,6 @@
from legs cimport TContingentLeg, TFeeLeg
from date cimport TDate
-from curve cimport TCurve, TRatePt, shared_ptr
+from curve cimport TCurve, TRatePt, shared_ptr, Carray
from libcpp.vector cimport vector
from libcpp.unordered_map cimport unordered_map
from libcpp.string cimport string
@@ -11,7 +11,7 @@ cdef class CurveList:
cdef vector[double] T
cdef vector[shared_ptr[TCurve]] curves
cdef unordered_map[string, size_t] tickers
- cdef vector[double[:]] recovery_rates
+ cdef vector[Carray] recovery_rates
cdef class CreditIndex(CurveList):
cdef TDate start_date
diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd
index 49b1c1b..6432d40 100644
--- a/pyisda/curve.pxd
+++ b/pyisda/curve.pxd
@@ -197,9 +197,13 @@ cdef class Curve:
cdef class YieldCurve(Curve):
cdef vector[TDate] dates
+ctypedef struct Carray:
+ shared_ptr[double] data
+ size_t size
+
cdef class SpreadCurve(Curve):
cdef string ticker
- cdef double[:] recovery_rates
+ cdef Carray recovery_rates
cdef fArray_to_list(TRatePt* fArray, int fNumItems)
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index 260ac4f..26b3c79 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -21,8 +21,6 @@ from numpy cimport npy_intp
cdef extern from "Python.h":
int PyMemoryView_Check(object)
Py_buffer *PyMemoryView_GET_BUFFER(object)
- object PyMemoryView_FromMemory(char* mem, Py_ssize_t data, int flags)
- cdef int PyBUF_WRITE
cdef extern from "numpy/arrayobject.h":
void PyArray_ENABLEFLAGS(np.ndarray arr, int flags)
@@ -41,6 +39,9 @@ cpdef public enum BadDay:
cdef inline shared_ptr[TCurve] make_shared(TCurve* ptr) nogil:
return shared_ptr[TCurve](ptr, JpmcdsFreeTCurve)
+cdef inline void double_free(double* ptr) nogil:
+ free(ptr)
+
cdef class Curve(object):
def __getstate__(self):
@@ -480,6 +481,7 @@ cdef class SpreadCurve(Curve):
cdef unsigned int includes = 0
cdef size_t i
cdef bint freeup = False
+
if cash_settle_date_c < yc._thisptr.get().fBaseDate:
raise ValueError("cash_settle_date: {0} is anterior to yc's base_date: {1}".
format(cash_settle_date, yc.base_date))
@@ -528,7 +530,10 @@ cdef class SpreadCurve(Curve):
raise ValueError("Didn't init the survival curve properly")
else:
self._thisptr = make_shared(curve)
- self.recovery_rates = recovery_rates
+ self.recovery_rates.size = recovery_rates.shape[0] * sizeof(double)
+ self.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size),
+ double_free)
+ memcpy(<void*>self.recovery_rates.data.get(), &recovery_rates[0], self.recovery_rates.size)
if ticker:
self.ticker = ticker.encode()
@@ -541,7 +546,7 @@ cdef class SpreadCurve(Curve):
TCurve* curve = self._thisptr.get()
size_t size = TCurve_size(curve.fNumItems)
size_t buf_size = size + sizeof(size_t) + self.ticker.length() + \
- sizeof(size_t) + sizeof(double) * self.recovery_rates.shape[0]
+ sizeof(size_t) + self.recovery_rates.size
unsigned char* buf = <unsigned char*>malloc(buf_size)
unsigned char* cursor = buf + size
serialize(curve, buf)
@@ -549,10 +554,10 @@ cdef class SpreadCurve(Curve):
memcpy(cursor, &size, sizeof(size_t))
cursor += sizeof(size_t)
cursor += self.ticker.copy(<char*>cursor, size, 0)
- size = self.recovery_rates.shape[0]
+ size = self.recovery_rates.size
memcpy(cursor, &size, sizeof(size_t))
cursor += sizeof(size_t)
- memcpy(cursor, &self.recovery_rates[0], sizeof(double) * self.recovery_rates.shape[0])
+ memcpy(cursor, self.recovery_rates.data.get(), self.recovery_rates.size)
return <bytes>buf[:buf_size]
@cython.initializedcheck(False)
@@ -571,15 +576,20 @@ cdef class SpreadCurve(Curve):
self.ticker = string(<char*>cursor, ticker_length)
cursor += ticker_length
memcpy(&size, cursor, sizeof(size_t))
- temp = <double*>malloc(size * sizeof(char))
+ self.recovery_rates.size = size
+ self.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size),
+ double_free)
cursor += sizeof(size_t)
- memcpy(temp, cursor, size)
- self.recovery_rates = <double[:size/sizeof(double)]>(temp)
+ memcpy(self.recovery_rates.data.get(), cursor, size)
def __deepcopy__(self, dict memo):
cdef SpreadCurve sc = SpreadCurve.__new__(SpreadCurve)
sc._thisptr = make_shared(JpmcdsCopyCurve(self._thisptr.get()))
sc.ticker = self.ticker
+ sc.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size),
+ double_free)
+ memcpy(sc.recovery_rates.data.get(), self.recovery_rates.data.get(), self.recovery_rates.size)
+ sc.recovery_rates.size = self.recovery_rates.size
memo[id(self)] = sc
return sc
@@ -589,7 +599,7 @@ cdef class SpreadCurve(Curve):
SpreadCurve instance = SpreadCurve.__new__(SpreadCurve)
unsigned char* cursor
TCurve* curve = <TCurve*>malloc(sizeof(TCurve))
- size_t ticker_length
+ size_t ticker_length, size
Py_buffer* py_buf
if PyMemoryView_Check(state):
@@ -603,6 +613,11 @@ cdef class SpreadCurve(Curve):
memcpy(&ticker_length, cursor, sizeof(size_t))
cursor += sizeof(size_t)
instance.ticker = string(<char*>cursor, ticker_length)
+ memcpy(&size, cursor, sizeof(size_t))
+ instance.recovery_rates.size = size
+ instance.recovery_rates.data = shared_ptr[double](<double*>malloc(size), double_free)
+ cursor += sizeof(size_t)
+ memcpy(instance.recovery_rates.data.get(), cursor, size)
return instance
def __hash__(self):
@@ -743,7 +758,11 @@ cdef class SpreadCurve(Curve):
@property
def recovery_rates(self):
- return np.asarray(self.recovery_rates)
+ cdef np.npy_intp* shape = <np.npy_intp*>&self.recovery_rates.size
+ cdef np.ndarray[np.float64_t] out = \
+ np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE,
+ self.recovery_rates.data.get())
+ return out
@cython.boundscheck(False)
@cython.wraparound(False)