Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
inplace arithmetic operators for dense features
  • Loading branch information
gsomix committed Jul 16, 2012
1 parent 2f6ce63 commit b5127eb
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 10 deletions.
Expand Up @@ -9,11 +9,33 @@
parameter_list = [[data]]

def features_dense_real_modular(in_data=data):
m_real=array(in_data, dtype=float64)
m_long=array(in_data, dtype=int64)
m_real=array(in_data, dtype=float64, order='F')
m_long=array(in_data, dtype=int64, order='F')

f_real=RealFeatures(m_real)
f_long=LongIntFeatures(m_long)

f_real+=m_real
f_long+=m_long

f_real*=m_real
f_long*=m_long

f_real-=m_real
f_long-=m_long

f_real+=f_real
f_long+=f_long

f_real*=f_real
f_long*=f_long

f_real-=f_real
f_long-=f_long

print f_real
print f_long

try:
mem_real=memoryview(f_real)
mem_long=memoryview(f_long)
Expand All @@ -24,8 +46,8 @@ def features_dense_real_modular(in_data=data):
ret_real=array(f_real)
ret_long=array(f_long)

# print ret_real
# print ret_long
print ret_real
print ret_long

if __name__=='__main__':
print('dense_real')
Expand Down
109 changes: 103 additions & 6 deletions src/interfaces/python_modular/swig_typemaps.i
Expand Up @@ -770,6 +770,92 @@ static bool spvector_to_numpy(PyObject* &obj, SGSparseVector<type> sg_vector, in

%}

/* Numeric operators for DenseFeatures */
%define NUMERIC_DENSEFEATURES(class_name, type_name, format_str, operator_name, operator)

PyObject* class_name ## _inplace ## operator_name ## (PyObject *self, PyObject *o2)
{
CDenseFeatures< type_name > * arg1 = 0;

void *argp1 = 0 ;
int res1 = 0;
int res2 = 0;
int res3 = 0;

PyObject* resultobj = 0;
Py_buffer view;

int num_feat, num_vec;
int shape[2];

type_name *lhs;
type_name *buf;

res1 = SWIG_ConvertPtr(self, &argp1, SWIG_TypeQuery("shogun::CDenseFeatures<type_name>"), 0 | 0 );
arg1 = reinterpret_cast< CDenseFeatures< type_name > * >(argp1);

res2 = PyObject_CheckBuffer(o2);
if (!res2)
{
SWIG_exception_fail(SWIG_ArgError(res1), "this object don't support buffer protocol");
}

res3 = PyObject_GetBuffer(o2, &view, PyBUF_F_CONTIGUOUS | PyBUF_ND | PyBUF_STRIDES | 0);
if (res3 != 0 || view.buf==NULL)
{
SWIG_exception_fail(SWIG_ArgError(res1), "bad buffer");
}

// checking that buffer is right
if (view.ndim != 2)
{
printf("%d\n", view.ndim);
SWIG_exception_fail(SWIG_ArgError(res1), "same dimension is needed");
}

if (view.itemsize != sizeof(type_name))
{
SWIG_exception_fail(SWIG_ArgError(res1), "same type is needed");
}

if (view.shape == NULL)
{
SWIG_exception_fail(SWIG_ArgError(res1), "same shape is needed");
}

shape[0] = view.shape[0];
shape[1] = view.shape[1];
if (shape[0] != arg1->get_num_features() || shape[1] != arg1->get_num_vectors())
SWIG_exception_fail(SWIG_ArgError(res1), "same size is needed");

if (view.len != (shape[0]*shape[1])*view.itemsize)
SWIG_exception_fail(SWIG_ArgError(res1), "bad buffer length");

// result calculation
lhs = arg1->get_feature_matrix(num_feat, num_vec);

// TODO strides support!
buf = (type_name*) view.buf;
for (int i = 0; i < num_vec; i++)
{
for (int j = 0; j < num_feat; j++)
{
lhs[num_feat*i + j] ## operator ## = buf[num_feat*i + j];
}
}

resultobj = self;
PyBuffer_Release(&view);

Py_INCREF(resultobj);
return resultobj;

fail:
return NULL;
}

%enddef

/* Buffer protocol stuff for DenseFeatures */
%define BUFFER_DENSEFEATURES(class_name, type_name, format_str)

Expand Down Expand Up @@ -805,14 +891,17 @@ static int class_name ## _getbuffer(PyObject *exporter, Py_buffer *view, int fla
stride = new Py_ssize_t[2];
stride[0] = sizeof( type_name );
stride[1] = sizeof( type_name ) * num_feat;

view->len = shape[0]*stride[0];
view->itemsize = stride[0];
view->readonly = 0;
view->format = format;
view->ndim = 2;

view->ndim = 2;

view->format = format;
view->itemsize = stride[0];

view->len = (shape[0]*shape[1])*view->itemsize;
view->shape = shape;
view->strides = stride;

view->readonly = 0;
view->suboffsets = NULL;
view->internal = NULL;

Expand All @@ -834,6 +923,10 @@ static void class_name ## _releasebuffer(PyObject *exporter, Py_buffer *view)
delete[] view->strides;
}

NUMERIC_DENSEFEATURES(class_name, type_name, format_str, add, +)
NUMERIC_DENSEFEATURES(class_name, type_name, format_str, sub, -)
NUMERIC_DENSEFEATURES(class_name, type_name, format_str, mul, *)

static long class_name ## _flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_BASETYPE;
%}

Expand All @@ -846,6 +939,10 @@ SwigPyBuiltin__shogun__CDenseFeaturesT_ ## type_name ## _t_type.ht_type.tp_flags
%feature("python:bf_getbuffer") CDenseFeatures< type_name > #class_name "_getbuffer"
%feature("python:bf_releasebuffer") CDenseFeatures< type_name > #class_name "_releasebuffer"

%feature("python:nb_inplace_add") CDenseFeatures< type_name > #class_name "_inplaceadd"
%feature("python:nb_inplace_subtract") CDenseFeatures< type_name > #class_name "_inplacesub"
%feature("python:nb_inplace_multiply") CDenseFeatures< type_name > #class_name "_inplacemul"

%enddef

/* CFeatures to ... */
Expand Down

0 comments on commit b5127eb

Please sign in to comment.