# Path: deeppy/base.py
# class PickleMixin(object):
#     _pickle_ignore = ['_tmp_']
# 
#     def _pickle_discard(self, attr_name):
#         for s in self._pickle_ignore:
#             if attr_name.startswith(s):
#                 return True
#         return False
# 
#     def __getstate__(self):
#         return dict((k, None) if self._pickle_discard(k) else (k, v)
#                     for k, v in self.__dict__.items())
# 
# Path: deeppy/filler.py
# class Filler(object):
#     def __init__(self):
#         raise NotImplementedError()
# 
#     @classmethod
#     def from_any(cls, arg):
#         if isinstance(arg, Filler):
#             return arg
#         elif isinstance(arg, (int, float)):
#             return ConstantFiller(arg)
#         elif isinstance(arg, (np.ndarray, ca.ndarray)):
#             return CopyFiller(arg)
#         elif isinstance(arg, tuple):
#             if len(arg) == 2:
#                 if arg[0] == 'normal':
#                     return NormalFiller(**arg[1])
#                 elif arg[0] == 'uniform':
#                     return UniformFiller(**arg[1])
#         raise ValueError('Invalid fillter arguments')
# 
#     def array(self, shape):
#         raise NotImplementedError()


import numpy as np
import cudarray as ca
import logging
from .base import PickleMixin
from .filler import Filler

    def setup(self, shape):
        if self._array is None:
            self._array = self.filler.array(shape)
        else:
            if isinstance(shape, int):
                shape = (shape,)
            if self._array.shape != shape:
                raise ValueError('Shape %s does not match existing shape %s' %
                                 (shape, self._array.shape))

    @property
    def array(self):
        return self._array

    @property
    def grad_array(self):
        ''' Returns the gradient array. '''
        if self._tmp_grad_array is None:
            if self.array is None:
                raise ValueError('Parameter not setup')
            self._tmp_grad_array = ca.zeros_like(self.array)
        return self._tmp_grad_array

    def grad(self):
        ''' Returns a parameter step calculated from the gradient.
        This differs from grad_array() as the parameter may be shared such
        that its gradient has multiple sources. '''
        grad = self.grad_array
        for param in self.shares:

# Path: deeppy/base.py
# class PickleMixin(object):
#     _pickle_ignore = ['_tmp_']
# 
#     def _pickle_discard(self, attr_name):
#         for s in self._pickle_ignore:
#             if attr_name.startswith(s):
#                 return True
#         return False
# 
#     def __getstate__(self):
#         return dict((k, None) if self._pickle_discard(k) else (k, v)
#                     for k, v in self.__dict__.items())
# 
# Path: deeppy/filler.py
# class Filler(object):
#     def __init__(self):
#         raise NotImplementedError()
# 
#     @classmethod
#     def from_any(cls, arg):
#         if isinstance(arg, Filler):
#             return arg
#         elif isinstance(arg, (int, float)):
#             return ConstantFiller(arg)
#         elif isinstance(arg, (np.ndarray, ca.ndarray)):
#             return CopyFiller(arg)
#         elif isinstance(arg, tuple):
#             if len(arg) == 2:
#                 if arg[0] == 'normal':
#                     return NormalFiller(**arg[1])
#                 elif arg[0] == 'uniform':
#                     return UniformFiller(**arg[1])
#         raise ValueError('Invalid fillter arguments')
# 
#     def array(self, shape):
#         raise NotImplementedError()


# Path: deeppy/parameter.py
import numpy as np
import cudarray as ca
import logging
from .base import PickleMixin
from .filler import Filler


    def setup(self, shape):
        if self._array is None:
            self._array = self.filler.array(shape)
        else:
            if isinstance(shape, int):
                shape = (shape,)
            if self._array.shape != shape:
                raise ValueError('Shape %s does not match existing shape %s' %
                                 (shape, self._array.shape))

    @property
    def array(self):
        return self._array

    @property
    def grad_array(self):
        ''' Returns the gradient array. '''
        if self._tmp_grad_array is None:
            if self.array is None:
                raise ValueError('Parameter not setup')
            self._tmp_grad_array = ca.zeros_like(self.array)
        return self._tmp_grad_array

    def grad(self):
        ''' Returns a parameter step calculated from the gradient.
        This differs from grad_array() as the parameter may be shared such
        that its gradient has multiple sources. '''
        grad = self.grad_array
        for param in self.shares:

            grad += param.grad_array