diff --git a/docs/sphinx/source/intro/installation.rst b/docs/sphinx/source/intro/installation.rst index 41292ba60..5bfde3a0e 100644 --- a/docs/sphinx/source/intro/installation.rst +++ b/docs/sphinx/source/intro/installation.rst @@ -34,9 +34,9 @@ You can use one of the following lines according to your needs: .. note:: - - Platforms supported: Linux x86/x64 and MacOS + - Platforms supported: Linux and MacOS - .. tab:: GPU + .. tab:: GPU (CUDA) .. code:: bash @@ -44,7 +44,17 @@ You can use one of the following lines according to your needs: .. note:: - - Platforms supported: Linux x86/x64 + - Platforms supported: Linux + + .. tab:: GPU (cuDNN) + + .. code:: bash + + conda install -c deephealth eddl-cudnn + + .. note:: + + - Platforms supported: Linux .. image:: ../_static/images/logos/homebrew.svg diff --git a/examples/nn/4_NLP/5_nlp_text_generation.cpp b/examples/nn/4_NLP/5_nlp_text_generation.cpp index 5161072b0..adb799fea 100644 --- a/examples/nn/4_NLP/5_nlp_text_generation.cpp +++ b/examples/nn/4_NLP/5_nlp_text_generation.cpp @@ -86,8 +86,12 @@ int main(int argc, char **argv) { setDecoder(ldecin); + model old_net = net; + net = Model({image_in}, {out}); + delete old_net; + plot(net, "model.pdf"); optimizer opt=adam(0.01); @@ -113,7 +117,6 @@ int main(int argc, char **argv) { summary(net); - // Load dataset Tensor *x_train=Tensor::load("flickr_trX.bin","bin"); //x_train->info(); //1000,256,256,3 diff --git a/formulas/brew/eddl.rb b/formulas/brew/eddl.rb index 9abc7fb1f..e5b4eaafd 100644 --- a/formulas/brew/eddl.rb +++ b/formulas/brew/eddl.rb @@ -4,12 +4,14 @@ class Eddl < Formula desc "European Distributed Deep Learning Library (EDDL)" homepage "https://github.com/deephealthproject/eddl" - url "https://github.com/deephealthproject/eddl/archive/v0.8.3a.tar.gz" - sha256 "3d0678b4e00b9a5fb9c3905cf5bd3f5daa596684af47d1e77fbabbfd82f4e064" + url "https://github.com/deephealthproject/eddl/archive/v0.9a.tar.gz" + sha256 "93372aca9133f847c9dd2dd678a2107e9424d512e806929065fbe2a17270a425" depends_on "cmake" => :build depends_on "eigen" => :build depends_on "protobuf" => :build + depends_on "zlib" => :build + depends_on "openssl@1.1" => :build depends_on "graphviz" => :build depends_on "wget" => :build diff --git a/formulas/conda/eddl/build.sh b/formulas/conda/eddl/build.sh index 34734c8fb..ad05725b9 100644 --- a/formulas/conda/eddl/build.sh +++ b/formulas/conda/eddl/build.sh @@ -11,18 +11,32 @@ if [[ "$OSTYPE" == "darwin"* ]]; then # If I don't do this, I get errors like: "undefined reference to `expf@GLIBC_2.27'" elif [[ "$OSTYPE" == "linux"* ]]; then - CXX=g++ - CC=gcc + CXX=g++-7 + CC=gcc-7 fi +# Prints vars +echo "#################################################" +echo "##### CONDA BUILD CONSTANTS #####################" +echo "#################################################" +echo "PREFIX=$PREFIX" +echo "CMAKE_LIBRARY_PATH=$CMAKE_LIBRARY_PATH" +echo "CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH" +echo "SRC_DIR=$SRC_DIR" +echo "CC=$CC" +echo "CXX=$CXX" +echo "CPU_COUNT=$CPU_COUNT" +echo "#################################################" # Build makefiles -mkdir build -cd build/ cmake -DBUILD_TARGET=CPU \ -DBUILD_SUPERBUILD=OFF \ -DBUILD_EXAMPLES=OFF \ -DBUILD_TESTS=OFF \ + -DCMAKE_C_COMPILER=$CC \ + -DCMAKE_CXX_COMPILER=$CXX \ + -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \ + -DCMAKE_PREFIX_PATH=$PREFIX \ -DCMAKE_INSTALL_PREFIX=$PREFIX \ $SRC_DIR diff --git a/formulas/conda/eddl/meta.yaml b/formulas/conda/eddl/meta.yaml index b2c96918c..17882ea28 100644 --- a/formulas/conda/eddl/meta.yaml +++ b/formulas/conda/eddl/meta.yaml @@ -1,6 +1,6 @@ {% set name = "eddl-cpu" %} # If this is a package for GPU, use: "eddl-gpu" -{% set version = "0.8.3a" %} -{% set sha256 = "3d0678b4e00b9a5fb9c3905cf5bd3f5daa596684af47d1e77fbabbfd82f4e064" %} +{% set version = "0.9a" %} +{% set sha256 = "93372aca9133f847c9dd2dd678a2107e9424d512e806929065fbe2a17270a425" %} package: name: {{ name|lower }} @@ -19,20 +19,22 @@ requirements: build: - {{ compiler('cxx') }} host: - - cmake>=3.9.2 + - cmake>=3.17.2 - eigen==3.3.7 - protobuf==3.11.4 - libprotobuf==3.11.4 # We need to avoid problems with paths (idk why) - - cudatoolkit - - graphviz # Build & Run + - zlib==1.2.11 + - openssl==1.1.1i + - graphviz # Build & Run (versions can be problematic) - wget run: - - cmake>=3.9.2 + - cmake>=3.17.2 - eigen==3.3.7 - protobuf==3.11.4 - libprotobuf==3.11.4 # We need to avoid problems with paths (idk why) - - cudatoolkit - - graphviz # Build & Run + - zlib==1.2.11 + - openssl==1.1.1i + - graphviz # Build & Run (versions can be problematic) - wget test: diff --git a/include/eddl/layers/layer.h b/include/eddl/layers/layer.h index 95e033100..5a11bbbbc 100644 --- a/include/eddl/layers/layer.h +++ b/include/eddl/layers/layer.h @@ -31,7 +31,7 @@ class Net; class Layer { private: - void * my_owner; + int reference_counter; public: string name; @@ -132,9 +132,8 @@ class Layer { virtual void enable_distributed() {} - bool set_my_owner(void * net); - bool is_my_owner(void * net); - void * get_my_owner(); + int decrease_and_get_reference_counter(); + void increase_reference_counter(); }; diff --git a/src/layers/layer.cpp b/src/layers/layer.cpp index 0f56659b1..1050409e2 100644 --- a/src/layers/layer.cpp +++ b/src/layers/layer.cpp @@ -48,7 +48,7 @@ Layer::Layer(string name, int dev, int mem) { // init = new IGlorotNormal(1234); this->init = new IGlorotUniform(1234); // Has problems with the drive dataset - this->my_owner = nullptr; + this->reference_counter = 0; // accounts how many nets are referencing this layer } Layer::~Layer(){ @@ -251,24 +251,13 @@ void Layer::copy(Layer *l2){ } } -bool Layer::set_my_owner(void * net) +void Layer::increase_reference_counter() { - if (this->my_owner == nullptr) { - this->my_owner = net; - return true; - } else { - return false; - } + reference_counter++; } - -bool Layer::is_my_owner(void * net) -{ - return this->my_owner == net; -} - -void * Layer::get_my_owner() +int Layer::decrease_and_get_reference_counter() { - return this->my_owner; + return --reference_counter; } //////////////////////////////////// diff --git a/src/net/net.cpp b/src/net/net.cpp index f7da05292..f16821df0 100644 --- a/src/net/net.cpp +++ b/src/net/net.cpp @@ -76,14 +76,8 @@ Net::Net(vlayer in, vlayer out):Net() { // Set input/outlayer //lin = in; //lout = out; - for (auto l : in) { - lin.push_back(l); - l->set_my_owner(this); - } - for (auto l : out) { - lout.push_back(l); - l->set_my_owner(this); - } + for (auto l : in) lin.push_back(l); + for (auto l : out) lout.push_back(l); // Walk through the pointers of all layers, to get a plain // vector with all the layers @@ -111,9 +105,11 @@ Net::Net(vlayer in, vlayer out):Net() { // It is important that layers vector keep the forward sort fts(); while (layers.size()) layers.pop_back(); - for(auto l: vfts ) layers.push_back(l); + for(auto l: vfts ) { + l->increase_reference_counter(); + layers.push_back(l); + } while (vfts.size()) vfts.pop_back(); - } @@ -160,7 +156,7 @@ Net::~Net(){ } } - if (snets[0] != this){ + if (snets.size() == 0 || snets[0] != this){ if (this->optimizer != nullptr && this->do_optimizer_delete){ delete this->optimizer; } @@ -176,24 +172,22 @@ Net::~Net(){ for(int i=0;ilayers.size();j++) { if (snets[i]->layers[j]!=nullptr) { - //fprintf(stderr, "%s(%d) %d %d : %p %p %p %p\n", __FILE__, __LINE__, i, j, snets[i]->layers[j]->get_my_owner(), this, snets[i], rnet); - if (snets[i]->layers[j]->is_my_owner(this) || snets[i]->layers[j]->is_my_owner(snets[i])) { + if (snets[i]->layers[j]->decrease_and_get_reference_counter() == 0) { delete snets[i]->layers[j]; - snets[i]->layers[j] = nullptr; } + snets[i]->layers[j] = nullptr; } } } // net running on device != CPU // clean also CPU mem - if (snets[0]!=this){ + if (snets.size() == 0 || snets[0]!=this){ for(int j=0;jget_my_owner(), this); - if (layers[j]->is_my_owner(this)) { + if (layers[j]->decrease_and_get_reference_counter() == 0) { delete layers[j]; - layers[j] = nullptr; } + layers[j] = nullptr; } } @@ -237,7 +231,6 @@ void Net::walk(Layer *l,vlayer lout) { if (!inNetF(l)) { l->net=this; layersf.push_back(l); - l->set_my_owner(this); } else return; @@ -253,7 +246,6 @@ void Net::walk_back(Layer *l) { if (!inNetB(l)) { layersb.push_back(l); - l->set_my_owner(this); l->net=this; } else return; diff --git a/src/net/net_build.cpp b/src/net/net_build.cpp index e04bc5e15..e600809f4 100644 --- a/src/net/net_build.cpp +++ b/src/net/net_build.cpp @@ -479,6 +479,8 @@ void Net::removeLayer(string lname) for(int k=0;kchild.size();k++) { if (p->child[k]==l) { p->child.erase(p->child.begin() + k); + p->lout--; + break; } }//child // create new outputs from parents @@ -489,7 +491,10 @@ void Net::removeLayer(string lname) //layers.erase(layers.begin() + i); for(int j=0;jname<name==lname) lout.erase(lout.begin()+j); + if (lout[j]->name==lname) { + lout.erase(lout.begin()+j); + break; + } } // remove lname from list of layers layers.erase(layers.begin() + i); diff --git a/src/serialization/onnx/eddl_onnx_import.cpp b/src/serialization/onnx/eddl_onnx_import.cpp index c9bd0086d..b4a6430c6 100644 --- a/src/serialization/onnx/eddl_onnx_import.cpp +++ b/src/serialization/onnx/eddl_onnx_import.cpp @@ -15,7 +15,10 @@ #include #include -#define NEW_FROM_VECTOR_PTR(v) (copy((v)->begin(), (v)->end(), new float[(v)->size()]) - (v)->size()) +// #define NEW_FROM_VECTOR_PTR(v) (copy((v)->begin(), (v)->end(), new float[(v)->size()]) - (v)->size()) -- this generates memory leaks +#define COPY_FROM_VECTOR_PTR_TO_TENSOR(v, t) (copy((v)->begin(), (v)->end(), t->ptr)) +#define COPY_FROM_VECTOR_PTR_TO_FLOAT_PTR(v, ptr) (copy((v)->begin(), (v)->end(), ptr)) + std::vector vf2vi(const std::vector &vf) { std::vector vi; @@ -906,19 +909,23 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in actual_layer = new LBatchNorm(parent, momentum, epsilon, affine, name, dev, mem); - Tensor *scale_tensor = new Tensor(scale_dims, NEW_FROM_VECTOR_PTR(scale_weights), dev); + Tensor *scale_tensor = new Tensor(scale_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(scale_weights, scale_tensor); Tensor::copy(scale_tensor, ((LBatchNorm *)(actual_layer))->bn_g); delete scale_tensor; - Tensor *bias_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_weights), dev); + Tensor *bias_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_weights, bias_tensor); Tensor::copy(bias_tensor, ((LBatchNorm *)(actual_layer))->bn_b); delete bias_tensor; - Tensor *mean_tensor = new Tensor(mean_dims, NEW_FROM_VECTOR_PTR(mean_weights), dev); + Tensor *mean_tensor = new Tensor(mean_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(mean_weights, mean_tensor); Tensor::copy(mean_tensor, ((LBatchNorm *)(actual_layer))->mean); delete mean_tensor; - Tensor *variance_tensor = new Tensor(variance_dims, NEW_FROM_VECTOR_PTR(variance_weights), dev); + Tensor *variance_tensor = new Tensor(variance_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(variance_weights, variance_tensor); Tensor::copy(variance_tensor, ((LBatchNorm *)(actual_layer))->variance); delete variance_tensor; } @@ -1032,11 +1039,13 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in bias = &(map_init_values[bias_name]); vector bias_shape; bias_shape.push_back(bias->size()); - Tensor *bias_tensor = new Tensor(bias_shape, NEW_FROM_VECTOR_PTR(bias), dev); + Tensor *bias_tensor = new Tensor(bias_shape, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, bias_tensor); Tensor::copy(bias_tensor, cd->bias); delete bias_tensor; } - Tensor *weights_tensor = new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev); + Tensor *weights_tensor = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, weights_tensor); Tensor::copy(weights_tensor, cd->K); delete weights_tensor; } @@ -1110,7 +1119,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in Tensor *input_size = parent->output; LDense *dense = new LDense(parent, neuronas, use_bias, name, dev, mem); - Tensor *weights_tensor = new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev); + Tensor *weights_tensor = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, weights_tensor); if (transB) weights_tensor->permute_({1, 0}); @@ -1121,7 +1131,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in bias_name = node->input(2); bias = &(map_init_values[bias_name]); bias_dims = map_init_dims[bias_name]; - Tensor *bias_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias), dev); + Tensor *bias_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, bias_tensor); Tensor::copy(bias_tensor, dense->bias); delete bias_tensor; } @@ -1581,7 +1592,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in vector *bias = &(map_init_values[bias_name]); vector bias_shape; bias_shape.push_back(bias->size()); - Tensor *bias_tensor = new Tensor(bias_shape, NEW_FROM_VECTOR_PTR(bias), dev); + Tensor *bias_tensor = new Tensor(bias_shape, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, bias_tensor); if (!cd->use_bias) { cd->use_bias = true; // We need to enable the bias @@ -1607,7 +1619,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in { log_string("Setting the bias values of the parent Dense to the Add parameters.", log_level, LOG_LEVEL::DEBUG); dense->use_bias = true; - dense->bias = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias), dev); + dense->bias = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, dense->bias); dense->params.push_back(dense->bias); dense->gbias = new Tensor(bias_dims, dev); dense->gradients.push_back(dense->gbias); @@ -1615,7 +1628,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in else { // If dense already has a bias, we sum it in top of the bias log_string("The parent Dense already has a bias. Adding the parameters of the Add operator to the parent bias.", log_level, LOG_LEVEL::DEBUG); - Tensor *add_to_bias = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias), dev); + Tensor *add_to_bias = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, add_to_bias); Tensor::add(add_to_bias, dense->bias, dense->bias); delete add_to_bias; } @@ -1993,7 +2007,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in Layer *parent = parents[1 - index_parameter]; bool use_bias = false; LDense *dense = new LDense(parent, neuronas, use_bias, name, dev, mem); - Tensor *weights_tensor = new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev); + Tensor *weights_tensor = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, weights_tensor); Tensor::copy(weights_tensor, dense->W); delete weights_tensor; actual_layer = dense; @@ -2233,49 +2248,57 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in /* * The Weights are permuted before copying them to the LSTM layer (mismatch between ONNX standad and EDDL implementation) */ - Tensor *weights_input_tensor = new Tensor(dims_input_lstm, NEW_FROM_VECTOR_PTR(weights_input_g), dev); + Tensor *weights_input_tensor = new Tensor(dims_input_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_input_g, weights_input_tensor); weights_input_tensor->permute_({1, 0}); Tensor::copy(weights_input_tensor, lstm->Wix); delete weights_input_tensor; delete weights_input_g; - Tensor *weights_output_tensor = new Tensor(dims_input_lstm, NEW_FROM_VECTOR_PTR(weights_output_g), dev); + Tensor *weights_output_tensor = new Tensor(dims_input_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_output_g, weights_output_tensor); weights_output_tensor->permute_({1, 0}); Tensor::copy(weights_output_tensor, lstm->Wox); delete weights_output_tensor; delete weights_output_g; - Tensor *weights_forget_tensor = new Tensor(dims_input_lstm, NEW_FROM_VECTOR_PTR(weights_forget_g), dev); + Tensor *weights_forget_tensor = new Tensor(dims_input_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_forget_g, weights_forget_tensor); weights_forget_tensor->permute_({1, 0}); Tensor::copy(weights_forget_tensor, lstm->Wfx); delete weights_forget_tensor; delete weights_forget_g; - Tensor *weights_cell_tensor = new Tensor(dims_input_lstm, NEW_FROM_VECTOR_PTR(weights_cell_g), dev); + Tensor *weights_cell_tensor = new Tensor(dims_input_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_cell_g, weights_cell_tensor); weights_cell_tensor->permute_({1, 0}); Tensor::copy(weights_cell_tensor, lstm->Wcx); delete weights_cell_tensor; delete weights_cell_g; - Tensor *recurrence_weights_input_tensor = new Tensor(dims_recurrent_lstm, NEW_FROM_VECTOR_PTR(recurrence_weights_input_g), dev); + Tensor *recurrence_weights_input_tensor = new Tensor(dims_recurrent_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_input_g, recurrence_weights_input_tensor); recurrence_weights_input_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_input_tensor, lstm->Wih); delete recurrence_weights_input_tensor; delete recurrence_weights_input_g; - Tensor *recurrence_weights_output_tensor = new Tensor(dims_recurrent_lstm, NEW_FROM_VECTOR_PTR(recurrence_weights_output_g), dev); + Tensor *recurrence_weights_output_tensor = new Tensor(dims_recurrent_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_output_g, recurrence_weights_output_tensor); recurrence_weights_output_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_output_tensor, lstm->Woh); delete recurrence_weights_output_tensor; delete recurrence_weights_output_g; - Tensor *recurrence_weights_forget_tensor = new Tensor(dims_recurrent_lstm, NEW_FROM_VECTOR_PTR(recurrence_weights_forget_g), dev); + Tensor *recurrence_weights_forget_tensor = new Tensor(dims_recurrent_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_forget_g, recurrence_weights_forget_tensor); recurrence_weights_forget_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_forget_tensor, lstm->Wfh); delete recurrence_weights_forget_tensor; delete recurrence_weights_forget_g; - Tensor *recurrence_weights_cell_tensor = new Tensor(dims_recurrent_lstm, NEW_FROM_VECTOR_PTR(recurrence_weights_cell_g), dev); + Tensor *recurrence_weights_cell_tensor = new Tensor(dims_recurrent_lstm, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_cell_g, recurrence_weights_cell_tensor); recurrence_weights_cell_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_cell_tensor, lstm->Wch); delete recurrence_weights_cell_tensor; @@ -2323,43 +2346,51 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in } - Tensor *bias_input_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_input), dev); + Tensor *bias_input_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_input, bias_input_tensor); Tensor::copy(bias_input_tensor, lstm->inbias); delete bias_input_tensor; delete bias_input; - Tensor *bias_output_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_output), dev); + Tensor *bias_output_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_output, bias_output_tensor); Tensor::copy(bias_output_tensor, lstm->onbias); delete bias_output_tensor; delete bias_output; - Tensor *bias_forget_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_forget), dev); + Tensor *bias_forget_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_forget, bias_forget_tensor); Tensor::copy(bias_forget_tensor, lstm->fnbias); delete bias_forget_tensor; delete bias_forget; - Tensor *bias_cell_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_cell), dev); + Tensor *bias_cell_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_cell, bias_cell_tensor); Tensor::copy(bias_cell_tensor, lstm->cnbias); delete bias_cell_tensor; delete bias_cell; // Add the recurrent bias values - Tensor *bias_recurrence_input_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_input), dev); + Tensor *bias_recurrence_input_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_input, bias_recurrence_input_tensor); Tensor::add(bias_recurrence_input_tensor, lstm->inbias, lstm->inbias); delete bias_recurrence_input_tensor; delete bias_recurrence_input; - Tensor *bias_recurrence_output_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_output), dev); + Tensor *bias_recurrence_output_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_output, bias_recurrence_output_tensor); Tensor::add(bias_recurrence_output_tensor, lstm->onbias, lstm->onbias); delete bias_recurrence_output_tensor; delete bias_recurrence_output; - Tensor *bias_recurrence_forget_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_forget), dev); + Tensor *bias_recurrence_forget_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_forget, bias_recurrence_forget_tensor); Tensor::add(bias_recurrence_forget_tensor, lstm->fnbias, lstm->fnbias); delete bias_recurrence_forget_tensor; delete bias_recurrence_forget; - Tensor *bias_recurrence_cell_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_cell), dev); + Tensor *bias_recurrence_cell_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_cell, bias_recurrence_cell_tensor); Tensor::add(bias_recurrence_cell_tensor, lstm->cnbias, lstm->cnbias); delete bias_recurrence_cell_tensor; delete bias_recurrence_cell; @@ -2496,37 +2527,43 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in /* * The Weights are permuted before copying them to the GRU layer (mismatch between ONNX standad and EDDL implementation) */ - Tensor *weights_z_tensor = new Tensor(dims_input_gru, NEW_FROM_VECTOR_PTR(weights_z_g), dev); + Tensor *weights_z_tensor = new Tensor(dims_input_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_z_g, weights_z_tensor); weights_z_tensor->permute_({1, 0}); Tensor::copy(weights_z_tensor, gru->Wz_x); delete weights_z_tensor; delete weights_z_g; - Tensor *weights_r_tensor = new Tensor(dims_input_gru, NEW_FROM_VECTOR_PTR(weights_r_g), dev); + Tensor *weights_r_tensor = new Tensor(dims_input_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_r_g, weights_r_tensor); weights_r_tensor->permute_({1, 0}); Tensor::copy(weights_r_tensor, gru->Wr_x); delete weights_r_tensor; delete weights_r_g; - Tensor *weights_n_tensor = new Tensor(dims_input_gru, NEW_FROM_VECTOR_PTR(weights_n_g), dev); + Tensor *weights_n_tensor = new Tensor(dims_input_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_n_g, weights_n_tensor); weights_n_tensor->permute_({1, 0}); Tensor::copy(weights_n_tensor, gru->Wn_x); delete weights_n_tensor; delete weights_n_g; - Tensor *recurrence_weights_z_tensor = new Tensor(dims_recurrent_gru, NEW_FROM_VECTOR_PTR(recurrence_weights_z_g), dev); + Tensor *recurrence_weights_z_tensor = new Tensor(dims_recurrent_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_z_g, recurrence_weights_z_tensor); recurrence_weights_z_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_z_tensor, gru->Uz_h); delete recurrence_weights_z_tensor; delete recurrence_weights_z_g; - Tensor *recurrence_weights_r_tensor = new Tensor(dims_recurrent_gru, NEW_FROM_VECTOR_PTR(recurrence_weights_r_g), dev); + Tensor *recurrence_weights_r_tensor = new Tensor(dims_recurrent_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_r_g, recurrence_weights_r_tensor); recurrence_weights_r_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_r_tensor, gru->Ur_h); delete recurrence_weights_r_tensor; delete recurrence_weights_r_g; - Tensor *recurrence_weights_n_tensor = new Tensor(dims_recurrent_gru, NEW_FROM_VECTOR_PTR(recurrence_weights_n_g), dev); + Tensor *recurrence_weights_n_tensor = new Tensor(dims_recurrent_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(recurrence_weights_n_g, recurrence_weights_n_tensor); recurrence_weights_n_tensor->permute_({1, 0}); Tensor::copy(recurrence_weights_n_tensor, gru->Un_h); delete recurrence_weights_n_tensor; @@ -2568,35 +2605,41 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in bias_recurrence_n->assign(zero_bias.begin(), zero_bias.begin() + hidden_size); } - Tensor *bias_z_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_z), dev); + Tensor *bias_z_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_z, bias_z_tensor); Tensor::copy(bias_z_tensor, gru->bias_z_t); delete bias_z_tensor; delete bias_z; - Tensor *bias_r_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_r), dev); + Tensor *bias_r_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_r, bias_r_tensor); Tensor::copy(bias_r_tensor, gru->bias_r_t); delete bias_r_tensor; delete bias_r; - Tensor *bias_n_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_n), dev); + Tensor *bias_n_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_n, bias_n_tensor); Tensor::copy(bias_n_tensor, gru->bias_n_t); delete bias_n_tensor; delete bias_n; // Add the recurrent bias values for gates z and r - Tensor *bias_recurrence_z_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_z), dev); + Tensor *bias_recurrence_z_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_z, bias_recurrence_z_tensor); Tensor::add(bias_recurrence_z_tensor, gru->bias_z_t, gru->bias_z_t); delete bias_recurrence_z_tensor; delete bias_recurrence_z; - Tensor *bias_recurrence_r_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_r), dev); + Tensor *bias_recurrence_r_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_r, bias_recurrence_r_tensor); Tensor::add(bias_recurrence_r_tensor, gru->bias_r_t, gru->bias_r_t); delete bias_recurrence_r_tensor; delete bias_recurrence_r; // The recurrent bias for h goes to its own tensor beacuse we need it for applying the linear transformation // before the r gate. See "linear_before_reset" attribute in https://github.com/onnx/onnx/blob/master/docs/Operators.md#GRU - Tensor *bias_recurrence_n_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_recurrence_n), dev); + Tensor *bias_recurrence_n_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_recurrence_n, bias_recurrence_n_tensor); Tensor::copy(bias_recurrence_n_tensor, gru->bias_n_t_hidden); delete bias_recurrence_n_tensor; delete bias_recurrence_n; @@ -2771,13 +2814,15 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in /* * The Weights are permuted before copying them to the RNN layer (mismatch between ONNX standad and EDDL implementation) */ - Tensor *weights_x_tensor = new Tensor(dims_input_gru, NEW_FROM_VECTOR_PTR(weights_x), dev); + Tensor *weights_x_tensor = new Tensor(dims_input_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_x, weights_x_tensor); weights_x_tensor->permute_({1, 0}); Tensor::copy(weights_x_tensor, rnn->Wx); delete weights_x_tensor; delete weights_x; - Tensor *weights_h_tensor = new Tensor(dims_recurrent_gru, NEW_FROM_VECTOR_PTR(weights_h), dev); + Tensor *weights_h_tensor = new Tensor(dims_recurrent_gru, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights_h, weights_h_tensor); weights_h_tensor->permute_({1, 0}); Tensor::copy(weights_h_tensor, rnn->Wy); delete weights_h_tensor; @@ -2794,13 +2839,15 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in bias_x->assign(biases->begin() + hidden_size * 0, biases->begin() + hidden_size * 1); bias_h->assign(biases->begin() + hidden_size * 1, biases->begin() + hidden_size * 2); - Tensor *bias_x_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_x), dev); + Tensor *bias_x_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_x, bias_x_tensor); Tensor::copy(bias_x_tensor, rnn->bias); delete bias_x_tensor; delete bias_x; // Add the recurrent bias values for gates z and r - Tensor *bias_h_tensor = new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias_h), dev); + Tensor *bias_h_tensor = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias_h, bias_h_tensor); Tensor::add(bias_h_tensor, rnn->bias, rnn->bias); delete bias_h_tensor; delete bias_h; @@ -2853,7 +2900,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in vector parent_shape = parent->output->shape; LEmbedding *embedding = new LEmbedding(parent, dims[0], 1 /*parent_shape[1]*/, dims[1], 0, name, dev, mem); - Tensor *weights_tensor = new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev); + Tensor *weights_tensor = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, weights_tensor); Tensor::copy(weights_tensor, embedding->E); delete weights_tensor; @@ -3132,7 +3180,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in vector new_shape = parent->getShape(); string weights_name = node->input(2); - float *dim_scales = NEW_FROM_VECTOR_PTR(&(map_init_values[weights_name])); + float *dim_scales = new float [(&(map_init_values[weights_name]))->size()]; + COPY_FROM_VECTOR_PTR_TO_FLOAT_PTR(&(map_init_values[weights_name]), dim_scales); // Compute new shape by scaling the parent output shape for (int i = 0; i < new_shape.size(); ++i) @@ -3140,6 +3189,8 @@ Net *build_net_onnx(onnx::ModelProto model, vector input_shape, int mem, in new_shape[i] = new_shape[i] * dim_scales[i]; } + delete [] dim_scales; + actual_layer = new LScale(parent, {new_shape[2], new_shape[3]}, reshape_out, getWrappingMode(da_mode), constant, name, DEV_CPU, 0); } break; @@ -3486,7 +3537,9 @@ map> get_tensors_from_onnx(onnx::ModelProto model) vector *weights = &(map_init_values[weights_name]); vector dims = map_init_dims[weights_name]; - conv_tensors.push_back(new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev)); + Tensor * temp = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, temp); + conv_tensors.push_back(temp); if (node.input_size() > 2) { // This means we also have a bias @@ -3494,7 +3547,9 @@ map> get_tensors_from_onnx(onnx::ModelProto model) vector *bias = &(map_init_values[bias_name]); vector bias_shape; bias_shape.push_back(bias->size()); - conv_tensors.push_back(new Tensor(bias_shape, NEW_FROM_VECTOR_PTR(bias), dev)); + temp = new Tensor(bias_shape, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, temp); + conv_tensors.push_back(temp); } tensors[name] = conv_tensors; @@ -3509,14 +3564,18 @@ map> get_tensors_from_onnx(onnx::ModelProto model) vector *weights = &(map_init_values[weights_name]); vector dims = map_init_dims[weights_name]; - dense_tensors.push_back(new Tensor(dims, NEW_FROM_VECTOR_PTR(weights), dev)); + Tensor * temp = new Tensor(dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(weights, temp); + dense_tensors.push_back(temp); if (node.input_size() > 2) { string bias_name = node.input(2); vector *bias = &(map_init_values[bias_name]); vector bias_dims = map_init_dims[bias_name]; - dense_tensors.push_back(new Tensor(bias_dims, NEW_FROM_VECTOR_PTR(bias), dev)); + temp = new Tensor(bias_dims, nullptr, dev); + COPY_FROM_VECTOR_PTR_TO_TENSOR(bias, temp); + dense_tensors.push_back(temp); } tensors[name] = dense_tensors;