#NEWLINE# @ staticmethod #NEWLINE# def c_code_template( dtype ) : #NEWLINE# #INDENT# init_decl = '\n        npy_intp* Nx = PyArray_DIMS(%(x)s);\n        npy_intp Sx = 0;\n        npy_intp Sb = 0;\n        npy_intp Ssm = 0;\n\n\n        if (PyArray_NDIM(%(x)s) != 2)\n        {\n            PyErr_SetString(PyExc_ValueError, "not a 2d tensor");\n            %(fail)s;\n        }\n        if (PyArray_NDIM(%(b)s) != 1)\n        {\n            PyErr_SetString(PyExc_ValueError, "b not 1d tensor");\n            %(fail)s;\n        }\n        if ((PyArray_TYPE(%(x)s) != NPY_DOUBLE) &&\n            (PyArray_TYPE(%(x)s) != NPY_FLOAT))\n        {\n            PyErr_SetString(PyExc_TypeError, "not a float");\n            %(fail)s;\n        }\n        if ((PyArray_TYPE(%(b)s) != NPY_DOUBLE) &&\n            (PyArray_TYPE(%(b)s) != NPY_FLOAT))\n        {\n            PyErr_SetString(PyExc_TypeError, "b not float");\n            %(fail)s;\n        }\n        if ((PyArray_DIMS(%(x)s)[1] != PyArray_DIMS(%(b)s)[0]))\n        {\n            PyErr_Format(PyExc_ValueError,\n                         "number of columns in x (%%ld) does not match length of b (%%ld)",\n                (long int)PyArray_DIMS(%(x)s)[1], (long int)PyArray_DIMS(%(b)s)[0]);\n            %(fail)s;\n        }\n\n        if ((NULL == %(sm)s)\n            || (PyArray_DIMS(%(sm)s)[0] != PyArray_DIMS(%(x)s)[0])\n            || (PyArray_DIMS(%(sm)s)[1] != PyArray_DIMS(%(x)s)[1]))\n        {\n            if (NULL != %(sm)s) Py_XDECREF(%(sm)s);\n            %(sm)s = (PyArrayObject*)PyArray_SimpleNew(2, PyArray_DIMS(%(x)s),\n                                                       PyArray_TYPE(%(x)s));\n            if(!%(sm)s) {\n                PyErr_SetString(PyExc_MemoryError,\n                     "failed to alloc sm output");\n                %(fail)s\n            }\n        }\n        Sx = PyArray_STRIDES(%(x)s)[1]/sizeof(dtype_%(x)s);\n        Sb = PyArray_STRIDES(%(b)s)[0]/sizeof(dtype_%(b)s);\n        Ssm = PyArray_STRIDES(%(sm)s)[1]/sizeof(dtype_%(sm)s);\n\n        ' #NEWLINE# begin_row_loop = '\n        for (size_t i = 0; i < Nx[0]; ++i)\n        {\n            size_t j;\n            double sum = 0.0;\n\n            const dtype_%(x)s* __restrict__ x_i = (dtype_%(x)s*)(PyArray_BYTES(%(x)s) + PyArray_STRIDES(%(x)s)[0] * i);\n            const dtype_%(b)s* __restrict__ b_i = (dtype_%(b)s*)(PyArray_BYTES(%(b)s));\n            dtype_%(sm) s* __restrict__ sm_i = (dtype_%(sm)s*)(PyArray_BYTES(%(sm)s) + PyArray_STRIDES(%(sm)s)[0] * i);\n\n            npy_intp Sx = PyArray_STRIDES(%(x)s)[1]/sizeof(dtype_%(x)s);\n            npy_intp Sb = PyArray_STRIDES(%(b)s)[0]/sizeof(dtype_%(b)s);\n            npy_intp Ssm = PyArray_STRIDES(%(sm)s)[1]/sizeof(dtype_%(sm)s);\n\n            size_t row_max_j=0;\n            dtype_%(sm)s row_max = x_i[0] + b_i[0];\n            //std::cout << "0 " << row_max << "\\n";\n            // Get the maximum value of the row\n            for (j = 1; j < Nx[1]; ++j)\n            {\n                dtype_%(sm)s row_ij = x_i[j * Sx] +  b_i[j * Sb];\n                //std::cout << "1 " << row_ij << "\\n";\n                row_max_j = (row_ij > row_max) ? j : row_max_j;\n                row_max   = (row_ij > row_max) ? row_ij : row_max;\n            }\n\n        ' #NEWLINE# inside_row_loop = '\n            for (j = 0; j < Nx[1]; ++j)\n            {\n                dtype_%(sm)s row_ij = x_i[j * Sx] +  b_i[j * Sb];\n                //std::cout << "2 " << j << " " << row_ij << " " << row_max << "\\n";\n                dtype_%(sm)s sm_ij = exp(row_ij - row_max);\n                //std::cout << "3 " << j << " " << sm_ij << "\\n";\n                sum += sm_ij;\n                sm_i[j * Ssm] = sm_ij;\n            }\n\n            //cblas_dscal(x.N, 1.0 / sum, &mat_at(s,i,0), s.n);\n            double sum_inv = 1.0 / sum;\n            for (j = 0; j < Nx[1]; ++j)\n            {\n                sm_i[j * Ssm] *= sum_inv;\n            }\n\n        ' #NEWLINE# try : #NEWLINE# #INDENT# vec_exp = theano . scalar . exp . c_code_contiguous_raw ( dtype , 'Nx[1]' , 'sm_i' , 'sm_i' ) #NEWLINE# inside_row_loop_contig = ( '\n            for (j = 0; j < Nx[1]; ++j)\n            {\n                dtype_%%(sm)s row_ij = x_i[j * Sx] +  b_i[j * Sb];\n                //std::cout << "2 " << j << " " << row_ij << " " << row_max << "\\n";\n                dtype_%%(sm)s sm_ij = row_ij - row_max;\n                //std::cout << "3 " << j << " " << sm_ij << "\\n";\n                sm_i[j * Ssm] = sm_ij;\n            }\n            %(vec_exp)s;\n            for (j = 0; j < Nx[1]; ++j)\n            {\n                sum += sm_i[j * Ssm];\n            }\n\n            //cblas_dscal(x.N, 1.0 / sum, &mat_at(s,i,0), s.n);\n            double sum_inv = 1.0 / sum;\n            for (j = 0; j < Nx[1]; ++j)\n            {\n                sm_i[j * Ssm] *= sum_inv;\n            }\n\n        ' % locals ( ) ) #NEWLINE# inside_row_loop = ( '\n            if(Ssm == 1){\n                %(inside_row_loop_contig)s\n            }else{\n                %(inside_row_loop)s\n            }\n            ' % locals ( ) ) #NEWLINE# #UNINDENT# except theano . gof . utils . MethodNotDefined : #NEWLINE# #INDENT# pass #NEWLINE# #UNINDENT# end_row_loop = '\n        }\n        ' #NEWLINE# return ( init_decl , begin_row_loop , inside_row_loop , end_row_loop )