From ab81ee805af8d7ba5ca18aa80de666cc6836388e Mon Sep 17 00:00:00 2001 From: David Date: Fri, 2 Aug 2019 12:23:58 +0930 Subject: [PATCH] dump_lpcnet generates constant size sparse arrays --- src/dump_lpcnet.py | 49 ++++++++++++++++++++++++++++++++-------------- src/nnet.h | 30 ++++++++++++++-------------- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/src/dump_lpcnet.py b/src/dump_lpcnet.py index 52e70f4..0e585f5 100755 --- a/src/dump_lpcnet.py +++ b/src/dump_lpcnet.py @@ -43,8 +43,8 @@ max_mdense_tmp = 1 def printVector(f, vector, name, dtype='float'): v = np.reshape(vector, (-1)); - #print('static const float ', name, '[', len(v), '] = \n', file=f) - f.write('static const {} {}[{}] = {{\n '.format(dtype, name, len(v))) + #print('static float ', name, '[', len(v), '] = \n', file=f) + f.write('static {} {}[{}] = {{\n '.format(dtype, name, len(v))) for i in range(0, len(v)): f.write('{}'.format(v[i])) if (i!=len(v)-1): @@ -78,9 +78,28 @@ def printSparseVector(f, A, name): idx = np.append(idx, j) W = np.concatenate([W, A[j, i*16:(i+1)*16]]) idx[pos] = nb_nonzero - printVector(f, W, name) #idx = np.tile(np.concatenate([np.array([N]), np.arange(N)]), 3*N//16) + + # set a maximum length to accomodate run time loading of other + # networks that may not have been sparsified, or sparsified to + # different lengths + + print(A.shape[0]*A.shape[1]) + print(W.shape) + print(idx.shape) + max_W = A.shape[0]*A.shape[1] + sz = max_W - W.shape[0] + zeropad = np.zeros((sz,), dtype='int') + W = np.concatenate((W,zeropad)) + + max_idx = 32767 + sz = 32767 - idx.shape[0] + zeropad = np.zeros((sz,), dtype='int') + idx = np.concatenate((idx,zeropad)) + + printVector(f, W, name) printVector(f, idx, name + '_idx', dtype='int') + return; def dump_layer_ignore(self, f, hf): @@ -105,11 +124,11 @@ def dump_sparse_gru(self, f, hf): reset_after = 1 neurons = weights[0].shape[1]//3 max_rnn_neurons = max(max_rnn_neurons, neurons) - f.write('const SparseGRULayer {} = {{\n {}_bias,\n {}_recurrent_weights_diag,\n {}_recurrent_weights,\n {}_recurrent_weights_idx,\n {}, ACTIVATION_{}, {}\n}};\n\n' + f.write('SparseGRULayer {} = {{\n {}_bias,\n {}_recurrent_weights_diag,\n {}_recurrent_weights,\n {}_recurrent_weights_idx,\n {}, ACTIVATION_{}, {}\n}};\n\n' .format(name, name, name, name, name, weights[0].shape[1]//3, activation, reset_after)) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) hf.write('#define {}_STATE_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) - hf.write('extern const SparseGRULayer {};\n\n'.format(name)); + hf.write('extern SparseGRULayer {};\n\n'.format(name)); return True def dump_gru_layer(self, f, hf): @@ -130,11 +149,11 @@ def dump_gru_layer(self, f, hf): reset_after = 1 neurons = weights[0].shape[1]//3 max_rnn_neurons = max(max_rnn_neurons, neurons) - f.write('const GRULayer {} = {{\n {}_bias,\n {}_weights,\n {}_recurrent_weights,\n {}, {}, ACTIVATION_{}, {}\n}};\n\n' + f.write('GRULayer {} = {{\n {}_bias,\n {}_weights,\n {}_recurrent_weights,\n {}, {}, ACTIVATION_{}, {}\n}};\n\n' .format(name, name, name, name, weights[0].shape[0], weights[0].shape[1]//3, activation, reset_after)) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) hf.write('#define {}_STATE_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3)) - hf.write('extern const GRULayer {};\n\n'.format(name)); + hf.write('extern GRULayer {};\n\n'.format(name)); return True CuDNNGRU.dump_layer = dump_gru_layer GRU.dump_layer = dump_gru_layer @@ -142,10 +161,10 @@ GRU.dump_layer = dump_gru_layer def dump_dense_layer_impl(name, weights, bias, activation, f, hf): printVector(f, weights, name + '_weights') printVector(f, bias, name + '_bias') - f.write('const DenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, ACTIVATION_{}\n}};\n\n' + f.write('DenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, weights.shape[0], weights.shape[1], activation)) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights.shape[1])) - hf.write('extern const DenseLayer {};\n\n'.format(name)); + hf.write('extern DenseLayer {};\n\n'.format(name)); def dump_dense_layer(self, f, hf): name = self.name @@ -167,10 +186,10 @@ def dump_mdense_layer(self, f, hf): printVector(f, np.transpose(weights[2], (1, 0)), name + '_factor') activation = self.activation.__name__.upper() max_mdense_tmp = max(max_mdense_tmp, weights[0].shape[0]*weights[0].shape[2]) - f.write('const MDenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}_factor,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' + f.write('MDenseLayer {} = {{\n {}_bias,\n {}_weights,\n {}_factor,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, name, weights[0].shape[1], weights[0].shape[0], weights[0].shape[2], activation)) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[0])) - hf.write('extern const MDenseLayer {};\n\n'.format(name)); + hf.write('extern MDenseLayer {};\n\n'.format(name)); return False MDense.dump_layer = dump_mdense_layer @@ -183,22 +202,22 @@ def dump_conv1d_layer(self, f, hf): printVector(f, weights[-1], name + '_bias') activation = self.activation.__name__.upper() max_conv_inputs = max(max_conv_inputs, weights[0].shape[1]*weights[0].shape[0]) - f.write('const Conv1DLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' + f.write('Conv1DLayer {} = {{\n {}_bias,\n {}_weights,\n {}, {}, {}, ACTIVATION_{}\n}};\n\n' .format(name, name, name, weights[0].shape[1], weights[0].shape[0], weights[0].shape[2], activation)) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[2])) hf.write('#define {}_STATE_SIZE ({}*{})\n'.format(name.upper(), weights[0].shape[1], (weights[0].shape[0]-1))) hf.write('#define {}_DELAY {}\n'.format(name.upper(), (weights[0].shape[0]-1)//2)) - hf.write('extern const Conv1DLayer {};\n\n'.format(name)); + hf.write('extern Conv1DLayer {};\n\n'.format(name)); return True Conv1D.dump_layer = dump_conv1d_layer def dump_embedding_layer_impl(name, weights, f, hf): printVector(f, weights, name + '_weights') - f.write('const EmbeddingLayer {} = {{\n {}_weights,\n {}, {}\n}};\n\n' + f.write('EmbeddingLayer {} = {{\n {}_weights,\n {}, {}\n}};\n\n' .format(name, name, weights.shape[0], weights.shape[1])) hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights.shape[1])) - hf.write('extern const EmbeddingLayer {};\n\n'.format(name)); + hf.write('extern EmbeddingLayer {};\n\n'.format(name)); def dump_embedding_layer(self, f, hf): name = self.name diff --git a/src/nnet.h b/src/nnet.h index 14b0bce..1320e06 100644 --- a/src/nnet.h +++ b/src/nnet.h @@ -35,17 +35,17 @@ #define ACTIVATION_SOFTMAX 4 typedef struct { - const float *bias; - const float *input_weights; + float *bias; + float *input_weights; int nb_inputs; int nb_neurons; int activation; } DenseLayer; typedef struct { - const float *bias; - const float *input_weights; - const float *factor; + float *bias; + float *input_weights; + float *factor; int nb_inputs; int nb_neurons; int nb_channels; @@ -53,9 +53,9 @@ typedef struct { } MDenseLayer; typedef struct { - const float *bias; - const float *input_weights; - const float *recurrent_weights; + float *bias; + float *input_weights; + float *recurrent_weights; int nb_inputs; int nb_neurons; int activation; @@ -63,18 +63,18 @@ typedef struct { } GRULayer; typedef struct { - const float *bias; - const float *diag_weights; - const float *recurrent_weights; - const int *idx; + float *bias; + float *diag_weights; + float *recurrent_weights; + int *idx; int nb_neurons; int activation; int reset_after; } SparseGRULayer; typedef struct { - const float *bias; - const float *input_weights; + float *bias; + float *input_weights; int nb_inputs; int kernel_size; int nb_neurons; @@ -82,7 +82,7 @@ typedef struct { } Conv1DLayer; typedef struct { - const float *embedding_weights; + float *embedding_weights; int nb_inputs; int dim; } EmbeddingLayer;