# HG changeset patch # User Frederic Bastien # Date 1246027605 14400 # Node ID b6670cb571012011fee19111267e5e97e78e5fcb # Parent e768674aa51f2cd19b232739782c374e17647967 implemented FillMissing.c_code. It use the new c_no_compile_args to remove -ffast-math and -ffinite-math-only as they broke isnan. diff -r e768674aa51f -r b6670cb57101 pylearn/sandbox/scan_inputs_groups.py --- a/pylearn/sandbox/scan_inputs_groups.py Wed Jun 24 10:53:55 2009 -0400 +++ b/pylearn/sandbox/scan_inputs_groups.py Fri Jun 26 10:46:45 2009 -0400 @@ -657,6 +657,195 @@ def grad(self, inputs, (out_grad, mask_grad, )): return [out_grad] +#def c(): + def c_no_compile_args(self): +#-ffast-math and "-ffinite-math-only" SHOULD NOT BE ACTIVATED as they make isnan don't work! + return ["-ffast-math", "-ffinite-math-only"] + + def c_headers(self): + return ['"Python.h"', '"numpy/noprefix.h"', ''] + + def c_support_code(self): + return """ +using namespace std; +""" + + def c_code(self, node, name, (input,), (value, mask), sub): + if self.fill_with==None: + print "OPTIMISATION WARNING: FillMissing don't implement this case in c. We don't support fill_with=None in c. We revert to python version", self.fill_with_is_array, node.inputs[0].ndim + return super(FillMissing,self).c_code(node, name, (input,),(value,mask), sub) + if (self.fill_with_is_array and not node.inputs[0].ndim in [1,2]) or (not node.inputs[0].ndim in [1,2,3]): + print "OPTIMISATION WARNING: FillMissing don't implement this case in c. We revert to python version", self.fill_with_is_array, node.inputs[0].ndim + return super(FillMissing,self).c_code(node, name, (input,),(value,mask), sub) + + + d=locals() + d.update(sub) + d["self.fill_with_is_array"] = 1 if self.fill_with_is_array else 0 + d["self.fill_with"] = self.fill_with + if self.fill_with_is_array: + d["self.fill_with_length"]=str(self.fill_with.size) + s="" + for i in self.fill_with.flatten(): + s+=","+str(i) + d["self.fill_with_data"]=s[1:] + d["self.fill_with.ndim"]=str(self.fill_with.ndim) + else: + d["self.fill_with_length"]=str(1) + d["self.fill_with_data"]=str(self.fill_with) + d["self.fill_with.ndim"]=0 + if node.inputs[0].type.dtype=="float32": d["type"]="float" + elif node.inputs[0].type.dtype=="float64": d["type"]="double" + else: raise Exception("Type %s not implemented "%node.inputs[0].type.dtype) + + return """ +int typenum; +PyArrayObject* input = %(input)s, *value = %(value)s, *mask = %(mask)s; +%(type)s fill_with[%(self.fill_with_length)s] = {%(self.fill_with_data)s}; + +if(!PyArray_Check(input)){ + PyErr_SetString(PyExc_ValueError, "input must be an ndarray"); + %(fail)s; +} + +typenum = PyArray_ObjectType((PyObject*)input, 0); +if(!value || !PyArray_SAMESHAPE(value,input)){ + Py_XDECREF(value); + value = (PyArrayObject*) PyArray_ZEROS(input->nd, input->dimensions, typenum,0); + %(value)s = value; +} + +if (!mask || !PyArray_SAMESHAPE(mask,input)){ + Py_XDECREF(mask); + mask = (PyArrayObject*) PyArray_ZEROS(input->nd, input->dimensions, typenum,0); + %(mask)s = mask; +} + +if(!PyArray_ISCONTIGUOUS(input)){ + cout<<"OPTIMISATION WARNING: in FillMissing, the input is not contiguous in memory, so we create a new version that is contiguous. This can be optimized by using directly the data."<nd==value->nd==mask->nd); +#if %(self.fill_with_is_array)s + if(input->nd==1){ + %(type)s* value_ = (%(type)s*)(value->data); + %(type)s* mask_ = (%(type)s*)(mask->data); + %(type)s* input_ = (%(type)s*)(input->data); + for(int i=0;idimensions[0];i++){ + if(isnan(input_[i])){ + value_[i]=fill_with[i]; + mask_[i]=0; + }else{ + value_[i]=input_[i]; + mask_[i]=1; + + } + } + }else if(input->nd==2 && %(self.fill_with.ndim)s==1){ + for(int i=0; idimensions[0];i++){ + %(type)s* value_ = (%(type)s*) PyArray_GETPTR2(value,i,0); + %(type)s* mask_ = (%(type)s*) PyArray_GETPTR2(mask,i,0); + %(type)s* input_ = (%(type)s*) PyArray_GETPTR2(input,i,0); + for(int j=0; jdimensions[1];j++){ + if(isnan(input_[j])){ + value_[j]=fill_with[j]; + mask_[j]=0; + }else{ + value_[j]=input_[j]; + mask_[j]=1; + } + } + } + }else{//not implemented! +//SHOULD not happen as c_code should revert to the python version in that case + std:stringstream temp; + temp << "In FillMissing, we try to fill with an array and the input ndim is implemented only for 1 and 2. This case is not implemented."<