From 351bd137e48c5276963274ac741b172483e98d21 Mon Sep 17 00:00:00 2001 From: giuros01 Date: Fri, 23 Aug 2019 14:27:30 +0100 Subject: compmid-2573: Investigate FP16 Winograd reference implementations Change-Id: I5a3e692c046a5ad28a676c03e3e51950c64cf503 Signed-off-by: giuros01 Reviewed-on: https://review.mlplatform.org/c/1845 Reviewed-by: Pablo Marquez Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins --- examples/graph_inception_v3.cpp | 92 ++++++++++++++++---------------- src/graph/mutators/NodeFusionMutator.cpp | 23 +++++--- utils/GraphUtils.cpp | 51 +++++++++++++++--- utils/GraphUtils.h | 6 +++ utils/ImageLoader.h | 13 +++-- utils/Utils.h | 2 +- 6 files changed, 122 insertions(+), 65 deletions(-) diff --git a/examples/graph_inception_v3.cpp b/examples/graph_inception_v3.cpp index bce093d0f5..1de6a5fad7 100644 --- a/examples/graph_inception_v3.cpp +++ b/examples/graph_inception_v3.cpp @@ -85,8 +85,8 @@ public: "/cnn_data/inceptionv3_model/Conv2d_1a_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, "/cnn_data/inceptionv3_model/Conv2d_1a_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), get_weights_accessor(data_path, - "/cnn_data/inceptionv3_model/Conv2d_1a_3x3_BatchNorm_beta.npy"), + nullptr, get_weights_accessor(data_path, + "/cnn_data/inceptionv3_model/Conv2d_1a_3x3_BatchNorm_beta.npy"), 0.001f) .set_name("Conv2d_1a_3x3/BatchNorm/batchnorm") << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_1a_3x3/Relu") @@ -98,8 +98,8 @@ public: "/cnn_data/inceptionv3_model/Conv2d_2a_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, "/cnn_data/inceptionv3_model/Conv2d_2a_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), get_weights_accessor(data_path, - "/cnn_data/inceptionv3_model/Conv2d_2a_3x3_BatchNorm_beta.npy"), + nullptr, get_weights_accessor(data_path, + "/cnn_data/inceptionv3_model/Conv2d_2a_3x3_BatchNorm_beta.npy"), 0.001f) .set_name("Conv2d_2a_3x3/BatchNorm/batchnorm") << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2a_3x3/Relu") @@ -112,8 +112,8 @@ public: "/cnn_data/inceptionv3_model/Conv2d_2b_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, "/cnn_data/inceptionv3_model/Conv2d_2b_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), get_weights_accessor(data_path, - "/cnn_data/inceptionv3_model/Conv2d_2b_3x3_BatchNorm_beta.npy"), + nullptr, get_weights_accessor(data_path, + "/cnn_data/inceptionv3_model/Conv2d_2b_3x3_BatchNorm_beta.npy"), 0.001f) .set_name("Conv2d_2b_3x3/BatchNorm/batchnorm") << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_2b_3x3/Relu") @@ -128,8 +128,8 @@ public: "/cnn_data/inceptionv3_model/Conv2d_3b_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, "/cnn_data/inceptionv3_model/Conv2d_3b_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), get_weights_accessor(data_path, - "/cnn_data/inceptionv3_model/Conv2d_3b_1x1_BatchNorm_beta.npy"), + nullptr, get_weights_accessor(data_path, + "/cnn_data/inceptionv3_model/Conv2d_3b_1x1_BatchNorm_beta.npy"), 0.001f) .set_name("Conv2d_3b_1x1/BatchNorm/batchnorm") << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_3b_1x1/Relu") @@ -142,8 +142,8 @@ public: "/cnn_data/inceptionv3_model/Conv2d_4a_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, "/cnn_data/inceptionv3_model/Conv2d_4a_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), get_weights_accessor(data_path, - "/cnn_data/inceptionv3_model/Conv2d_4a_3x3_BatchNorm_beta.npy"), + nullptr, get_weights_accessor(data_path, + "/cnn_data/inceptionv3_model/Conv2d_4a_3x3_BatchNorm_beta.npy"), 0.001f) .set_name("Conv2d_4a_3x3/BatchNorm/batchnorm") << ActivationLayer(ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::RELU)).set_name("Conv2d_4a_3x3/Relu") @@ -249,7 +249,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -265,7 +265,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id0 + "1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id0 + "1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id0 + "1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d" + conv_id0 + "1x1/BatchNorm/batchnorm") @@ -279,7 +279,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv" + conv_id1 + "5x5_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv" + conv_id1 + "5x5_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv" + conv_id1 + "5x5_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d" + conv_id1 + "5x5/BatchNorm/batchnorm") @@ -295,7 +295,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -309,7 +309,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/BatchNorm/batchnorm") @@ -323,7 +323,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0c_3x3/BatchNorm/batcnorm") @@ -340,7 +340,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm/batchnorm") @@ -364,7 +364,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_1a_1x1/BatchNorm/batchnorm") @@ -380,7 +380,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -394,7 +394,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0b_3x3/BatchNorm/batchnorm") @@ -408,7 +408,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_1a_1x1/BatchNorm/batchnorm") @@ -437,7 +437,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -453,7 +453,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -467,7 +467,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/BatchNorm/batchnorm") @@ -481,7 +481,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/BatchNorm/batchnorm") @@ -497,7 +497,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -511,7 +511,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_7x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0b_7x1/BatchNorm/batchnorm") @@ -525,7 +525,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x7_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0c_1x7/BatchNorm/batchnorm") @@ -539,7 +539,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_7x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0d_7x1/BatchNorm/batchnorm") @@ -553,7 +553,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0e_1x7_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0e_1x7/BatchNorm/batchnorm") @@ -570,7 +570,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm/batchnorm") @@ -594,7 +594,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -608,7 +608,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_1a_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_1a_3x3/BatchNorm/batchnorm") @@ -624,7 +624,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -638,7 +638,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x7_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0b_1x7/BatchNorm/batchnorm") @@ -652,7 +652,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0c_7x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0c_7x1/BatchNorm/batchnorm") @@ -666,7 +666,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_1a_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_1a_3x3/BatchNorm/batchnorm") @@ -703,7 +703,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_0_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_0/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -719,7 +719,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -735,7 +735,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d_0b_1x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d_0b_1x3/BatchNorm/batchnorm") @@ -751,7 +751,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id + "3x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id + "3x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_1_Conv2d" + conv_id + "3x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_1/Conv2d" + conv_id + "3x1/BatchNorm/batchnorm") @@ -770,7 +770,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0a_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0a_1x1/BatchNorm/batchnorm") @@ -784,7 +784,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0b_3x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0b_3x3/BatchNorm/batchnorm") @@ -800,7 +800,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0c_1x3_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0c_1x3/BatchNorm/batchnorm") @@ -816,7 +816,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_3x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_3x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_2_Conv2d_0d_3x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_2/Conv2d_0d_3x1/BatchNorm/batchnorm") @@ -836,7 +836,7 @@ private: << BatchNormalizationLayer( get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_mean.npy"), get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_moving_variance.npy"), - get_random_accessor(1.f, 1.f), + nullptr, get_weights_accessor(data_path, total_path + "Branch_3_Conv2d_0b_1x1_BatchNorm_beta.npy"), 0.001f) .set_name(param_path + "/Branch_3/Conv2d_0b_1x1/BatchNorm/batchnorm") diff --git a/src/graph/mutators/NodeFusionMutator.cpp b/src/graph/mutators/NodeFusionMutator.cpp index f7f3454fad..4c3a905598 100644 --- a/src/graph/mutators/NodeFusionMutator.cpp +++ b/src/graph/mutators/NodeFusionMutator.cpp @@ -71,11 +71,10 @@ void fuse_convolution_with_batch_normalization(Graph &g, const Edge *output_edge FastMathHint fast_math_hint = conv_node->fast_math_hint(); // Extract bn inputs - const auto bn_mean_id = bn_node->input_edge(1)->producer_id(); - const auto bn_var_id = bn_node->input_edge(2)->producer_id(); - const auto bn_beta_id = bn_node->input_edge(3)->producer_id(); - const auto bn_gamma_id = bn_node->input_edge(4)->producer_id(); - const auto epsilon = bn_node->epsilon(); + const auto bn_mean_id = bn_node->input_edge(1)->producer_id(); + const auto bn_var_id = bn_node->input_edge(2)->producer_id(); + + const auto epsilon = bn_node->epsilon(); // Create the fused node const NodeID fused_id = g.add_node(epsilon, conv_info, num_groups, conv_method, fast_math_hint, act_info); @@ -91,8 +90,18 @@ void fuse_convolution_with_batch_normalization(Graph &g, const Edge *output_edge g.add_connection(conv_weights_id, 0, fused_id, 1); g.add_connection(bn_mean_id, 0, fused_id, 3); g.add_connection(bn_var_id, 0, fused_id, 4); - g.add_connection(bn_beta_id, 0, fused_id, 5); - g.add_connection(bn_gamma_id, 0, fused_id, 6); + + if(bn_node->input_edge(3) != nullptr) + { + const auto bn_beta_id = bn_node->input_edge(3)->producer_id(); + g.add_connection(bn_beta_id, 0, fused_id, 5); + } + + if(bn_node->input_edge(4) != nullptr) + { + const auto bn_gamma_id = bn_node->input_edge(4)->producer_id(); + g.add_connection(bn_gamma_id, 0, fused_id, 6); + } auto fused_node = g.node(fused_id); std::vector bn_driving_nodes = get_driving_nodes(*bn_node); diff --git a/utils/GraphUtils.cpp b/utils/GraphUtils.cpp index 00165cd6c2..3646facab2 100644 --- a/utils/GraphUtils.cpp +++ b/utils/GraphUtils.cpp @@ -62,18 +62,34 @@ TFPreproccessor::TFPreproccessor(float min_range, float max_range) { } void TFPreproccessor::preprocess(ITensor &tensor) +{ + if(tensor.info()->data_type() == DataType::F32) + { + preprocess_typed(tensor); + } + else if(tensor.info()->data_type() == DataType::F16) + { + preprocess_typed(tensor); + } + else + { + ARM_COMPUTE_ERROR("NOT SUPPORTED!"); + } +} + +template +void TFPreproccessor::preprocess_typed(ITensor &tensor) { Window window; window.use_tensor_dimensions(tensor.info()->tensor_shape()); const float range = _max_range - _min_range; - execute_window_loop(window, [&](const Coordinates & id) { - const float value = *reinterpret_cast(tensor.ptr_to_element(id)); - float res = value / 255.f; // Normalize to [0, 1] - res = res * range + _min_range; // Map to [min_range, max_range] - *reinterpret_cast(tensor.ptr_to_element(id)) = res; + const T value = *reinterpret_cast(tensor.ptr_to_element(id)); + float res = value / 255.f; // Normalize to [0, 1] + res = res * range + _min_range; // Map to [min_range, max_range] + *reinterpret_cast(tensor.ptr_to_element(id)) = res; }); } @@ -87,16 +103,32 @@ CaffePreproccessor::CaffePreproccessor(std::array mean, bool bgr, floa } void CaffePreproccessor::preprocess(ITensor &tensor) +{ + if(tensor.info()->data_type() == DataType::F32) + { + preprocess_typed(tensor); + } + else if(tensor.info()->data_type() == DataType::F16) + { + preprocess_typed(tensor); + } + else + { + ARM_COMPUTE_ERROR("NOT SUPPORTED!"); + } +} + +template +void CaffePreproccessor::preprocess_typed(ITensor &tensor) { Window window; window.use_tensor_dimensions(tensor.info()->tensor_shape()); - const int channel_idx = get_data_layout_dimension_index(tensor.info()->data_layout(), DataLayoutDimension::CHANNEL); execute_window_loop(window, [&](const Coordinates & id) { - const float value = *reinterpret_cast(tensor.ptr_to_element(id)) - _mean[id[channel_idx]]; - *reinterpret_cast(tensor.ptr_to_element(id)) = value * _scale; + const T value = *reinterpret_cast(tensor.ptr_to_element(id)) - T(_mean[id[channel_idx]]); + *reinterpret_cast(tensor.ptr_to_element(id)) = value * T(_scale); }); } @@ -370,6 +402,9 @@ bool ValidationOutputAccessor::access_tensor(arm_compute::ITensor &tensor) case DataType::QASYMM8: tensor_results = access_predictions_tensor(tensor); break; + case DataType::F16: + tensor_results = access_predictions_tensor(tensor); + break; case DataType::F32: tensor_results = access_predictions_tensor(tensor); break; diff --git a/utils/GraphUtils.h b/utils/GraphUtils.h index 3417135f17..4c25dd2460 100644 --- a/utils/GraphUtils.h +++ b/utils/GraphUtils.h @@ -70,6 +70,9 @@ public: void preprocess(ITensor &tensor) override; private: + template + void preprocess_typed(ITensor &tensor); + std::array _mean; bool _bgr; float _scale; @@ -90,6 +93,9 @@ public: void preprocess(ITensor &tensor) override; private: + template + void preprocess_typed(ITensor &tensor); + float _min_range; float _max_range; }; diff --git a/utils/ImageLoader.h b/utils/ImageLoader.h index 24fcbe179a..5d3a84c59a 100644 --- a/utils/ImageLoader.h +++ b/utils/ImageLoader.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018 ARM Limited. + * Copyright (c) 2018-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -249,14 +249,14 @@ public: * * @note If the image is a CLImage, the function maps and unmaps the image * - * @param[in,out] tensor Tensor with 3 planes to fill (Must be allocated, and of matching dimensions with the opened image). Data types supported: U8/F32 + * @param[in,out] tensor Tensor with 3 planes to fill (Must be allocated, and of matching dimensions with the opened image). Data types supported: U8/F16/F32 * @param[in] bgr (Optional) Fill the first plane with blue channel (default = false) */ template void fill_planar_tensor(T &tensor, bool bgr = false) { ARM_COMPUTE_ERROR_ON(!is_open()); - ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::U8, DataType::F32); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&tensor, 1, DataType::U8, DataType::F32, DataType::F16); const DataLayout data_layout = tensor.info()->data_layout(); const TensorShape tensor_shape = tensor.info()->tensor_shape(); @@ -324,6 +324,13 @@ public: *reinterpret_cast(out.ptr() + 2 * stride_z) = static_cast(bgr ? red : blue); break; } + case DataType::F16: + { + *reinterpret_cast(out.ptr() + 0 * stride_z) = static_cast(bgr ? blue : red); + *reinterpret_cast(out.ptr() + 1 * stride_z) = static_cast(green); + *reinterpret_cast(out.ptr() + 2 * stride_z) = static_cast(bgr ? red : blue); + break; + } default: { ARM_COMPUTE_ERROR("Unsupported data type"); diff --git a/utils/Utils.h b/utils/Utils.h index ec08896257..7fa74ab08b 100644 --- a/utils/Utils.h +++ b/utils/Utils.h @@ -401,7 +401,7 @@ public: void fill_tensor(T &tensor) { ARM_COMPUTE_ERROR_ON(!is_open()); - ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(&tensor, arm_compute::DataType::QASYMM8, arm_compute::DataType::S32, arm_compute::DataType::F32); + ARM_COMPUTE_ERROR_ON_DATA_TYPE_NOT_IN(&tensor, arm_compute::DataType::QASYMM8, arm_compute::DataType::S32, arm_compute::DataType::F32, arm_compute::DataType::F16); try { // Map buffer if creating a CLTensor -- cgit v1.2.1