shithub: opus

Download patch

ref: 94ac0841df4dc5aa9f72706d637dae62d330ff37
parent: c025744e34df941db169d5061e3c07a767fe32d8
author: Jean-Marc Valin <jmvalin@jmvalin.ca>
date: Sat Nov 24 10:47:48 EST 2018

Precomputing sizes

--- a/dnn/dump_lpcnet.py
+++ b/dnn/dump_lpcnet.py
@@ -12,6 +12,9 @@
 import h5py
 import re
 
+max_rnn_neurons = 1
+max_conv_inputs = 1
+
 def printVector(f, vector, name):
     v = np.reshape(vector, (-1));
     #print('static const float ', name, '[', len(v), '] = \n', file=f)
@@ -36,6 +39,7 @@
 Layer.dump_layer = dump_layer_ignore
 
 def dump_gru_layer(self, f, hf):
+    global max_rnn_neurons
     name = self.name
     print("printing layer " + name + " of type " + self.__class__.__name__)
     weights = self.get_weights()
@@ -50,9 +54,12 @@
         reset_after = 0
     else:
         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'
             .format(name, name, name, name, weights[0].shape[0], weights[0].shape[1]//3, activation, reset_after))
-    hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1]//3))
+    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));
     return True
 CuDNNGRU.dump_layer = dump_gru_layer
@@ -67,7 +74,7 @@
     activation = self.activation.__name__.upper()
     f.write('const DenseLayer {} = {{\n   {}_bias,\n   {}_weights,\n   {}, {}, ACTIVATION_{}\n}};\n\n'
             .format(name, name, name, weights[0].shape[0], weights[0].shape[1], activation))
-    hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1]))
+    hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1]))
     hf.write('extern const DenseLayer {};\n\n'.format(name));
     return False
 Dense.dump_layer = dump_dense_layer
@@ -82,12 +89,13 @@
     activation = self.activation.__name__.upper()
     f.write('const MDenseLayer {} = {{\n   {}_bias,\n   {}_weights,\n   {}_factor,\n   {}, {}, {}, ACTIVATION_{}\n}};\n\n'
             .format(name, name, name, name, weights[0].shape[0], weights[0].shape[1], weights[0].shape[2], activation))
-    hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[0]))
+    hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[0]))
     hf.write('extern const MDenseLayer {};\n\n'.format(name));
     return False
 MDense.dump_layer = dump_mdense_layer
 
 def dump_conv1d_layer(self, f, hf):
+    global max_conv_inputs
     name = self.name
     print("printing layer " + name + " of type " + self.__class__.__name__)
     weights = self.get_weights()
@@ -94,11 +102,13 @@
     printVector(f, weights[0], name + '_weights')
     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'
             .format(name, name, name, weights[0].shape[1], weights[0].shape[0], weights[0].shape[2], activation))
-    hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1]))
+    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('extern const Conv1DLayer {};\n\n'.format(name));
-    return False
+    return True
 Conv1D.dump_layer = dump_conv1d_layer
 
 
@@ -109,7 +119,7 @@
     printVector(f, weights[0], name + '_weights')
     f.write('const EmbeddingLayer {} = {{\n   {}_weights,\n   {}, {}\n}};\n\n'
             .format(name, name, weights[0].shape[0], weights[0].shape[1]))
-    hf.write('#define {}_SIZE {}\n'.format(name.upper(), weights[0].shape[1]))
+    hf.write('#define {}_OUT_SIZE {}\n'.format(name.upper(), weights[0].shape[1]))
     hf.write('extern const EmbeddingLayer {};\n\n'.format(name));
     return False
 Embedding.dump_layer = dump_embedding_layer
@@ -125,7 +135,6 @@
 hf = open(sys.argv[3], 'w')
 
 
-
 f.write('/*This file is automatically generated from a Keras model*/\n\n')
 f.write('#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n#include "nnet.h"\n#include "foo.h"\n\n')
 
@@ -137,9 +146,12 @@
     if layer.dump_layer(f, hf):
         layer_list.append(layer.name)
 
+hf.write('#define MAX_RNN_NEURONS {}\n\n'.format(max_rnn_neurons))
+hf.write('#define MAX_CONV_INPUTS {}\n\n'.format(max_conv_inputs))
+
 hf.write('struct RNNState {\n')
 for i, name in enumerate(layer_list):
-    hf.write('  float {}_state[{}_SIZE];\n'.format(name, name.upper())) 
+    hf.write('  float {}_state[{}_STATE_SIZE];\n'.format(name, name.upper())) 
 hf.write('};\n')
 
 hf.write('\n\n#endif\n')
--- a/dnn/nnet.c
+++ b/dnn/nnet.c
@@ -157,11 +157,11 @@
    int i;
    int N, M;
    int stride;
-   float tmp[MAX_NEURONS];
-   float z[MAX_NEURONS];
-   float r[MAX_NEURONS];
-   float h[MAX_NEURONS];
-   celt_assert(gru->nb_neurons <= MAX_NEURONS);
+   float tmp[MAX_RNN_NEURONS];
+   float z[MAX_RNN_NEURONS];
+   float r[MAX_RNN_NEURONS];
+   float h[MAX_RNN_NEURONS];
+   celt_assert(gru->nb_neurons <= MAX_RNN_NEURONS);
    M = gru->nb_inputs;
    N = gru->nb_neurons;
    stride = 3*N;
--- a/dnn/nnet.h
+++ b/dnn/nnet.h
@@ -28,9 +28,6 @@
 #ifndef _NNET_H_
 #define _NNET_H_
 
-#define MAX_NEURONS 1024
-#define MAX_CONV_INPUTS 1024
-
 #define ACTIVATION_LINEAR  0
 #define ACTIVATION_SIGMOID 1
 #define ACTIVATION_TANH    2
--