# Path: pynet/model.py
# class MLP(Model):
# 
#     def __init__(self, **kwargs):
#         super(MLP, self).__init__(**kwargs)
# 
#     def add_layer(self, layer):
# 
#         prev_layer_dim = 0
# 
#         if len(self.layers) == 0:
#             prev_layer_dim = self.input_dim
#         else:
#             prev_layer_dim = self.layers[-1].dim
# 
#         if layer.W is None:
# 
#             # W_values = np.asarray(np.random.uniform(
#             #                     low = -4 * np.sqrt(6. / (layer.dim + prev_layer_dim)),
#             #                     high = 4 * np.sqrt(6. / (layer.dim + prev_layer_dim)),
#             #                     size = (prev_layer_dim, layer.dim)),
#             #                     dtype = floatX)
#             #
#             # layer.W = theano.shared(value=W_values, name='W_'+layer.name, borrow=True)
# 
#             W_values = np.asarray(np.random.normal(loc = 0, scale = 0.1,
#                                   size = (prev_layer_dim, layer.dim)),
#                                   dtype = floatX)
#             layer.W = theano.shared(value=W_values, name='W_'+layer.name, borrow=True)
# 
#         if layer.b is None:
#             layer.b = theano.shared(np.zeros(layer.dim, dtype=floatX),
#                                     name='b_'+layer.name, borrow=True)
# 
#         self.layers.append(layer)
# 
#     def pop_layer(self, index):
#         return self.layers.pop(index)
# 
#     def test_fprop(self, input_state):
#         test_layers_stats = []
#         for i in xrange(len(self.layers)):
#             layer_output = self.layers[i]._test_fprop(input_state)
#             stats = self.layers[i]._layer_stats(input_state, layer_output)
#             input_state = layer_output
#             class_name = self.layers[i].__class__.__name__
#             stats = [(str(i)+'_'+class_name+'_'+a, b) for (a,b) in stats]
#             test_layers_stats += stats
# 
#         return input_state, test_layers_stats
# 
# 
#     def train_fprop(self, input_state):
#         train_layers_stats = []
#         for i in xrange(len(self.layers)):
#             layer_output = self.layers[i]._train_fprop(input_state)
#             stats = self.layers[i]._layer_stats(input_state, layer_output)
#             input_state = layer_output
#             class_name = self.layers[i].__class__.__name__
#             stats = [(str(i)+'_'+class_name+'_'+a, b) for (a,b) in stats]
#             train_layers_stats += stats
# 
#         return input_state, train_layers_stats
# 
#     def fprop(self, input_values):
#         input_state = T.matrix('X', dtype=floatX)
#         output, stats = self.test_fprop(input_state)
#         f = theano.function([input_state], output)
#         return f(input_values)
# 
#     def get_layers(self):
#         return self.layers


import argparse
import cPickle
import theano.tensor as T
import numpy as np
import copy
import theano
import pynet.layer as layers
from theano.sandbox.cuda.var import CudaNdarraySharedVariable
from pynet.model import MLP


floatX = theano.config.floatX

parser = argparse.ArgumentParser(description='''Convert gpu pickle pynet model to cpu pickle pynet model''')
parser.add_argument('--gpu_model', metavar='Path', required=True, help='the path to the gpu model pickle file')
parser.add_argument('--cpu_model', metavar='Path', required=True, help='''path to save the cpu model pickle file''')
args = parser.parse_args()

print ('loading gpu mlp..')
fin = open(args.gpu_model)
gpu_model = cPickle.load(fin)

mlp = MLP(input_dim=gpu_model.input_dim)
for layer in gpu_model.layers:
    layerW = T._shared(np.array(layer.W.get_value(), floatX),

# Path: pynet/model.py
# class MLP(Model):
# 
#     def __init__(self, **kwargs):
#         super(MLP, self).__init__(**kwargs)
# 
#     def add_layer(self, layer):
# 
#         prev_layer_dim = 0
# 
#         if len(self.layers) == 0:
#             prev_layer_dim = self.input_dim
#         else:
#             prev_layer_dim = self.layers[-1].dim
# 
#         if layer.W is None:
# 
#             # W_values = np.asarray(np.random.uniform(
#             #                     low = -4 * np.sqrt(6. / (layer.dim + prev_layer_dim)),
#             #                     high = 4 * np.sqrt(6. / (layer.dim + prev_layer_dim)),
#             #                     size = (prev_layer_dim, layer.dim)),
#             #                     dtype = floatX)
#             #
#             # layer.W = theano.shared(value=W_values, name='W_'+layer.name, borrow=True)
# 
#             W_values = np.asarray(np.random.normal(loc = 0, scale = 0.1,
#                                   size = (prev_layer_dim, layer.dim)),
#                                   dtype = floatX)
#             layer.W = theano.shared(value=W_values, name='W_'+layer.name, borrow=True)
# 
#         if layer.b is None:
#             layer.b = theano.shared(np.zeros(layer.dim, dtype=floatX),
#                                     name='b_'+layer.name, borrow=True)
# 
#         self.layers.append(layer)
# 
#     def pop_layer(self, index):
#         return self.layers.pop(index)
# 
#     def test_fprop(self, input_state):
#         test_layers_stats = []
#         for i in xrange(len(self.layers)):
#             layer_output = self.layers[i]._test_fprop(input_state)
#             stats = self.layers[i]._layer_stats(input_state, layer_output)
#             input_state = layer_output
#             class_name = self.layers[i].__class__.__name__
#             stats = [(str(i)+'_'+class_name+'_'+a, b) for (a,b) in stats]
#             test_layers_stats += stats
# 
#         return input_state, test_layers_stats
# 
# 
#     def train_fprop(self, input_state):
#         train_layers_stats = []
#         for i in xrange(len(self.layers)):
#             layer_output = self.layers[i]._train_fprop(input_state)
#             stats = self.layers[i]._layer_stats(input_state, layer_output)
#             input_state = layer_output
#             class_name = self.layers[i].__class__.__name__
#             stats = [(str(i)+'_'+class_name+'_'+a, b) for (a,b) in stats]
#             train_layers_stats += stats
# 
#         return input_state, train_layers_stats
# 
#     def fprop(self, input_values):
#         input_state = T.matrix('X', dtype=floatX)
#         output, stats = self.test_fprop(input_state)
#         f = theano.function([input_state], output)
#         return f(input_values)
# 
#     def get_layers(self):
#         return self.layers


# Path: scripts/gpu_mlp_to_cpu_mlp.py
import argparse
import cPickle
import theano.tensor as T
import numpy as np
import copy
import theano
import pynet.layer as layers
from theano.sandbox.cuda.var import CudaNdarraySharedVariable
from pynet.model import MLP



floatX = theano.config.floatX

parser = argparse.ArgumentParser(description='''Convert gpu pickle pynet model to cpu pickle pynet model''')
parser.add_argument('--gpu_model', metavar='Path', required=True, help='the path to the gpu model pickle file')
parser.add_argument('--cpu_model', metavar='Path', required=True, help='''path to save the cpu model pickle file''')
args = parser.parse_args()

print ('loading gpu mlp..')
fin = open(args.gpu_model)
gpu_model = cPickle.load(fin)

mlp = MLP(input_dim=gpu_model.input_dim)
for layer in gpu_model.layers:
    layerW = T._shared(np.array(layer.W.get_value(), floatX),

                        name=layer.W.name, borrow=False)