From 6ab94e0b318884bbcb95e2ea3835f951502e1d99 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 14 Oct 2020 12:47:28 +0200 Subject: Move firmware into subdirectory --- .../cifar10/RTE/Compiler/EventRecorderConf.h | 44 + .../cifar10/RTE/_ARMCM0/RTE_Components.h | 24 + .../cifar10/RTE/_ARMCM3/RTE_Components.h | 22 + .../cifar10/RTE/_ARMCM4_FP/RTE_Components.h | 22 + .../cifar10/RTE/_ARMCM7_SP/RTE_Components.h | 22 + .../cifar10/arm_nnexamples_cifar10.cpp | 196 ++++ .../cifar10/arm_nnexamples_cifar10_inputs.h | 6 + .../cifar10/arm_nnexamples_cifar10_parameter.h | 43 + .../cifar10/arm_nnexamples_cifar10_weights.h | 26 + .../gru/RTE/Compiler/EventRecorderConf.h | 44 + .../gru/RTE/_ARMCM0/RTE_Components.h | 24 + .../gru/RTE/_ARMCM3/RTE_Components.h | 22 + .../gru/RTE/_ARMCM4_FP/RTE_Components.h | 22 + .../gru/RTE/_ARMCM7_SP/RTE_Components.h | 22 + .../ARM/arm_nn_examples/gru/arm_nnexamples_gru.cpp | 221 +++++ .../gru/arm_nnexamples_gru_test_data.h | 23 + .../Drivers/CMSIS/NN/Include/arm_nn_tables.h | 59 ++ .../Drivers/CMSIS/NN/Include/arm_nnfunctions.h | 1010 ++++++++++++++++++++ .../CMSIS/NN/Include/arm_nnsupportfunctions.h | 202 ++++ .../nn_test/RTE/_ARMCM0/RTE_Components.h | 20 + .../nn_test/RTE/_ARMCM3/RTE_Components.h | 26 + .../nn_test/RTE/_ARMCM4_FP/RTE_Components.h | 26 + .../nn_test/RTE/_ARMCM7_SP/RTE_Components.h | 26 + .../Ref_Implementations/arm_convolve_HWC_q15_ref.c | 71 ++ .../arm_convolve_HWC_q15_ref_nonsquare.c | 83 ++ .../Ref_Implementations/arm_convolve_HWC_q7_ref.c | 72 ++ .../arm_convolve_HWC_q7_ref_nonsquare.c | 78 ++ .../arm_depthwise_separable_conv_HWC_q7_ref.c | 70 ++ ...depthwise_separable_conv_HWC_q7_ref_nonsquare.c | 75 ++ .../arm_fully_connected_mat_q7_vec_q15_opt_ref.c | 120 +++ .../arm_fully_connected_mat_q7_vec_q15_ref.c | 43 + .../arm_fully_connected_q15_opt_ref.c | 119 +++ .../arm_fully_connected_q15_ref.c | 43 + .../arm_fully_connected_q7_opt_ref.c | 138 +++ .../arm_fully_connected_q7_ref.c | 43 + .../nn_test/Ref_Implementations/arm_nn_mult_ref.c | 58 ++ .../nn_test/Ref_Implementations/arm_pool_ref.c | 96 ++ .../nn_test/Ref_Implementations/arm_relu_ref.c | 42 + .../fully_connected_testing_weights.h | 7 + .../nn_test/Ref_Implementations/ref_functions.h | 250 +++++ .../nn_test/arm_nnexamples_nn_test.cpp | 801 ++++++++++++++++ .../NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.h | 78 ++ .../ActivationFunctions/arm_nn_activations_q15.c | 101 ++ .../ActivationFunctions/arm_nn_activations_q7.c | 91 ++ .../NN/Source/ActivationFunctions/arm_relu_q15.c | 106 ++ .../NN/Source/ActivationFunctions/arm_relu_q7.c | 110 +++ .../arm_convolve_1x1_HWC_q7_fast_nonsquare.c | 235 +++++ .../arm_convolve_HWC_q15_basic.c | 207 ++++ .../arm_convolve_HWC_q15_fast.c | 255 +++++ .../arm_convolve_HWC_q15_fast_nonsquare.c | 265 +++++ .../ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c | 279 ++++++ .../arm_convolve_HWC_q7_basic.c | 230 +++++ .../arm_convolve_HWC_q7_basic_nonsquare.c | 228 +++++ .../arm_convolve_HWC_q7_fast.c | 408 ++++++++ .../arm_convolve_HWC_q7_fast_nonsquare.c | 379 ++++++++ .../arm_depthwise_separable_conv_HWC_q7.c | 418 ++++++++ ...arm_depthwise_separable_conv_HWC_q7_nonsquare.c | 411 ++++++++ .../arm_nn_mat_mult_kernel_q7_q15.c | 187 ++++ .../arm_nn_mat_mult_kernel_q7_q15_reordered.c | 138 +++ .../arm_fully_connected_mat_q7_vec_q15.c | 199 ++++ .../arm_fully_connected_mat_q7_vec_q15_opt.c | 403 ++++++++ .../arm_fully_connected_q15.c | 193 ++++ .../arm_fully_connected_q15_opt.c | 332 +++++++ .../arm_fully_connected_q7.c | 198 ++++ .../arm_fully_connected_q7_opt.c | 484 ++++++++++ .../NN/Source/NNSupportFunctions/arm_nn_mult_q15.c | 147 +++ .../NN/Source/NNSupportFunctions/arm_nn_mult_q7.c | 119 +++ .../NN/Source/NNSupportFunctions/arm_nntables.c | 297 ++++++ .../NNSupportFunctions/arm_q7_to_q15_no_shift.c | 134 +++ .../arm_q7_to_q15_reordered_no_shift.c | 145 +++ .../NN/Source/PoolingFunctions/arm_pool_q7_HWC.c | 448 +++++++++ .../NN/Source/SoftmaxFunctions/arm_softmax_q15.c | 120 +++ .../NN/Source/SoftmaxFunctions/arm_softmax_q7.c | 121 +++ 73 files changed, 11827 insertions(+) create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/Compiler/EventRecorderConf.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM0/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM3/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM4_FP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM7_SP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10.cpp create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_inputs.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_parameter.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_weights.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/Compiler/EventRecorderConf.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM0/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM3/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM4_FP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM7_SP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru.cpp create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru_test_data.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nn_tables.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnfunctions.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM0/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM3/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM4_FP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM7_SP/RTE_Components.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_opt_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_opt_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_opt_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_nn_mult_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_pool_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_relu_ref.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/fully_connected_testing_weights.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/ref_functions.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.cpp create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.h create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c create mode 100644 fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c (limited to 'fw/hid-dials/Drivers/CMSIS/NN') diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/Compiler/EventRecorderConf.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/Compiler/EventRecorderConf.h new file mode 100644 index 0000000..5958233 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/Compiler/EventRecorderConf.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ + * MDK - Component ::Event Recorder + * Copyright (c) 2016 ARM Germany GmbH. All rights reserved. + *------------------------------------------------------------------------------ + * Name: EventRecorderConf.h + * Purpose: Event Recorder Configuration + * Rev.: V1.0.0 + *----------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// Event Recorder + +// Number of Records +// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 +// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 +// <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288 +// <1048576=>1048576 +// Configure size of Event Record Buffer (each record is 16 bytes) +// Must be 2^n (min=8, max=1048576) +#define EVENT_RECORD_COUNT 64U + +// Time Stamp Source +// <0=> DWT Cycle Counter <1=> SysTick +// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset) +// Selects source for 32-bit time stamp +#define EVENT_TIMESTAMP_SOURCE 1 + +// SysTick Configuration +// Configure values when Time Stamp Source is set to SysTick + +// SysTick Input Clock Frequency [Hz] <1-1000000000> +// Defines SysTick input clock (typical identical with processor clock) +#define SYSTICK_CLOCK 100000000U + +// SysTick Interrupt Period [us] <1-1000000000> +// Defines time period of the SysTick timer interrupt +#define SYSTICK_PERIOD_US 1000U + +// + +// + +//------------- <<< end of configuration section >>> --------------------------- diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM0/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM0/RTE_Components.h new file mode 100644 index 0000000..182fb76 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM0/RTE_Components.h @@ -0,0 +1,24 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_cifar10' + * Target: 'ARMCM0' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM0.h" + +#define RTE_Compiler_EventRecorder + #define RTE_Compiler_EventRecorder_DAP +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_EVR /* Compiler I/O: STDOUT EVR */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM3/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM3/RTE_Components.h new file mode 100644 index 0000000..2aa5627 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM3/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_cifar10' + * Target: 'ARMCM3' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM3.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM4_FP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM4_FP/RTE_Components.h new file mode 100644 index 0000000..bdf6fb9 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM4_FP/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_cifar10' + * Target: 'ARMCM4_FP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM4_FP.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM7_SP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM7_SP/RTE_Components.h new file mode 100644 index 0000000..9d43970 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/RTE/_ARMCM7_SP/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_cifar10' + * Target: 'ARMCM7_SP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM7_SP.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10.cpp b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10.cpp new file mode 100644 index 0000000..ee1083b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10.cpp @@ -0,0 +1,196 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2018 Arm Limited. All rights reserved. +* +* +* Project: CMSIS NN Library +* Title: arm_nnexamples_cifar10.cpp +* +* Description: Convolutional Neural Network Example +* +* Target Processor: Cortex-M4/Cortex-M7 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Arm LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +/** + * @ingroup groupExamples + */ + +/** + * @defgroup CNNExample Convolutional Neural Network Example + * + * \par Description: + * \par + * Demonstrates a convolutional neural network (CNN) example with the use of convolution, + * ReLU activation, pooling and fully-connected functions. + * + * \par Model definition: + * \par + * The CNN used in this example is based on CIFAR-10 example from Caffe [1]. + * The neural network consists + * of 3 convolution layers interspersed by ReLU activation and max pooling layers, followed by a + * fully-connected layer at the end. The input to the network is a 32x32 pixel color image, which will + * be classified into one of the 10 output classes. + * This example model implementation needs 32.3 KB to store weights, 40 KB for activations and + * 3.1 KB for storing the \c im2col data. + * + * \image html CIFAR10_CNN.gif "Neural Network model definition" + * + * \par Variables Description: + * \par + * \li \c conv1_wt, \c conv2_wt, \c conv3_wt are convolution layer weight matrices + * \li \c conv1_bias, \c conv2_bias, \c conv3_bias are convolution layer bias arrays + * \li \c ip1_wt, ip1_bias point to fully-connected layer weights and biases + * \li \c input_data points to the input image data + * \li \c output_data points to the classification output + * \li \c col_buffer is a buffer to store the \c im2col output + * \li \c scratch_buffer is used to store the activation data (intermediate layer outputs) + * + * \par CMSIS DSP Software Library Functions Used: + * \par + * - arm_convolve_HWC_q7_RGB() + * - arm_convolve_HWC_q7_fast() + * - arm_relu_q7() + * - arm_maxpool_q7_HWC() + * - arm_avepool_q7_HWC() + * - arm_fully_connected_q7_opt() + * - arm_fully_connected_q7() + * + * Refer + * \link arm_nnexamples_cifar10.cpp \endlink + * + * \par [1] https://github.com/BVLC/caffe + */ + +#include +#include +#include "arm_math.h" +#include "arm_nnexamples_cifar10_parameter.h" +#include "arm_nnexamples_cifar10_weights.h" + +#include "arm_nnfunctions.h" +#include "arm_nnexamples_cifar10_inputs.h" + +#ifdef _RTE_ +#include "RTE_Components.h" +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#endif +#endif + +// include the input and weights + +static q7_t conv1_wt[CONV1_IM_CH * CONV1_KER_DIM * CONV1_KER_DIM * CONV1_OUT_CH] = CONV1_WT; +static q7_t conv1_bias[CONV1_OUT_CH] = CONV1_BIAS; + +static q7_t conv2_wt[CONV2_IM_CH * CONV2_KER_DIM * CONV2_KER_DIM * CONV2_OUT_CH] = CONV2_WT; +static q7_t conv2_bias[CONV2_OUT_CH] = CONV2_BIAS; + +static q7_t conv3_wt[CONV3_IM_CH * CONV3_KER_DIM * CONV3_KER_DIM * CONV3_OUT_CH] = CONV3_WT; +static q7_t conv3_bias[CONV3_OUT_CH] = CONV3_BIAS; + +static q7_t ip1_wt[IP1_DIM * IP1_OUT] = IP1_WT; +static q7_t ip1_bias[IP1_OUT] = IP1_BIAS; + +/* Here the image_data should be the raw uint8 type RGB image in [RGB, RGB, RGB ... RGB] format */ +uint8_t image_data[CONV1_IM_CH * CONV1_IM_DIM * CONV1_IM_DIM] = IMG_DATA; +q7_t output_data[IP1_OUT]; + +//vector buffer: max(im2col buffer,average pool buffer, fully connected buffer) +q7_t col_buffer[2 * 5 * 5 * 32 * 2]; + +q7_t scratch_buffer[32 * 32 * 10 * 4]; + +int main() +{ + #ifdef RTE_Compiler_EventRecorder + EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder + #endif + + printf("start execution\n"); + /* start the execution */ + + q7_t *img_buffer1 = scratch_buffer; + q7_t *img_buffer2 = img_buffer1 + 32 * 32 * 32; + + /* input pre-processing */ + int mean_data[3] = INPUT_MEAN_SHIFT; + unsigned int scale_data[3] = INPUT_RIGHT_SHIFT; + for (int i=0;i<32*32*3; i+=3) { + img_buffer2[i] = (q7_t)__SSAT( ((((int)image_data[i] - mean_data[0])<<7) + (0x1<<(scale_data[0]-1))) + >> scale_data[0], 8); + img_buffer2[i+1] = (q7_t)__SSAT( ((((int)image_data[i+1] - mean_data[1])<<7) + (0x1<<(scale_data[1]-1))) + >> scale_data[1], 8); + img_buffer2[i+2] = (q7_t)__SSAT( ((((int)image_data[i+2] - mean_data[2])<<7) + (0x1<<(scale_data[2]-1))) + >> scale_data[2], 8); + } + + // conv1 img_buffer2 -> img_buffer1 + arm_convolve_HWC_q7_RGB(img_buffer2, CONV1_IM_DIM, CONV1_IM_CH, conv1_wt, CONV1_OUT_CH, CONV1_KER_DIM, CONV1_PADDING, + CONV1_STRIDE, conv1_bias, CONV1_BIAS_LSHIFT, CONV1_OUT_RSHIFT, img_buffer1, CONV1_OUT_DIM, + (q15_t *) col_buffer, NULL); + + arm_relu_q7(img_buffer1, CONV1_OUT_DIM * CONV1_OUT_DIM * CONV1_OUT_CH); + + // pool1 img_buffer1 -> img_buffer2 + arm_maxpool_q7_HWC(img_buffer1, CONV1_OUT_DIM, CONV1_OUT_CH, POOL1_KER_DIM, + POOL1_PADDING, POOL1_STRIDE, POOL1_OUT_DIM, NULL, img_buffer2); + + // conv2 img_buffer2 -> img_buffer1 + arm_convolve_HWC_q7_fast(img_buffer2, CONV2_IM_DIM, CONV2_IM_CH, conv2_wt, CONV2_OUT_CH, CONV2_KER_DIM, + CONV2_PADDING, CONV2_STRIDE, conv2_bias, CONV2_BIAS_LSHIFT, CONV2_OUT_RSHIFT, img_buffer1, + CONV2_OUT_DIM, (q15_t *) col_buffer, NULL); + + arm_relu_q7(img_buffer1, CONV2_OUT_DIM * CONV2_OUT_DIM * CONV2_OUT_CH); + + // pool2 img_buffer1 -> img_buffer2 + arm_maxpool_q7_HWC(img_buffer1, CONV2_OUT_DIM, CONV2_OUT_CH, POOL2_KER_DIM, + POOL2_PADDING, POOL2_STRIDE, POOL2_OUT_DIM, col_buffer, img_buffer2); + +// conv3 img_buffer2 -> img_buffer1 + arm_convolve_HWC_q7_fast(img_buffer2, CONV3_IM_DIM, CONV3_IM_CH, conv3_wt, CONV3_OUT_CH, CONV3_KER_DIM, + CONV3_PADDING, CONV3_STRIDE, conv3_bias, CONV3_BIAS_LSHIFT, CONV3_OUT_RSHIFT, img_buffer1, + CONV3_OUT_DIM, (q15_t *) col_buffer, NULL); + + arm_relu_q7(img_buffer1, CONV3_OUT_DIM * CONV3_OUT_DIM * CONV3_OUT_CH); + + // pool3 img_buffer-> img_buffer2 + arm_maxpool_q7_HWC(img_buffer1, CONV3_OUT_DIM, CONV3_OUT_CH, POOL3_KER_DIM, + POOL3_PADDING, POOL3_STRIDE, POOL3_OUT_DIM, col_buffer, img_buffer2); + + arm_fully_connected_q7_opt(img_buffer2, ip1_wt, IP1_DIM, IP1_OUT, IP1_BIAS_LSHIFT, IP1_OUT_RSHIFT, ip1_bias, + output_data, (q15_t *) img_buffer1); + + arm_softmax_q7(output_data, 10, output_data); + + for (int i = 0; i < 10; i++) + { + printf("%d: %d\n", i, output_data[i]); + } + + return 0; +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_inputs.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_inputs.h new file mode 100644 index 0000000..4ff8dc2 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_inputs.h @@ -0,0 +1,6 @@ +/* Here are two different test images */ + +//#define IMG_DATA {158,112,49,159,111,47,165,116,51,166,118,53,160,112,46,156,109,41,162,115,47,159,113,45,158,111,44,159,113,41,161,116,41,160,111,52,161,111,49,166,117,41,169,117,45,170,119,44,167,117,40,162,113,38,160,111,39,160,112,43,156,109,44,149,107,45,150,107,45,148,106,43,149,107,44,143,101,39,140,98,43,141,97,41,143,97,38,137,95,36,126,91,36,116,85,33,152,112,51,151,110,40,159,114,45,166,116,56,162,112,49,160,113,43,164,117,47,162,114,45,163,116,46,156,110,38,155,111,41,159,110,54,163,113,52,170,119,41,171,117,40,171,115,33,169,115,30,160,111,33,154,112,41,151,115,50,145,110,53,139,104,55,140,102,52,141,100,48,149,105,50,147,102,46,145,102,45,142,97,38,143,98,34,136,95,31,125,91,32,119,88,34,151,110,47,151,109,33,158,111,36,167,111,48,160,106,42,163,115,44,165,117,45,165,117,45,163,115,43,162,115,43,158,114,48,157,109,57,161,111,51,166,115,38,167,114,37,169,113,35,170,116,39,159,114,47,145,111,54,121,96,49,110,90,52,98,78,50,101,77,47,114,85,50,120,86,48,134,96,55,143,103,51,140,99,39,142,99,35,139,98,34,130,95,34,120,89,33,155,107,40,155,110,32,160,109,31,174,112,44,167,110,43,167,117,46,169,120,48,169,119,48,165,115,44,165,117,45,167,123,57,191,146,95,177,130,75,157,111,41,162,115,47,164,114,54,158,112,58,149,111,67,104,80,47,103,87,65,98,90,76,92,90,84,80,75,66,74,63,50,86,70,52,83,62,39,113,85,45,132,98,46,140,102,43,140,101,39,136,99,39,127,94,36,155,107,41,156,114,48,161,115,49,170,114,47,169,114,43,163,113,40,169,120,47,166,116,44,164,113,41,164,116,42,173,128,59,246,214,164,195,156,107,151,114,56,146,111,60,142,108,71,111,80,50,78,53,31,85,69,56,113,103,98,112,110,111,106,114,118,97,102,105,93,94,93,74,72,67,84,78,70,85,73,47,105,83,45,128,96,48,138,101,46,133,94,36,129,93,36,148,109,54,133,104,64,130,100,57,147,112,53,161,115,44,165,113,39,167,116,41,167,115,41,163,111,37,165,116,39,163,118,42,180,138,85,157,122,78,128,102,58,97,75,43,66,50,31,69,58,43,66,56,45,89,83,76,118,113,110,122,121,120,119,122,122,114,116,116,94,96,96,99,100,97,91,91,86,58,58,47,67,58,37,108,84,49,140,105,58,138,98,44,134,95,40,127,100,57,109,95,80,47,37,17,88,74,28,153,117,48,170,118,43,168,115,40,170,118,43,169,117,42,166,116,37,164,120,39,147,107,52,129,98,59,127,108,75,100,87,70,68,67,57,78,83,72,72,75,64,83,84,74,132,130,121,146,142,132,124,118,108,105,99,90,107,102,94,115,111,103,85,83,77,63,71,69,46,47,39,79,61,36,132,98,58,141,99,48,134,93,39,131,115,90,99,96,92,42,43,38,70,64,41,143,111,56,167,117,42,165,114,36,168,116,39,171,119,49,161,113,51,140,109,51,120,94,49,130,110,77,144,131,107,116,106,93,88,87,79,91,95,88,85,88,82,77,77,69,124,118,107,163,153,140,136,124,112,102,93,81,106,98,88,100,93,84,85,81,74,54,60,58,49,53,49,57,47,32,107,83,50,138,103,51,136,97,39,170,161,144,103,105,105,54,58,59,124,121,113,153,124,82,161,113,43,163,117,41,166,122,50,165,121,66,174,135,95,113,89,59,125,105,78,157,141,121,156,143,128,121,111,101,86,80,74,82,81,77,84,85,82,80,78,73,81,71,61,138,125,112,146,135,123,113,103,93,87,79,70,83,77,69,86,82,76,71,73,67,56,57,53,40,35,27,74,59,35,133,106,59,137,103,45,180,176,163,134,139,143,94,100,105,154,154,149,174,149,112,158,116,51,156,116,47,153,118,60,207,180,146,237,214,198,207,180,166,156,131,119,174,153,145,148,131,125,125,110,107,93,85,79,86,84,79,74,74,71,59,57,53,76,68,58,137,125,112,143,133,122,133,124,114,106,98,89,86,81,74,87,85,78,84,85,78,75,76,71,50,49,43,40,30,15,95,75,44,132,103,57,183,183,175,108,116,122,142,151,158,165,169,168,177,156,122,155,112,50,159,118,51,122,89,47,213,197,179,237,224,226,220,191,188,164,135,131,183,159,155,156,137,132,125,108,104,120,111,104,78,76,69,80,80,77,45,44,40,91,85,77,175,165,154,157,147,137,155,147,138,107,100,92,87,83,77,103,102,96,88,88,79,78,79,73,59,59,59,41,36,33,59,46,31,104,81,46,188,191,189,100,108,116,135,144,153,170,175,178,187,167,136,166,120,59,173,123,55,134,93,44,117,95,80,194,182,188,199,171,164,170,142,133,185,161,151,189,171,159,134,119,106,117,107,95,102,98,89,84,84,79,38,38,34,125,121,113,210,201,192,160,152,142,146,139,130,93,89,82,83,80,75,94,93,88,104,104,94,85,87,81,73,75,78,55,53,55,62,55,48,76,56,26,189,194,194,90,96,105,127,134,144,175,180,185,174,156,133,166,123,68,178,123,53,159,109,47,97,68,44,168,154,152,168,144,126,137,114,94,186,166,148,216,202,183,160,149,129,123,113,98,120,114,105,115,114,109,50,50,47,150,147,140,194,187,178,155,149,140,123,118,111,91,88,83,84,83,79,84,84,80,95,95,85,86,87,81,84,87,89,73,73,73,79,74,64,73,55,24,189,192,193,93,95,103,152,154,163,185,188,192,119,110,98,136,106,66,173,124,58,167,116,50,103,72,39,147,132,120,145,125,103,167,149,127,189,174,155,226,216,200,180,172,157,141,131,117,126,117,107,117,114,109,71,71,68,154,152,147,186,181,174,149,144,136,114,110,104,87,85,80,80,80,76,72,73,70,80,80,72,99,100,94,100,101,99,90,88,81,97,89,69,94,73,34,194,196,196,108,107,112,168,167,172,186,186,188,105,109,109,99,89,67,156,119,62,167,122,55,100,74,34,115,106,88,138,123,103,198,185,169,190,180,169,172,165,159,145,140,140,154,143,134,146,136,125,103,100,95,71,71,70,152,152,149,179,175,170,137,133,127,130,128,122,110,109,105,85,86,83,91,93,91,95,96,90,109,110,104,115,116,111,100,96,80,97,85,53,117,95,47,197,197,197,132,129,136,172,167,174,184,178,181,130,137,142,78,83,77,140,120,88,155,125,77,115,94,52,130,120,93,143,131,116,230,221,211,242,236,230,145,138,137,135,130,130,131,121,112,121,112,101,108,104,95,95,88,75,144,134,118,168,159,146,152,147,138,112,108,101,87,85,80,71,72,68,87,88,87,105,104,99,112,109,99,120,110,93,103,86,54,121,96,48,136,104,48,203,203,204,146,146,160,168,164,178,191,182,188,168,170,172,78,86,90,126,125,126,138,126,113,138,121,82,96,80,37,154,143,133,173,163,155,162,152,141,140,132,117,113,106,88,113,106,90,101,101,92,105,101,87,112,90,58,171,143,104,156,138,109,148,141,126,135,130,118,109,105,97,78,76,72,79,79,77,94,93,94,101,91,82,107,83,55,125,88,45,151,108,55,144,104,46,214,215,215,163,166,180,164,167,184,183,184,194,176,182,186,94,102,105,96,96,102,156,149,145,148,137,111,106,93,61,129,116,105,118,105,95,114,102,89,116,105,89,102,91,73,115,110,98,86,91,88,101,103,95,144,128,102,118,96,64,68,56,32,128,120,105,133,126,115,75,69,61,60,56,51,58,56,53,71,70,65,102,93,78,116,94,64,143,112,68,150,116,64,140,110,54,212,211,205,178,184,192,167,175,189,173,181,193,176,184,188,124,131,133,86,88,96,141,139,143,153,148,141,135,128,111,104,90,80,77,64,55,134,121,108,124,111,96,129,117,100,147,143,133,85,92,93,92,96,93,150,139,120,132,117,93,117,109,92,107,99,86,75,68,58,64,59,52,44,41,39,65,62,60,86,69,40,133,105,59,155,119,62,160,120,54,154,115,45,151,111,46,199,192,180,187,189,187,171,176,181,174,179,185,177,182,184,144,149,152,86,90,99,119,121,132,122,124,130,137,136,135,144,134,126,70,59,51,129,118,108,108,97,86,145,134,123,184,176,168,116,118,118,73,75,73,131,119,103,137,124,105,134,129,118,89,86,78,51,49,44,52,51,50,47,49,52,90,90,93,121,91,60,163,118,68,171,121,64,164,113,52,158,111,50,149,107,46,165,156,146,195,193,187,179,178,175,177,173,172,181,181,180,152,157,160,99,103,111,131,135,146,171,175,185,103,105,111,93,90,87,80,77,73,93,90,86,122,118,116,178,173,173,191,182,177,150,148,148,100,100,101,89,78,66,87,77,63,60,61,57,46,52,54,38,46,51,24,33,41,46,57,69,60,71,83,108,100,75,144,125,82,144,123,76,128,109,61,127,113,69,120,105,63,117,120,124,195,200,200,177,178,176,178,169,168,181,179,179,138,144,147,83,87,91,150,153,159,245,247,250,219,222,225,133,140,144,134,141,147,149,156,164,176,182,192,190,196,208,194,192,197,168,172,181,125,133,143,110,109,109,61,62,62,35,49,58,34,54,68,49,70,87,58,81,102,61,85,110,58,84,111,69,99,122,72,101,119,78,104,120,69,96,112,59,92,112,55,90,115,79,105,133,175,197,213,174,183,192,176,172,177,177,177,182,140,146,150,109,112,113,211,211,209,253,252,247,252,253,252,208,224,232,124,143,157,114,132,149,124,141,162,116,133,156,122,133,152,104,124,148,68,93,119,68,87,104,60,82,101,52,84,111,50,84,110,51,85,115,56,93,125,56,94,131,51,91,130,43,96,135,51,104,141,59,108,142,48,97,132,43,97,137,42,95,132,41,89,135,96,137,168,144,168,188,168,174,188,178,182,192,165,170,174,165,166,164,246,245,237,253,251,241,227,231,228,110,136,153,60,88,111,53,80,105,49,76,105,49,75,107,48,72,101,45,79,115,42,81,120,46,81,113,42,82,116,38,86,125,46,90,125,46,89,126,43,87,128,42,89,132,46,93,139,46,94,137,50,96,137,55,96,135,53,94,134,51,95,139,45,90,133,29,91,141,29,87,130,59,102,134,131,153,176,166,179,191,132,136,137,194,189,181,254,250,242,241,245,245,141,159,175,61,94,127,50,84,118,50,84,119,51,85,121,49,83,120,50,84,116,47,86,117,42,84,117,39,82,115,34,79,113,35,83,120,39,86,125,38,85,125,42,89,130,45,92,134,56,103,145,62,103,142,59,101,142,56,102,146,50,99,144,46,94,140,51,103,149,48,111,162,30,94,140,34,85,124,73,106,136,128,148,167,128,136,143,215,213,209,255,253,249,187,198,205,66,93,118,54,91,128,50,88,125,52,90,127,52,90,127,46,83,121,45,82,115,43,82,113,41,81,112,36,80,113,39,83,117,40,86,123,40,89,131,43,92,134,46,95,138,59,108,150,62,110,152,64,109,147,59,108,149,54,108,154,50,105,152,70,123,167,83,137,182,52,114,165,35,99,147,31,86,130,41,83,122,66,95,126,128,145,164,224,229,234,240,245,247,124,143,153,58,92,114,49,87,123,56,94,131,54,92,129,44,82,119,44,82,119,47,83,119,46,84,119,43,83,119,43,86,123,44,88,127,44,90,131,45,97,141,54,106,150,58,110,154,54,105,150,46,97,141,43,95,140,36,91,138,51,108,158,73,130,178,85,138,182,76,125,169,50,110,162,35,98,149,29,89,138,35,86,133,44,83,126,78,106,138,202,219,233,211,228,234,97,126,140,65,104,126,54,94,129,48,87,124,58,97,133,48,87,123,40,80,116,45,82,119,47,84,122,48,87,126,47,89,130,46,89,132,51,97,140,39,92,138,39,93,139,48,102,148,47,101,147,39,93,139,28,85,133,40,101,153,67,129,182,67,126,176,46,98,142,51,96,139,50,108,161,35,97,147,32,92,143,33,88,141,41,88,138,46,84,125,104,133,159,170,197,211,64,100,119,54,97,121,52,94,128,53,95,130,61,103,139,58,100,135,54,96,131,45,83,120,42,79,118,41,80,120,46,88,130,49,92,135,46,92,136,42,95,139,40,93,138,39,92,136,37,90,135,40,93,138,44,102,151,63,125,178,47,110,164,31,90,140,15,60,103,51,93,136,68,124,177,42,100,148,31,88,137,38,91,146,37,87,139,43,89,132,42,79,113,71,107,133,49,89,114,31,77,105,27,71,105,38,82,117,49,93,128,56,100,135,58,102,137,53,92,128,56,94,131,60,99,137,57,99,139,53,97,138,50,95,137,45,94,136,39,88,131,33,83,125,42,91,133,62,112,154,79,132,179,73,131,181,56,116,168,38,97,146,13,64,108,40,85,127,61,116,168,49,102,148,35,85,132,43,91,143,39,90,139,42,92,134,44,88,125,40,81,112,42,85,115,27,72,104,23,67,102,30,74,109,27,71,106,29,73,108,36,80,115,47,86,120,56,95,128,62,101,135,66,109,144,75,119,156,69,113,152,49,95,134,43,88,127,43,88,127,60,105,144,85,130,170,109,156,197,93,145,190,60,115,164,26,82,130,29,82,126,20,64,107,54,107,160,56,105,149,45,89,132,43,86,134,40,89,134,40,92,132,40,87,123,38,81,115,36,79,114,26,69,105,22,66,101,29,73,108,25,69,104,29,73,108,19,63,98,18,58,89,32,70,100,47,87,118,61,104,137,74,119,152,66,111,145,53,96,131,52,95,130,45,87,123,67,109,145,89,131,167,105,146,182,89,135,175,48,99,145,24,77,124,34,84,129,21,67,110} + + +#define IMG_DATA {235,235,235,231,231,231,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,232,233,233,231,233,232,231,233,231,233,233,230,233,232,232,232,234,232,231,234,232,232,232,233,233,230,232,233,231,233,233,233,232,232,232,232,232,232,232,232,232,233,233,233,233,233,233,232,232,232,238,238,238,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,237,234,233,236,234,233,236,236,234,234,236,234,234,235,237,234,234,238,235,236,237,236,236,235,236,236,234,236,236,236,235,235,235,235,235,235,235,235,235,236,236,236,236,236,236,235,235,235,237,237,237,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,235,235,235,235,234,234,236,233,231,236,234,231,235,235,234,234,235,236,227,230,233,231,235,238,231,233,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,234,234,234,238,238,238,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,235,235,235,235,235,234,233,233,230,232,232,231,228,230,232,223,226,231,186,192,197,209,216,219,207,210,213,228,228,230,236,235,235,234,234,234,234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,235,235,235,237,237,237,234,234,234,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,234,234,234,234,234,234,235,235,235,235,235,235,234,234,234,234,234,234,235,235,235,235,235,235,236,238,236,233,237,237,219,225,230,203,210,219,163,172,179,195,205,208,214,218,221,230,229,232,237,235,237,235,235,235,235,235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236,236,239,239,238,236,235,235,236,235,235,236,235,235,236,235,235,236,235,235,235,236,235,235,235,235,234,234,234,235,235,235,237,236,236,237,236,236,234,235,236,232,233,234,235,237,237,229,231,232,208,216,218,194,205,210,185,198,207,174,188,200,165,179,189,184,196,202,207,215,220,226,228,232,236,235,237,236,236,235,236,236,235,236,236,235,236,236,236,237,237,237,237,237,237,237,237,237,228,229,229,228,227,228,232,230,231,231,228,230,234,232,233,237,236,236,237,237,235,236,237,235,237,235,236,237,235,236,239,236,237,239,237,238,225,229,230,224,228,229,233,237,238,221,226,228,183,197,204,161,180,190,159,180,191,154,176,190,144,163,177,143,159,171,156,169,177,198,206,211,233,238,239,236,237,234,235,236,233,235,235,235,235,236,236,236,238,237,237,237,237,239,237,238,212,220,222,224,230,233,230,234,238,227,232,234,229,234,234,234,237,236,237,238,235,238,237,236,239,237,238,239,237,238,239,236,237,240,238,239,201,204,203,219,222,221,233,236,235,214,218,218,193,204,210,185,201,210,184,201,211,173,191,203,165,182,196,159,174,187,162,176,185,186,199,204,229,239,240,234,239,238,233,238,237,233,238,238,234,239,238,236,239,238,237,239,238,238,238,238,216,234,241,221,236,243,225,238,246,225,239,243,227,240,240,231,238,237,236,237,235,238,236,235,238,236,237,238,236,237,237,237,237,239,239,239,197,198,196,220,221,218,233,234,231,230,231,229,209,213,217,209,216,222,219,228,235,208,218,227,209,221,234,210,224,235,217,233,240,218,235,241,225,240,243,228,238,240,228,239,240,230,240,240,230,240,239,235,240,239,237,240,239,238,238,238,118,140,149,119,138,148,124,142,153,136,155,161,172,188,191,225,234,233,235,236,233,237,234,232,236,233,234,235,235,235,235,237,236,233,237,235,214,216,214,226,228,226,232,234,232,236,237,236,228,230,232,227,230,235,231,236,241,225,232,239,225,237,247,217,233,243,201,219,226,185,204,211,172,189,195,167,179,186,167,180,185,186,199,201,223,235,235,235,241,239,236,240,239,238,240,239,109,130,141,103,121,133,108,125,137,111,127,137,146,159,165,222,229,231,227,228,225,229,226,224,236,232,233,234,234,234,231,236,234,230,237,235,229,234,235,231,235,236,232,237,238,230,235,236,231,236,238,231,237,240,229,237,241,223,232,238,191,206,213,164,184,191,146,165,172,137,156,163,134,149,159,128,140,153,121,133,143,149,162,166,216,228,229,234,241,239,235,240,238,237,240,239,195,212,224,188,202,215,199,211,224,200,211,223,209,217,227,223,227,231,213,213,211,211,209,206,216,213,214,220,222,222,219,226,225,210,221,219,209,219,223,211,221,225,216,225,230,220,229,233,225,234,237,226,236,239,225,237,241,218,231,237,183,204,208,175,198,203,181,200,207,178,194,202,186,197,211,170,178,196,142,151,164,185,195,202,219,230,233,231,240,238,234,241,239,236,240,239,193,207,222,191,202,217,202,211,224,214,217,234,223,225,241,214,219,227,203,208,208,171,174,174,177,180,183,207,213,214,174,184,188,98,112,121,93,114,126,101,121,132,111,129,139,122,138,147,137,152,161,153,167,174,202,216,220,223,236,237,218,232,235,220,233,238,223,234,240,217,226,233,221,228,237,212,219,229,196,203,212,222,230,237,219,227,234,221,230,233,232,239,242,235,241,242,113,130,152,111,125,147,113,125,141,125,131,151,138,145,165,170,182,193,191,201,205,190,199,204,208,219,226,216,230,234,158,172,183,54,71,92,45,70,91,49,73,91,53,73,90,66,84,98,102,114,129,159,168,179,221,227,233,234,239,241,233,237,241,227,231,237,223,228,233,207,211,217,202,208,212,211,218,220,212,219,223,199,206,214,179,186,196,188,197,205,211,221,227,221,231,234,61,81,108,69,86,114,63,79,100,68,85,102,123,141,155,139,155,164,151,157,164,195,200,207,214,228,234,206,223,228,163,180,190,103,121,138,95,112,131,101,117,135,138,151,168,181,192,207,207,212,223,221,222,232,219,219,227,205,203,212,183,186,195,158,166,174,147,154,163,131,138,147,125,133,140,130,139,144,136,146,152,133,142,151,128,137,147,138,153,160,182,197,203,197,212,216,40,53,77,58,70,94,85,98,116,127,144,153,132,151,156,96,107,110,119,115,118,163,158,161,173,180,182,184,194,197,182,194,198,181,193,200,183,194,202,198,209,217,218,228,236,200,210,217,174,181,186,159,165,172,145,150,159,132,136,149,116,125,138,98,111,123,94,106,118,99,111,123,105,118,128,107,121,130,122,135,145,138,151,161,150,164,174,157,174,184,188,206,213,185,203,208,13,15,35,26,29,47,134,140,151,206,216,220,138,150,150,118,123,123,141,133,134,172,162,162,181,181,180,207,209,211,220,224,225,228,234,233,224,234,232,230,241,240,226,238,238,176,189,190,144,159,163,138,154,162,142,158,170,145,163,177,154,171,187,149,165,182,149,165,182,154,171,187,157,174,189,160,177,191,173,190,204,187,204,217,190,207,218,178,196,208,165,183,193,157,175,183,5,5,24,58,62,79,200,207,217,225,232,239,197,205,212,199,207,211,212,212,218,226,224,229,229,230,237,233,236,246,232,238,245,230,238,239,209,221,220,223,238,239,221,238,241,210,228,234,198,217,228,180,200,214,193,216,230,188,213,229,189,212,231,194,214,234,192,212,232,184,204,224,172,193,212,171,191,209,161,181,197,144,165,179,136,156,169,131,146,161,128,143,158,138,154,165,39,45,71,145,155,179,190,204,222,186,196,216,184,197,217,192,211,229,194,211,230,194,208,227,194,206,227,191,203,228,192,207,228,190,207,221,177,193,207,180,198,215,154,176,193,147,169,188,145,161,184,156,171,195,146,163,186,113,133,156,114,137,161,132,157,180,126,150,173,111,135,158,92,115,138,91,112,135,93,114,133,94,116,131,105,125,140,121,133,151,129,141,158,129,142,156,122,135,161,162,179,207,143,160,194,137,154,189,131,152,187,128,152,190,127,150,192,130,150,193,131,150,192,128,147,190,127,147,189,129,149,189,129,149,188,124,145,186,104,126,163,100,122,154,102,120,154,118,134,170,112,128,163,94,109,145,94,112,148,94,117,153,87,112,144,83,103,136,80,97,130,83,103,134,93,111,139,101,117,141,108,121,144,115,125,146,121,133,148,130,144,156,73,87,109,76,90,113,77,90,122,80,93,127,84,98,134,87,102,142,87,102,147,90,105,150,94,111,152,102,119,160,107,124,165,113,131,172,115,137,181,118,136,186,118,132,180,120,133,175,115,136,172,110,133,168,106,127,163,100,119,155,95,109,148,85,101,139,79,97,132,80,92,127,80,94,129,77,100,133,80,100,129,82,98,122,92,104,126,113,119,138,125,135,146,136,149,156,13,25,41,3,11,25,9,16,35,18,26,48,18,26,52,21,25,56,20,25,58,22,30,61,26,36,62,34,43,70,42,51,77,48,59,87,52,69,106,60,75,121,66,77,126,70,79,126,71,87,127,72,88,126,67,81,120,60,72,112,55,67,106,53,68,104,53,69,103,57,69,102,57,71,105,57,78,110,72,89,115,87,100,119,104,113,128,120,124,136,130,136,141,137,146,149,36,46,55,11,16,20,8,13,19,32,44,53,36,45,58,22,25,41,8,11,30,3,8,24,1,4,17,0,2,15,0,2,15,0,4,20,6,13,42,5,18,56,1,19,60,3,23,62,13,29,71,24,38,81,21,33,77,21,31,76,21,38,78,22,44,79,30,50,83,39,58,90,57,70,101,85,90,118,113,115,138,123,123,138,116,115,125,122,123,128,134,139,137,153,160,158,35,41,45,26,27,26,13,19,18,27,41,41,71,81,84,70,70,76,49,50,57,27,31,37,15,15,21,5,5,11,2,2,7,0,0,7,17,17,35,57,64,91,31,50,78,10,36,62,4,30,60,4,30,62,7,30,63,14,35,69,25,43,74,41,55,83,62,71,99,86,97,123,122,124,146,144,131,149,132,120,135,114,105,114,117,111,116,132,134,133,146,152,146,172,179,175,16,15,17,13,10,9,4,10,8,3,12,11,45,44,46,65,52,57,54,43,47,36,33,35,18,18,20,4,4,7,2,2,4,0,1,3,7,8,15,118,117,134,161,158,179,131,128,148,112,112,131,105,105,125,105,103,124,109,105,127,118,107,126,138,115,133,154,126,144,151,126,141,127,106,116,105,86,91,106,94,97,120,116,116,129,130,129,142,147,144,164,172,165,184,194,190,40,40,35,12,10,7,0,3,3,0,4,4,12,6,7,30,12,17,32,12,17,21,10,12,7,6,7,2,1,3,2,1,2,3,2,3,0,0,2,68,58,64,182,128,146,205,130,148,196,127,144,194,123,141,195,119,137,187,113,129,172,110,122,150,96,106,123,75,83,103,66,69,95,71,70,104,93,88,122,118,113,129,132,126,132,141,135,152,162,158,171,182,176,185,197,194,69,77,64,26,29,21,1,1,1,1,1,2,4,1,0,12,2,5,18,3,9,12,2,5,4,1,2,2,0,0,2,0,0,4,0,1,1,1,1,32,12,11,153,45,59,203,47,68,195,46,67,191,48,69,179,50,67,155,49,59,119,42,49,91,38,42,81,48,46,94,77,71,117,110,102,125,126,116,125,128,120,129,135,128,144,153,147,162,176,171,173,187,183,184,198,196,83,94,82,47,52,43,1,1,1,2,1,2,2,0,0,5,1,2,7,1,5,4,0,2,1,0,0,1,0,0,1,0,0,3,0,0,1,2,0,27,3,2,142,25,38,205,32,54,198,25,46,169,25,43,121,25,36,85,29,34,74,41,39,85,66,56,102,92,82,121,113,105,128,124,115,122,126,115,121,127,118,132,139,131,147,157,150,165,179,174,176,191,187,186,201,199,92,102,93,54,60,50,6,7,3,3,2,1,2,2,0,1,3,1,1,3,3,1,2,2,1,1,1,1,0,0,1,0,0,1,1,1,0,3,2,15,1,0,102,19,28,157,31,47,117,17,23,74,13,12,56,27,22,74,58,55,99,90,81,115,115,99,122,126,111,124,124,112,123,123,113,125,130,119,128,135,126,136,145,137,148,159,151,162,176,171,177,192,188,188,202,201,87,99,89,43,51,37,19,23,11,11,12,4,8,10,2,5,11,4,2,10,4,2,7,2,3,4,1,3,4,1,3,4,1,2,3,2,0,6,6,4,5,2,42,13,13,71,21,24,53,27,25,57,50,41,80,77,62,113,98,82,132,113,101,134,126,113,123,126,112,116,125,111,120,128,115,131,138,126,139,148,137,143,154,145,156,168,161,169,184,179,182,197,193,188,202,201,82,96,82,46,57,36,36,44,22,31,35,17,27,30,15,22,28,15,17,26,13,16,23,12,18,21,12,19,21,13,20,22,14,19,23,15,19,27,20,23,31,21,37,40,27,64,55,45,87,70,67,104,88,81,116,102,85,128,112,88,139,121,105,131,122,110,117,122,107,115,127,112,123,133,119,131,139,127,139,149,138,148,160,151,159,172,164,174,189,183,185,200,196,187,202,200,85,101,83,62,75,48,58,67,38,55,61,37,51,56,35,47,53,33,46,53,34,48,55,38,49,55,40,51,56,41,53,58,44,55,62,46,59,67,45,68,71,48,81,84,59,104,96,74,116,103,83,127,109,92,133,116,97,127,121,97,127,127,107,118,124,106,114,125,108,122,131,117,129,136,123,136,145,133,141,152,141,149,162,153,158,171,163,168,183,178,180,195,191,186,200,199} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_parameter.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_parameter.h new file mode 100644 index 0000000..423d069 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_parameter.h @@ -0,0 +1,43 @@ +#define CONV1_IM_DIM 32 +#define CONV1_IM_CH 3 +#define CONV1_KER_DIM 5 +#define CONV1_PADDING 2 +#define CONV1_STRIDE 1 +#define CONV1_OUT_CH 32 +#define CONV1_OUT_DIM 32 + +#define POOL1_KER_DIM 3 +#define POOL1_STRIDE 2 +#define POOL1_PADDING 0 +#define POOL1_OUT_DIM 16 + +#define CONV2_IM_DIM 16 +#define CONV2_IM_CH 32 +#define CONV2_KER_DIM 5 +#define CONV2_PADDING 2 +#define CONV2_STRIDE 1 +#define CONV2_OUT_CH 16 +#define CONV2_OUT_DIM 16 + +#define POOL2_KER_DIM 3 +#define POOL2_STRIDE 2 +#define POOL2_PADDING 0 +#define POOL2_OUT_DIM 8 + +#define CONV3_IM_DIM 8 +#define CONV3_IM_CH 16 +#define CONV3_KER_DIM 5 +#define CONV3_PADDING 2 +#define CONV3_STRIDE 1 +#define CONV3_OUT_CH 32 +#define CONV3_OUT_DIM 8 + +#define POOL3_KER_DIM 3 +#define POOL3_STRIDE 2 +#define POOL3_PADDING 0 +#define POOL3_OUT_DIM 4 + +#define IP1_DIM 4*4*32 +#define IP1_IM_DIM 4 +#define IP1_IM_CH 32 +#define IP1_OUT 10 diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_weights.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_weights.h new file mode 100644 index 0000000..2c3cedd --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/cifar10/arm_nnexamples_cifar10_weights.h @@ -0,0 +1,26 @@ +#define CONV1_WT {-9,-1,2,6,-4,6,4,-11,8,-9,-11,10,-12,5,15,11,-1,-1,33,-25,-18,47,-35,-23,25,-27,-5,0,-4,9,2,-5,0,34,-25,-21,55,-40,-33,34,-32,-16,5,-7,2,-21,16,14,-4,5,3,14,-10,-7,3,-10,-2,-8,5,8,-29,23,12,-25,15,8,-15,4,7,-16,5,8,-13,17,12,2,-4,-1,-1,-10,9,6,-4,21,11,0,12,-10,-9,-4,13,10,12,19,11,27,0,-5,11,-21,-26,-28,-7,3,-15,16,14,26,-22,-25,-8,-29,-24,-23,0,6,-13,13,25,0,-21,-18,-3,-21,-19,-13,11,14,4,13,18,-4,6,16,-1,-10,-14,-7,12,9,5,13,8,-4,9,10,-9,-4,7,-3,7,7,-12,7,3,0,-1,-7,2,-8,-5,9,-3,6,-4,7,-10,-25,7,-7,-7,10,2,14,-4,2,17,-9,5,-3,7,-10,-25,4,-10,-8,0,0,16,-7,11,25,-14,13,4,7,-12,-23,5,-16,-17,8,0,11,2,13,21,-11,9,-3,2,-9,-9,-3,-14,-11,1,-1,6,-6,6,14,-1,16,11,7,3,-14,21,6,-6,17,13,4,1,7,-3,-6,2,2,27,13,-5,18,0,-7,-6,-4,2,-24,-11,0,-18,-8,6,24,8,-14,11,-6,-8,-8,0,12,-22,-2,13,-15,-3,7,29,6,-16,10,-6,-4,-12,-7,11,-26,-14,3,-10,-8,0,16,5,-8,-5,-5,3,-15,-2,23,-17,-5,17,1,1,12,10,3,-5,-7,-18,-7,-3,-4,2,3,6,4,4,2,-7,17,20,12,-23,-27,-15,-3,3,6,5,15,6,-2,2,-5,22,22,11,-26,-30,-19,-6,-5,3,10,12,6,2,1,-3,20,14,4,-15,-26,-18,0,-9,1,14,8,6,1,-7,-9,8,11,6,-10,-13,-11,-4,-4,8,2,5,17,-9,0,11,-9,-11,21,6,13,39,-7,1,30,2,12,36,-11,-1,28,-2,-25,-6,6,-16,-6,-9,-34,-24,3,-17,-15,2,-20,-11,0,-13,-11,25,13,6,0,-15,-20,16,7,-11,7,-3,-10,-5,-2,-6,14,22,12,-16,-5,-12,7,23,7,-10,5,-2,-10,-1,-9,7,21,8,-19,-2,-13,2,21,3,-15,9,-2,-4,-2,-2,-12,2,13,-19,1,6,0,16,-1,5,8,-28,11,-2,-4,-10,-1,21,-30,-4,22,-8,14,9,11,14,-21,20,-9,-23,0,-4,19,-28,-9,31,-30,-1,12,3,14,-11,30,3,-24,3,-8,6,-22,-9,31,-29,2,26,-5,11,8,24,2,-36,24,3,-9,-6,-17,4,-8,-8,12,1,-1,5,3,-12,15,-6,-2,-1,0,15,-11,-18,6,-18,-10,6,3,6,-3,3,-12,13,-14,-1,43,-23,-3,52,-16,-11,28,-8,4,-6,5,-11,16,-6,-20,32,-28,-24,38,-31,-22,20,-16,5,-13,7,-2,5,3,-6,17,-10,-8,22,-13,-5,13,0,11,-16,14,-3,-14,6,3,-4,4,4,-2,2,-3,-9,5,2,1,-2,-10,-6,-3,-17,-2,1,-19,2,1,-14,8,11,14,3,7,1,-13,-13,2,-1,-3,-9,0,-5,-18,4,0,18,3,9,15,-10,-8,10,-12,-18,5,-3,-16,-10,0,-14,5,4,14,14,-1,10,16,-6,-2,14,-1,-12,8,2,-18,-13,-1,17,-2,2,24,-4,-3,17,8,-1,12,9,-6,-3,-2,-9,3,-2,-13,-1,-5,-17,-5,-7,-16,-7,-8,-14,-9,3,-9,-1,0,-13,-7,4,-9,-7,3,-6,-8,-2,-4,-7,5,-7,-4,1,-8,-11,10,6,-3,14,12,-1,6,10,-2,0,-12,-16,-3,-9,-19,0,1,-12,9,12,-2,1,10,-1,10,4,-8,6,3,-11,11,14,1,12,19,8,3,16,9,-7,-1,4,-11,-1,3,1,12,8,7,15,13,-5,-2,4,-7,-5,1,-8,-3,2,1,10,9,-1,8,9,-11,-9,-2,0,-1,6,-14,-13,-6,1,3,10,3,4,11,-1,-5,5,7,4,10,-14,-17,-10,-12,-13,-6,-11,-14,-6,1,-6,1,2,-1,1,-5,-7,-3,-2,-4,1,-11,-13,-9,-12,-16,-12,-2,-1,-2,-9,-5,-4,-7,-3,3,-1,-3,8,9,-2,1,8,11,13,5,14,17,1,10,17,-1,3,18,0,-6,0,-1,0,3,4,13,16,-1,8,14,-4,2,14,-16,-20,-14,-3,-3,0,13,21,25,5,11,14,-5,-2,9,1,-5,2,-6,-9,-14,-7,-4,-8,-10,-9,-13,-10,-12,-12,7,-1,-2,-5,2,-14,-5,3,-6,1,9,3,-8,3,-1,-9,2,0,-12,-4,-21,6,17,8,17,28,22,-5,6,2,-15,-8,-7,8,21,-3,2,20,-5,-1,16,-8,7,17,3,0,6,1,11,26,0,-22,-4,-33,-36,-16,-40,-2,14,1,2,10,5,1,17,-10,-16,3,-22,-22,-1,-14,-9,10,6,-7,7,7,10,-8,5,-3,-4,-1,-7,-7,-7,1,0,-2,-7,11,9,5,-2,2,12,14,16,12,7,2,0,-9,-23,-14,-8,-23,-1,-11,-14,-7,-9,-7,14,11,7,44,35,19,34,38,12,1,3,9,-6,-4,8,-32,-28,-19,-41,-45,-37,-14,-17,-17,-7,4,-3,-5,8,8,3,16,21,8,14,24,-3,-5,6,-11,-15,-18,-8,-12,-12,-6,-14,-8,9,-6,1,16,3,11,3,3,-8,-5,0,-6,-13,-13,-13,-6,-15,-15,6,-5,-4,9,16,5,1,14,5,-4,7,-1,-12,-11,-18,0,-6,-12,5,14,0,-1,13,2,2,18,6,-9,-4,-16,0,-3,-17,4,12,0,-1,13,2,0,16,6,-6,1,-9,-5,-8,-19,18,-1,-4,16,-2,-6,18,-1,-4,9,-4,1,-12,-13,-4,9,-3,-9,6,-4,-14,15,5,-2,-5,-5,-1,-20,-9,-3,16,2,-5,12,3,-7,15,7,1,-12,-7,-2,-15,-2,2,18,7,-1,10,2,-5,-1,-8,-8,-18,-15,-7,-2,7,9,-15,-15,-17,-7,-6,-7,-12,-12,-6,-17,-12,-6,9,14,12,13,7,6,3,-3,2,-6,-7,1,-7,-4,3,-11,-12,-6,12,11,6,-4,-3,-2,-15,-12,-4,-7,-4,3,-9,-9,-4,15,17,12,-3,1,2,-18,-13,-6,4,5,10,6,1,5,9,14,8,-6,1,3,-21,-15,-7,-2,-1,5,4,-1,2,4,17,14,-4,4,9,-24,-20,-11,-7,-7,3,-2,-6,1,5,9,-10,6,9,-12,12,11,-7,4,1,-15,11,9,-6,25,15,5,21,13,5,23,14,7,13,2,-3,17,10,6,-1,-10,-2,-20,-21,-14,-11,-11,-2,-11,-12,-3,-16,-15,-3,-4,-14,6,-16,-19,-1,-3,-2,13,-1,-3,12,-6,-10,8,0,-5,10,-11,-10,4,-4,-1,8,-11,-5,3,-6,-1,8,-8,-15,0,-3,0,9,4,11,14,-3,3,4,-15,-9,-6,-12,-14,-1,-18,-8,-1,-26,-12,-8,-28,-12,-9,-30,-13,-8,10,-1,-6,15,17,5,11,22,8,15,24,8,17,25,12,10,-5,-9,4,4,-5,1,10,1,2,4,-8,6,7,-7,5,-10,-6,-1,-5,-3,3,8,10,1,4,-2,-1,0,-8,2,-8,3,0,-6,9,1,-2,-8,6,1,-3,1,-10,6,5,-6,7,-8,-12,0,11,17,-4,-7,-1,-12,1,-2,9,11,2,17,-35,-32,-21,38,52,20,-27,-17,-30,4,2,17,18,10,19,-44,-34,-34,43,59,28,-25,-17,-31,6,0,16,10,4,18,-31,-27,-22,27,31,16,-10,-9,-16,3,-6,6,-2,-11,15,10,0,14,-2,-8,-8,0,-7,-7,13,0,11,2,-7,3,10,4,3,0,-2,-14,-1,-1,-16,-1,3,-6,8,-4,3,12,4,2,4,1,-17,7,10,-8,0,10,-2,-3,-15,0,10,4,8,-10,-13,-24,-7,-2,-16,0,8,-3,-6,-6,7,7,11,13,2,9,-6,-4,11,-15,2,22,0,2,-4,-2,-10,-12,-5,24,15,25,-1,-4,-2,-11,-1,-3,7,11,5,-16,-17,-23,-29,-35,-30,53,45,54,-11,-9,-12,-3,5,4,44,39,36,-45,-51,-51,-19,-28,-16,25,24,28,-15,0,-12,7,1,2,44,42,40,-36,-41,-41,5,0,3,-1,18,5,-17,-15,-15,7,8,14,11,3,4,1,-11,-8,10,-1,-2,-5,-10,-3,6,6,10,5,9,9,-6,3,0,-14,-21,-16,-40,-39,-26,0,4,16,15,20,24,-14,-7,-5,3,-5,1,-13,-12,0,-16,-11,6,4,7,20,-11,-9,-1,11,-4,7,14,7,22,-14,-14,5,-7,-6,12,-4,-9,4,18,-6,5,14,-4,12,-2,-11,6,3,-5,11,4,-10,1,2,-1,-14,4,-6,-23,26,11,-15,12,-7,-33,6,-10,-15,13,6,-20,14,0,-25,2,-14,-34,1,-4,-11,3,9,23,1,6,-5,-6,-2,-8,-7,6,17,-5,18,42,-19,10,42,-3,-1,-2,-2,1,8,4,11,29,-18,-12,7,-16,-7,2,1,-1,9,-9,-9,15,-7,-5,18,-1,-4,6,1,2,-6,-10,7,-2,1,4,-2,-2,-4,6,5,-7,4,3,-7,-2,-11,17,0,-15,-18,-24,40,25,30,-9,-20,-18,1,4,1,-32,-12,-22,54,43,41,0,-19,-9,-29,-29,-25,5,16,20,20,6,8,29,5,16,-60,-74,-65,37,39,43,-5,-2,-2,21,-7,9,-21,-38,-19,6,22,14,2,25,17,-22,4,-11,3,6,-15,-5,2,-13,-2,12,-8,0,13,5,-4,1,5,-8,19,4,-5,28,29,-18,18,19,-20,1,-2,-9,-2,-10,-30,1,8,-57,-26,-3,-47,-28,-10,4,1,3,15,4,-1,-4,-8,4,12,-3,10,48,16,25,38,1,-1,15,-7,-4,23,-2,2,31,-7,-15,23,-17,-19,6,-20,-21,-2,-1,4,4,-4,3,9,0,8,10,-6,-3,17,-2,-11,14,-2,-20,-12,-8,18,-15,-9,20,-4,-1,23,7,6,20,-2,-3,-5,-12,-3,26,-27,-15,17,-22,-10,19,-10,-3,16,-10,-3,0,-7,-1,19,-16,-6,16,-12,-5,16,-7,-5,6,-6,-4,-9,-5,-4,8,-6,-2,9,1,-1,4,7,0,-6,9,5,-13,12,6,4,8,15,10,-22,-12,-15,-34,-20,-19,-14,-2,-3,9,0,7,13,18,21,3,21,22,-31,-11,-6,-24,-5,0,8,-10,-1,-12,-20,-13,8,13,13,16,28,24,5,21,22,3,-11,-5,1,-15,-11,18,6,0,3,1,-8,-1,2,6,-1,-5,-8,8,-5,-8,22,7,-6,6,-4,-13,-4,-12,-6,-12,-9,-10,-9,-9,-11,-6,-6,-9,-6,-7,-10,-6,-9,-10,-11,-8,-8,-9,-7,-7,-5,-3,-4,-5,-4,-4,-6,-5,-3,1,4,4,-1,3,3,1,4,4,-2,1,2,-2,1,5,-3,3,6,-5,1,4,-5,1,3,-4,0,3,-3,2,6,-9,-2,2,-6,1,3,-5,1,1,-5,0,2,-5,1,4,0,-4,-1,20,6,2,20,-2,-17,7,-1,-15,-10,4,-3,-12,-1,16,-1,-4,6,23,1,-7,22,0,-13,10,2,-2,-32,-10,14,-25,-13,11,16,3,6,25,0,-13,19,-1,-10,-27,-2,11,-41,-18,8,-1,0,11,17,-3,-12,26,0,-13,-6,10,10,-22,-1,16,-16,0,17,-3,-3,7,3,-11,-8,-19,14,-3,-12,13,2,-5,1,9,4,-1,-4,10,0,2,-20,18,2,-15,11,14,0,-6,11,20,-11,-17,17,-12,-13,-27,23,10,-18,15,25,4,-14,5,30,-16,-29,26,-13,-21,-33,21,14,-20,13,32,4,-19,2,32,-19,-29,22,-11,-18,-24,19,8,-11,12,22,5,-16,-3,25,-11,-16,7,-7,-11,-6,-3,-14,8,11,2,4,5,-2,9,-1,-1,17,-4,2,-10,-1,-9,-9,3,-4,-26,-13,-19,11,11,14,16,4,12,-11,2,-1,-19,-1,-5,-32,-12,-17,19,23,23,8,0,4,-16,-4,-5,-17,1,-3,-13,4,0,17,19,15,1,-8,-7,-16,-5,-5,-2,14,11,-3,10,6,10,7,3,-2,-11,-13} + +#define CONV1_BIAS {-49,-18,-7,-20,-12,-15,7,2,-10,-84,-72,-65,-53,-6,-87,-63,-64,-28,-28,-4,-3,-10,-52,-15,-5,-7,-31,-44,-102,-19,-5,-65} + +#define CONV2_WT {-3,-9,-16,-14,8,-17,-10,-9,-20,37,-11,-5,-21,9,-22,-10,-11,18,4,12,8,22,11,6,-14,-6,14,15,8,-15,-6,-10,-23,-32,-11,-11,34,29,-5,-14,-13,14,-31,-17,-12,8,-19,-9,11,12,-8,31,35,24,-35,7,16,-16,-6,20,3,0,9,-28,-36,-21,-12,-35,-6,-2,-10,23,10,-2,8,7,-16,26,-13,-15,-11,17,-3,16,15,-2,-23,-9,-23,-13,6,-21,7,-4,-40,-38,-24,-20,-3,-47,19,26,-3,4,21,-4,-4,9,1,24,14,-17,-26,-1,-12,38,19,13,-7,-18,49,1,1,-11,8,-7,-26,-8,-30,14,-28,-49,11,-15,-16,-8,39,1,6,-16,-23,35,4,-8,-7,-15,-15,33,14,8,-9,-2,42,27,4,15,0,-25,-13,-22,14,-10,-44,-35,-10,3,-16,14,-10,15,8,14,6,26,0,10,19,23,15,5,-8,12,-23,7,-18,14,8,19,-4,-9,4,-5,18,-31,-44,-35,9,7,-23,7,13,0,-15,-17,-2,25,-6,13,9,24,-12,26,16,35,-34,-14,19,10,-8,8,-8,16,14,-17,5,-21,4,-17,-20,6,7,43,26,-4,-2,-10,-1,30,-17,-9,-16,6,9,24,15,-21,-41,16,-4,34,11,-8,-6,-4,-39,-19,-3,-39,-21,-9,-5,-1,8,27,10,-21,-7,-3,-5,-10,-11,-11,-36,5,-14,12,6,25,-21,0,2,43,12,-13,3,-14,-36,-11,-10,-35,-37,-49,-7,-13,4,24,22,-16,-4,-16,-17,-18,-8,-13,-22,7,-30,34,6,23,-15,-22,26,3,-7,-5,-3,-20,-8,-22,21,-44,-34,3,-18,11,-27,15,15,4,25,12,-5,33,-4,-3,-5,26,-4,-8,-17,-1,-43,7,-17,13,2,-23,-23,-13,-21,-9,26,-46,-47,-5,-5,8,-34,2,28,-4,33,-23,-24,41,-15,-9,-15,5,-12,-17,6,-21,-20,-22,-6,8,-8,-22,-26,8,-1,-17,25,-28,6,-6,-35,15,-21,48,30,-5,24,-12,-48,70,-13,-12,-1,11,13,3,17,-4,-25,-9,-33,1,13,-18,-16,-15,4,-24,37,-26,11,-39,-17,8,-4,22,23,-7,21,-1,-31,44,-7,2,-37,-5,13,-16,1,2,-37,-20,-3,3,5,-14,-5,-32,-26,-2,10,16,20,-51,-9,12,4,13,9,-24,-19,13,-15,50,9,6,-16,-27,19,23,14,35,-12,-30,39,-18,2,2,-10,8,-17,29,9,-15,-12,14,-19,23,-7,-28,8,6,3,-15,-12,-26,20,-3,13,35,23,-25,-59,-32,10,36,-40,12,8,-8,15,-22,-20,1,-2,-54,-32,-14,-16,10,-30,-54,-3,0,-2,-10,-22,-10,5,-15,-5,26,23,-40,-60,-6,-12,9,-28,-21,4,-29,11,4,-28,8,4,-26,-17,-25,-44,30,-4,-24,18,4,13,-5,-23,15,22,-7,3,33,48,-28,-22,-20,-22,-3,-58,-2,32,5,22,2,-10,-20,-5,-23,15,-36,-28,42,-1,-41,12,1,18,6,-35,-4,14,1,-27,44,35,-36,-21,3,-21,-11,-50,-7,14,7,21,34,-24,1,-2,-12,3,-27,-8,54,1,-10,16,-24,-13,-27,-35,-10,7,-12,-5,21,-19,6,12,4,9,-42,-6,-16,7,-20,4,35,-9,63,-7,7,35,16,-10,49,13,-26,55,-28,17,-35,16,-40,17,4,19,32,-2,-20,-51,-21,5,38,-8,26,-2,-17,25,-6,0,21,-11,-20,8,-1,0,27,8,-38,14,-28,11,-44,3,-32,-19,-8,-25,15,-9,-16,-47,1,7,-10,-8,7,-4,1,20,-9,-34,16,-9,-26,22,-3,-15,49,11,5,21,-27,28,-31,15,54,10,-16,-21,-1,8,-2,-10,19,3,-1,-24,4,15,10,24,17,7,-13,-25,-27,26,-12,-3,9,-2,-5,34,-12,15,-23,-16,26,-2,-10,-1,-11,6,23,-21,15,6,20,-19,17,-2,-20,11,34,-8,16,-19,-3,38,-2,9,28,-9,11,21,-8,-22,-48,-15,-15,-13,-7,24,-7,-3,35,-9,18,-8,13,-1,27,-21,6,-10,36,41,32,11,12,-3,22,-10,13,-2,-16,7,-16,25,31,14,-11,6,7,6,7,-5,35,-22,3,37,18,54,-9,2,-17,-5,-6,2,-7,-1,2,21,8,5,14,8,-48,-18,-3,-3,7,-17,-11,7,23,-6,-21,-25,22,-26,21,-19,13,77,7,-29,-2,-12,1,23,-18,-4,-18,34,-1,2,19,53,6,3,9,5,4,-7,36,5,-6,-11,-18,-5,49,-15,9,15,-5,17,2,-14,12,8,42,59,-40,39,-9,7,-13,-3,-22,47,-9,-7,8,32,2,-27,0,-33,14,-10,-27,0,39,-15,23,-3,0,10,22,-7,-23,5,17,1,17,26,26,37,15,3,18,21,-20,3,-4,23,29,-7,-21,-32,34,-6,-2,42,22,-7,34,11,2,30,34,-4,-14,-7,10,14,4,6,-9,-9,37,-39,0,2,-14,21,-45,-5,28,-2,-6,8,0,16,37,-8,3,-25,30,57,15,-16,-28,-8,-17,4,-2,-45,1,-8,10,-18,1,19,-17,-11,-39,3,-27,-6,14,-19,-14,12,16,-25,-24,-41,-26,-11,57,20,-12,16,-3,-17,-1,-9,-3,-1,-5,-38,43,4,16,1,-14,38,-3,17,-5,-2,16,-16,17,26,-2,4,-17,-16,0,-10,47,25,9,22,13,-15,-16,14,13,-1,-17,-5,32,-13,5,5,-33,4,-34,9,12,10,18,-1,-27,-21,-1,1,7,11,-21,-13,4,6,12,46,24,-25,-4,-1,9,-25,18,-1,43,12,17,-15,0,-11,-22,-2,-3,-4,17,-30,3,-22,7,-12,22,34,-48,-22,-8,2,2,-6,18,-14,15,-5,16,-2,1,14,-22,-14,4,-42,-19,-30,11,16,10,-28,10,22,-7,5,-30,-14,46,29,-53,1,-37,29,2,-74,12,13,20,0,21,-40,-2,20,-10,-60,-16,-38,-4,-24,-13,0,-6,-12,-14,-1,-16,5,-20,-42,4,30,-110,-3,-6,5,-6,-85,-1,6,8,-12,-2,-49,1,-14,24,-17,11,-50,21,18,25,38,-22,-3,-16,-1,-15,24,-19,3,-16,39,-52,3,-24,3,27,-64,37,18,26,8,-4,-43,2,2,-14,-70,-15,-58,-6,-23,2,2,-8,-2,-4,15,-18,3,-27,-20,-21,3,-115,3,-33,31,14,-50,28,-13,20,8,-55,-51,34,19,-16,-42,17,-62,-9,-24,11,5,5,22,1,12,34,16,-19,-19,23,18,-103,-13,-34,29,12,-57,-2,3,17,0,-17,-25,8,9,-22,-36,-20,-34,15,-9,12,32,31,-18,17,-3,-23,-8,-8,-1,31,15,-37,-3,-29,24,1,-34,24,28,-7,11,21,-18,-21,18,-54,-68,-35,-63,-1,-19,-1,-16,8,-19,0,-19,-18,-2,-17,-39,16,3,-68,-21,-75,-17,-3,-80,-12,24,-46,4,-7,-45,-6,5,-26,4,-1,-44,39,20,18,4,-8,-2,12,-5,-16,12,-5,-17,15,6,-17,1,-75,-25,3,-51,12,46,24,19,-3,-31,1,23,-11,-58,-23,-88,8,-5,-24,-6,18,8,7,1,-27,21,-2,-32,11,-18,-88,2,-74,-6,-15,-52,-7,24,6,11,-36,-48,19,19,41,-13,3,-67,6,20,-13,31,33,5,-7,-4,4,20,11,-2,23,17,-43,-6,-49,-12,-15,24,19,34,42,8,-9,-27,-5,20,39,12,-17,-18,20,6,3,31,-11,-5,-26,26,16,-7,-5,-2,23,29,47,11,28,13,8,35,21,-7,21,3,50,1,-23,2,3,-10,-8,-36,-9,-25,-4,28,-23,-25,-17,-11,-1,2,-11,-2,-7,32,-5,1,-16,4,8,-12,-12,-5,3,1,-4,-19,-6,-28,5,17,-1,-2,19,9,32,17,-17,-18,13,-17,10,8,-5,1,-23,8,27,34,-42,-25,-8,-4,16,10,18,23,9,29,-5,3,6,-46,-26,-50,-37,-13,6,-27,6,1,-8,15,0,-7,5,-10,-18,4,-9,28,-14,-30,6,36,19,1,6,15,-35,-17,10,26,21,-1,15,6,-25,39,4,4,10,22,-26,23,-1,-1,13,16,9,-9,-2,21,7,2,22,56,25,28,36,19,4,26,9,-7,3,15,-6,-21,5,-14,28,-4,-44,8,-16,16,8,14,-18,25,-21,-5,13,-12,5,-2,4,-5,-13,27,-11,13,-13,-10,11,4,20,50,-10,11,12,1,42,-7,-5,-12,14,4,-4,3,-28,24,-14,14,0,-14,9,-1,-22,2,13,15,-17,21,3,-16,9,31,43,-36,12,8,-4,15,40,-6,29,12,14,-4,-5,-2,-37,38,-14,-5,-1,-23,-5,12,-21,-8,35,15,-4,21,-13,20,22,12,-22,-26,-13,-7,7,-26,17,-26,-11,3,-15,8,17,0,-15,-5,-16,4,-31,-3,-68,0,-22,-38,16,-3,2,21,-26,-45,10,15,-3,-25,-25,30,20,-20,15,22,-13,-5,10,-6,20,4,5,1,-12,-13,-12,-4,-2,19,-37,-17,0,17,11,15,-3,3,29,-7,-22,19,9,-11,5,19,24,-17,-51,23,-31,-19,22,4,-17,14,-30,-22,-20,-15,14,22,-23,5,-17,25,11,11,-2,-17,-6,3,4,32,14,3,13,19,12,-33,0,31,-13,0,3,-20,-30,0,16,11,-19,-33,-18,6,8,25,-2,13,-1,5,-18,-18,10,27,44,-11,22,2,-22,26,11,4,38,22,-9,11,-7,-31,-16,14,46,-2,-38,-24,-19,-3,30,24,59,-15,-20,-2,-29,43,2,0,-31,-21,-50,-27,-21,2,16,-5,-4,25,-12,-5,-15,-10,-10,-14,6,13,-55,-18,13,17,8,-43,31,-28,0,0,5,-37,-8,25,-25,-22,-61,-10,-14,25,18,38,-17,9,12,9,24,-21,-15,0,1,4,-15,-9,-18,34,-21,-8,14,-15,16,-18,25,-1,15,-15,-16,-14,5,18,-37,24,23,-17,-20,9,-22,-15,33,2,13,18,-7,-32,-2,-15,-14,3,-26,-3,1,10,-8,-24,12,37,-28,-12,52,-19,11,-6,-2,18,2,-6,14,0,-11,-4,-27,-10,18,7,33,10,-13,3,-22,7,-13,35,32,-5,-29,-18,-18,54,-16,-13,66,11,26,-9,4,14,-40,1,36,-16,14,-20,-58,-20,9,-17,26,2,-25,-10,-16,-16,14,24,74,-26,-11,-9,-27,99,13,-24,-29,-1,2,-4,-18,8,-11,21,-2,-3,6,-13,-6,18,-13,-14,-1,25,-49,0,12,-10,1,0,23,-19,-5,-17,-7,20,-13,-10,1,43,-12,-5,0,36,9,44,24,-1,29,10,30,-6,-3,-12,33,9,-14,9,30,17,-38,-12,23,-29,22,-33,5,12,-1,-27,17,-9,-9,5,-5,2,12,-5,14,9,-32,10,33,15,36,-2,23,-5,-19,-8,-18,-3,24,-14,7,25,3,-15,33,27,6,-32,13,13,7,-14,-2,-25,-40,4,7,-5,-17,-11,-30,27,17,21,18,-18,-12,4,-20,-4,10,-40,0,0,-53,-10,26,58,-13,-42,5,34,23,20,-3,-58,-98,-17,25,-17,1,-30,-74,-5,19,4,-19,-48,12,15,-22,-17,1,23,-43,-13,-32,-7,10,74,-7,-53,15,22,12,10,8,-87,-83,-1,9,-23,2,-40,-21,5,-12,19,-31,-12,-7,24,-20,-42,-23,-13,-65,-21,2,-10,-22,1,-34,-24,9,34,-10,-9,24,-70,-60,25,14,-7,7,-21,14,0,12,-25,7,-16,1,25,20,4,-18,-24,-51,-30,2,-14,6,6,-12,5,15,-9,-12,-26,31,-2,2,-7,-23,14,-30,25,-10,16,56,-6,2,9,10,-5,24,7,-16,20,41,18,-5,-8,9,1,10,-15,7,0,13,-32,-8,-23,-37,-7,-19,-7,-9,-3,-30,4,32,14,-12,-17,10,-2,2,11,-35,-4,7,2,-37,-5,4,30,-14,-52,25,41,1,11,-41,-48,-70,6,1,-31,-24,-35,-22,-22,0,8,-20,-24,22,25,23,-6,-15,33,-45,-11,-17,-1,7,27,10,-60,26,25,0,27,-34,-63,-63,4,-10,-17,-34,-35,6,-5,-14,20,7,-20,6,37,9,-25,-16,28,-32,-28,-15,-5,3,4,-48,-30,12,8,3,8,-24,-58,-65,1,-4,-9,-36,-8,3,2,67,-35,32,-13,10,36,38,6,-28,50,-25,-44,-9,-12,0,-11,-35,28,18,-7,-13,7,28,18,-13,6,6,7,0,-26,7,59,18,-2,22,6,-2,-80,33,6,-11,4,-5,-9,33,-2,-16,-20,-19,16,12,1,-36,-6,22,45,-3,-28,32,17,-7,-55,6,1,-5,12,-11,-15,21,-37,23,-14,-5,-4,2,-8,8,4,36,37,-53,-16,3,1,-11,-1,48,13,25,-22,23,0,-23,-49,17,-22,16,4,-8,1,4,-14,-23,4,16,-26,18,-21,12,1,7,-6,24,-6,30,-44,-25,-50,-11,-35,22,-37,-21,-6,8,-8,16,14,13,-9,-9,23,-50,-20,-55,7,1,-50,16,19,12,3,-16,-36,5,18,-4,7,15,1,17,1,17,-33,-16,-11,16,1,-16,20,3,-12,-23,11,-2,-17,33,13,3,-15,18,15,48,-6,-12,-27,10,-35,33,6,-7,5,10,14,-26,3,-15,23,-10,-27,-2,22,20,20,6,21,46,-44,8,-10,-14,38,-26,-34,22,-35,-14,-6,-33,-18,19,35,-1,42,14,46,-19,-1,22,10,-25,-37,16,-21,-2,23,-18,33,39,-9,58,-29,23,61,50,-24,11,-25,14,30,-47,-37,-6,-3,-19,18,9,2,10,-5,-20,5,-20,-18,17,-15,3,-3,0,27,23,25,13,1,34,8,40,-19,-15,-11,26,-15,-24,-15,-6,-54,-33,-41,-3,-36,-2,-25,-30,0,-3,-7,-1,-16,5,-7,17,-3,-49,-5,-65,14,-8,-49,14,25,-14,-4,-2,-52,-2,-4,-37,-22,14,-6,11,-21,14,-8,-21,6,3,-25,-1,-12,26,-5,12,-22,-9,5,-45,5,-7,-46,19,26,14,-17,-9,-48,3,-51,33,25,-8,52,-32,21,2,5,0,5,-4,-8,-7,-17,-14,-13,-14,29,28,-25,39,8,-16,30,11,-11,-23,6,8,18,5,-17,22,25,3,47,18,30,18,-8,-12,-6,-28,1,8,-22,-7,-22,6,33,9,22,48,-17,30,74,9,-20,-38,5,3,46,-2,-14,-24,-25,-7,8,-2,-13,31,-22,-33,-3,-12,-3,-32,-10,9,-17,6,38,8,28,-7,26,8,-10,-9,-28,-43,21,28,-4,-22,18,-26,-58,-29,-35,-7,-36,-4,-21,-17,-12,-2,12,25,-10,-1,-8,11,19,-46,17,-60,10,-29,-67,-33,16,-20,19,-14,-56,-6,28,-43,-18,11,-19,7,-20,-3,-16,-33,0,-9,22,36,-4,25,-2,11,27,-24,27,-43,-14,-27,-31,-3,11,-8,8,-16,-47,-2,-26,-17,-4,-22,-9,-17,16,-3,2,5,-15,-19,3,-24,-34,-21,-30,-28,25,-17,-35,-14,2,11,-3,22,7,-8,15,-38,-22,14,-7,-12,-8,-12,6,15,38,14,26,-5,-16,-15,14,-2,-39,-12,-25,-10,13,-48,12,-17,-1,3,22,-18,5,5,12,-34,0,-2,0,-21,-33,15,-6,-29,-6,14,2,-7,-13,-6,0,5,-17,-6,4,1,11,-11,20,-28,25,7,-36,3,5,-4,14,2,-27,-9,35,-16,-52,-24,-25,-16,-42,-20,-5,6,-10,-14,15,-2,-12,-3,0,-7,7,-31,-3,-47,13,-18,-51,-3,31,-15,13,-13,-49,1,38,-20,-20,-22,-22,14,-36,-2,-5,-6,5,-40,25,16,-9,1,6,1,18,-33,22,-29,-8,-19,-38,6,18,-4,11,-9,-57,13,-5,10,26,10,-5,-48,-13,-11,26,23,-34,-16,7,-2,-28,-22,17,13,-16,36,-10,13,-2,-22,48,29,10,-24,-25,-31,-26,-7,-11,6,11,35,28,-15,-1,19,48,17,-9,-21,31,3,-40,-19,11,11,-4,9,20,-21,-8,-5,23,16,6,4,-16,-22,-4,-2,-14,-30,-46,24,11,-23,-29,11,36,7,4,-9,-4,13,-29,-14,6,8,24,27,1,-9,17,10,-12,25,9,-3,-4,6,-26,16,15,-3,-41,-15,-11,-21,-32,-5,-2,19,1,-6,3,16,-16,-13,-4,9,6,-17,-3,-40,-4,10,-25,-27,37,-9,8,13,-53,3,18,-22,-9,-42,-26,-11,-28,21,-16,6,2,-26,14,5,-14,-18,-8,-6,7,-35,18,-21,-15,13,-30,-3,23,2,4,-3,-56,26,-29,-17,-2,13,10,-55,-25,-44,-63,21,9,5,24,-32,-46,-23,-24,-24,-7,-41,2,-26,8,-23,6,17,-8,17,7,15,14,30,-9,-27,-15,43,31,7,-7,-30,-1,3,1,-14,-6,-12,-28,-26,5,4,1,20,25,-41,5,-5,-21,2,-12,8,7,-21,38,10,-1,-17,-6,47,22,-2,16,-27,14,-36,10,-13,-6,10,-2,-27,24,42,-9,20,2,-23,14,7,-16,31,-11,0,15,4,46,26,19,-10,-15,21,-21,-7,17,-32,1,8,-1,-29,2,-14,-30,-10,28,25,-10,8,-24,-34,5,3,-15,11,-25,11,10,9,-13,-1,1,-9,5,10,13,26,58,-14,23,-13,-13,-13,-26,-26,-6,-30,24,-12,-1,23,-29,4,7,-12,23,14,-20,41,5,27,-12,15,-10,6,0,-2,16,-24,-21,3,-21,9,-14,-38,9,-11,-3,-3,-12,0,23,0,-4,4,20,15,18,15,-26,21,3,-10,-8,40,19,-23,-1,10,21,7,4,-18,6,-2,-27,-32,-19,-9,-16,8,2,-32,16,34,20,5,17,10,14,-18,-40,15,-5,-15,45,-11,25,3,26,27,41,21,6,-22,23,-32,0,31,-22,2,15,-16,1,-30,-6,23,13,-2,28,18,17,19,-15,8,4,-9,64,48,64,-10,-16,13,-5,-7,-12,-10,-6,5,-9,20,-32,-32,15,-25,26,-15,-18,14,-13,-26,24,-5,25,4,-14,18,3,9,26,17,38,19,-25,38,-17,-23,-2,0,-15,-18,-2,-20,-14,-6,-11,-27,20,-11,-6,11,-41,-21,-4,-8,25,-2,-17,-42,-13,-1,-15,7,5,19,8,13,39,40,-10,17,-33,2,-10,-10,0,1,22,-16,31,52,1,-7,-9,41,2,19,5,-23,-8,-19,17,5,15,36,55,9,2,-4,12,25,14,-3,-14,14,-16,-8,1,48,4,7,7,18,12,4,19,23,-51,17,18,15,-25,30,9,-10,44,-14,60,-2,5,3,22,43,16,9,-13,15,32,20,-24,11,3,-2,-27,8,6,-18,20,-4,-23,-1,27,47,3,20,6,-15,53,50,75,-9,15,-14,0,31,2,10,-13,23,15,18,-22,-19,4,9,8,18,-14,9,-1,-28,-3,-19,-13,20,23,32,2,-7,-12,20,10,32,-10,48,-8,-6,6,18,-34,17,22,16,23,-17,-20,12,7,18,-12,9,-45,-11,-30,2,13,2,22,10,0,-29,-31,28,-7,-13,-25,9,9,53,13,17,-38,17,-26,-17,-26,23,27,-9,14,12,-23,-28,-3,24,-9,-20,-11,0,2,17,-2,-13,7,31,25,-9,-42,-37,-27,7,14,17,-27,28,-27,-13,-2,7,-2,-20,3,-19,-3,-17,6,-62,-44,-8,-40,14,-12,-3,-9,-20,-1,-36,58,-3,-29,-17,-33,4,-25,23,-36,37,-1,18,10,18,-3,-7,-22,-11,-27,-50,15,-60,-10,25,-37,17,8,4,2,-29,-9,-10,57,13,-21,-12,-40,17,-13,11,-49,2,-9,-1,6,-6,-6,8,6,14,-33,-28,-14,-61,9,11,-18,18,36,-25,-1,-28,-32,-28,-10,42,-13,36,-8,26,-14,33,-62,-24,-12,-22,8,3,-22,13,11,19,-55,15,-30,-75,-11,7,43,-17,34,16,-10,-21,14,8,-8,10,-14,-12,-24,60,-1,5,11,-7,-4,17,16,46,30,0,-15,49,32,-9,-27,5,-21,17,-9,19,-23,28,-5,35,-5,-1,24,-27,-53,10,-21,41,13,8,-16,-3,-22,31,9,25,34,-10,-8,36,15,12,-9,-29,-20,9,-33,14,-31,-9,0,-19,-8,-9,30,15,-16,-10,-34,21,-51,19,-48,22,-1,23,20,5,24,-6,12,29,2,-24,4,-50,-26,0,-9,34,-15,1,-2,-12,-45,-15,26,20,24,-6,-44,34,-4,14,-71,28,17,10,17,6,2,6,24,12,5,-12,-25,-39,-4,21,-1,10,19,-11,-4,-7,-21,-6,-15,25,26,34,32,57,3,17,-54,6,11,13,4,-10,-12,24,19,-5,-5,39,-37,-59,4,35,-10,-21,34,-11,-7,-48,45,17,-17,27,10,-19,-17,-10,-19,-11,-1,-37,21,-24,-15,6,4,32,-14,-6,-14,4,-18,10,27,5,-18,14,22,6,-13,-12,-41,-1,-27,18,33,-25,10,10,-1,3,-16,-24,12,-3,-7,-7,-6,11,-27,-22,-8,-4,-3,-8,-5,13,-10,18,-9,-2,-20,11,-11,19,-6,20,54,-10,13,32,1,-21,-10,-8,17,-26,-4,-12,35,7,-14,-23,-10,11,-13,1,-8,-15,12,-3,-7,-3,-3,24,21,14,9,-21,12,2,37,-31,-3,3,4,2,-7,-20,23,-16,49,2,-9,-8,-16,3,-26,14,-14,-21,-18,-17,-17,26,8,14,0,-4,30,-8,22,13,-2,-24,-16,-6,3,10,-9,-23,-3,-23,27,3,-19,-6,-41,-9,-4,-13,-17,-25,-40,-45,-16,-1,17,6,-22,15,-25,37,12,-3,-5,25,-11,-1,23,0,42,-8,0,4,-1,43,-6,46,16,-21,-1,-7,17,8,21,39,-5,0,0,20,-42,10,-26,13,20,-19,-13,22,9,20,6,3,13,-1,-14,-20,-7,10,-13,19,9,-18,2,-5,-27,-3,-15,14,1,10,-20,37,-31,18,-3,6,58,7,-12,19,6,-2,-26,27,18,1,-7,-21,6,32,-5,-13,-8,4,-15,-1,-32,8,27,-41,11,-9,-18,32,-11,-37,6,-8,9,36,11,-30,4,-1,-4,-3,-21,-13,-6,-7,-20,-17,3,-13,2,-11,-18,-16,2,32,-4,-38,-2,-11,-1,-5,-8,-24,14,0,-9,21,-9,-13,-8,8,5,11,-50,-21,-19,-19,-25,-36,-11,-16,-1,-19,5,-40,-8,3,-9,-51,-8,-24,8,-26,-13,3,-13,36,-14,18,-5,36,-52,1,45,15,0,-30,32,-21,24,13,-2,10,12,-52,19,-40,6,-51,-46,44,-47,-19,33,23,-37,7,-11,34,30,11,-17,19,-35,11,6,31,-14,-23,17,-21,10,16,12,-16,-28,-24,17,-32,-11,-30,-12,22,-28,-16,17,28,-17,7,3,-11,108,32,1,18,3,-6,-43,30,-1,7,0,-10,-22,33,6,2,-24,-7,-10,-44,-18,37,21,-26,4,12,7,7,-31,-17,-3,17,34,27,-17,-21,3,-2,-35,1,4,13,11,7,-49,-11,5,13,12,-17,-30,-34,8,22,19,-31,6,12,-10,-29,14,3,-6,15,22,33,-15,-14,0,14,-15,-6,-12,15,-39,36,-52,-35,0,-13,47,-38,3,-26,-29,47,28,4,0,8,-24,-17,9,9,-3,17,-28,10,-29,-11,-49,13,24,22,-16,-10,33,-11,0,-8,-28,-17,16,-51,18,-45,-18,-7,-34,16,-30,-25,47,-26,-27,-2,-10,24,18,41,-12,-38,-27,10,-20,33,-1,-23,29,-22,-6,-1,5,-9,-24,-25,0,-44,-20,29,42,1,-18,-29,28,-12,-9,-11,-6,-17,49,45,2,-23,25,-18,-41,-2,14,0,0,-12,-31,21,11,-11,-42,-26,-36,-36,-3,46,15,-8,-8,-24,18,-26,-5,-20,-5,-27,23,27,-17,-21,16,-20,-25,-26,28,-3,13,-9,-37,-10,8,6,-11,-10,-41,5,15,36,38,-21,18,-3,-21,-22,19,48,4,0,-4,7,-9,17,25,4,-27,-18,28,12,-22,49,-30,-19,15,6,7,-25,13,0,0,1,18,6,35,-10,-40,8,26,42,-21,-8,-18,50,-23,1,-37,35,14,6,-29,13,22,-30,8,-13,-5,-8,2,-9,-9,-14,-23,36,-4,25,-36,-15,21,-34,-30,-11,-28,7,9,78,-15,-22,-7,3,-9,-1,-6,-8,16,-15,3,-7,51,4,0,-13,-34,-35,5,32,24,-7,-21,-16,6,-9,-5,-22,-4,4,6,42,-9,-30,29,-39,-9,-7,14,-23,-42,-6,-20,-15,25,-5,-19,-19,-33,-21,-32,8,0,8,-13,-10,5,-25,26,-51,19,8,-5,-12,-14,-25,26,-33,-12,-33,24,-35,-29,8,-22,-34,-9,0,-16,-22,-25,1,33,0,34,16,4,-10,-2,1,32,33,23,-16,14,32,0,25,42,18,0,-14,32,4,-10,33,-14,-15,12,-14,25,10,30,-6,35,11,36,27,17,4,-8,3,40,44,14,-3,-8,36,-16,-3,-2,-11,11,36,-5,2,7,-39,-27,-28,8,-26,-14,4,-8,-22,-26,-6,-21,15,-2,0,-5,49,-2,31,10,-50,-4,-2,24,9,2,6,-11,12,-12,-16,22,-35,-16,-26,22,-20,-20,25,13,-5,25,-20,-45,-25,13,17,-15,33,-11,20,7,-59,5,-17,17,6,-11,1,-8,2,-25,-10,26,-27,-7,-14,-5,-10,-15,-11,-2,-41,8,-13,-55,-38,28,44,-23,12,-28,-8,13,-14,-27,6,-19,3,-14,-9,-18,28,-26,-16,23,-24,-31,-9,-10,-6,-16,-26,4,-45,10,-12,-38,-31,19,4,-26,-1,-9,5,-8,16,-4,37,20,21,10,-7,-14,27,-27,-32,37,-30,0,23,-24,-16,2,15,9,16,1,-17,-16,-4,4,26,-29,13,23,32,16,-5,-10,27,-5,-17,-12,-2,22,16,-3,21,30,1,0,-18,4,-5,-23,-13,8,-22,-15,-35,8,-25,5,8,7,27,-28,9,22,-16,-34,25,3,11,7,0,30,25,7,1,27,2,-17,6,1,10,-12,-20,18,-40,12,-21,-37,-20,12,8,1,21,-20,-12,-1,-47,-59,-23,-6,32,-2,-11,15,4,-15,0,-16,-11,4,6,-9,11,-7,-5,4,-95,10,4,-77,-6,4,16,-8,-15,-50,-28,1,-6,-61,-17,-40,8,-13,-14,-18,12,-2,-4,-28,-13,-16,-6,-12,-6,4,-28,0,-91,4,18,-65,-13,6,-8,-5,-2,-43,-10,0,-2,-20,28,6,11,-11,3,-13,-10,-8,1,-5,-2,11,69,-13,-1,10,6,9,-23,10,8,-23,13,4,-1,-1,17,9,29,8,38,5,-20,2,-18,-32,-12,6,-7,6,3,-31,-27,1,-14,10,-46,3,-6,-6,34,6,-2,2,3,-16,6,7,13,11,30,-1,-5,7,2,32,20,-10,-15,14,-11,28,-30,0,23,-9,-2,11,1,11,-1,16,24,0,-22,14,-7,-18,-8,13,4,47,8,1,-11,-14,-29,-21,34,2,-28,7,-37,40,2,6,58,-9,8,-31,11,26,-37,-2,-24,-7,7,-31,31,-13,-10,7,-21,-19,-17,-14,2,-24,-44,-28,0,-17,-32,0,11,33,-2,-32,24,-13,-2,-16,9,5,-8,-7,-55,-12,18,-10,33,-13,-24,13,0,-21,-11,21,39,10,16,10,1,28,-11,-6,0,0,2,-16,-26,20,60,-18,13,23,8,-11,3,-2,-4,48,29,-9,-12,14,6,36,-17,-11,2,-3,-1,-11,-26,-7,18,-23,-7,9,-21,11,-28,36,16,-3,7,-13,-1,-19,-20,-9,36,34,-18,-21,-7,-5,-4,28,14,-17,24,-9,21,13,-6,19,34,23,19,8,-44,9,23,8,-4,6,33,9,52,8,13,14,35,26,-31,-25,0,19,-8,33,-19,-13,-7,-9,13,23,50,26,42,11,14,46,8,18,37,0,-6,9,65,42,10,31,-24,-10,49,-7,25,1,46,10,1,-11,-9,-7,13,-35,-30,2,39,9,27,25,18,21,5,-18,-10,35,-27,-15,60,39,17,6,11,-36,34,-43,24,4,1,18,2,-16,15,33,15,40,16,33,23,37,18,28,7,7,5,8,-21,37,20,2,22,19,62,0,40,-22,1,15,-3,-14,-14,11,3,36,-18,-8,7,-57,9,36,-11,-22,-17,-16,38,-19,-10,5,-32,16,-1,3,-13,-53,36,-19,-5,0,8,54,-13,-34,-38,8,-34,-7,40,-30,-36,-19,-23,7,13,10,-2,-27,25,4,5,-34,17,-4,-14,5,-13,-4,44,-9,-22,4,26,15,-20,-23,-30,10,-22,11,-11,-23,-10,-13,3,50,41,-1,8,-1,-4,28,19,0,21,-14,10,44,-6,12,33,26,-34,-13,36,36,9,-2,-3,-4,3,-27,-27,-19,9,-30,-41,-9,29,-5,-7,10,-5,6,15,-32,18,-14,-2,-3,16,-13,1,5,-29,9,28,-24,2,14,-26,1,16,-62,6,-15,-5,7,-56,24,40,25,16,2,-20,-25,4,-7,1,-8,4,-16,17,-20,44,1,64,-35,2,-3,5,0,-26,-9,-12,1,-2,18,-15,8,9,-24,15,11,10,-27,3,14,-9,8,-25,-16,4,6,-4,23,-19,-11,-6,11,-18,-6,16,36,-15,-10,-3,11,-3,5,1,-2,3,-9,32,18,21,-6,11,-6,0,17,-27,30,-21,5,-11,-7,2,-3,11,-22,-2,27,-13,28,37,-17,-20,-10,2,9,0,-17,17,-4,3,-25,1,-13,3,-8,4,20,-53,16,17,-7,1,-9,17,-33,7,23,-9,10,-18,11,5,-10,-2,2,0,15,13,11,5,0,-22,-23,-17,-9,-8,-1,-10,-11,-32,-8,25,-4,10,-23,-5,-9,-5,27,-6,28,7,-2,-40,-8,-10,9,-1,-4,6,44,20,-10,-20,-4,7,9,39,30,-17,-16,-15,-11,27,-17,0,27,-17,-11,-22,7,10,21,14,-1,10,10,7,34,-15,-11,-5,0,-10,2,-26,8,14,-16,3,1,25,11,-25,-9,16,5,-20,31,16,9,29,1,14,-5,-46,25,-33,-2,-18,-1,-6,1,-18,-13,32,3,-9,3,51,-18,4,-8,1,-5,-46,-13,-8,21,-9,-2,30,-1,-44,-22,-5,-40,-19,8,-16,-3,6,-10,29,-1,2,-31,15,-2,-25,-26,6,-31,-11,6,-14,-1,-37,-4,25,-10,-9,-27,11,-18,-21,15,6,45,4,-6,-38,-12,-16,7,-19,-15,31,-22,-12,13,-30,-10,-28,-6,-12,5,-36,-45,-12,6,28,-42,-8,-11,11,3,-24,5,19,99,29,-22,-13,-8,2,-6,-24,-3,15,17,-9,-2,-2,-12,15,16,19,-7,-15,-14,-18,11,21,-31,-10,12,-6,17,28,4,-14,34,4,-8,5,-3,-5,-12,-11,-13,-25,5,-9,16,-7,-2,17,2,21,14,27,-12,38,-40,17,-16,-1,12,9,-4,57,21,-6,-30,-5,27,-6,1,3,11,-24,-33,22,-33,-2,20,-10,-2,46,5,2,33,22,-1,-43,-21,-20,-11,7,-12,9,-1,-19,45,26,-1,5,11,-15,-6,-9,22,-10,-15,52,34,12,16,-7,-47,-34,-6,-10,4,-4,-22,-60,14,-5,-27,10,-31,6,-7,-28,32,26,127,55,-12,-9,-17,-13,30,-35,-13,70,47,9,-1,0,-22,-48,-9,18,-11,-14,-51,-14,19,9,-36,2,-2,8,6,-55,-1,-2,110,17,-28,-30,-14,-6,-8,-13,-1,16,11,25,23,9,-15,4,4,24,2,22,-22,5,10,29,-1,-7,-8,17,14,-16,2,-4,20,-7,9,-9,5,-5,-13,-11,-22,-11,-20,-6,6,-19,-19,-48,10,34,4,11,13,35,-34,16,4,-15,22,-23,-26,65,5,-6,24,-19,7,-26,17,-18,33,-8,-26,18,13,-16,-6,1,-29,-49,0,12,8,-22,-26,-5,2,-8,-28,4,-2,-2,-19,1,6,0,25,25,-8,-33,-3,-18,-2,-29,-35,72,53,47,-17,-8,-35,-68,-8,-15,-31,-21,-32,-38,3,-14,-12,4,-29,-28,4,-56,24,7,95,19,-36,-57,3,-27,8,-8,-20,68,-4,59,-25,-19,-22,-16,-26,-24,-20,13,-13,-14,1,-4,9,-33,-27,-26,8,-94,-29,-30,23,11,-7,-45,5,-27,-2,-13,6,26,-16,12,-9,-20,-6,37,-60,20,6,7,9,-39,-16,-4,2,9,-21,-5,-12,-52,-31,-37,-18,2,20,-31,0,-22,-15,-23,-50,33,25,41,0,-32,-33,-93,-11,1,-33,0,-34,-12,3,6,2,14,-21,-42,-41,9,-1,33,21,19,22,-24,11,-8,3,10,-33,-7,34,35,4,17,-13,-58,-16,-23,9,0,-30,4,17,15,5,-27,-20,-4,0,-7,-24,37,18,-12,7,-63,9,6,-1,-46,-41,-5,35,-3,14,2,-5,14,-11,-4,21,28,26,12,-2,4,17,-38,-23,-12,-11,19,-18,-1,-9,-11,-23,2,0,3,-35,1,-33,-2,-9,15,-46,15,2,48,12,6,5,19,32,19,-11,-19,25,4,-21,-14,9,17,-27,-5,-11,24,-4,4,-16,11,2,24,-4,24,-3,3,-9,3,25,61,12,33,42,-13,8,-14,-6,-7,10,11,9,-20,-9,-18,-4,-8,-8,54,23,12,-8,-16,-23,-6,-32,31,4,-30,-38,-11,-38,3,-21,-16,6,24,0,0,20,2,-17,-13,-52,0,2,2,-14,-19,-6,-29,0,-13,-5,-16,29,16,-11,-10,-9,-16,-40,-11,-16,17,0,-7,19,-15,1,17,14,-23,-35,-4,-56,-6,9,60,-18,-26,-32,-27,-14,10,-4,-6,2,1,-4,-31,19,-7,-2,-6,7,28,57,19,16,-7,22,31,11,-15,21,-21,3,9,28,76,-40,8,-44,-22,-37,21,0,26,-20,-22,1,-17,53,-15,6,-19,29,21,31,15,2,6,4,-21,8,-7,-25,-19,6,-3,21,16,-18,3,-13,-21,-27,-24,19,43,4,-13,3,-20,23,-5,21,-14,8,-2,16,-12,-19,-11,0,-24,18,-18,-23,-7,-5,-14,20,25,-20,1,21,1,1,-15,7,2,20,-15,-36,31,-13,-29,-14,21,-40,-10,-34,12,-16,-23,7,-26,7,-1,-24,0,-43,2,17,33,-7,-10,11,6,7,18,10,-26,-17,9,-31,16,-19,-47,-31,11,-26,-2,-8,13,-25,-17,-8,-8,19,-24,-35,-16,-8,-10,1,16,-27,-17,-4,14,1,24,0,-21,-46,-11,-30,-29,5,-31,-7,37,10,33,11,-3,-10,10,-27,34,4,-17,1,-23,-12,-22,-4,55,-14,-12,23,-14,-18,-16,-2,-2,-51,3,-29,-29,30,-14,-12,-16,0,29,-3,-2,-8,-16,-6,29,5,5,-17,-19,-19,-7,-8,31,-14,-13,40,-21,-19,-33,4,20,-18,11,-18,30,18,-18,12,-13,0,9,8,-14,-29,-25,-14,-15,35,-16,-31,-23,-18,-2,14,12,-9,-18,31,-18,-4,10,0,21,24,-16,-38,16,-45,-30,-49,-19,-16,-35,-36,16,-2,-3,-3,-28,-23,3,-27,-7,-9,-11,-15,14,6,54,-2,15,39,3,7,-30,-17,-15,-40,24,-23,-28,-44,-28,-18,-20,-34,17,-21,-3,-16,-28,-29,-4,-26,6,-6,-40,-18,12,-29,24,-5,15,47,33,0,-31,-53,-33,-53,31,-17,-28,-26,-9,9,0,-17,4,-21,18,-46,21,-22,-2,0,11,8,-29,-17,21,-30,37,-5,20,56,54,-2,-19,-14,-10,-45,5,-2,-29,-32,-19,16,23,-22,-35,-29,-1,-6,31,-5,-3,2,-6,-11,-24,-32,39,-11,25,29,43,46,4,-6,23,12,24,-34,39,15,9,15,-6,0,14,2,-13,-23,-10,6,31,5,1,-7,-5,-28,-6,-22,-23,4,-6,42,28,5,13,-12,-30,-4,-18,-29,53,-36,-2,-34,0,-24,-31,-36,27,-8,11,-17,-17,-18,23,-17,-36,-21,-23,-12,26,-5,-7,21,18,28,-11,7,-48,-23,-21,-28,51,-15,-12,-36,3,-24,-5,-28,27,5,-3,-6,-3,-20,9,-9,-6,-13,-32,-23,-7,-24,24,3,37,34,-17,4,-47,-24,-24,-34,28,-28,9,-38,17,-12,10,-26,9,6,-24,-27,16,-33,7,14,9,-2,12,-13,-15,-34,24,42,24,40,-18,9,-37,2,-21,-11,31,-14,9,-34,-8,-16,22,-36,7,3,-17,-4,12,-8,-10,-8,-7,-9,10,8,10,-5,14,21,40,28,-1,1,-28,18,-10,1,-5,14,40,-5,7,-14,27,-37,11,6,-2,-5,-14,-2,8,-3,-23,4,-12,-6,13,-41,13,28,0,-19,-6,-18,-33,-19,-24,-27,71,-11,23,-43,16,-9,-28,-54,33,-17,26,-11,-10,-21,0,1,-14,-20,8,-14,-20,-36,50,49,0,31,-1,3,-22,20,6,-21,26,-24,18,-49,11,-13,-4,-53,-6,-5,13,-21,19,-7,-15,-2,-25,-21,-19,-17,-21,-26,62,26,-10,40,-32,-6,-49,23,-22,-34,16,-15,25,-35,21,-7,11,-24,-3,-10,-4,-26,61,-16,-8,-19,-18,13,13,-13,-24,-35,59,21,40,53,-25,-5,-54,0,-4,-7,-14,-31,39,-18,-3,-13,18,3,23,12,-16,-9,31,12,22,-25,6,2,4,10,-11,-32,50,53,54,42,-49,-7,-39,26,-12,-2,6,-8,49,-14,-6,-8,20,-1,28,31,-9,11,2,5,55,-4,20,11,1,-1,-50,-24,71,3,36,4,-55,-6,-9,-7,-24,11,23,0,25,24,-16,-67,2,-27,-2,3,-58,21,-33,6,28,-47,-26,-2,-13,-21,-20,-22,-8,3,-19,-20,31,-32,-13,16,4,-9,10,28,-43,19,21,-47,-33,-40,-14,12,-27,10,2,-8,-6,-35,54,8,-21,-8,5,28,-6,61,44,-16,-46,18,9,27,10,-3,11,-28,-6,-32,-9,-66,-13,-25,-21,2,-28,-10,14,4,18,-11,32,14,-35,5,23,2,-5,-12,-13,-21,-1,21,-38,-26,-2,-10,20,-24,8,-1,-10,-63,3,19,-10,-19,-13,-17,42,10,10,-25,7,-37,0,40,57,-16,-18,-24,-5,-28,40,9,-26,-8,-10,-19,27,-3,12,13,-38,-42,20,9,24,-30,-13,15,-24,6,36,-20,-5,-24,-5,-25,-7,1,-31,-2,17,-25,20,4,10,-22,-23,26,-15,-23,15,7,5,-12,28,-29,-13,-33,10,-13,-17,30,16,21,-83,-4,11,-1,-12,-6,10,6,-34,12,50,-17,0,12,-17,-10,-11,-35,58,7,22,42,-42,-43,-3,9,21,15,27,-42,-2,5,25,-1,2,-5,-1,24,32,70,60,10,-26,28,6,37,-6,-10,-13,-2,22,-8,5,26,-38,-34,-12,-15,-38,66,70,-32,-19,2,83,5,-26,-21,2,16,15,6,30,2,9,26,60,-9,2,-10,7,41,-20,-21,12,13,9,52,12,-9,-21,-24,-9,-3,-5,23,11,-22,3,1,92,1,-8,-25,28,-11,31,5,49,-16,-4,-22,-1,36,-17,0,-13,13,37,30,29,-11,7,-29,-20,11,1,8,-41,-11,-15,-14,-16,-17,-7,-11,-25,0,-25,4,4,12,-5,30,13,-20,-21,21,-23,-21,34,-15,20,-64,2,19,-12,20,17,13,-77,-17,-27,-13,-5,22,-20,-32,-42,11,-18,-17,-2,3,6,-13,-21,-7,48,-8,6,23,-44,16,-15,-19,-5,1,10,-22,-14,-15,-1,-1,18,-18,15,1,11,0,11,-21,15,18,2,25,24,-46,40,-2,33,54,-2,25,-71,22,-38,-34,15,-18,60,-16,-9,-30,58,-16,8,-14,53,8,-20,56,88,-30,-3,11,94,7,-6,-34,24,22,-21,15,-19,10,-18,4,-23,-4,-9,-38,31,-15,-16,-1,-2,-2,11,-9,27,22,-27,23,82,-40,18,-8,73,-22,-34,-16,-1,44,-20,-6,-24,-4,39,7,14,-17,-6,-9,-11,41,-13,12,-68,-26,-1,-1,0,-21,-41,14,-14,-11,-39,-8,-3,-6,-6,14,-24,-5,-17,-11,-24,9,22,-10,16,-1,8,30,-15,7,22,21,-55,-12,-34,-9,15,-2,-27,-49,-24,24,-9,-25,14,-7,24,-8,2,15,30,11,-11,21,-29,12,-21,21,-11,22,13,2,-6,-5,-23,-1,-19,-13,37,-33,-30,-27,-21,7,18,7,32,-10,-21,-24,4,10,4,20,19,-2,-53,49,-30,-10,-14,14,-12,-28,17,-10,13,-32,-44,-1,26,-6,35,22,0,-3,-1,10,28,23,-37,-31,43,-3,14,20,16,17,-18,16,-6,0,-22,-36,5,9,22,18,-6,6,-15,-1,-27,6,6,24,-4,-13,-27,-13,17,1,-28,-28,19,-16,-9,-22,-16,10,13,-2,-8,-15,-29,30,-27,21,-9,16,-46,5,-20,0,-18,-13,8,-3,6,-3,12,-3,-1,-33,12,2,-9,27,7,-16,-19,-27,10,-17,14,14,-10,-28,-63,20,-24,10,-13,-20,1,-10,32,21,-2,-43,-22,15,15,-18,6,4,35,-7,-27,30,-3,4,-30,11,-11,3,-13,59,-26,-24,-6,6,-22,18,-1,-5,-9,-32,35,30,18,-35,-18,21,-10,7,21,8,8,-8,16,19,-26,-43,-9,-8,-19,29,7,13,-34,-22,15,6,16,-30,20,16,-30,-36,-17,41,16,-20,-14,6,-17,6,27,21,-23,-10,34,15,26,5,18,9,-18,11,17,-9,-40,9,-17,-3,20,6,2,34,-13,4,4,-5,22,5,13,10,-35,0,-4,13,18,-21,31,-36,14,-5,-6,6,12,5,-4,-19,-25,34,-36,17,-19,29,-42,-14,-16,-2,-1,-6,9,4,-8,-2,-13,10,-16,25,-4,-10,10,2,10,21,-13,-5,-1,15,28,23,-21,-6,-36,-13,11,19,-20,10,-13,-36,-12,26,19,14,22,-11,60,-3,26,-7,7,17,32,-12,-30,-26,32,-11,39,-3,42,1,-18,22,1,-6,-28,-6,-3,2,-25,-2,1,5,5,1,12,-1,21,14,-30,1,-15,34,2,-7,-6,-46,-24,16,3,-3,4,16,-38,37,1,35,2,-35,26,-7,-24,-38,19,25,-8,-13,5,7,34,14,-17,4,-31,49,-27,16,-6,3,0,21,24,9,21,5,-16,-1,-13,2,11,9,-14,-3,6,-37,19,10,2,1,-11,10,25,-8,8,11,-29,35,-9,4,-3,12,10,15,35,1,2,3,-3,11,20,-18,-18,19,-48,4,21,-22,11,4,-4,3,1,18,-32,-13,-4,6,-21,1,7,-42,-9,-18,9,-32,-16,-42,-26,20,-28,-18,-31,-18,9,14,-16,25,-19,-16,-42,-3,-28,36,11,28,14,-17,-5,0,4,23,20,-12,-1,-19,-10,-32,12,-13,-22,34,40,22,-5,-16,-12,-12,-8,2,-22,0,15,-11,10,44,-12,22,-20,-1,12,-9,-14,3,1,0,39,-46,-19,-7,8,-22,-39,32,26,29,-43,11,1,-33,6,-18,-9,-22,27,33,-11,-21,-24,34,-17,-8,57,5,0,9,-7,24,-13,-14,-4,4,21,-53,-14,17,-29,8,-39,0,-3,10,-37,5,5,-9,11,-13,-3,2,-24,34,-22,-23,-11,-17,-5,42,1,16,19,21,8,6,21,-39,-12,-17,-30,13,38,18,-8,0,-24,11,-21,-34,24,-22,23,-13,-1,27,28,-12,12,38,-14,-9,9,-48,6,-4,14,-4,-26,-20,-4,-16,5,-60,-16,-17,39,-2,14,-6,29,-7,-21,-18,13,33,-10,7,-11,-7,6,0,7,-16,40,14,7,40,17,4,8,-8,-21,-42,26,5,-2,1,3,-9,-1,-53,50,-2,38,23,8,85,-15,1,-16,2,-5,12,-49,14,-8,11,35,18,-13,42,37,-5,-23,1,21,1,16,45,-39,-32,2,-1,39,-14,60,81,-47,-17,-39,15,39,-2,38,10,-16,31,-31,22,-1,33,-21,19,55,-10,-6,13,-2,3,-19,20,2,-3,-21,38,42,19,-15,7,31,-21,-20,-1,-21,-9,38,-13,-9,42,-7,-25,16,-9,21,1,9,-35,-17,-4,-7,13,18,1,18,-6,-14,45,-9,-6,-33,-2,26,-12,63,27,6,4,-41,12,6,-27,20,9,-32,-7,6,-35,-56,-10,50,1,24,-34,22,5,32,-18,-24,-10,43,-9,-6,4,-16,-2,-15,-12,-59,-5,18,-23,-15,-26,-12,43,23,50,-1,11,-52,-13,7,-65,-5,-22,-60,-7,6,-10,-55,-46,20,-11,-6,16,-12,18,-32,-39,-85,-19,-18,21,-27,-7,-14,-5,2,26,-38,49,7,7,-16,-17,-44,-48,3,90,-21,-17,-24,-45,35,-14,20,12,-45,-7,-65,-11,-33,-16,11,44,-17,14,-29,7,9,13,-16,12,30,-15,-11,17,9,-7,40,19,-11,-3,-16,-22,50,28,-31,-20,-8,-30,-11,-16,6,5,20,-8,-10,19,10,-11,23,-25,13,-20,-4,-40,-7,-2,8,14,23,-21,33,21,37,16,-17,-4,-38,-2,-3,-30,38,11,14,0,-25,-13,-7,-28,-4,19,-11,45,5,-47,-43,-14,12,6,0,-45,21,30,25,10,-6,18,-1,-5,46,4,-17,3,29,-30,-1,9,3,-12,-24,-24,-12,86,45,27,-36,-5,-34,-16,-22,-50,-44,-46,-17,15,-15,12,-37,-6,-1,7,14,26,-14,21,-11,-43,-75,-41,-32,16,-1,-17,27,55,10,22,-26,13,3,-14,-36,15,-50,-29,-3,20,-20,29,-52,-7,9,15,-10,-50,-43,60,-8,-22,2,-33,24,68,-14,44,-5,16,-17,17,20,-2,39,-2,8,65,-7,5,31,-3,-12,-8,-13,21,-2,30,-30,-6,-14,-25,-9,-11,38,12,37,-8,-26,45,-37,-24,-12,-29,18,-7,-18,-34,29,23,20,5,44,-5,20,13,52,47,-34,-18,-24,0,13,-34,36,17,37,28,0,-32,0,-16,2,-14,8,-7,-8,-13,4,19,28,-22,-2,-16,-20,-20,-31,5,-25,-11,-29,7,11,-17,23,-21,-16,6,4,-4,-21,12,6,-22,10,-39,8,-5,-13,-24,6,8,8,-1,-12,25,10,-33,6,25,-49,-20,-13,39,11,-10,20,18,-10,10,-18,-1,3,17,12,-26,1,-13,31,12,-33,-7,-27,35,-7,1,-24,-13,2,-21,9,17,-37,-20,18,6,-5,-34,-14,10,-31,3,26,11,11,46,-4,-4,16,-13,28,23,-18,-3,-14,42,3,28,0,-2,10,-44,-1,-19,-19,-22,18,-6,31,-18,-30,6,-6,0,30,3,-23,-3,19,-7,11,-3,3,-22,-17,27,-17,7,-3,12,-11,-14,-11,18,16,34,-23,-19,-22,-16,13,0,-42,-14,-17,17,-3,-9,-25,1,-29,-10,-7,-14,3,-37,-22,-4,-10,0,5,-30,11,-11,-41,-11,-35,-6,-13,-17,-26,-4,-38,-31,10,-44,-33,-13,-8,-7,-22,6,8,-6,-17,15,10,6,11,14,7,24,7,-24,0,11,-27,15,-7,23,-19,23,3,24,5,-30,13,-13,-31,-15,9,-4,11,23,4,-6,-20,-14,35,-23,-9,-14,-5,84,-5,5,-32,-11,-17,13,-17,-37,-27,-16,8,-17,55,-32,26,-57,-48,-18,3,-8,21,52,8,16,-31,-20,15,-26,-6,-18,19,77,18,41,-36,-18,22,4,-4,-5,12,-20,-17,-1,61,-24,-4,-30,-40,-11,0,-12,21,58,15,12,21,-7,12,-25,46,10,28,36,30,68,-17,-13,57,8,35,23,46,2,-54,-7,5,-27,-44,-9,-14,-8,32,-15,14,8,-16,-8,7,-8,12,-15,-30,4,-25,-16,-12,-8,9,-4,-4,-11,-8,-4,-17,-14,-25,-12,16,-1,-11,-26,21,-6,-6,-10,-13,-16,15,-2,1,31,11,3,-27,5,-5,4,3,-8,28,-10,-17,-13,-35,14,-26,-36,-27,-5,-26,-16,10,-8,-25,10,21,-7,15,-12,-18,-8,4,-12,19,-7,-40,-3,-22,32,6,-2,29,0,-10,22,-14,-38,-38,-49,-5,-43,-3,5,13,-24,-26,19,-2,-9,0,33,11,-16,38,-58,-1,-30,-23,-3,7,84,-2,4,-21,-3,12,17,18,-9,-2,-24,-30,9,41,-23,-35,-11,-17,11,-30,15,34,33,12,-14,12,-28,6,22,43,-26,24,45,26,24,-47,-5,33,30,24,-22,-1,-5,-22,6,21,-21,-5,-33,-1,-30,-9,5,33,22,9,19,-1,-9,6,17,16,-16,-24,-11,-31,-11,11,-13,-10,-5,-18,-6,-4,-10,-39,-1,12,17,5,18,12,-6,-8,-13,-10,6,13,10,-28,30,37,-14,17,-15,-11,12,-15,-9,3,-16,-9,-22,-17,9,5,-23,-37,0,-9,-9,-14,-28,-3,13,20,-11,-17,-8,5,-7,32,7,21,8,20,-11,-20,-10,-16,-7,28,26,2,-8,30,-9,13,-22,-25,-31,-21,4,-27,21,10,21,-15,1,-1,-19,13,-27,49,-21,-21,-11,-2,11,-1,33,2,-9,-18,18,-9,-6,19,-18,5,-11,-29,3,-21,17,-29,42,8,19,-13,30,-3,-19,20,-28,14,-31,-14,13,-12,-4,17,31,17,5,-31,26,39,12,-5,-37,-5,6,16,-5,-17,-8,-13,34,-4,-7,-30,35,4,-21,2,15,5,16,2,16,17,-2,-12,-9,-31,1,11,-10,4,2,3,-9,10,7,-30,-4,-6,14,-13,-12,-5,-2,1,1,-5,20,19,27,-4,12,5,-1,2,10,-12,23,-18,1,-8,17,19,-28,7,32,13,4,6,8,-33,-27,-14,9,6,6,5,-8,-16,28,8,16,-6,11,13,6,-8,-2,-11,1,-14,1,27,28,10,-18,12,28,6,-6,9,-20,-2,-4,1,10,-1,9,-4,-1,-6,-18,19,-10,16,31,-24,2,-20,10,-2,-18,-10,-9,16,6,12,6,2,-8,-2,-11,11,16,13,22,8,-8,-31,18,-6,23,-17,-21,20,-20,-11,16,-21,2,-34,-3,25,-2,0,-24,-33,-13,-13,0,-25,1,4,-8,13,-4,11,-2,0,-4,-21,-3,19,41,-16,-35,-1,-24,20,-5,-14,-13,-18,-10,-33,-19,-14,-21,-14,-14,-17,-22,-3,24,-4,-5,-24,-3,-23,2,-7,11,19,3,-6,19,-9,8,-2,-18,-12,0,-1,2,2,3,-20,-17,14,2,2,6,-9,-20,19,2,-16,14,-19,8,9,30,10,-17,12,13,13,8,-1,-11,6,-20,-1,22,-25,15,-10,-2,-6,-15,19,1,31,-1,-13,-7,12,-23,-18,-15,-6,14,16,3,30,-31,-6,1,16,-10,5,-9,11,-20,-11,12,7,-5,-18,-15,3,-8,11,-13,30,-5,4,-5,2,3,-19,15,-23,18,5,-6,18,-31,-26,-13,19,-10,12,-15,6,-31,-6,13,5,-29,10,-23,-20,8,6,-18,-6,7,28,-4,-3,-20,-21,-21,-14,15,48,-4,-8,-33,-16,6,10,-12,18,19,-7,0,25,-3,9,-6,-23,3,-21,5,-1,2,4,16,-20,-5,16,23,9,10,-10,-13,-48,7,12,-18,-3,14,-12,3,5,20,2,-11,-6,16,27,-12,8,-3,-20,-9,1,10,9,17,18,0,25,-4,6,13,-50,9,-11,17,16,-57,-7,14,23,10,16,-10,1,-9,-30,32,7,5,12,-9,-20,-22,3,-8,39,-3,12,19,27,-11,-14,10,-15,19,-20,-14,8,-39,-13,0,-7,3,32,4,-34,-21,-3,23,5,12,8,-22,1,-10,-2,-23,31,-13,-19,11,7,18,-45,3,-15,7,-31,-35,-17,-43,-51,-18,22,-4,21,22,-7,-32,-28,8,3,-15,2,-17,-9,-8,-16,-24,-3,23,11,-3,4,7,-38,-3,-30,22,19,-9,-24,37,-48,-5,-1,-11,-5,16,5,29,-8,1,40,14,-35,-9,-25,2,12,-18,1,-7,-3,-23,-2,9,3,2,-65,-5,-16,16,2,-47,1,3,19,-11,-19,23,-24,7,30,8,-5,-34,-15,-15,-30,-31,-5,-10,-1,-28,48,-17,11,-15,5,14,-61,-14,-23,4,-9,22,27,-7,19,0,12,-6,-30,-7,16,12,0,-24,-4,1,-22,-17,-30,-15,16,-45,63,-5,36,0,-23,11,-32,-13,32,-6,-2,8,62,-11,-8,1,9,0,-18,-7,-37,-1,26,-3,-27,4,-7,9,-34,-2,11,-36,20,8,24,-5,-54,-4,-22,0,-4,17,-10,-24,32,-21,-4,-5,22,13,0,-16,-2,33,28,-10,-8,12,8,7,-23,5,-2,-9,3,16,30,17,-25,-11,-28,25,16,-13,-19,22,-44,-28,3,-19,14,33,24,19,40,-6,3,14,-16,3,-43,32,14,10,-15,-12,18,-8,3,16,-9,12,-32,-4,6,5,38,29,19,-10,14,0,-30,19,-12,-6,68,36,-31,-11,2,-12,-25,-13,20,8,-24,-51,-18,-22,8,-22,-30,69,-25,-5,-44,-1,98,76,58,-26,8,0,4,-1,-10,-16,59,14,-9,-40,5,-10,-27,12,4,-15,2,-32,-2,11,30,18,-32,24,-47,-38,6,-11,38,1,32,-32,24,3,-5,13,-16,10,-8,-19,13,-26,-37,2,-36,5,-31,4,2,-28,14,38,32,7,-44,-13,-31,-15,30,8,-6,-56,-15,-32,14,6,-22,43,-23,9,-29,36,17,-9,-46,5,-10,13,-27,18,-37,-28,-12,23,25,9,-21,-28,-14,-3,52,7,-2,-36,-29,-30,26,1,7,27,7,13,38,16,-9,2,17,29,-34,18,-6,22,-23,9,14,28,-15,24,9,-5,-12,-26,-18,7,16,19,0,12,3,5,5,5,-16,-7,23,36,-35,18,27,15,-22,-10,-10,-14,-31,-9,-22,-6,-17,-25,-6,35,-6,-21,-40,15,45,3,-7,3,-28,17,11,-8,-7,-7,-25,20,15,-12,23,18,-31,-31,-7,-29,1,-7,2,-8,-15,21,7,10,-28,-31,-12,23,9,-44,-30,-8,-17,16,-27,30,1,13,-18,39,3,-14,12,5,-41,-11,-10,-5,1,3,4,36,2,20,3,12,-25,-6,46,-9,-25,7,-30,2,13,12,-22,24,-9,21,-27,62,-9,7,-16,-1,-7,26,6,9,-21,1,8,52,1,14,-16,21,-22,-12,61,50,-11,-30,-34,-5,34,16,-18,-3,3,12,-40,-22,-12,-48,17,-40,-19,-1,31,-4,-8,-7,-17,-2,-24,-5,-29,-9,-42,5,29,-25,-32,13,0,4,20,-8,-3,-32,12,18,-34,3,-12,-20,3,15,-1,27,-9,17,-1,-9,21,5,-27,-29,-6,-41,-50,-28,25,3,-23,-55,-4,1,53,-2,24,-21,-21,4,-81,4,-54,-16,10,38,16,11,-11,28,-32,-10,15,-5,-32,0,-3,-46,-29,-40,53,2,-41,-68,-44,-9,47,4,53,-37,-33,19,-51,10,-31,-24,0,36,53,22,-1,7,7,-14,39,-12,-21,5,-13,-38,-14,-23,15,29,-37,-43,-18,-14,48,2,43,-18,-13,4,-2,9,3,-9,25,34,63,20,-3,4,-1,-10,6,-9,-14,1,-24,-15,0,-7,58,30,3,-28,-16,-11,33,8,30,18,20,19,18,13,34,6,-12,-46,-4,22,22,21,5,55,23,-3,4,16,8,13,0,32,4,-37,0,34,-9,8,9,-11,-4,-7,20,17,2,-20,-6,-24,-16,-8,-38,19,2,14,6,6,7,34,-9,-27,1,-13,10,-11,24,-6,-29,-12,-13,10,-5,-12,34,-3,-22,24,-30,15,-26,12,9,65,-34,13,-13,16,0,-10,6,18,-7,-4,-18,1,-7,-25,90,16,-50,-67,-61,6,13,3,16,-13,-19,31,-49,16,-21,-7,-9,62,18,20,-11,29,-8,-9,21,-19,-13,16,-18,1,-38,-18,56,-7,-58,-22,-63,-10,8,-2,45,-31,-51,13,-29,19,-14,-23,-9,24,34,39,-15,9,19,-61,41,-15,-32,-15,6,26,-25,-41,5,-8,2,-45,-43,-6,38,5,47,-29,-28,2,41,5,31,-6,0,-27,14,-12,14,-5,29,34,1,-13,4,-5,-3,-8,0,20,42,-3,34,34,12,1,13,-10,-17,5,33,7,46,-30,-8,-20,2,-8,2,-26,8,5,-2,5,25,26,-9,-29,-5,-2,-1,9,5,-33,-3,4,-13,17,-1,-4,4,11,-2,-2,-6,8,-18,-12,10,23,-29,38,-23,-4,-13,9,6,7,-11,-8,-18,-14,0,-6,47,-14,-40,16,-40,7,-30,-3,20,12,8,5,-36,14,-31,-22,-26,20,-23,46,-19,-18,-14,-21,4,24,-8,17,-49,-19,-46,-24,75,-15,-58,-37,-43,-13,-10,-15,38,8,-21,12,-15,31,-36,-19,-21,26,-8,29,-3,13,22,0,72,-3,-14,-26,6,4,-17,-43,70,25,-37,-25,-17,-3,15,-6,39,-4,-28,-15,-5,-21,16,-13,-29,-23,22,17,2,21,2,2,-10,15,9,-21,21,-9,-22,17,19,21,11,-11,-7,6,5,9,-12,-15,10,0,9,-45,-12,-17,-20,-26,16,12,13,19,-1,13,13,17,-3,-40,5,2,10,9,-9,-15,-7,14,-17,17,-27,4,18,14,13,-26,-2,12,-18,7,-5,2,2,5,0,-8,-6,-28,-12,47,-5,-20,-15,-13,-3,-2,-9,-30,-37,4,-30,14,-6,-19,17,-7,51,-24,-22,-38,-18,-17,-38,-15,-24,15,-4,-12,-2,-3,-2,24,10,7,-36,-28,-29,-4,29,-6,-59,-26,-31,-1,-25,-11,12,1,20,-20,-16,22,1,-1,5,3,-50,31,12,3,8,0,-22,11,33,-17,-26,16,-22,-32,29,2,-31,-14,-29,14,-18,-5,27,-12,12,-2,-2,-24,-15,15,-39,-28,46,12,10,-18,1,58,-30,21,16,-12,13,-19,-28,6,26,-5,-3,25,10,19,-9,4,-12,-13,9,-3,11,-19,-3,6,-42,-20,17,16,-10,-7,-13,19,-15,3,1,-20,-5,-25,27,29,-15,-17,4,-10,3,22,0,2,-3,24,-4,-21,-6,-16,0,22,-6,9,16,16,5,-31,-3,-12,2,3,-2,22,-13,-31,34,9,2,-13,7,33,10,10,-13,-13,-5,12,53,-36,-3,-20,17,-16,-40,-36,0,0,-8,-9,-4,15,-2,-14,40,33,-13,-27,33,17,36,-25,-4,52,-7,-8,9,-9,4,27,10,-32,8,11,-3,-4,-6,-14,-39,4,3,12,40,19,-22,-26,36,6,-25,0,17,13,50,-9,5,41,-8,1,-5,9,3,14,33,5,-9,-10,4,-15,47,-49,-21,-15,-26,-15,33,-7,-10,-6,-32,13,-11,5,-1,-2,-62,22,-20,-31,-13,7,-14,-5,-24,5,37,23,-12,-27,22,10,34,-60,-12,7,-27,-14,16,18,-25,16,-19,-5,1,-3,-10,-5,-15,-23,-16,-27,-31,0,-9,-10,-4,-10,16,21,-3,0,11,15,-1,13,-25,-15,-14,12,-20,13,-80,13,1,20,-2,-16,6,1,-8,-24,-25,-5,-16,4,23,-8,9,31,21,-10,27,25,0,37,9,23,-32,31,19,13,-19,-30,-50,-6,41,39,-33,-16,37,-10,3,-16,3,1,-55,-26,-9,-4,16,46,-4,-36,9,33,45,8,62,2,40,-3,41,21,6,-25,49,8,38,-47,24,13,26,19,27,3,-19,20,-26,19,-22,11,4,-5,-1,13,-42,-11,17,9,-11,-25,-25,0,-10,-10,28,-24,41,-14,-35,9,-10,26,-16,-11,-21,25,15,8,23,6,16,-7,-38,4,14,23,-32,-14,-8,-10,-13,-40,-17,4,-5,-39,20,-2,-5,17,-30,-28,2,1,-12,-14,-13,7,-11,-14,4,7,-2,-17,5,-23,8,15,-50,-9,10,10,-44,11,-36,0,-23,-7,-5,-28,-57,-1,-10,7,-10,-36,-3,-37,-54,9,-54,-23,-33,10,2,-20,5,14,-1,-22,-26,21,6,4,-34,21,-28,-17,6,-19,-24,-47,-81,-28,-6,37,-35,-46,47,-13,-61,-35,-16,-26,-68,-27,-27,7,24,37,-32,-20,44,24,43,26,7,-2,30,5,8,16,-9,-15,21,-33,5,-14,-16,31,31,6,-11,-7,-16,-5,-56,12,30,36,-20,-3,-4,29,-6,-19,24,1,3,-4,13,34,7,19,-12,-14,56,-17,0,31,37,37,-10,24,3,7,12,20,54,-14,16,-4,1,-9,-5,26,3,30,-5,-19,15,22,22,-10,7,-14,-7,3,-7,30,-6,10,43,36,-29,12,-6,-5,-10,27,35,13,-11,-4,21,-15,-2,9,-43,10,-12,18,-4,26,1,3,-27,16,-29,-13,-39,19,16,19,-9,-16,10,0,4,36,-79,1,13,12,-12,-7,28,30,11,-39,-35,33,16,35,-9,36,-15,1,4,-6,-41,-22,-55,-34,14,29,-50,-58,50,26,-23,-13,-28,-32,-31,-34,-50,5,18,26,7,-28,-10,60,43,55,-8,9,25,8,-29,9,-25,-12,-9,-7,-6,9,-44,31,17,40,-13,-24,-35,-5,-21,-14,5,6,-8,5,-15,9,3,-29,-12,0,-5,-3,14,-15,-5,5,-25,2,4,-11,-19,16,22,-1,3,16,-10,-13,17,-13,27,-8,20,17,-21,-18,-25,10,-4,26,-1,-7,-4,17,16,-16,-2,-20,-21,-2,-17,11,-5,26,-2,-25,-39,-11,-19,-2,-11,0,0,6,-16,23,22,-10,12,18,-31,6,7,17,-15,2,-3,7,9,10,-45,22,-33,11,1,12,-48,-51,-1,2,-9,6,-41,-30,-24,5,-30,13,17,3,25,-22,-45,46,27,-9,-40,19,-24,4,13,6,-14,-6,-47,-9,15,-5,-43,-63,34,16,-14,-15,-12,-39,-34,-39,-49,12,12,23,-12,-1,-18,25,39,18,-24,30,-3,41,-1,5,-3,-24,-7,5,3,2,-49,13,-19,31,-15,-1,-26,-21,-19,-16,-36,-4,42,15,-21,-9,-2,-11,3,-15,2,31,11,-11,-15,5,-2,-22,45,18,-28,6,7,1,22,15,-23,-27,36,-6,15,4,-19,14,15,5,-14,4,-4,6,1,-23,5,11,2,-25,-13,-8,25,0,21,7,-10,26,-28,1,-1,-11,-30,20,17,-4,31,17,-19,0,55,-11,22,21,-1,-19,12,21,-10,27,-1,-1,8,4,4,12,-11,-21,-7,16,-52,-14,-4,-2,14,-1,-13,-14,15,12,-35,-12,16,-16,28,-1,-6,27,3,2,-9,-4,20,-16,12,14,-1,25,-6,-23,9,-23,-46,-42,29,9,-7,15,2,-20,-17,-13,-27,-11,0,20,9,8,38,5,11,-12,-5,16,18,0,33,-3,-4,12,46,2,25,-3,-29,18,-31,-9,36,0,-16,-3,-17,-3,4,-3,20,18,-15,-6,21,14,26,14,-20,-18,13,-35,7,-14,-4,46,-61,7,-16,-3,-26,-28,-10,-6,-26,26,29,24,8,-10,-35,-20,9,30,7,-7,10,-19,35,7,-22,-20,-20,-53,25,-6,1,20,-61,-32,-3,-12,6,-23,-45,-9,-66,26,55,44,12,-13,-1,-16,-13,-20,48,-25,33,26,21,9,-29,-18,-16,-28,12,-7,-1,-2,-49,3,8,1,20,-4,-37,12,-9,41,64,2,-17,5,12,-7,-24,26,57,-29,1,47,2,22,-28,-20,4,-7,9,16,-7,18,-19,11,-9,23,-1,-19,-40,25,8,6,17,-15,-48,16,12,-1,-32,1,18,-8,-25,1,-19,-29,-58,6,11,16,4,24,1,20,-22,49,-8,2,-22,-16,-6,18,-18,17,-9,-30,-49,5,10,14,-39,-16,-13,-12,15,22,40,15,-10,10,19,-8,5,-10,-29,20,-63,23,-1,-27,-10,-11,6,-15,22,-8,-1,3,30,6,-10,-14,2,31,-1,-1,10,-50,23,-31,-5,-23,-4,-46,3,-3,-18,-13,-57,-5,-12,6,9,-10,-32,13,-43,15,17,-15,-20,-11,-41,-11,-34,-15,13,-13,-33,-16,17,-23,-22,-21,-16,-55,-10,-1,-26,4,-40,-9,4,9,16,-32,-35,-3,-31,18,-5,-1,-48,15,-15,-9,-22,-4,-5,-13,-9,27,-9,-20,-27,-35,-7,-37,-4,4,-32,1,-29,7,-5,13,19,-22,-29,17,19,-16,-33,-23,-47,16,7,-1,-18,-17,0,-3,1,20,-18,-20,-24,-6,4,13,12,13,-12,26,-42,26,-9,-7,-11,-2,-2,31,18,8,-29,-23,-28,15,25,2,-14,-19,-5,10,-62,88,23,23,-16,67,4,26,26,-13,-4,21,0,8,-7,-34,-15,14,39,-28,88,-9,38,3,-4,-1,42,-17,36,17,-22,11,-46,3,3,-4,-17,30,-5,17,-8,15,5,17,-10,-5,-13,6,16,19,-4,-1,22,-3,4,-23,-49,-4,23,3,17,-13,-15,-7,-13,-23,3,-40,-33,4,-24,-30,5,15,18,-12,-21,-2,-5,-2,-17,9,-36,-5,-61,11,10,-68,-30,20,20,9,20,-12,-16,-5,-1,0,5,-28,-29,-41,-28,-28,20,-11,20,4,-30,-2,-17,-8,-9,26,-15,10,-14,-27,36,6,-19,7,-13,12,-2,-28,-2,0,3,9,18,-4,-11,-14,-27,-3,20,-4,27,55,-52,33,-15,30,-30,37,-15,29,10,-1,41,40,14,-9,-18,4,1,-19,31,27,-3,42,-9,17,-29,70,-8,35,-25,4,-14,6,7,26,-19,-29,-15,-26,6,1,38,1,-21,1,8,18,14,2,35,7,-2,31,-39,11,-9,15,-12,55,-6,53,-2,4,-28,-14,6,22,-22,2,-3,-1,-20,4,47,23,-64,-34,4,13,44,10,31,-6,5,11,-6,-18,-30,-23,-5,20,-12,12,4,22,3,9,10,27,-8,-21,-26,22,13,-13,12,11,-19,-28,7,25,7,18,14,-13,-25,-9,19,-10,12,-27,-12,-32,-16,-23,16,-7,27,11,-7,-16,1,-16,-22,20,-6,5,-61,10,32,6,16,13,-24,6,-3,-18,10,-10,2,-12,26,11,-17,-25,-29,-26,3,-6,20,21,-3,10,25,32,-23,-2,-13,26,14,22,3,24,7,-12,-29,-3,-10,19,31,33,-13,-21,-20,-24,-33,20,-3,21,-4,-5,29,35,25,3,-3,-23,19,-16,-5,1,19,5,-4,31,31,29,14,23,3,-12,-15,14,5,32,-21,16,-5,50,10,30,-3,-33,-17,-11,10,7,-3,-18,1,4,10,-6,29,29,-4,5,16,11,35,17,20,-9,15,2,0,5,-27,2,-1,40,4,29,14,-6,-21,-7,12,15,3,-12,-8,6,17,-19,1,-3,-15,20,11,3,28,26,6,16,-34,1,1,-5,8,3,-14,-35,5,0,29,0,0,-7,-16,13,-2,-14,-14,9,16,-9,-25,-18,11,8,-14,-25,-5,6,22,-13,-14,-7,-25,-21,43,-5,-38,-20,-13,-4,13,10,37,6,11,-10,8,7,-9,-11,3,-2,-10,17,2,1,-14,-26,42,-11,-6,9,11} + +#define CONV2_BIAS {55,50,34,43,-37,35,-21,10,35,-53,-76,7,14,-1,92,20} + +#define CONV3_WT {15,10,3,1,-20,-11,5,-18,-9,-1,-4,-11,-5,-19,-26,-15,13,5,1,7,6,16,1,-20,3,35,0,-2,8,12,-41,-5,-20,4,6,3,-3,0,-28,-13,6,16,-4,-4,1,8,17,2,-4,-10,-9,-11,3,-2,-4,-9,-21,-10,-18,2,-6,-18,27,5,2,5,-5,-3,-4,-2,-16,17,1,-17,-13,-12,-1,-18,10,6,7,-4,-1,7,1,-4,7,-8,0,4,12,-4,-5,-13,8,-17,0,-22,-2,5,12,20,3,-6,4,10,16,4,-3,-7,0,-15,-17,-1,14,25,2,3,-15,-11,1,-4,-2,-14,-2,5,12,-2,5,-13,8,-1,-4,0,-6,12,-3,-22,-20,7,3,11,8,6,6,2,10,7,-5,-6,-6,18,-2,-23,2,1,-12,-9,-3,-2,0,-3,-9,4,-16,-3,-7,-23,-10,-8,-1,-26,-3,9,30,-16,-11,-13,-9,-11,-14,5,5,-9,-16,1,10,-5,-18,-14,31,-6,-1,1,5,-7,1,2,-17,3,8,1,2,-3,-4,3,-6,7,23,-10,-6,-3,-9,-9,-38,14,-3,9,-10,-3,17,13,-6,12,22,8,8,-6,9,9,-6,13,-1,-11,12,-2,-4,-3,-2,17,2,-8,-15,-2,-9,-10,-9,-19,2,-11,6,-5,-5,8,28,2,-23,12,-19,-12,-33,2,-8,-17,-3,-15,-1,23,-18,9,23,2,-9,18,-17,-29,17,9,21,6,13,3,13,32,-4,0,-7,10,-2,-2,-10,-5,-4,-5,8,-1,-1,-9,-20,11,1,4,-10,1,-1,-6,-24,-1,-6,-2,11,6,7,-9,2,8,-6,-8,-19,11,6,-10,5,-5,0,-14,18,-11,13,5,3,-7,0,6,-21,4,2,12,-14,3,-14,0,-10,-6,10,0,-21,17,3,19,-19,-2,13,21,-10,-11,-5,-18,-10,6,25,1,-19,0,2,-11,-36,-13,11,-24,4,-16,-3,-28,0,1,-9,-6,-3,-1,6,-11,-19,3,5,-6,-7,16,-22,-19,-11,-20,6,-2,-1,-12,24,3,-27,-2,-15,-18,-2,-3,5,-12,-8,-4,-23,1,5,19,-30,12,-5,-4,-1,10,-1,13,2,-4,-12,6,-3,2,13,5,-18,-3,2,1,4,20,13,8,22,-6,-3,8,-12,-10,-28,12,-12,-5,5,-12,-6,13,1,-17,-32,-11,20,-14,-9,-6,-11,-1,-8,-2,-13,-10,-1,31,-12,21,-32,-2,-14,-1,0,11,-1,-1,-13,16,-10,-8,-10,20,-2,1,3,-7,-17,-1,-12,-4,-14,-16,-20,-1,-2,-4,-3,11,16,6,-12,-11,3,0,2,-1,-2,-18,-21,-4,5,-9,12,16,7,21,9,13,-4,2,4,0,-21,-17,-3,2,-10,-24,-10,7,3,-15,3,-11,1,1,5,-8,0,-7,3,0,-3,2,0,31,-5,7,0,6,-13,-7,11,-15,-1,-13,2,13,-2,8,25,-6,-1,-16,-3,7,3,-21,10,0,-14,13,17,7,0,-7,14,10,-1,-6,-8,-14,-6,-16,4,-26,-11,-5,-1,-14,15,10,26,-1,-27,-22,6,23,-16,-14,-1,-12,-26,-21,-3,-5,1,-9,-13,-9,-9,-12,0,-6,-3,-6,-9,-2,-10,-3,-13,5,-4,4,-2,1,-3,1,-3,-13,6,-5,3,-18,-11,-6,-19,-2,-13,12,4,-10,23,-8,-23,15,10,-3,18,4,-5,2,5,10,1,-16,15,-14,2,33,-5,-4,5,-11,-19,-4,6,5,16,-14,20,12,6,-14,-24,-29,-11,1,16,-6,11,-8,-25,7,-9,-6,7,20,-19,-3,-7,-19,2,-8,15,-7,-5,2,-11,-11,-6,-4,4,-7,-1,-4,15,-2,-3,-2,7,-9,-16,-6,-4,-19,5,-6,6,12,14,-2,-3,-1,17,3,-11,-5,25,4,15,-7,8,7,1,-19,9,-32,19,17,6,4,8,2,-5,29,28,-9,14,14,-13,-3,5,-9,-20,-17,4,-12,0,-4,-2,14,9,5,9,-28,-15,8,-8,11,-16,-34,8,-3,-2,4,8,-20,-1,-11,-19,-14,-1,-14,-5,-3,25,-16,12,13,14,22,6,-4,1,-12,3,-15,3,-14,-12,-5,23,4,-13,3,-22,19,8,-3,-29,9,-12,-21,-12,-18,-15,-9,8,-6,1,-5,-21,7,-2,1,3,-9,-16,27,-11,-19,8,0,0,-1,-2,-9,-28,-25,-24,2,-7,-5,-20,1,-27,-15,2,8,-13,-1,-1,3,-21,-6,-10,9,4,15,-15,12,-12,-10,-6,-15,2,0,5,0,-2,-18,4,-8,-3,4,1,-9,-1,16,-8,20,11,7,12,-4,-34,11,-21,-6,-9,-12,-18,-39,7,14,-14,-1,-11,4,4,-5,-21,2,-7,9,-5,-9,20,31,17,-18,-14,-1,-6,1,-6,-14,-21,-11,-6,3,8,-4,5,26,2,-18,0,19,0,4,3,-8,2,-10,-6,13,7,-3,3,16,-7,-11,9,-11,19,-9,-6,-5,2,-1,-1,-8,-10,13,7,-9,-12,-2,0,24,10,-7,13,13,14,19,-6,0,-19,-14,10,-21,15,-1,-11,-3,21,0,1,23,-37,1,3,-9,0,13,10,13,31,-29,-3,-1,9,-2,-8,-11,-11,-6,-5,-17,15,-20,0,11,7,12,6,13,0,-12,-8,-13,-2,-3,-5,-1,-10,-6,4,6,0,8,-8,-7,10,-5,-6,-2,-23,-4,-4,-13,3,16,-1,16,5,-3,-12,9,-5,-2,11,-16,13,15,7,-12,0,-4,-18,-9,-7,4,-25,-6,-6,6,-19,-5,13,9,-1,-5,3,4,-7,16,5,-8,-6,3,5,1,-6,4,14,-4,14,2,2,-10,13,23,7,3,5,11,3,-13,-4,9,12,-6,-7,-2,-11,-3,0,-6,2,-2,23,8,-4,-13,-1,-7,4,-9,4,9,-8,-3,-8,5,-12,-14,-15,-13,-1,3,14,1,-9,4,-2,-8,-2,18,-5,-5,10,-4,-2,-8,12,30,-10,17,1,-10,-1,-15,-17,17,6,-3,-4,0,1,-13,0,2,-14,3,-4,-18,6,-12,9,12,-12,3,13,5,-6,-4,-7,2,-17,11,-7,3,-7,-2,12,0,-9,21,1,9,24,13,11,-2,-18,2,-3,-1,-14,-13,-14,2,-1,0,-2,19,-8,-3,-9,6,-20,-9,-5,-5,-4,-9,-17,-4,-4,3,-3,14,11,3,1,6,-20,12,-9,-16,-12,1,4,-6,-7,6,3,-5,0,-14,-2,20,-12,-2,-29,-15,-10,6,14,-17,1,-23,4,-2,-5,0,3,5,4,12,-20,1,6,-2,-1,1,-7,2,-2,-23,0,0,3,8,0,1,-20,17,-16,-7,-12,-2,5,1,-6,-15,6,-8,3,5,-14,-11,-2,3,-1,7,-2,13,-13,4,6,21,-18,-1,9,-7,-12,2,-12,-9,-6,1,10,5,-12,-5,5,-1,-18,-15,-13,19,1,10,-21,1,-8,8,-2,-5,-13,-8,9,0,-17,-11,-9,0,6,13,-4,10,0,-19,0,15,-15,-3,15,-7,-9,-8,-3,-5,2,5,-8,17,-5,1,-11,3,-10,10,8,4,11,-1,4,-12,-10,-11,9,-1,2,-6,-3,16,2,14,-15,2,0,0,8,-3,-20,-16,13,-1,-14,2,8,4,13,5,2,14,7,-26,11,2,-1,-13,-5,2,-9,1,-9,-3,-6,-2,19,-2,-26,0,8,-19,14,2,-8,2,-13,-16,-1,2,-12,-8,32,9,-23,-3,15,19,-22,2,25,-4,-1,-16,10,8,-18,4,23,8,4,8,-9,-12,-7,2,21,-4,3,-13,-13,-10,-12,-2,-13,-20,11,5,-8,8,-2,14,13,-5,8,-2,-10,-16,-4,-2,7,-7,12,-13,-5,10,11,18,10,6,12,-9,-12,17,15,3,13,7,-26,-13,16,-8,18,-9,1,8,-7,-3,4,6,11,-19,10,6,-4,-10,13,5,-16,-2,32,-2,-11,-2,-4,15,-30,-5,13,17,-14,9,-4,10,-30,-14,16,-17,0,-11,-8,-37,-5,9,-36,-6,-8,11,3,18,-11,-6,-1,-8,5,-10,0,-9,-7,4,-20,-7,-1,16,-5,-8,-3,-10,-7,-5,9,-2,-15,-11,2,8,-9,-18,16,7,-13,-1,0,10,-12,-12,13,21,-20,7,8,-17,-6,-9,15,9,11,-7,-17,-4,-11,-34,-5,0,-19,9,-15,-28,-10,0,-13,13,19,-7,-10,-10,-4,-8,4,-7,-15,18,18,10,-27,-9,-14,3,7,20,-5,1,-10,10,-3,-16,-1,2,14,-18,-2,-3,-2,5,8,12,-7,7,-9,14,1,-12,2,7,-12,4,-6,-7,-21,-3,15,0,-14,-9,-11,-11,3,-7,0,-4,-22,-15,2,-8,-25,11,15,6,8,2,4,-7,5,-2,-4,-13,-13,-17,-3,9,-9,-5,3,-5,-4,-1,-9,-7,3,-29,-1,0,-9,6,9,6,-13,-2,-5,10,0,4,-9,-3,12,-17,-3,-5,2,-3,13,2,-5,-6,-2,7,-8,9,5,5,-2,-15,-6,0,-9,-21,9,13,-13,-19,2,4,-2,-9,2,-12,4,-21,15,2,-12,0,-2,-17,-1,11,-7,2,27,-16,16,0,22,-18,-2,-8,-19,-16,-6,23,-12,-20,5,-24,-15,-3,-8,7,-1,-6,-1,-28,-6,0,11,-20,-1,-14,8,-8,-3,11,-4,-8,2,-15,-8,7,3,8,18,-20,-6,-17,3,-25,-6,-11,-15,-7,-12,20,3,0,-9,-31,20,-11,-16,-14,5,-5,-19,-10,-20,-11,-10,17,4,-18,-4,-5,-12,-6,-13,-11,-4,-8,1,-28,7,7,-7,16,1,-7,2,3,1,19,25,-10,12,-13,16,2,11,7,1,-2,5,8,-9,-7,0,3,27,-2,-11,-3,2,8,23,4,-7,-7,-3,-5,6,1,3,-1,12,8,3,-15,-2,0,-7,1,8,9,18,26,10,13,1,-7,17,2,-13,-2,17,-19,-7,-7,0,-4,6,-3,-5,-9,-12,-13,7,-11,-2,-11,5,-1,15,-12,-24,7,-13,0,-1,24,4,-21,-4,27,16,-9,-2,5,-7,-11,-19,-6,-7,33,2,6,9,-15,15,11,-16,-3,-26,13,-7,5,-15,-12,13,-9,-7,-1,3,-10,8,18,-2,-14,0,0,-5,-2,15,6,-4,15,-18,23,-2,-9,20,8,-21,-16,0,-8,11,-28,11,-8,2,-2,-11,6,-18,-11,-1,4,-16,-7,2,11,-15,-26,11,3,-20,-1,-14,14,-6,-8,-4,-16,3,6,13,-4,9,9,3,-14,-13,-11,13,5,0,-4,9,4,-13,10,-1,-19,-1,-5,-6,-12,-14,-23,-1,-19,-2,2,19,38,-8,-18,11,-2,-7,-12,14,-7,-18,-1,6,3,4,-12,-5,-20,3,8,4,4,-22,-5,-20,-2,10,-1,-3,-7,3,-2,9,-23,3,13,20,-3,19,-18,-29,-12,-4,-6,7,-2,-18,-8,2,-13,4,3,10,0,-1,15,5,-8,-5,2,14,18,4,-1,5,4,13,2,-1,-11,-2,20,16,12,3,-5,-16,1,10,3,9,13,3,-14,18,8,7,-1,8,-3,-22,7,-28,-7,8,19,-19,-12,2,3,-9,-1,13,2,9,-9,-4,-18,-19,0,-6,-1,0,-14,5,16,-14,-23,-14,-29,-12,-2,17,-11,-1,28,21,6,1,-2,5,1,-10,6,17,8,-2,-16,-11,0,-6,-1,-2,-18,6,1,0,-5,-3,5,-3,1,9,-16,-12,-13,-13,-7,-11,-11,4,26,5,-5,-4,1,-6,2,13,2,-21,-9,-12,-7,-24,-26,5,28,-8,-15,10,-23,-7,8,20,35,-4,-12,-19,-16,-21,-16,-4,-7,-16,10,9,9,-24,0,-4,8,-1,-5,1,15,8,-26,-23,0,2,1,-17,3,7,16,-14,1,-9,-7,-10,-22,8,-4,-6,-18,-14,-7,-19,3,-10,4,13,-4,-2,-2,-10,-24,-1,-18,3,-16,-7,2,-2,7,-12,1,-3,-32,-6,2,1,-31,-6,-24,-2,15,-13,-6,11,-6,9,2,26,14,1,9,-17,-22,-11,-16,5,-6,4,3,15,32,0,17,2,0,3,32,5,-8,-16,13,-1,-13,7,0,-8,-12,-18,-2,-22,-11,8,-11,-5,-17,-2,7,-9,-22,-4,-10,-6,-8,-4,1,8,4,25,-6,13,-3,-8,1,-10,-25,-5,-5,-10,-13,-2,19,-11,-7,10,9,-13,-19,-4,4,1,-6,5,1,-8,-7,8,4,-11,2,3,14,-3,-15,-18,14,-6,-4,24,-11,-4,1,-13,-8,-7,13,2,2,30,1,-18,32,-18,-15,24,6,5,-2,-24,2,-21,-1,8,-23,-3,21,-5,-5,-8,-9,7,-9,-13,-12,-17,-13,-2,5,21,6,5,10,-12,-16,-1,29,21,3,-7,-31,4,-25,-6,18,-8,10,-7,-2,-14,-19,3,26,33,10,0,-10,5,-11,-20,-4,-9,-14,10,-16,-12,6,21,3,10,-14,-20,4,-29,12,-8,9,1,29,-13,-4,9,-12,-20,-10,-1,-6,18,7,-16,-1,-25,14,-10,1,-22,6,8,-10,-27,-13,-8,-11,2,-1,1,13,-15,-1,15,-5,8,3,-8,3,-3,7,6,2,-3,-18,17,-15,-9,-21,0,0,18,-16,-22,-9,-9,-9,9,-16,-12,-17,25,-11,-15,-9,11,-21,21,-14,-9,7,-12,-24,-7,-5,-2,0,11,27,-12,0,25,17,2,8,23,-6,13,0,-10,8,-12,3,-25,10,12,2,-29,5,-6,-18,16,6,-9,2,-1,17,-9,-1,0,14,-2,-1,-2,-10,0,-16,-19,-15,6,18,-12,19,5,-10,43,-1,4,6,-8,-6,18,-11,6,-12,6,5,17,-34,-17,-3,-6,-17,-4,4,-1,3,12,5,41,10,-16,-16,-15,8,-6,-8,-27,6,-14,-14,-11,-13,-10,22,11,2,4,-5,-7,-2,-11,-10,-19,0,14,-8,-10,-1,-1,-7,10,6,-20,-11,-8,13,-2,-17,2,-11,-8,4,1,5,-10,-18,3,-9,-1,-10,-13,-4,15,2,11,8,-11,4,0,-17,19,0,3,-18,16,-10,1,-14,-5,-3,-10,7,-11,0,-9,5,-4,-1,16,4,-2,-24,6,9,-18,-22,-5,-9,1,-9,-3,-14,-7,-3,-16,18,37,-7,1,0,-3,-4,-1,2,12,-7,-3,-11,4,1,11,-9,-1,16,5,24,10,6,-5,1,-1,6,-10,-11,-7,-1,6,3,12,-1,2,5,-17,-1,6,13,8,-4,-11,-24,0,-2,0,1,16,10,17,6,-6,-4,8,-1,16,-8,-10,-6,-5,-9,14,1,-22,-13,6,1,-11,-18,1,4,10,-1,0,-1,-25,-4,-6,-8,-2,5,-2,20,9,1,-18,22,-9,-8,11,-25,1,5,5,-12,7,5,-15,15,-4,15,1,3,0,-17,1,-21,-11,-4,4,6,-4,4,-2,-12,-18,-3,-9,3,-10,-23,-8,-14,-1,-14,14,-7,4,-7,-4,4,-19,-14,-13,-9,-2,0,1,-2,-11,-5,8,1,15,-6,-2,-1,-13,-12,-9,18,-2,-8,-1,0,8,12,-4,-8,-23,-8,0,6,-4,-8,-4,32,-28,-3,1,-9,6,-24,-8,-11,12,22,7,1,6,-4,1,11,3,-6,-6,-22,14,1,14,-3,1,6,-11,-1,-8,-9,-1,0,-2,-14,-13,-7,9,-4,9,-15,12,13,-22,6,-1,-21,-2,-25,9,-7,-13,-11,16,9,4,20,12,-8,-25,12,0,-6,-12,14,6,1,9,-4,1,4,-3,-2,-21,-7,13,-1,-13,3,5,-1,-11,2,-16,-15,-6,-35,3,-11,0,11,47,-1,-13,3,7,-15,-2,-1,-9,-25,6,-12,-10,-15,-6,6,19,-1,-4,-15,7,-13,0,-4,2,1,4,15,-24,-23,18,22,-3,0,8,-1,5,-19,22,1,15,8,12,10,-1,-5,-5,14,-31,18,-8,10,-19,-17,1,2,-3,23,-6,-8,7,-3,-3,-2,1,-14,-16,12,-3,-14,0,0,-7,27,-6,-15,-8,13,-1,-23,47,-19,-15,13,3,-5,4,-4,-2,3,9,-34,-2,1,7,-22,20,-14,0,-2,26,-5,-17,-4,-5,-5,-7,10,-16,-28,13,-7,8,-13,-12,11,0,1,-14,-13,4,20,-9,2,3,-14,-5,-4,-10,1,-5,32,-26,12,-13,-9,-23,6,-1,-10,5,-2,-4,3,-25,-5,-2,-6,-5,17,23,0,-6,22,-9,29,-8,7,-14,-5,-9,1,-8,-13,28,1,6,-5,6,-1,-6,-20,15,-4,-2,-5,-25,-6,-19,-14,31,-10,-17,4,-6,-7,12,-2,-8,-7,-5,-7,-12,-13,-9,5,1,4,-4,-13,17,6,2,-1,3,3,-23,12,-8,19,-5,-7,-9,17,-8,-4,-2,3,-1,-13,-30,25,-17,-25,9,1,-1,2,-31,6,-5,-21,-15,2,1,-11,4,20,-10,-17,5,-3,-2,6,3,12,0,-11,13,12,0,-9,-1,-13,11,0,-2,-17,5,0,-15,8,5,-6,-5,-3,4,7,13,15,5,-10,0,-14,-10,-7,-9,-9,7,-4,-15,-11,12,-7,-2,13,-28,-7,-14,-2,-8,16,-9,-3,-8,16,-4,14,1,-12,1,-10,1,-7,-16,-7,0,7,-25,13,5,-17,-10,-2,-11,27,3,11,-2,-2,2,10,4,-11,-9,-6,3,-18,22,15,-4,-2,-9,-7,-2,1,-5,-15,-3,11,-20,2,6,-2,4,-6,4,1,-2,13,-9,2,-5,-13,6,1,0,-3,16,12,-13,0,10,-18,6,-12,-14,0,6,18,30,-3,-19,-16,0,21,-15,-1,-4,-4,8,-10,18,5,-2,-20,-6,-8,8,-8,21,0,-16,-19,6,17,-4,-22,24,-13,4,-8,4,-27,14,8,5,-11,0,-10,4,1,21,16,1,0,6,-23,-5,-10,-25,-17,16,-12,15,-11,9,-2,29,13,3,21,2,-34,-1,-11,1,-14,13,-1,-19,-7,-3,-9,-14,-14,-5,17,22,-24,17,12,-12,-23,0,-3,-8,-3,-3,5,-9,-24,-16,7,-19,5,-7,5,-2,-11,-8,1,-10,17,18,4,6,-6,7,9,-12,20,-10,-18,6,-2,4,0,-15,-2,0,15,6,-8,-20,6,-4,-3,-7,-5,-10,0,-4,-19,-10,-22,4,-2,20,7,-4,-15,-2,-7,-1,6,8,1,-15,-8,-17,-9,-9,-1,4,-3,7,-9,8,-7,-11,2,-9,-4,-5,-17,4,15,-2,24,21,10,-1,-2,-13,9,7,-4,-24,-25,-17,6,12,21,6,13,-18,8,1,-6,-9,8,-26,-14,-9,-28,6,22,19,4,-6,13,-17,5,-11,12,-7,-21,-2,-21,-5,-7,21,-3,-17,-11,-13,1,-15,2,-6,-22,-1,-8,-7,-1,8,-6,14,-3,-17,-2,-10,18,9,-6,-15,-15,3,-5,-17,1,3,-10,10,-7,-4,27,-1,-1,22,16,4,4,9,-13,-3,3,7,-6,-13,-43,0,3,21,-10,-3,-2,13,2,-11,-12,2,-11,-19,-12,-5,-10,-18,15,11,-6,-10,-7,-4,-17,8,14,-4,-4,-16,-10,-26,-19,-11,-9,-8,15,11,-11,-5,-19,-4,9,4,8,10,8,14,-10,4,16,2,17,13,-13,-2,2,18,12,1,6,3,10,18,4,-14,8,-2,13,5,-3,-9,-20,37,-16,-19,18,2,-15,-21,5,-1,-9,3,-12,-11,-2,16,-2,1,-12,-6,-3,-3,-27,-10,-16,16,22,-13,22,16,-17,-8,-23,-1,7,-15,9,-6,5,-22,-6,15,3,-7,-1,26,9,-3,-6,-5,8,4,8,-11,-5,2,-14,7,7,15,-6,19,14,9,-5,8,9,0,2,11,-4,15,-8,-4,4,-4,-4,-8,-5,-5,-4,-20,-9,-5,-40,-40,-20,-3,60,-16,-24,-3,-25,-23,-20,-4,4,-10,-5,-1,2,-17,-18,-19,35,25,-32,4,20,-6,-25,-25,-10,2,-2,2,2,1,8,-25,-1,12,-6,-15,11,-7,-18,-5,11,10,-10,19,-8,7,-13,-6,-13,-1,-8,1,0,-23,1,5,5,3,8,6,-6,1,-7,15,-7,-8,1,-1,-2,-9,-2,-6,0,-25,-4,-7,-13,-3,-4,-13,68,-31,-6,-7,-27,-10,7,-18,12,-1,12,-11,16,-12,20,-7,-4,-9,7,14,-14,-10,3,-10,-9,4,15,-22,3,-2,-1,-25,-26,0,8,-12,-19,-15,1,7,12,3,-21,9,-3,3,6,-16,-11,-1,-8,0,-4,-2,1,-2,9,1,-2,-8,6,-12,-12,-4,-7,0,6,-10,7,-6,5,2,6,15,-6,-2,-7,-8,-7,-26,5,-23,2,11,-25,-15,5,-26,8,-8,-10,5,3,4,22,-7,-30,0,16,10,-16,5,-7,-13,-8,-8,-2,-7,17,9,14,2,-28,6,-2,0,16,8,9,5,-10,3,-7,1,9,-2,14,28,-11,-2,-6,7,19,6,-7,8,-2,14,9,-14,5,-6,-8,22,-12,5,1,-4,6,14,4,3,1,18,10,-6,-8,-24,-5,-2,-4,-5,-15,-4,-5,-1,-7,-14,-11,15,7,2,-2,-7,2,-3,13,3,-12,-11,-1,10,-9,-28,2,12,-18,-3,-12,0,-4,-17,-6,-5,14,2,-16,-1,-19,-7,2,-16,-8,6,-4,14,-8,-7,-15,-6,5,36,-8,1,-20,11,5,1,-2,9,-1,-5,6,-21,-1,-7,9,16,-5,13,1,1,-14,-17,9,23,-10,14,-6,-4,-13,-9,-16,-21,-13,15,-21,-3,-19,3,25,8,-14,9,1,-9,-12,3,8,-3,-8,23,-5,-13,-16,-11,-6,-14,-15,-10,12,-13,-3,-10,19,-9,-18,-11,-9,-8,-7,-9,-12,-3,-10,-2,-22,-6,4,3,-10,3,-4,-1,-23,6,-2,-7,14,-6,14,10,-17,-13,-13,-13,-7,-11,-4,-6,-5,8,-12,26,-22,0,-9,9,-10,-27,-13,-4,3,0,11,-11,-1,25,0,24,-2,-5,-19,27,13,-15,-11,1,38,5,-3,8,-8,5,-14,2,-19,-6,0,-8,39,-10,-13,11,2,19,-11,26,-18,-12,0,4,-20,-4,-10,-16,-10,-17,9,-6,-3,-7,-1,-4,-19,0,-1,15,4,9,8,5,-2,-2,-12,-3,-9,-14,-4,-4,0,-9,-3,4,-7,-20,-5,12,5,-13,10,-3,8,2,24,-8,-10,-6,6,-20,11,-15,-9,21,1,-27,27,-1,-12,-17,10,-1,-10,-4,16,-7,9,2,22,-3,1,18,10,24,4,-1,-8,1,15,-7,-9,-13,-4,1,10,-8,-8,-3,12,3,-9,1,-3,-11,13,0,15,2,3,-6,0,2,-1,11,22,13,-13,-25,21,-1,-7,13,3,-9,7,-15,5,-29,-4,-37,-7,-18,-2,11,-2,17,15,-13,10,-18,4,-18,-8,-6,11,-1,-2,-17,2,10,-6,-21,2,-11,1,17,-4,-12,-12,-4,5,16,-9,18,4,1,8,6,-7,-6,-7,6,7,4,-1,-1,2,1,6,20,10,-26,2,-5,-3,29,-4,12,7,11,5,17,7,0,-9,-13,2,0,-11,-10,-16,-15,-1,9,-5,13,3,16,1,13,-1,-1,8,10,4,-12,-13,6,5,9,-11,-14,8,-3,12,9,2,-12,8,3,-2,-9,-12,-11,-2,-9,18,-22,11,-10,5,1,4,-10,-20,8,-1,-13,1,-10,-4,-7,-6,-12,4,-5,-12,12,-13,-25,21,-10,-15,9,-5,20,-2,14,-19,-9,7,-12,-2,-10,-5,-39,13,2,-2,-16,7,-15,-11,-6,-4,3,0,-15,-7,-7,-10,-11,-18,-5,-9,-21,-12,2,5,-9,6,11,-8,-9,5,-11,3,-4,-10,0,6,-21,5,8,19,4,-18,27,-25,-6,15,-4,-17,-23,-14,-7,-4,-10,13,-15,4,6,-5,1,-18,-8,-7,2,-10,-1,6,10,-1,-6,-22,3,2,5,-16,-11,-4,0,1,-10,-3,23,-14,-6,7,-30,3,20,-15,3,16,-22,5,-16,-7,-8,7,9,3,-20,-8,-14,4,4,-4,-15,22,-1,-11,-5,6,-5,4,9,12,12,7,-13,22,0,5,-3,17,11,6,-14,-5,0,-3,-12,-13,1,3,24,18,8,-19,13,-8,2,1,-20,-11,-1,26,26,-16,6,1,5,-8,-7,-2,1,17,-17,-33,8,16,-30,16,89,-24,13,8,-16,-3,8,16,14,15,-24,-14,3,-16,-9,4,-6,9,-1,9,1,-13,3,-4,-5,20,-9,5,16,-9,-10,0,-1,16,5,5,-5,-19,-8,-4,-8,11,7,14,39,-9,14,-13,-14,-5,12,-1,13,-5,2,-16,6,-10,-14,23,-17,1,3,-2,-18,-13,-8,-20,18,-2,-19,16,-1,5,-12,0,0,24,-19,-26,11,0,-12,8,-3,-13,-9,0,8,-13,3,10,15,-3,12,2,-3,-2,19,3,-9,15,2,4,-4,-3,2,4,-11,4,-2,1,-5,-5,7,-6,-1,4,-1,-2,-8,-10,-14,-6,1,-8,11,-10,-9,-17,1,-3,-16,-8,0,15,4,-13,4,6,-23,8,3,9,-19,-6,-6,1,-9,1,-11,11,4,-7,-3,-3,-6,6,-14,18,-6,-1,0,-3,-4,4,4,-6,-12,8,6,-17,0,-8,-5,-3,-2,-15,-6,-8,8,4,-4,-20,6,-5,5,0,0,-15,-6,-1,-10,-7,-12,-10,15,-7,-23,-36,-5,-9,19,19,-5,-14,-13,-11,21,-15,-21,-21,-16,6,5,0,-10,2,11,16,-4,-16,-11,-1,6,-5,-10,-2,-15,-11,18,2,5,1,-3,5,-1,-6,2,9,0,-17,7,-16,6,-16,-15,6,20,2,-2,-17,-2,12,-9,1,11,-28,-4,4,-11,7,-8,-4,-2,1,-2,-7,1,11,4,0,-4,1,-14,-3,13,4,-9,-23,17,-10,-5,-23,1,4,-8,3,2,0,-2,9,16,1,20,-12,8,-11,-2,1,-3,6,-8,-8,12,-13,4,-5,5,4,3,-10,7,-4,-2,10,12,10,-4,0,34,-7,17,7,15,0,-9,16,0,-8,-12,-2,-6,-7,-7,23,-8,-25,-19,15,-33,-5,3,6,4,-9,1,-11,-5,-6,-2,11,-8,-4,-31,11,0,-16,-1,30,-7,-10,-9,-22,-15,-9,1,-2,-5,30,-23,13,1,2,15,5,-1,4,-17,-11,2,7,-9,10,-2,2,-5,-9,-11,-17,-2,-1,-2,14,-2,-7,-6,-4,-12,3,16,-1,-1,2,-1,-17,9,-24,4,-12,-22,1,-5,-28,-29,18,-12,9,-11,7,-25,3,-1,-28,-3,-13,-7,-12,1,-22,-11,-7,-15,1,-24,13,-9,-19,13,20,-18,-13,1,-22,-9,-22,-4,-32,-22,45,-9,14,-6,-3,-5,31,-4,-13,-12,-24,-1,-6,9,0,-11,-9,-1,7,-2,-3,-5,15,-1,-8,-13,-16,-3,0,-3,-6,-5,-6,-8,-8,-13,-9,31,-8,11,-8,-16,5,-11,-4,7,28,23,13,16,26,-22,11,6,-13,-1,-5,6,-8,-2,-15,-7,-8,16,10,-4,4,-24,3,15,-23,7,-9,22,-5,7,0,18,-24,-12,12,-4,7,-4,4,1,-23,3,-12,-5,-6,0,-1,31,-16,10,0,7,11,19,-18,-4,0,10,-4,-19,-2,-18,6,7,16,3,-9,-5,10,3,0,-10,18,2,8,-10,-13,-15,-6,-2,1,8,6,0,-2,-3,-10,23,6,-5,-2,-1,2,23,0,2,-15,-9,-3,-5,10,-20,4,-4,-21,5,-17,34,17,-10,-2,-5,2,-6,6,-3,2,-9,-9,1,-14,-7,-21,-7,-9,-6,4,-15,-6,10,-10,10,7,11,-26,-12,-10,9,-24,4,-20,10,7,7,13,24,8,-3,17,-14,11,-2,1,-19,9,-16,-8,-6,-9,-10,-8,-4,-1,-8,-2,8,-3,12,26,2,7,-5,-11,-3,-12,-6,-2,-14,9,-4,-1,4,-1,1,-2,0,-3,11,-9,-28,6,-10,-1,-20,3,-6,0,10,-9,-23,-20,-11,2,-11,-12,-5,-11,-26,3,17,-30,-2,-3,9,13,-23,-8,4,-9,-8,-11,-1,2,-12,0,16,-12,0,1,-12,-15,-13,-13,-28,14,9,-19,-16,0,-5,-12,2,-7,-1,-7,5,13,27,7,9,20,-27,-22,-7,-7,-23,-17,1,-2,9,5,-6,9,30,29,-10,19,-20,11,-19,-9,-4,-20,-17,27,-5,20,4,4,-5,13,-17,19,-30,-3,-23,-2,13,1,-6,3,-15,-29,5,-13,-18,30,21,34,-15,0,-12,40,12,1,-13,-11,-4,-20,-8,0,-8,-11,2,-8,-4,-10,10,-2,-6,-14,3,-9,0,-5,-4,0,-20,-29,-12,6,0,-1,10,-4,-10,-16,22,-14,3,3,-4,19,11,0,-13,34,-14,1,-4,-7,-15,-18,-8,4,-7,12,18,19,2,5,-6,11,0,-5,-13,-14,-6,-1,-4,-6,-7,-9,3,1,-4,23,-6,21,6,-1,2,10,-1,7,-9,3,6,-3,-10,13,29,-1,10,-12,8,13,-15,2,1,15,1,-3,-8,-12,-20,-15,-19,-11,8,-9,-9,19,-6,3,-4,-21,-13,8,-12,-5,-9,-6,-7,-7,15,17,-13,10,-4,-8,-22,-8,10,8,-7,13,20,16,11,2,1,-10,5,-5,-13,-14,-5,-9,-3,-5,-15,8,7,5,12,11,6,-5,-3,0,10,4,-14,6,3,3,-7,8,-7,-9,-19,-13,-13,-4,-4,-7,-4,1,-11,-8,3,22,11,-4,-3,26,-29,-18,3,-7,2,14,5,2,4,9,6,-6,3,3,4,-14,27,21,-13,4,2,6,10,-3,22,9,-5,-16,18,-1,-18,-17,22,4,-14,5,20,10,-10,-1,27,-10,-18,7,5,-7,8,2,-3,6,-7,-5,-3,10,3,-10,-13,12,5,-3,-1,3,7,6,-7,-11,-9,0,4,-8,-16,-2,5,-15,-30,-2,0,-14,2,2,-16,-23,5,3,-3,-8,-27,-13,-11,-11,-8,-6,-14,-31,6,-12,11,0,24,13,-2,-2,-7,-23,-23,9,3,-16,-20,-11,-31,-9,22,0,8,-5,6,-19,-14,-2,7,-4,-13,-8,-15,-7,-12,-17,28,-8,-8,-4,-8,-10,-15,-11,-3,4,20,-18,-4,-11,1,-9,-11,-31,0,-11,11,28,8,-5,-5,1,15,7,4,-2,21,19,-18,-22,8,9,-2,14,11,-1,5,-7,7,1,-2,-10,24,-12,-3,-19,11,21,-1,15,27,-7,-20,1,-15,-6,-13,-10,-2,-13,18,1,-5,-7,2,-5,0,-17,8,9,-8,12,1,-8,-5,-13,8,-2,2,3,-6,2,4,-12,-12,-1,7,7,-2,5,9,3,14,-9,-12,4,-12,-16,1,10,-3,10,-21,-9,-8,5,6,2,1,-10,2,2,-2,12,-20,2,6,-7,0,14,-7,-4,13,-13,2,-10,5,14,-1,-6,8,-12,-22,-11,-12,-15,-5,-17,-14,-8,18,9,-21,1,-9,-3,-13,-17,-3,-12,4,-17,5,5,19,-12,2,1,-1,-2,-7,3,-16,4,3,-8,-4,21,1,6,16,-28,7,0,-18,17,-17,-2,-2,0,-10,5,17,-16,-9,16,-9,-1,-3,-5,-4,5,3,19,5,16,11,-10,17,-8,8,-5,5,-4,-1,-14,12,-20,27,2,-6,0,-20,0,15,5,-4,-28,-18,1,10,2,-5,-12,9,-13,-3,-12,-15,9,25,-16,4,-3,-4,-12,-3,-23,-2,-12,3,-2,16,8,-7,0,-5,8,14,-7,13,-21,-2,-22,5,-5,0,-11,-15,-7,14,-30,25,6,1,25,4,-15,3,-7,-9,-5,15,-12,10,-1,6,-9,9,-2,17,7,4,-24,2,11,-11,-23,4,4,-8,-14,-13,35,-7,-15,-12,-6,3,-23,7,13,-4,-3,15,-1,-9,-7,-3,19,-12,-13,4,-9,-1,-18,5,-20,6,-1,4,3,-4,0,0,-27,-16,6,-3,-4,-7,0,2,-19,16,-1,-2,5,-5,-7,13,-15,7,10,-28,16,1,17,9,-4,-6,4,-7,-6,11,-18,-18,-13,13,10,-16,23,-11,4,2,11,-24,-8,5,-16,15,3,-22,2,-9,-10,-18,-16,-24,0,0,17,7,-12,8,-6,8,14,-7,15,14,-18,12,-19,-5,-4,4,-9,15,-15,4,14,-7,17,1,-4,11,15,8,-11,9,-12,-8,13,1,-13,9,8,3,3,-3,-25,-21,5,3,13,16,4,3,-16,28,-11,-11,5,2,-37,-13,-2,-1,42,-16,28,6,-11,-7,-1,-5,-2,-10,-15,21,2,6,-4,-4,-7,-25,-20,-41,9,-18,-9,22,7,-10,0,-2,15,-18,-8,39,-8,19,-25,17,-4,-5,-6,5,6,-12,9,-2,-28,-11,-17,11,8,-2,-13,0,-15,0,-13,7,-6,10,4,9,7,0,-7,6,-20,1,-18,2,9,2,-20,-3,-12,-16,14,-12,-16,-6,21,-7,-11,26,-16,16,-1,-10,0,-24,-7,-11,-17,-27,-6,3,-21,-15,-21,-4,-22,-34,-1,-27,-17,-13,2,0,3,-8,-11,8,7,11,8,9,-5,3,-26,13,-3,9,28,-13,8,15,-15,0,-14,-19,0,5,11,15,-3,8,-13,-9,-5,-7,-11,-11,6,-7,3,2,-4,5,-18,13,7,17,1,-16,-4,-4,5,-18,-27,16,19,9,9,9,7,2,0,9,4,-29,-15,4,-11,-14,8,1,9,-24,-2,-6,-33,-34,11,-8,6,-1,3,22,-11,-13,28,0,11,-19,16,4,1,5,-25,-8,14,14,2,-9,6,6,-2,4,-9,2,-6,5,27,6,-3,4,1,-8,14,-8,-3,-17,-10,-13,-4,-6,-14,-11,8,-20,-4,-5,29,-13,33,-3,-26,-3,-8,-14,-10,-24,12,-19,-8,1,12,1,26,16,2,-21,19,4,0,6,-7,-5,-2,2,3,5,7,-10,-23,8,-23,-3,-12,-3,5,-6,3,6,-4,16,5,1,-20,-13,-15,-27,14,-3,-1,-6,-4,1,25,21,-5,-2,-6,-3,0,19,8,0,17,4,-26,-13,-9,-11,8,-2,-7,-12,-2,-15,9,6,15,-4,23,5,-10,18,-6,2,-10,-7,-1,3,-9,-5,2,9,4,-3,-24,-9,-17,14,13,23,-15,5,3,-8,-5,-2,-1,-10,-25,-17,-18,14,-21,-17,7,-3,-6,9,-6,-9,2,-5,-4,-13,-13,-11,-3,-6,-9,-3,1,18,2,0,4,-3,-15,-12,3,-6,1,6,6,4,-19,16,-2,-4,26,7,-20,26,-20,-13,36,-4,-9,8,5,-9,13,9,38,-5,-1,17,-21,9,-6,0,-4,7,-21,9,-5,-9,-7,-6,31,-6,2,16,-2,-1,-15,-29,4,18,8,-8,2,10,0,-15,5,-18,-12,-7,-24,-11,-24,0,-13,2,10,8,7,-2,-6,2,11,13,-1,0,-11,-11,-8,-8,-17,-12,-17,40,-2,-16,-20,-3,16,-21,-16,-12,-3,11,-11,-20,-8,1,-5,-8,-25,-27,11,8,-20,-4,-17,8,19,-14,-1,9,-5,7,-13,-5,7,-8,2,-9,-10,-19,18,-1,31,-16,-5,-8,11,16,6,-22,-2,15,-14,-10,5,-7,-7,-13,-2,-5,-3,12,-11,15,17,-19,9,9,12,-27,7,-3,-15,-20,-18,-12,-7,-12,-18,-29,-21,-4,-21,-9,-13,-3,26,-12,-6,0,3,34,4,-4,-4,-12,-9,-8,2,-34,1,-14,-26,13,1,15,18,9,17,25,-23,-8,-17,-5,3,3,9,-11,-18,1,6,2,2,-1,2,3,-13,0,7,9,14,8,-4,8,5,-10,-5,-4,-1,9,9,19,5,18,9,14,17,0,3,19,-10,-7,-16,-22,-15,-2,-8,8,10,-16,-10,2,-16,-23,-10,-28,6,0,-18,-15,5,3,4,12,1,4,2,4,-13,-14,0,-7,-1,3,-15,-13,2,-11,-9,-7,1,5,-3,0,-12,15,-2,-10,14,-3,-21,-2,17,-3,-13,1,-22,2,4,14,1,-1,25,-10,-20,1,35,3,-11,2,-2,2,-4,-17,-18,-6,32,-11,-9,-13,-13,-2,24,2,-7,-1,5,15,-1,-10,-15,-18,-17,-16,19,-16,7,19,-11,-13,7,9,1,7,-2,1,6,17,-14,-9,15,-13,5,20,2,-6,-1,-7,-9,-28,-13,0,-2,10,-17,1,4,-12,15,16,-16,13,-6,-9,4,-4,4,6,-7,-3,-3,0,3,-19,-1,19,-7,16,4,0,-4,15,1,-16,3,9,13,-3,-11,-19,0,1,-15,18,-15,-9,0,3,-22,8,13,-24,-4,-10,-8,10,25,-2,9,-11,3,22,9,-9,-1,16,9,7,-7,1,-7,11,-17,-14,-14,-12,-15,-2,-1,-19,0,-17,7,-9,-23,29,4,-9,0,4,-15,-29,0,10,-17,-2,9,-12,3,-12,-9,7,34,-1,24,30,-20,-1,17,2,-18,9,-11,-14,2,11,9,8,12,6,-3,0,-28,-5,-16,-13,-3,1,-19,-5,15,-8,-4,-20,-8,7,19,11,-5,11,5,9,-7,-16,-21,11,-20,-11,-9,-29,-2,12,-8,-17,6,0,-1,-9,3,-23,-8,-19,-17,-16,4,10,7,22,-13,-26,-3,-13,-16,-11,-6,-19,16,-4,2,5,3,10,8,3,0,-2,-20,-14,4,3,-21,-6,11,5,-13,8,3,-9,-9,17,-3,-1,-5,-22,-3,-10,-3,1,-1,-8,-3,0,3,7,2,-1,20,-6,-14,11,-14,3,6,-8,-5,-7,-10,4,-14,-10,-4,-4,-18,16,-7,3,7,-8,-2,-2,-23,7,-14,-12,11,1,-6,-6,1,11,13,5,-4,6,-4,-8,-8,12,-9,1,4,-20,-21,2,15,-6,23,9,2,7,-5,-6,14,17,8,1,-10,-9,-22,3,13,-3,9,-3,-7,10,-4,-1,8,-7,-32,29,-13,-20,2,0,-4,-2,4,-15,16,9,19,6,-9,-17,4,36,-11,4,17,29,-10,-24,-4,24,6,19,4,-19,11,-4,0,-20,-17,-10,-14,3,-17,-5,-1,6,-5,22,-11,8,-5,-4,-18,-13,-12,-4,18,-13,-14,-9,-6,15,1,7,-8,25,-10,-10,1,5,7,-3,-2,-24,-2,-6,8,7,16,0,-11,5,12,-18,-33,-34,1,-13,-11,3,19,6,-4,-13,11,-5,-6,12,-5,-13,-5,-9,13,4,8,24,-8,-17,-15,1,-13,-17,-6,-19,9,-12,-3,-13,-1,4,-24,6,4,-5,1,2,-2,-34,4,-18,-3,-14,-7,-14,7,-19,-6,-3,-6,-2,12,8,-15,-14,3,-1,1,-2,-3,12,12,-6,-25,-20,-4,-4,10,-7,-21,-20,-2,-14,21,14,-3,-29,5,-11,-18,-18,5,4,-4,13,-19,-20,-18,48,-5,3,9,-11,23,0,-23,-14,-22,3,-30,4,-24,-21,-16,1,1,11,2,-4,10,5,-21,-25,18,14,-27,-3,-11,-4,-20,10,-10,19,4,-5,17,4,-2,22,11,0,-5,-4,-9,-8,-4,22,1,29,0,23,18,-2,-7,0,-11,-8,-12,1,7,-6,8,3,-15,19,-7,-11,-19,-11,-6,-23,-14,7,-15,-5,-23,-7,-22,-2,-4,12,12,-9,-14,-5,-12,-5,-9,15,-18,-8,-16,-9,-20,-15,-18,-7,5,-11,-3,-7,9,-1,8,-2,-18,-4,-16,4,11,-8,-11,-10,9,-12,-12,14,-5,5,-1,-1,8,-6,4,-13,-13,9,-2,6,15,-7,-5,3,4,-1,-6,-7,0,5,1,6,3,16,-8,27,-12,8,1,-6,0,-10,-8,10,1,2,-11,-2,2,-9,-3,6,1,15,2,-16,-15,-1,-7,7,-14,8,-6,-11,-15,-8,-12,-6,-5,4,3,-13,7,-8,21,7,-4,4,6,15,16,-14,3,1,16,-10,-10,2,-7,7,10,7,14,-3,13,4,8,-7,18,9,13,12,-2,-5,-7,-5,-2,-9,-12,8,11,-14,0,-15,6,4,-2,11,-2,-5,-3,-4,-27,-4,14,-8,5,-20,9,6,-7,-1,-1,22,-1,-11,13,-10,-23,-1,1,-11,7,-21,10,8,-11,-8,-12,24,2,-18,-10,-12,0,-9,-13,1,-21,-16,-14,4,-4,-17,-10,-7,-9,-7,-6,7,6,-3,-8,0,-5,-7,0,9,12,1,-4,8,-7,-2,-5,21,0,3,-6,15,-6,-14,-6,5,-3,17,-10,13,1,-5,11,14,5,-13,17,1,11,8,4,9,-1,-10,-7,17,-3,-19,11,6,4,-7,31,-7,-13,4,1,5,12,-10,-27,2,18,-25,0,-13,-12,-6,10,-10,-8,10,-8,17,-5,-21,-11,-13,0,-1,5,-5,20,-1,12,-8,-13,0,1,0,14,-14,9,0,1,-18,-2,6,-3,-13,7,18,-8,7,28,3,18,15,-1,-12,9,-10,8,3,12,-10,-7,-3,-12,2,-12,13,-12,5,-6,8,-10,-12,4,-18,-2,-7,3,3,-19,7,-17,-12,-23,10,-20,-19,18,23,8,-31,-15,19,-12,-27,2,-6,-22,-23,-16,-6,13,-12,-7,34,11,-25,15,15,-2,-6,5,-11,-11,-13,-9,-19,13,-1,12,12,6,-27,-3,-12,-15,-7,24,6,8,0,-11,-21,8,-6,-13,-9,-7,-16,-13,12,-14,3,-17,3,9,-13,9,-2,2,-9,-17,-6,0,-5,-16,9,-3,14,-4,9,3,-20,-7,17,-6,-22,13,-2,-6,-9,-8,21,-10,-10,-3,16,-10,-13,2,2,8,-11,-7,0,-11,-14,-2,13,-3,-7,2,14,-22,-15,4,1,5,3,6,2,-7,-10,-4,-5,-16,-16,11,-6,-5,-10,-24,1,-14,8,9,-23,9,-10,-12,-7,0,3,-8,2,13,10,-12,4,-19,-1,18,-8,9,-5,-5,-1,2,5,25,9,17,8,-11,15,-4,0,3,0,13,-1,-1,-12,-16,-11,-10,17,-2,5,11,0,12,-11,-10,-4,12,0,11,5,-1,-11,9,9,-15,1,-11,1,5,0,-15,0,14,2,4,-1,-7,-7,29,8,-15,10,0,-14,3,8,-7,12,-3,-24,3,10,0,-21,-21,-13,-17,-33,-30,22,18,-6,-7,13,-29,-33,-11,3,-6,-17,-13,-12,-18,-29,-23,33,13,-4,-16,31,17,-12,8,31,15,-9,-3,12,-17,-21,-19,4,-10,6,3,-3,20,16,10,-4,5,5,14,4,-9,6,-14,-10,-5,4,5,-29,-7,-3,-2,-17,-20,1,-13,9,-9,24,0,-7,15,1,-5,23,-1,-12,17,9,-19,-7,-1,-4,-18,-27,-7,2,9,-5,-8,2,-1,-5,18,1,-23,-1,-9,-5,-10,5,-7,5,-15,3,-20,-15,5,-14,26,-7,-9,-8,-11,-12,-15,-1,-2,9,-8,12,-11,-17,6,-12,-8,-12,5,12,7,-16,-6,-6,7,-6,6,12,22,-3,0,-17,-10,8,-9,18,2,6,7,4,-8,-15,16,-5,-2,15,14,-9,3,13,-5,2,15,-7,-10,5,-4,-8,-6,-2,-5,-7,2,19,12,5,-7,-6,3,10,-11,3,15,-16,7,-2,-1,-14,-1,-4,17,10,4,-20,-2,2,-13,-15,-11,-33,-9,-12,-13,-7,7,13,-14,-13,16,3,-9,-3,12,-3,-6,-10,6,-7,9,13,11,2,2,4,-11,-8,-16,-10,3,-8,18,-18,0,-4,14,0,-5,6,1,2,-16,-16,9,-11,-10,8,1,-3,-1,18,5,-23,8,8,2,1,-19,-4,1,9,-6,16,-4,6,-4,5,-7,0,-6,2,14,10,-2,-8,12,1,-30,14,12,-7,-11,-7,-8,-7,8,4,-23,-15,1,-10,1,-8,3,8,2,-13,8,17,7,-7,1,4,-9,1,-16,-23,-10,0,5,17,-2,-7,13,9,7,-2,-7,-3,15,4,-23,-16,-7,-6,-16,-15,14,0,-6,0,5,-11,12,-9,-2,-4,-5,-11,-3,-7,-12,0,-12,2,-12,4,15,-7,25,0,11,7,8,12,23,15,-18,2,-4,5,-16,9,-3,-13,0,-7,-14,-19,16,19,7,5,7,-3,-2,-5,4,10,-3,-3,-15,9,-8,-7,5,-4,-2,-3,8,5,-4,0,-9,-4,18,11,-2,6,5,-11,1,-8,33,2,-12,1,-5,4,-7,24,19,-14,15,-17,-1,-7,4,-15,-8,-6,-4,-16,12,1,17,5,-2,-19,0,-4,-15,-13,-1,4,-9,-8,-7,-14,26,9,-2,6,-5,-16,-1,4,-23,-15,-22,-12,-13,-2,-8,4,-13,15,4,2,-11,-5,11,16,-10,-8,-13,-12,4,-7,-21,1,-8,10,17,-2,-9,24,11,13,-4,-8,1,4,-2,11,6,-4,6,-11,-7,-10,15,6,-11,-17,-6,1,11,-12,-3,-5,-15,12,12,-18,-8,-10,-3,-25,-16,-4,-19,2,-13,3,-8,-19,-5,12,9,-13,-8,-4,-1,-8,-2,1,-14,-2,-7,2,-14,-7,-19,16,-9,0,5,-13,-4,6,7,5,-6,3,-1,0,1,-14,-7,-1,-6,-3,20,3,6,10,-7,3,-7,11,8,3,-14,4,8,-4,6,-8,-4,-14,18,5,-2,-13,-3,-5,-13,-3,-10,-2,-5,12,-9,2,2,-10,10,-27,-2,12,-20,-6,-9,3,-9,-16,3,15,4,12,-3,-12,-5,-19,-20,-4,-2,-9,-19,-1,-27,-14,-10,2,-6,27,11,-20,3,-24,-1,2,-5,-1,-16,8,-15,-13,4,-5,2,-7,14,8,8,-25,-10,-8,2,-13,-14,3,5,9,-7,25,2,-19,-3,-9,-3,-27,-12,-18,-6,-16,-18,-1,-7,-3,-7,8,6,-12,7,-15,-1,-29,-7,-10,-7,-2,-4,6,-23,-10,9,27,13,-12,-8,-6,7,-27,-37,-8,15,-1,-10,15,-19,-6,-5,5,10,-14,-1,-4,13,-10,-30,-19,39,-12,-16,8,-19,11,-5,9,5,12,8,9,0,-15,-13,15,3,-2,-7,10,15,-4,-7,2,-3,14,-1,-9,-5,4,-6,-18,-14,3,6,-7,-5,-8,2,-10,1,19,-5,-31,-17,5,-3,3,4,19,10,-8,18,-1,23,10,8,20,-11,-12,-13,18,-11,-10,10,11,17,1,5,2,-9,7,-12,7,-19,2,2,26,-13,4,35,-1,15,-2,-20,4,-25,-4,-4,8,-18,-5,-29,-16,16,-23,8,1,16,-15,-2,24,-1,-1,-2,8,-24,-3,-11,-8,-11,-12,-5,3,0,-19,-11,8,1,-22,-21,4,-18,2,-7,-20,-24,-32,21,18,3,8,2,-17,3,5,-25,-2,-11,-13,8,-19,-5,-28,4,24,-3,-1,-19,-7,-10,-14,-9,9,-10,-6,-28,-16,-10,-8,1,3,1,3,-2,5,10,2,-8,-16,-16,-6,-10,-2,17,-5,14,-19,10,17,-6,-6,-14,8,16,15,-9,-16,5,-1,-4,-9,-3,8,0,5,-2,-3,-10,-10,1,10,-14,-8,-18,-1,-12,-15,-2,20,9,-6,0,-2,-1,3,-18,-12,-11,-18,-1,-27,9,1,-17,3,-6,13,4,-10,-12,-10,-10,0,6,2,-18,-6,1,0,-13,-7,7,4,5,-2,2,15,-8,27,5,-12,-14,3,5,4,-14,-14,10,-20,4,8,2,31,-10,8,-5,-3,-1,-12,-6,-17,-1,-9,8,14,-1,3,-4,4,-1,16,-5,-5,-4,10,-15,-14,10,11,15,12,1,-3,1,-21,9,15,0,-22,14,-5,2,-1,23,-17,8,18,-7,-12,7,-1,-8,6,6,12,14,-9,5,-5,13,12,6,-8,12,3,-8,27,1,-10,15,-5,2,-4,-11,-20,-21,1,-19,7,-3,-6,8,5,14,10,-9,-15,-6,-6,-3,-22,-18,14,-6,-16,8,4,29,-12,-14,-12,-20,0,3,5,-28,-12,18,-9,-14,1,-8,-15,-11,-34,-11,-23,-9,-12,-13,13,-17,-9,26,-6,-13,1,-9,12,-3,-16,-21,-16,10,-11,5,14,-13,-15,9,-2,-18,-21,-10,4,-21,-6,6,8,13,20,20,2,8,14,-8,0,13,9,0,7,1,-21,10,3,10,-17,2,-10,9,-12,-10,32,18,-10,11,-2,9,-7,-11,10,-3,5,-4,-14,16,-14,3,-12,17,1,-3,6,-3,-8,-29,5,0,3,-7,-4,11,-13,-18,-12,19,6,-4,7,-17,-15,-15,5,26,13,-2,-2,-1,0,16,5,5,-8,4,4,-6,-1,11,-3,-11,-2,8,-10,-9,-1,1,-11,-2,-6,-7,3,-14,-7,3,19,4,14,7,-18,-11,-5,-12,10,-8,-8,1,16,0,23,-26,12,13,-23,21,-10,-13,-13,2,3,6,3,1,-16,-20,20,-12,-5,4,4,-1,-6,10,-11,16,5,-2,-10,-1,15,-23,-7,4,-13,-2,18,-22,-19,-5,-9,6,-10,4,-20,-1,38,-5,-5,7,-24,-4,15,-20,-13,19,1,21,2,4,8,6,1,-10,-13,18,4,18,15,-1,-12,-7,-5,-12,7,-7,-1,1,10,-10,-8,5,3,14,-9,-7,-3,-11,1,-7,-11,3,-19,8,-1,-6,0,-10,7,-4,-4,-13,-3,3,-3,3,3,-7,-18,1,-8,-15,-1,-4,-3,-12,4,-5,-10,0,-3,-8,-5,0,4,11,-12,20,-5,9,-18,-31,6,-15,12,6,-21,6,-11,-9,33,9,5,18,6,-15,23,9,-28,-1,23,12,-6,-10,10,-15,19,22,-16,-2,-21,2,5,29,-32,11,0,9,-2,-2,4,-14,-1,7,-9,6,-24,15,16,-1,-24,0,-2,-5,-3,-2,34,8,3,8,2,-6,-2,-1,12,-33,8,16,11,-6,-2,-8,2,-13,13,2,2,8,-5,-3,-15,-34,-8,1,-6,-17,-5,-29,-13,-9,48,8,-12,-4,4,-7,3,-10,-13,18,-14,-9,-5,-13,-11,-2,-6,-2,-1,-13,-18,-7,-14,2,-30,9,-18,6,7,7,-6,-4,-2,-1,-1,0,8,-2,-17,-10,-7,-2,2,11,1,4,12,10,2,-6,7,-12,-5,-2,3,-20,4,8,-1,10,6,0,-12,-10,10,-17,12,4,13,-25,-13,-11,-1,17,-17,-10,13,-11,-3,0,-22,-6,-14,-13,-17,0,-6,2,14,20,4,-19,-8,-16,-2,-8,-28,-20,5,-10,-7,12,27,9,-8,-4,0,0,15,7,1,-13,-20,-21,1,-7,-4,-8,18,15,-10,-11,17,10,8,-4,6,10,-6,-3,-2,-19,2,-17,6,5,8,2,7,13,4,-14,-1,10,1,-6,0,-10,26,-18,1,6,-18,-8,-10,4,-18,-5,9,0,-8,-5,4,1,-3,17,-10,15,-15,-8,-1,-1,9,1,-16,-4,-18,10,-4,-32,-3,-4,-1,5,9,14,-5,-3,-10,1,-3,-10,-14,3,-1,2,-5,-11,-7,-5,-7,-4,-1,-3,-10,15,7,8,7,7,1,-12,19,-7,-5,10,13,9,13,-21,-6,-6,-15,-1,1,20,-21,-9,-18,1,9,-5,1,4,0,15,-5,-12,7,4,5,0,3,9,-15,-10,2,3,6,8,14,-15,3,-6,-17,-11,-15,24,-5,-11,-15,-14,-1,1,1,-1,-2,-23,-18,-4,-5,-5,-23,17,1,10,-20,-23,-7,-7,-18,-23,-1,0,-3,10,-3,10,-6,28,2,-8,7,-6,6,0,33,0,1,-12,-4,-5,-8,8,-6,18,-3,9,-10,14,-23,6,-2,11,6,7,-2,6,8,-2,-17,-11,-11,12,27,-13,-9,8,12,6,-4,-12,4,2,-14,-4,-5,0,-18,3,17,-15,-1,10,24,18,9,-1,17,6,-1,-6,-13,8,-26,14,27,-11,-2,-1,-3,-21,-2,-1,7,6,-20,-5,-20,-14,-14,-7,11,-9,-4,-30,20,-5,-7,-18,14,1,-3,21,-19,3,16,7,8,-25,-15,-22,4,-8,10,-17,-15,7,0,-8,8,-3,-12,-7,0,-5,-7,-11,17,3,14,-7,-13,-4,23,-12,-2,-13,-11,16,-8,-12,-2,12,10,12,-7,-18,-1,-13,20,-23,-5,-35,-9,12,-3,-23,-1,-6,0,7,1,13,-11,3,11,1,13,-12,-24,9,-12,2,11,-27,3,-7,0,3,-10,9,12,4,-13,7,-2,-12,15,1,5,-18,3,13,-7,-2,-17,-7,-9,19,-2,-1,-13,11,-18,-16,12,-12,5,11,-9,2,-4,-12,14,15,-9,-4,-10,13,-8,-14,12,-7,28,1,-14,-11,-7,0,9,3,-22,-9,1,12,-8,-26,-6,-22,8,19,-10,-4,12,9,-1,-13,1,6,-1,-5,-2,-8,13,-16,1,3,2,16,-2,2,-9,17,4,-7,-8,5,11,-8,-3,-12,-13,-4,29,4,1,-32,0,-19,3,-7,-15,2,-1,-12,-1,-8,2,-19,-6,22,15,-10,1,13,-13,-12,-2,16,3,-16,-4,-4,13,-14,-3,-2,9,4,-5,-6,-13,-6,-5,-8,-6,-22,0,1,-5,-14,-9,-3,16,3,5,-10,2,-4,0,-6,-1,-17,2,9,11,-15,-15,-8,-5,-16,-2,0,-1,23,15,-23,7,8,-1,-28,20,-11,-2,-25,15,-17,-6,6,19,-6,-13,-8,5,-19,-1,-28,0,-11,-6,2,15,-2,-15,10,28,10,0,5,4,-6,1,4,7,11,34,-27,-12,2,-11,-15,-2,3,2,-15,-9,-27,11,19,-2,1,6,-3,-26,-12,1,5,-18,-4,-7,1,-15,-14,9,6,-10,4,-7,-13,-12,-26,-6,14,2,6,-3,-10,-21,-19,-6,9,-6,-1,-26,-17,-17,12,-14,9,0,-5,-7,-15,8,7,-9,8,-7,30,-9,5,-15,-2,6,15,-3,12,2,7,4,6,10,11,7,29,-1,-6,-17,0,-11,3,-13,7,-9,1,-25,-10,21,23,2,-4,12,2,-11,-4,-1,-1,-15,-12,1,3,-11,-11,13,-1,-6,17,2,-4,-7,-8,-22,0,-12,-7,-9,-23,1,-14,6,32,12,11,-31,2,-24,13,-17,-25,-18,-4,-7,-21,3,1,-22,31,-12,-5,-21,22,-11,-10,18,4,7,3,7,6,9,-10,-2,-19,-22,-11,-10,13,2,-5,8,1,6,6,-8,3,-10,-3,-9,-9,-8,-11,-11,-2,1,4,-7,-8,-3,11,-1,15,-6,-4,11,0,0,6,0,3,1,-1,-12,-15,-7,-10,-4,7,3,-9,11,9,-9,9,4,7,-6,12,-1,-5,-16,-7,-1,-12,2,24,-4,11,11,1,-6,-2,-3,0,15,17,-19,21,-2,11,11,-9,16,-10,-10,2,-4,4,0,3,4,-6,-2,-6,5,4,9,-13,8,2,-7,9,-18,9,-7,-1,-2,1,-2,9,1,15,9,-4,11,6,6,-3,-10,5,6,-10,-21,-24,-6,-3,1,15,0,-6,2,-2,6,-5,-14,6,-9,-7,-17,-14,-2,-5,3,-21,3,-2,-10,-1,-15,-14,-5,0,-4,-13,-8,-5,-13,6,-7,-9,8,-15,14,-20,1,4,-20,-9,-18,21,17,1,6,-2,-8,-2,9,-22,8,-8,-14,-22,4,-15,-17,41,6,-24,4,-16,-6,-14,-3,-17,-21,-11,-9,27,17,0,-21,27,-12,-39,-4,-19,-6,-27,10,2,-7,-11,5,6,2,-1,-11,-9,6,-8,3,-5,-11,-11,14,0,-14,7,-14,-11,8,-8,3,-12,1,-6,4,8,-13,-13,11,-14,9,-1,-14,4,-10,-2,-19,-5,8,10,-8,15,-11,2,6,-17,13,-7,7,-14,-12,-11,-15,6,8,-2,-3,-9,9,8,7,-13,10,-5,25,4,1,-8,34,0,-9,-6,4,-23,-2,-27,-22,-4,-3,-22,-6,17,1,-6,-23,-13,4,-13,3,-17,2,-17,-5,11,-8,0,-9,-4,-5,-14,-2,-20,8,-21,8,6,1,-9,3,-18,-12,1,4,-9,-11,2,-23,-20,24,6,2,8,-4,1,-11,5,-7,-18,-8,-1,-4,10,-7,-25,-6,15,5,16,5,21,3,-10,1,-21,33,-3,5,10,25,-6,-10,9,22,-4,-5,-1,-13,10,20,6,-16,10,17,-2,2,-2,12,-15,-15,4,0,-9,-1,3,19,20,-8,-5,15,-6,17,-16,8,-2,-14,11,4,-6,3,-5,-1,13,-4,14,9,-10,3,-8,-5,-4,-7,2,13,-15,6,-3,-10,5,2,0,9,0,-13,4,5,-4,-20,8,10,9,-12,-15,-6,-12,-15,-13,-10,6,-1,4,-1,-1,-13,1,-1,-4,-14,5,2,4,23,2,-8,16,4,9,-9,-11,-9,2,8,-7,-6,-2,12,15,26,-2,-7,-1,-1,-10,10,-9,17,5,6,-10,-6,-6,15,20,30,20,-20,-3,8,-4,-11,-11,-5,-8,11,-4,-8,3,-5,1,11,-9,-5,-8,-7,12,-3,-5,-3,9,-11,-18,-3,-10,0,-13,15,-7,-16,-18,-20,-6,-2,13,-4,-3,-14,-20,15,-19,1,-20,-1,-13,-5,6,-11,-19,-23,15,18,-11,0,33,-3,-7,6,7,8,-5,7,-19,0,-12,-18,-2,-5,-8,0,9,2,-8,-7,5,-19,-15,-6,7,-3,19,-1,-14,-18,1,-7,-3,9,-2,-15,-10,-27,6,-5,19,22,23,8,-12,-9,-8,-4,-16,-10,-6,21,-6,-14,4,-8,4,28,1,2,-13,-11,-21,-16,-16,-22,-21,-6,-18,-19,-4,-1,-12,-5,-14,-11,18,7,-27,-16,0,-9,-2,-5,20,-10,-13,-7,2,-2,-17,8,-7,-12,-17,-6,-3,-5,-5,-10,7,-12,-14,-21,22,-29,28,28,0,0,-5,-6,-15,1,19,-4,-5,-21,7,-13,6,0,8,12,10,-4,-14,-8,-14,-16,-10,23,0,-11,1,-31,-9,-8,-1,-3,-4,-25,-12,7,-12,-15,-16,-12,19,-10,-15,-24,20,-2,-8,-21,-15,-4,6,-22,-18,-2,-10,9,16,16,-20,5,40,6,3,17,19,-12,5,-1,-7,-30,-35,5,-10,-7,-2,-1,1,-1,-28,14,19,-14,3,28,2,-14,-23,0,14,-9,-14,18,-8,-8,-18,-16,0,-5,12,8,-8,8,-8,0,33,3,-5,-14,-8,-32,-14,0,-13,-14,3,1,4,-2,-7,16,11,3,-2,-6,5,7,27,-8,-16,-17,-4,-3,12,-5,12,4,-20,5,8,6,0,-18,6,24,15,7,-2,-11,-13,1,2,13,-27,3,40,1,-14,-10,-19,-3,19,30,1,4,17,1,-12,3,2,-1,14,-6,4,-11,-9,0,-17,10,-8,19,10,3,2,-5,-7,4,1,11,0,-9,18,15,-6,15,-6,14,8,13,2,13,11,5,2,4,-5,-2,4,7,-2,-5,10,6,12,4,-8,-16,-10,-6,-3,15,-6,0,-16,-5,3,5,16,2,-10,21,-4,-2,14,-4,10,8,-8,0,-5,-19,9,11,-4,-4,3,16,-8,-6,18,-1,6,-5,0,11,-5,-4,-9,-5,2,10,-8,5,-18,-14,13,-5,24,0,2,5,-9,-1,-23,-7,-3,-12,-10,-10,4,8,12,12,7,-14,11,-20,-10,1,8,-11,1,19,4,-17,1,2,-11,-3,-11,-19,-12,-34,2,-1,-15,-9,-12,8,-2,0,-14,6,2,-6,-22,-24,15,-6,1,-2,-26,-2,-12,-8,20,-9,12,-4,-16,1,-13,-8,4,-5,4,17,-14,1,-7,-20,14,16,7,5,-17,8,14,2,-12,0,-2,-13,-14,0,-3,-4,1,18,12,-5,4,8,4,-4,22,0,-3,3,1,-8,3,-7,0,-5,8,-2,-12,-2,-14,-14,-6,-7,18,-1,-9,-1,-25,-13,-13,14,5,-6,-19,11,-4,-10,25,12,14,-7,2,18,-11,8,0,4,6,1,-11,8,0,1,0,18,-8,18,-11,-3,-2,-4,-9,12,-3,15,2,-2,5,1,-19,4,-15,-11,-14,5,-2,-6,-7,9,9,2,0,-5,1,-8,0,10,5,-5,19,-8,-7,10,-11,-8,6,15,5,-8,-19,8,-5,12,0,2,-4,-6,-6,6,-1,-8,-5,1,-8,-1,-4,4,36,-18,0,6,7,-9,-4,20,2,1,-13,14,4,0,1,-8,24,-4,5,5,-10,-23,4,17,-11,-1,0,1,-6,0,9,-6,-11,-15,-8,-9,2,13,-4,-8,-10,19,9,-13,10,1,-18,-12,5,10,-10,4,3,-6,-20,-8,-5,-2,-5,-5,12,8,5,-1,-5,5,-16,-1,-9,5,-13,-15,-8,-5,-16,-8,-19,-7,-12,-11,-5,20,3,2,14,-9,-2,-13,-10,-22,-9,-3,1,-8,3,14,-20,5,-9,-1,-27,-13,-10,-1,-21,12,-6,-9,1,-5,1,2,2,4,-15,1,-12,-9,-14,-2,-16,20,-21,-1,-6,21,-2,-11,20,7,-7,10,-9,7,4,17,10,1,5,9,4,3,15,-18,-13,-5,6,-1,-3,-1,-8,3,-13,-1,1,8,-13,3,-9,-13,-12,4,-22,5,28,17,22,0,-28,-22,-25,19,5,4,4,8,-20,9,-25,-12,-5,10,-1,-18,-38,-11,-13,17,-3,0,-5,28,-4,23,-9,13,8,11,-4,1,-32,-14,-21,8,-12,6,-8,40,-13,-8,-15,-17,-2,-3,-8,-3,-15,4,-10,14,-13,7,-17,-19,-19,-14,-16,-5,21,26,8,-11,1,-1,-9,-6,-20,-7,-22,-16,10,11,13,-15,-8,29,1,-22,2,-2,-21,-3,-18,0,1,-4,4,1,7,-2,-9,-28,5,-12,-28,-10,11,0,5,-16,1,-1,-7,-10,1,10,2,15,2,4,0,-12,-4,15,-17,4,-21,7,-10,11,12,-19,0,-8,-21,18,-15,6,-15,2,2,-2,6,8,-2,-5,19,-12,-8,-2,-9,-4,-8,-11,-10,-4,7,3,20,11,11,10,21,-6,-6,-10,-4,-5,-9,-3,-23,-10,2,4,-6,-7,5,1,-5,5,-9,-14,-2,-5,-21,3,5,-27,40,-10,17,5,-12,-23,-7,4,-24,-9,3,15,5,9,12,19,24,-6,16,6,13,5,0,-4,-6,-34,-19,6,-3,-7,-19,-11,15,10,13,1,17,-15,10,1,0,-6,-9,1,-10,-1,10,-19,-5,34,20,-20,51,-4,9,8,-4,-19,-32,-9,-10,-13,10,-6,-16,15,-12,-17,24,21,-13,9,-7,-20,-22,8,-2,-29,-9,6,9,-10,-1,-14,2,6,-27,-9,-20,-3,31,2,33,6,-7,-17,-1,3,3,11,8,16,-15,1,-16,8,-10,-3,1,1,3,-3,1,-6,1,5,-6,8,-16,-4,2,17,-7,16,-11,-2,-11,-6,-13,0,-14,-12,-16,-12,9,-7,-14,-10,-5,13,-11,10,10,-11,-11,7,-12,-11,-18,-21,-1,-7,3,-4,-35,1,-10,9,14,12,-2,-15,-9,-9,-2,-20,-7,-8,11,14,-17,9,10,4,-17,5,-13,10,-12,-2,-13,-8,0,-1,-28,8,-6,-13,-8,-1,3,3,9,13,-5,-6,-9,11,-2,12,-9,0,25,3,-12,14,-5,8,-14,-6,-7,-17,-11,-24,0,9,-5,-10,5,-5,-27,32,1,-2,-7,2,9,-12,-1,-11,6,1,40,-8,-8,-7,-16,-6,-13,-5,-1,-25,5,1,14,-21,3,-17,52,-17,-5,13,-19,-10,-17,-10,-5,-19,-8,-3,15,-3,-18,-9,-6,-24,17,8,-2,-6,-38,-9,-8,-5,11,-18,14,-7,-33,-25,20,8,5,23,5,0,-3,8,-10,18,4,4,-1,4,5,-12,7,2,2,15,4,3,-8,12,-5,-7,-11,-4,11,-8,-7,14,4,-4,-6,-7,11,-19,-21,13,-1,3,16,10,-3,-13,-7,4,-9,-5,13,9,-16,12,-7,-7,-13,-22,-9,-9,4,-27,-16,-11,-4,-2,-31,-29,-6,-8,-15,-10,-10,-2,5,-7,0,-20,-24,-13,1,5,2,-23,-9,-1,9,8,-3,14,0,-3,2,-7,23,-11,1,-2,17,-5,-2,16,10,-9,-12,13,-11,-17,-12,-16,5,9,4,-14,-17,-4,5,-7,-2,12,-3,13,3,0,-9,-2,-5,22,-3,-21,-7,5,6,-1,-16,5,-19,-5,-7,-2,20,-12,2,1,-7,6,1,-22,7,17,4,-18,0,5,10,-16,2,-15,1,-14,1,30,2,0,5,12,-2,-6,-6,15,9,-7,1,-3,15,-8,1,4,10,10,-6,2,0,-10,-8,7,1,-32,-13,-13,4,-16,-8,-4,1,-12,-12,-15,-13,4,-6,1,-1,-21,-9,-14,-15,-2,11,-20,5,-3,-3,-13,-1,-7,-8,-13,-6,8,4,1,7,3,-15,16,16,6,0,16,-9,-17,5,7,5,8,-5,-3,-6,-13,-11,13,7,-2,12,3,1,11,-1,9,-13,9,2,8,20,0,3,-2,3,13,-2,10,-15,3,-12,2,4,-25,-14,-1,14,-7,-5,9,-6,-9,-10,1,23,21,-9,-4,-13,-11,-3,-2,-4,-12,4,-5,-4,-2,-1,-13,11,-18,-19,4,-23,-7,-4,21,8,-13,-4,9,13,1,-4,-3,0,-16,6,-4,-19,7,7,0,0,-12,-10,-6,-7,-7,-2,-13,3,-1,3,-2,-15,5,10,0,10,8,9,-6,5,5,1,13,-11,8,-1,14,-3,-6,-1,-3,-4,0,-1,0,-4,-4,-3,6,11,-9,18,14,-24,-16,13,2,-12,-1,14,-12,8,9,-2,-4,12,-7,7,32,-3,-24,-18,-5,-9,-29,6,4,0,-14,-5,-22,24,21,32,6,-13,-4,-11,3,-18,8,1,-2,2,-5,23,-4,-7,27,-15,-17,-23,2,-22,-5,-13,30,12,-5,4,0,6,11,-7,-14,-13,2,-11,-19,-2,-9,5,19,-5,-7,-8,-2,-13,-11,-6,-8,4,-5,10,-2,15,-12,10,-9,-11,-4,-9,-3,4,-23,-9,4,3,-11,-21,-7,16,4,-4,11,-8,-13,8,-2,4,-14,28,-17,-14,3,-13,-10,0,32,10,1,2,-13,-6,-11,11,17,13,-12,-8,-9,23,25,23,-9,20,-10,17,4,-2,0,-22,-5,12,-9,5,-8,4,10,15,-12,13,-15,-5,5,21,-5,-10,-2,18,6,2,0,14,-3,10,-15,-9,-1,-11,-6,0,13,8,1,-15,23,-11,-2,-17,-16,18,27,5,0,-16,13,2,-5,-14,-18,-25,11,-23,6,13,-19,-16,7,-25,-15,19,-5,13,-8,15,21,-1,-23,-7,7,5,-7,-11,1,-11,-22,6,-3,-1,10,-7,-8,-12,-5,2,8,-7,-9,0,2,10,-11,-7,26,7,17,-1,-26,1,2,7,4,15,7,0,-6,9,9,-14,-3,-11,-11,-19,-8,24,16,-4,0,-6,11,-8,-17,-13,-14,-4,-3,-23,-9,-33,0,-12,1,-3,0,7,-3,2,-25,-12,6,17,2,-6,-5,1,23,-20,0,-10,-11,5,-24,-8,3,-29,4,-20,1,-2,-1,2,8,-12,3,-1,5,-14,-11,-14,8,-12,16,-5,-15,14,-10,20,2,-12,7,-12,-14,-12,-14,7,-8,6,6,-1,-4,8,-6,-7,-10,-3,10,-15,10,-4,26,-24,-4,-10,-22,-18,9,-10,3,-24,2,-13,5,-1,-4,-5,8,11,-3,-2,-8,14,-5,0,-6,-5,9,-23,1,-15,4,-16,-12,-7,2,10,-16,7,-9,-5,-13,-10,6,0,9,2,9,-4,4,-20,16,4,-11,19,-12,2,-1,-2,25,2,9,11,10,22,-20,-16,2,-3,-9,-6,-5,4,16,-7,4,8} + +#define CONV3_BIAS {18,36,-46,-45,64,8,13,-19,28,1,14,-57,23,20,-2,32,48,-11,85,73,-7,52,125,33,125,13,92,-72,89,-1,11,70} + +#define IP1_WT {38,-13,5,-20,15,-4,-3,13,36,-19,10,14,-18,-17,-11,15,25,-18,-16,-9,-9,-8,-4,21,-11,10,4,6,7,9,-14,-9,17,-6,1,8,18,5,14,12,0,2,9,-8,-3,15,-7,2,-18,-6,-26,20,-6,9,10,-2,12,11,-10,-7,18,-12,-12,41,18,6,11,-3,-1,2,11,24,1,22,9,6,4,33,-18,-12,-26,-22,7,3,-2,-8,-3,-8,19,-16,28,-18,1,2,16,-26,-30,-18,-12,-30,9,9,-7,13,7,12,-11,16,-2,-1,14,-10,15,11,4,-15,-5,-12,7,22,-15,-12,-7,1,22,1,-12,29,3,1,-3,-12,-5,-7,-1,22,20,-6,-20,25,3,5,1,2,-17,-2,-2,4,4,0,15,-19,6,-7,-20,11,-18,-26,14,1,0,-9,4,-8,11,-16,-1,15,-16,-7,17,-13,-10,1,2,8,14,-2,-16,32,-10,-10,12,-16,9,-11,-10,-15,3,9,-30,58,4,-20,6,-10,-6,11,0,-1,13,14,-14,0,-3,-12,-4,22,2,2,14,1,10,1,-12,-8,17,-12,-1,-10,-9,-9,-2,11,-28,-25,-6,-5,4,10,-3,11,6,16,13,-3,-6,5,35,-12,-1,5,26,-3,-29,2,-4,-6,-15,-6,-11,8,-8,-12,1,-13,-2,7,12,-16,7,-5,11,20,-6,-2,42,21,36,-4,-12,1,-4,25,6,0,-12,5,28,-5,1,5,-15,1,-2,1,-5,-4,-10,41,-14,9,-11,-23,0,33,0,-9,13,-9,-3,6,1,4,1,3,-9,4,2,-16,-2,21,-32,-9,6,-12,-2,3,-7,29,-8,-27,10,-3,-3,10,-20,-3,12,0,-4,-4,-11,7,-6,8,2,-11,6,7,-6,-13,-2,-4,17,-11,5,0,11,1,4,-6,-17,-9,-25,7,4,4,21,17,14,-5,4,-12,-17,5,46,-7,17,-10,22,0,-9,-13,-13,12,-4,1,-4,-17,-2,-7,-14,-14,-14,7,9,-11,-2,3,6,15,4,6,3,8,20,10,16,-4,-20,-10,25,7,-4,5,3,1,-2,-2,8,2,9,-2,-6,2,-5,-11,4,1,24,-10,-11,11,-17,-4,-5,-14,11,2,2,0,10,13,-31,9,-14,13,19,21,-29,-10,4,9,-33,3,9,0,-13,-16,-1,-3,-4,20,3,-2,12,-6,-38,-16,-17,-8,10,12,18,-10,-8,16,25,8,-4,-1,4,-12,-6,-8,-2,11,-10,2,-16,-11,40,-17,11,5,4,-21,-1,25,33,-5,12,-7,1,6,2,-4,5,-17,17,12,-18,3,6,-8,-9,33,-5,10,-22,-3,16,-3,-22,29,45,-5,-5,-19,11,13,-10,-12,-15,8,1,16,14,-3,-4,7,-9,-5,-6,1,2,5,-15,-32,-11,-9,8,-8,9,3,-18,-4,23,12,4,-14,36,3,-4,41,14,-3,-2,2,-3,12,4,-4,8,-15,-2,7,8,8,3,2,4,11,-1,10,-26,12,-7,11,-16,-1,28,-25,19,8,-5,-8,-3,-8,-4,16,-8,-14,-9,3,16,8,8,8,4,-12,3,-6,-12,3,22,-7,-21,-11,-14,-4,-1,7,-10,-3,6,13,-14,61,-10,-14,-15,-3,13,5,-30,-20,-15,-25,5,10,-9,12,8,-1,-7,5,-17,-1,-13,0,11,-6,60,5,0,-20,6,21,-22,6,-12,-9,1,-3,1,-19,-21,-7,-4,7,-15,-6,-9,11,-5,-5,12,-12,6,8,15,2,-6,-23,-23,0,-4,6,-8,-9,-21,31,-5,3,-5,1,5,-1,-7,-6,30,-14,-3,11,11,5,-4,0,15,-7,-8,-3,-4,2,-15,-4,-20,-7,13,-10,-15,-19,-25,-16,76,-15,17,26,2,7,-16,-17,-14,-1,-9,21,-4,-5,2,42,-6,2,-8,-6,6,6,-5,3,-10,-2,6,14,-12,0,4,22,26,-5,-12,-1,-4,28,19,2,11,-22,27,-20,-6,15,-9,1,-10,-9,4,-6,-5,4,0,2,5,-11,-9,-11,-6,16,22,-4,-3,2,1,-7,11,6,6,8,-13,-9,-16,7,1,7,-16,-15,-2,-3,11,3,-12,6,-17,-15,18,-5,11,8,-10,-8,22,5,-6,-4,-17,-10,-2,12,-16,2,-7,-5,12,4,-18,1,9,-14,-5,1,-4,13,-6,-2,11,-8,4,1,-8,-8,0,1,6,-4,23,4,-3,-7,1,20,-11,-8,1,-14,3,12,10,-6,-5,44,11,5,-2,-3,24,3,6,2,1,0,-13,7,2,13,-9,7,9,2,-14,2,27,-14,1,-10,3,1,23,-10,6,4,-5,12,11,-7,-3,-7,1,-11,-9,12,-21,7,-10,-9,-14,17,-2,-2,-4,2,24,-8,-12,-4,4,14,5,21,12,-7,0,-3,3,-12,0,2,5,-5,11,-4,6,-2,33,-10,-2,15,-6,-10,12,-10,5,6,7,-2,11,3,1,16,2,-11,-6,11,-10,-5,-3,6,-7,-27,5,1,-1,-2,-2,3,-18,0,4,-10,4,1,-3,-10,5,-7,13,-16,-15,22,2,8,-2,16,23,-11,19,-3,-12,-11,9,-11,-24,8,-17,-5,-3,-22,6,2,8,12,-17,10,4,-1,-6,0,-17,5,5,-1,-22,1,1,3,31,-7,6,-3,5,6,8,-4,-1,-11,11,-12,-10,31,-8,-2,-10,-9,28,2,-10,-8,-19,6,7,4,-16,17,-5,9,-17,-11,-3,13,15,-14,-5,10,-19,0,-2,7,-6,1,2,13,3,4,-14,-1,-14,-7,-11,46,18,2,6,-10,-18,55,14,-4,-1,3,7,-12,23,19,8,0,-12,9,-4,-11,-10,-21,7,9,4,-16,-2,-6,18,-14,-15,-9,-11,-10,-8,3,4,-21,3,-9,9,13,0,19,8,-12,-8,-30,1,6,6,9,-23,-1,3,-25,39,-27,11,-19,8,-12,7,17,0,10,-7,-5,-2,19,-3,-12,-20,9,4,18,4,4,10,-6,10,-20,1,6,-3,6,4,5,-7,-3,-6,-8,5,16,14,12,-20,2,-6,9,-14,-2,-26,2,12,12,-15,-16,14,6,3,-8,-5,-1,-4,0,-12,1,6,6,1,8,-4,-9,-13,-5,-16,42,-11,7,-8,-21,-2,-5,-13,-15,-11,-7,5,-11,15,32,-3,-10,6,-10,11,-8,10,19,-17,-28,-1,-14,-8,-12,-5,2,-12,3,31,5,-19,33,3,10,-9,-1,4,-15,1,12,0,-8,-20,2,2,-13,1,-5,11,0,-17,1,-8,5,4,3,15,27,4,-2,5,-36,2,-2,-16,0,12,-5,-3,6,31,-12,-14,0,-8,-1,-14,8,29,-8,-2,5,-3,1,-12,-4,10,12,-4,-8,19,-1,-15,-1,9,14,2,-16,-2,15,3,10,-11,-5,-2,2,9,2,-12,4,11,0,3,2,-10,-11,15,1,0,-23,3,-3,-23,0,-6,-12,-1,11,-12,-13,2,-4,-5,-3,17,0,0,0,9,-3,4,5,-9,-11,4,-5,7,-9,-1,-9,11,-7,-16,-3,-9,-7,-11,8,-2,-6,3,11,3,-4,-7,-14,1,12,-12,-1,-9,15,19,8,5,2,26,7,-19,-7,-17,-4,-7,-1,33,-15,1,-8,1,-4,-6,-5,-3,-14,10,-1,-2,12,6,8,-7,26,-6,-12,6,0,31,-9,19,-11,-2,14,-6,16,-1,1,5,6,-4,-13,4,11,-6,2,7,-6,-15,2,-3,7,-3,-13,2,-5,-6,6,4,-4,11,-2,32,-3,12,0,20,-1,-8,-1,-10,5,18,-37,-13,-5,16,-3,11,6,10,-3,-2,9,1,-17,1,-13,4,4,5,-6,2,1,11,-18,-7,-11,11,-2,-9,-3,7,0,-16,6,3,3,9,-9,1,26,-9,3,-6,-12,3,1,17,1,-5,4,2,3,-22,6,-18,-18,-17,-15,27,6,9,5,9,12,-9,-2,-13,-3,-12,10,0,-3,-8,-3,8,7,16,1,-9,38,14,-9,-8,0,-8,6,-11,-19,-3,-9,-18,13,5,-5,13,-4,-2,-8,-15,5,42,-14,-4,0,0,-3,12,-2,-5,5,18,-39,13,-6,12,7,13,6,8,0,7,2,-49,23,-15,-11,23,3,1,11,-1,-3,7,-1,-26,24,7,-2,-11,3,15,2,14,3,-5,21,-19,-17,4,-4,-16,-18,9,-11,25,1,5,-7,7,-2,-15,0,-5,6,10,-2,5,7,-12,-8,-4,10,16,0,-32,7,-7,-26,-24,20,-5,4,-6,2,-5,-4,-3,6,13,-17,10,14,-3,-11,-9,15,4,1,-11,-8,-10,0,20,18,19,-5,22,-11,23,-2,-8,5,9,11,2,-11,31,-14,0,-14,1,11,-6,28,30,-7,-7,9,14,-6,8,1,-5,22,17,-19,-18,-13,5,18,3,11,-1,3,3,-7,4,-11,-3,-9,-30,20,-18,14,8,11,-1,23,-13,5,-11,0,-8,-4,-5,-9,10,2,2,0,17,14,-21,25,-18,-2,-8,0,1,0,-1,-29,17,-4,-18,18,-10,7,9,3,-3,0,-5,23,18,8,9,9,17,-14,4,10,-10,3,-13,-4,-3,6,-9,21,-25,2,6,-2,-26,23,-9,1,20,8,9,-12,-2,3,-6,-2,-10,-6,5,-3,23,-7,14,-7,-14,3,-7,-4,-16,-6,13,-3,-5,-5,30,-6,7,7,6,5,-23,12,8,-18,-14,-6,23,-14,-5,4,-1,19,18,1,-6,6,-14,-2,9,21,5,5,-1,2,2,-8,4,-5,2,-8,-14,-1,-3,15,13,6,-10,0,3,1,5,-12,12,-6,10,-7,16,3,22,10,-6,25,-19,-2,-11,-15,8,-14,6,-9,10,-3,8,5,-2,-13,-10,-4,-5,0,-1,-5,-1,-16,-3,3,6,4,22,9,17,-2,-6,-16,25,1,4,4,23,-10,0,-2,-26,10,2,25,22,-1,0,1,-16,-5,-7,-10,-22,-14,10,-7,15,31,15,-17,-7,36,12,-22,-3,-7,10,8,-2,2,7,-4,8,2,-11,6,17,-15,2,-22,-33,-19,19,-23,-8,1,9,-10,10,2,4,5,-6,17,6,0,11,-8,-10,-18,-6,-2,21,3,-11,-1,4,6,2,17,15,-13,-1,7,27,-11,-1,-2,2,-9,2,5,3,2,-3,-3,3,18,12,-1,11,-7,24,-7,-5,-9,16,3,6,-5,8,7,1,-12,-2,15,9,-18,1,-1,-12,0,-5,5,9,-17,31,-4,-8,-10,-12,9,-2,9,4,-18,12,-11,-6,5,0,3,16,2,1,10,-16,-4,9,-6,-3,-2,9,-10,-16,12,5,9,-6,31,11,-2,-16,-12,10,3,1,-9,-8,10,4,-7,-6,-15,6,-10,4,17,-24,17,2,-33,9,-23,-1,-1,32,-5,16,-8,3,12,21,-1,-24,-1,-24,27,-3,-8,18,-1,-10,-7,45,-39,-18,2,-4,-6,5,5,-19,34,15,36,11,8,-7,-14,-11,0,0,-11,2,6,-18,-25,-17,1,-3,-15,-31,37,-9,-14,10,-24,1,-16,1,13,-21,-11,-5,15,5,6,27,4,27,24,-5,-19,37,-19,-18,-10,-17,-17,-16,-1,18,14,11,12,6,35,-17,35,-14,-12,-5,7,1,-8,-9,10,-8,-14,1,23,1,-24,-7,-4,-20,49,18,15,8,-12,-30,10,0,-7,-8,10,-3,-2,6,-25,-22,-10,-10,0,1,9,-18,-7,6,-11,11,-6,7,-12,1,-16,-15,-10,22,-5,86,-12,16,-41,-11,-1,-1,12,26,11,-7,12,-20,42,6,8,16,6,-27,4,2,-24,-20,7,43,-15,-5,-2,-8,3,-15,12,-16,-4,5,-5,1,2,9,3,-17,19,4,-11,-1,8,0,-13,6,-10,15,12,-28,-14,55,-4,13,16,-42,-5,46,-10,-8,-3,-14,-13,-15,0,26,-7,-8,25,34,-12,-34,22,-10,-9,-17,-5,11,-11,-14,-6,-6,-9,0,14,7,-14,-19,7,-8,37,-13,-7,-7,17,-16,19,23,-14,-13,-7,-18,9,18,-20,-25,1,-22,-26,14,-28,16,-17,-6,4,6,-26,-6,-5,-6,-17,-5,-5,19,13,22,-16,-14,4,-8,-15,3,2,8,7,-3,-6,-2,17,9,5,1,-12,-14,0,-14,-9,11,15,39,-5,-25,2,-18,-5,4,-1,23,18,-9,-7,2,22,-10,10,-13,37,14,-11,-9,-6,-5,14,-6,-9,-8,0,-8,6,28,-7,7,25,-13,-6,25,-3,7,-11,-14,-8,-7,-14,15,10,6,11,33,-2,-23,-16,10,14,-3,8,-10,0,-14,17,7,2,24,-6,-9,23,-1,-19,-7,14,-14,-4,-2,6,2,5,6,-1,-11,9,5,-7,9,-7,-6,14,-14,-6,3,9,0,-1,-4,2,14,-22,-11,18,8,-36,2,-1,9,-14,-4,2,-8,4,-1,5,-8,29,-16,10,-1,1,-8,35,1,10,4,-17,-13,15,-4,0,0,22,-31,4,18,-7,0,-2,-11,-15,29,10,3,7,3,5,-16,26,-6,33,-8,8,2,-7,9,12,11,10,11,10,2,-4,-17,9,-16,-29,-7,-1,-19,29,-11,0,3,-3,1,26,23,-3,7,-4,19,-5,-29,20,21,7,-4,3,-23,-5,-11,3,1,-27,-5,20,-12,22,-5,7,14,-6,-15,-16,5,-19,-7,11,-2,-16,-7,-12,-12,-21,-9,3,-9,1,-14,11,-11,-9,6,-27,-13,-7,-6,4,49,-7,4,9,-13,-12,56,4,11,14,-15,12,19,-4,-25,11,-17,-22,15,4,-6,-8,2,-5,0,-11,1,-23,-6,3,21,-12,-1,-7,-22,-23,-1,19,1,-7,-10,-20,5,-8,5,-21,-1,-2,13,-6,-11,5,-9,-9,-13,18,-3,2,5,-12,-6,30,-13,-4,-18,20,0,8,-8,8,4,0,-7,6,5,6,29,9,42,-2,-12,7,14,-10,-13,1,-1,-17,8,-19,4,-17,-13,-20,8,25,-1,-17,19,10,5,10,-6,3,-12,14,30,-6,-11,-8,-4,-17,-12,-9,-12,41,-16,-21,-2,-15,22,2,9,2,-5,5,2,22,-8,-13,-19,56,-16,6,33,-4,35,-3,10,-15,13,-11,-5,11,0,1,-5,3,-6,21,-12,-6,-16,7,15,-6,-5,-15,1,-8,1,-3,-17,-29,-2,1,-12,9,-8,-8,-8,30,10,18,17,-34,10,5,2,17,-14,-6,-3,0,-22,6,20,-32,-5,-21,-16,8,-8,1,-2,16,-3,-6,-20,-13,5,3,10,13,-9,-13,11,0,4,5,-10,-9,5,-19,10,-4,-11,-3,-12,-4,-11,-7,-21,-30,-10,6,14,8,-2,-1,16,1,19,-15,-14,4,-1,-4,4,-7,12,-13,-12,29,-1,3,0,2,4,-11,-3,-3,-22,4,-6,3,6,9,-25,16,-4,-14,36,3,5,2,-15,-4,1,-11,13,-4,-3,-4,0,-4,-3,44,14,-2,-7,-7,13,-1,-6,-9,2,0,28,-13,-8,-6,1,-5,-6,-9,6,6,10,-3,6,-2,12,-15,5,0,0,17,-2,-18,4,6,2,3,-7,-2,-10,-19,-4,-7,-3,-4,3,9,-17,10,-4,-10,-12,-2,-10,7,-22,-7,-7,1,7,-2,6,-8,-8,7,18,9,-5,3,-6,-4,-10,4,-14,-11,-7,9,13,1,-5,-15,27,7,-4,-13,0,-9,11,8,11,0,-1,0,-4,9,5,9,-15,5,-10,27,-8,6,11,15,-11,13,-25,-15,-16,-9,9,-4,14,-7,-6,-2,-2,3,2,-21,-8,-1,-22,-5,-27,-6,4,9,7,13,0,-7,-2,-8,-12,5,6,-5,-8,-7,-2,-5,8,7,-16,1,16,1,4,0,-6,11,7,-14,-6,15,-4,17,-5,-1,5,24,5,5,-14,11,-8,-6,-18,-3,-14,-13,3,-4,-10,8,-7,19,-2,4,6,36,22,8,18,-20,-8,10,-7,1,-12,8,-5,4,-8,7,-2,-3,-7,-6,-16,0,-9,11,10,3,-1,-9,-6,0,-3,-8,-11,2,-13,19,-1,-22,4,0,-6,0,-10,-12,12,7,-12,-5,-17,3,-12,-4,12,-5,27,19,-11,10,-6,13,7,1,-1,27,-8,12,7,6,-2,-6,6,-7,-16,24,-10,-2,-12,-11,13,-10,-5,-19,-27,-14,-11,1,-1,-15,-2,18,-19,-10,3,3,-3,19,9,-11,-8,-5,24,-3,2,20,-18,-24,-5,11,4,14,14,2,-9,8,0,-9,-12,-2,12,-2,17,-19,-17,4,16,17,-10,5,-5,14,15,5,20,-10,3,-8,24,-16,-4,-1,4,-20,-10,-20,-5,-2,5,2,5,6,-22,-18,3,-8,-7,5,5,-3,12,0,18,-8,12,-2,13,-4,2,3,-4,11,-15,-13,-14,11,0,-4,-10,-10,-22,17,25,20,-4,-10,-5,34,-2,29,3,4,-12,-8,-11,9,-10,13,-16,-5,3,-2,6,8,-4,-5,-10,1,-2,-6,15,3,14,-7,-5,6,-5,-2,13,7,-9,-13,-10,14,-7,-4,6,-2,8,-15,29,15,-14,15,-8,48,-2,-13,-3,-8,-6,-20,12,-3,6,-9,-16,-4,-8,-8,31,-6,11,-3,0,-10,-10,-6,17,6,-12,1,18,-10,1,9,2,3,2,-27,17,-5,-8,-6,-7,-2,6,-15,-12,-12,13,-12,-10,1,-6,10,13,7,0,-13,8,-18,0,25,7,-7,4,-8,-5,1,9,-3,-2,-12,-3,-4,-22,-7,4,6,18,1,1,-11,-7,7,5,-3,15,-6,5,10,-22,11,-9,-16,10,-6,6,2,21,-2,-1,2,12,-10,-2,-4,5,3,20,3,10,-9,-7,-4,-10,12,-14,-6,2,1,-8,7,5,0,-9,-4,46,-14,4,12,-13,3,2,0,8,4,31,-13,6,-7,1,-14,-2,8,4,-12,9,-13,-7,5,4,1,10,-7,-14,-6,-7,10,15,1,-4,-4,11,-2,-3,-13,15,-4,-11,-8,4,2,7,10,-1,-7,37,-15,-3,-7,-16,2,13,11,-3,-23,3,-19,-5,-2,-21,9,-8,1,0,8,10,-4,0,-4,-17,11,6,9,-22,12,-11,11,-1,14,10,22,2,1,6,-11,-7,-4,-4,5,-5,-13,9,-9,-5,-7,-9,-17,1,9,-2,3,0,7,-1,16,-5,14,-4,3,-6,-12,8,16,1,7,-14,1,0,-4,9,-14,1,1,7,13,-3,11,7,9,5,-12,5,-8,0,-2,18,-15,-9,-5,-13,12,-7,-5,2,13,-11,3,2,19,21,-16,-8,12,13,7,4,2,-18,-4,-5,-6,-16,-12,-16,0,4,9,4,-10,9,0,-7,10,-8,6,-5,6,-20,-14,-6,-5,3,-23,-10,-4,18,3,-10,6,-7,15,-8,7,0,-22,3,-21,-2,5,-11,33,2,-6,6,-13,-7,14,1,10,0,13,-20,-16,-15,21,-16,16,5,40,5,1,15,-10,8,17,2,-21,-24,3,-9,5,3,-4,-6,-7,-13,-4,0,2,-23,28,-4,0,6,0,3,11,1,-13,-6,-8,16,-3,36,2,8,6,-12,20,6,8,9,-7,-5,6,3,-1,16,-14,-10,-1,40,-16,-5,12,26,-1,5,-3,23,21,-14,-5,0,2,-3,15,6,-13,5,-14,-4,-1,-16,-13,-16,20,-1,23,0,-38,-2,-10,17,16,-9,-24,-9,7,17,9,-8,-10,11,0,-26,6,-5,-5,-8,-17,1,1,10,0,-11,-16,-18,-10,5,11,14,7,-22,5,-1,-1,-9,1,-5,18,-17,17,-15,-6,-7,31,-4,-4,-1,4,6,-2,-4,-11,1,-15,-3,-5,11,1,1,-16,-6,-1,7,4,-5,18,0,-9,2,17,-14,-15,-8,-25,-7,-9,13,14,5,12,-4,31,-6,2,-1,0,7,3,-18,18,-5,-7,14,-13,-11,-6,-10,-6,2,-16,-14,26,9,-3,28,-9,9,7,-2,-2,-15,-1,3,9,-6,-24,-2,2,-7,-1,3,3,21,-3,3,-7,-10,18,-1,-7,14,1,22,-10,-18,-5,26,7,-6,-6,-8,-6,-2,7,2,-18,10,9,9,3,-2,5,-11,16,27,-5,-5,-16,-12,-14,-3,7,2,-16,-17,-1,-10,7,0,-8,22,-9,7,-5,-1,5,4,13,-6,8,7,-10,-2,-5,-8,4,-1,-2,7,-16,0,-2,-12,3,-10,-3,-2,1,-8,-1,-13,5,5,9,16,-4,14,6,12,4,7,29,14,3,-4,-6,-3,22,-23,-5,15,-28,5,2,8,-12,5,-18,8,5,-3,-18,-8,4,-17,18,5,-6,-8,-12,0,-5,-2,-10,1,6,-17,6,10,-8,-6,17,2,-5,5,11,1,-5,-4,-26,-3,14,-10,-4,3,-11,-11,-16,-3,-1,-5,2,9,2,24,17,8,4,-4,38,16,14,6,-6,-11,-2,14,-10,11,-11,12,4,-8,-8,-26,-13,13,-8,-14,21,1,-8,10,11,22,-17,7,-4,-7,-10,0,-11,18,9,5,0,10,-17,0,-2,2,15,1,-2,-7,-2,2,17,-6,-14,-13,7,11,3,1,14,0,10,8,-11,20,-19,0,-4,16,8,-13,3,4,-1,4,0,29,-12,-24,26,4,11,-14,-12,-10,15,15,-5,1,6,-3,-8,3,-13,-15,7,-6,1,-3,-11,2,-18,14,-1,-17,-2,12,12,-6,12,-23,-13,9,-18,4,0,5,-3,-14,20,7,-6,-6,-11,10,-7,-6,6,-24,4,-18,26,-23,-2,18,-14,-13,-3,-10,28,-4,30,-22,9,-13,-17,11,-19,-9,-12,14,2,-6,25,27,0,1,-7,-17,-6,-16,4,1,13,-12,-6,-6,-11,2,-12,-22,17,-5,-15,-7,-4,5,15,35,0,-3,10,-14,13,-16,4,7,-5,12,-1,11,-2,-23,-9,-3,10,-8,-3,-5,9,12,-3,-12,-4,6,3,-26,-7,5,-24,-11,-3,-9,23,-9,-32,-16,3,30,0,16,7,5,-1,0,-15,-7,40,-20,-6,-9,-2,-13,-7,-2,-2,-4,0,-22,-4,12,-14,5,-1,-3,-6,-8,2,41,32,-10,-6,3,-10,-15,-16,10,-12,-7,-12,-5,-13,51,4,-9,5,-16,15,2,1,-10,40,-14,9,36,1,-16,-7,-3,6,5,25,23,-15,-6,-14,-11,-4,-2,-9,3,-2,17,-5,-4,0,10,17,18,-1,1,-17,3,8,-6,6,15,-1,2,-14,5,-10,7,-5,11,-1,0,-10,3,13,1,-10,16,7,-8,-6,-6,-13,-3,9,20,4,2,-13,-9,-22,-8,-2,-16,12,5,-16,7,-15,9,6,1,5,2,8,9,-7,15,-2,7,35,-11,0,-2,1,1,-9,17,-7,7,-7,-20,-8,11,-2,6,9,0,10,-4,-11,29,7,0,-2,-10,-15,-3,-1,-4,4,-15,-27,1,12,22,-10,-3,20,-17,19,7,-3,5,37,-4,9,18,-3,-7,-12,-3,15,2,0,16,-11,-12,7,8,10,-2,-15,20,-14,2,13,-1,6,4,13,17,15,6,8,-6,9,-7,6,16,4,-2,-3,-7,14,-14,2,-3,-10,-7,-14,4,8,-3,10,0,12,-4,4,5,-5,-10,17,42,-9,2,5,2,5,3,-3,-14,12,2,6,4,-41,-6,2,-3,9,3,0,-7,-8,7,1,-3,11,-3,0,-11,4,2,-3,23,-11,-3,-8,10,-21,26,12,-9,16,-8,16,2,-8,13,-13,-8,-16,-18,18,-19,8,-3,2,-6,-21,8,1,-13,-17,-14,-7,6,18,-21,-36,16,8,20,-13,-8,-16,8,-9,2,-3,2,-5,-5,-7,-3,-12,-4,0,3,-7,-5,-9,12,17,-16,-6,-18,-19,7,25,-12,-17,9,1,-14,-3,-14,6,4,-17,-5,-1,-13,-7,-4,15,-6,5,1,-5,1,-4,-2,1,3,9,-28,-9,-28,-10,28,-3,-12,-6,24,6,-5,-7,-6,1,5,1,38,-34,-3,-14,-15,14,-4,37,2,-8,-21,-21,-6,-13,1,6,-46,-12,-8,-5,5,10,3,-15,28,-10,4,-4,-12,2,1,5,-13,10,19,-12,2,7,-8,-3,0,-13,-33,-5,10,0,13,-2,-2,1,-21,-6,6,-19,-3,14,-21,9,7,6,23,-1,-23,-13,8,-2,16,1,0,-4,11,7,5,-6,-11,-10,0,1,20,6,12,-2,-1,-5,20,-14,5,44,4,1,-7,-7,10,1,-12,22,6,1,10,-6,-9,4,3,3,0,5,-1,0,0,13,-10,-1,-14,13,0,8,11,-14,-15,19,-11,-4,-3,-15,2,4,-9,37,11,-28,-4,-6,-4,-2,-17,-3,-2,-5,-28,19,15,-8,-30,-1,-13,4,6,-3,8,-9,18,6,-2,-24,-14,-13,-16,3,12,34,8,9,0,-3,-9,18,-13,0,-8,-11,19,-1,15,-6,37,7,-12,-1,11,-2,-12,3,-3,-29,2,-10,0,-7,36,-18,-10,-4,-9,0,3,-1,12,-8,-6,-14,13,18,24,12,-1,-4,40,3,-10,10,4,-3,21,14,13,-2,11,12,-5,-11,-6,11,-2,18,7,4,-3,-3,-2,10,6,6,6,-11,9,-14,-14,6,17,11,0,0,1,-1,8,-3,1,-3,5,0,14,-3,4,12,3,-4,-1,-19,-9,-6,3,-1,-1,-7,8,7,10,-14,10,-19,-7,3,10,-8,-2,-1,2,-7,-8,-7,2,26,2,17,-3,5,0,6,4,32,-3,-4,-3,-13,-11,-7,-10,12,4,11,33,0,-12,-10,11,5,16,-7,9,-4,-4,-16,-8,-8,14,2,9,-6,-5,-11,-6,14,-13,-6,-5,-8,-7,-3,-11,28,9,8,6,5,10,-11,-8,3,-23,-16,1,12,-14,0,-2,18,3,-10,5,25,9,-20,0,15,-3,1,4,1,-10,-7,-7,16,23,-7,21,0,-14,2,3,6,-14,-3,-15,-5,-15,-4,-8,14,5,4,-19,4,-6,-18,-8,15,-2,8,-4,3,-6,-5,-11,14,16,-10,-12,-3,-10,6,-1,-6,-9,12,-4,-9,-8,-1,-4,30,-4,24,-11,16,-2,7,6,27,5,-10,-2,0,17,-8,-14,-7,-10,3,27,29,-19,-11,-5,2,-10,-1,-14,2,-2,0,-9,1,-2,23,-23,15,-8,-12,21,4,14,-6,-1,-11,-1,10,-5,11,16,-3,9,35,-7,2,1,6,-4,-11,-7,-14,-3,-8,18,9,12,7,-12,34,-1,-27,9,11,7,-9,-8,9,6,-9,-4,7,-4,-10,10,10,-11,6,-7,4,-11,-6,0,-4,-1,10,-2,15,-13,13,-31,24,1,-13,-19,8,-2,-5,7,-4,10,-4,-10,-10,-10,-8,-1,-10,-8,-3,1,-9,-3,1,1,-11,-2,6,-10,34,-5,12,-15,34,-1,-20} + +#define IP1_BIAS {30,-121,-51,77,40,20,46,-35,28,-33} + +#define CONV1_BIAS_LSHIFT 6 +#define CONV1_OUT_RSHIFT 9 +#define CONV2_BIAS_LSHIFT 4 +#define CONV2_OUT_RSHIFT 9 +#define CONV3_BIAS_LSHIFT 1 +#define CONV3_OUT_RSHIFT 7 +#define IP1_BIAS_LSHIFT 1 +#define IP1_OUT_RSHIFT 8 +#define INPUT_MEAN_SHIFT {125,123,114} +#define INPUT_RIGHT_SHIFT {8,8,8} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/Compiler/EventRecorderConf.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/Compiler/EventRecorderConf.h new file mode 100644 index 0000000..5958233 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/Compiler/EventRecorderConf.h @@ -0,0 +1,44 @@ +/*------------------------------------------------------------------------------ + * MDK - Component ::Event Recorder + * Copyright (c) 2016 ARM Germany GmbH. All rights reserved. + *------------------------------------------------------------------------------ + * Name: EventRecorderConf.h + * Purpose: Event Recorder Configuration + * Rev.: V1.0.0 + *----------------------------------------------------------------------------*/ + +//-------- <<< Use Configuration Wizard in Context Menu >>> -------------------- + +// Event Recorder + +// Number of Records +// <8=>8 <16=>16 <32=>32 <64=>64 <128=>128 <256=>256 <512=>512 <1024=>1024 +// <2048=>2048 <4096=>4096 <8192=>8192 <16384=>16384 <32768=>32768 +// <65536=>65536 <131072=>131072 <262144=>262144 <524288=>524288 +// <1048576=>1048576 +// Configure size of Event Record Buffer (each record is 16 bytes) +// Must be 2^n (min=8, max=1048576) +#define EVENT_RECORD_COUNT 64U + +// Time Stamp Source +// <0=> DWT Cycle Counter <1=> SysTick +// <3=> User Timer (Normal Reset) <4=> User Timer (Power-On Reset) +// Selects source for 32-bit time stamp +#define EVENT_TIMESTAMP_SOURCE 1 + +// SysTick Configuration +// Configure values when Time Stamp Source is set to SysTick + +// SysTick Input Clock Frequency [Hz] <1-1000000000> +// Defines SysTick input clock (typical identical with processor clock) +#define SYSTICK_CLOCK 100000000U + +// SysTick Interrupt Period [us] <1-1000000000> +// Defines time period of the SysTick timer interrupt +#define SYSTICK_PERIOD_US 1000U + +// + +// + +//------------- <<< end of configuration section >>> --------------------------- diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM0/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM0/RTE_Components.h new file mode 100644 index 0000000..73f80ad --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM0/RTE_Components.h @@ -0,0 +1,24 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_gru' + * Target: 'ARMCM0' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM0.h" + +#define RTE_Compiler_EventRecorder + #define RTE_Compiler_EventRecorder_DAP +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_EVR /* Compiler I/O: STDOUT EVR */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM3/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM3/RTE_Components.h new file mode 100644 index 0000000..1f91822 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM3/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_gru' + * Target: 'ARMCM3' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM3.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM4_FP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM4_FP/RTE_Components.h new file mode 100644 index 0000000..3df85a0 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM4_FP/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_gru' + * Target: 'ARMCM4_FP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM4_FP.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM7_SP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM7_SP/RTE_Components.h new file mode 100644 index 0000000..04bee02 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/RTE/_ARMCM7_SP/RTE_Components.h @@ -0,0 +1,22 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_gru' + * Target: 'ARMCM7_SP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM7_SP.h" + +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru.cpp b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru.cpp new file mode 100644 index 0000000..efb3257 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru.cpp @@ -0,0 +1,221 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2018 Arm Limited. All rights reserved. +* +* +* Project: CMSIS NN Library +* Title: arm_nnexamples_gru.cpp +* +* Description: Gated Recurrent Unit Example +* +* Target Processor: Cortex-M4/Cortex-M7 +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of Arm LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +/** + * @ingroup groupExamples + */ + +/** + * @defgroup GRUExample Gated Recurrent Unit Example + * + * \par Description: + * \par + * Demonstrates a gated recurrent unit (GRU) example with the use of fully-connected, + * Tanh/Sigmoid activation functions. + * + * \par Model definition: + * \par + * GRU is a type of recurrent neural network (RNN). It contains two sigmoid gates and one hidden + * state. + * \par + * The computation can be summarized as: + *
z[t] = sigmoid( W_z ⋅ {h[t-1],x[t]} )
+ * r[t] = sigmoid( W_r ⋅ {h[t-1],x[t]} ) 
+ * n[t] = tanh( W_n ⋅ [r[t] × {h[t-1], x[t]} ) 
+ * h[t] = (1 - z[t]) × h[t-1] + z[t] × n[t] 
+ * \image html GRU.gif "Gate Recurrent Unit Diagram" + * + * \par Variables Description: + * \par + * \li \c update_gate_weights, \c reset_gate_weights, \c hidden_state_weights are weights corresponding to update gate (W_z), reset gate (W_r), and hidden state (W_n). + * \li \c update_gate_bias, \c reset_gate_bias, \c hidden_state_bias are layer bias arrays + * \li \c test_input1, \c test_input2, \c test_history are the inputs and initial history + * + * \par + * The buffer is allocated as: + * \par + * | reset | input | history | update | hidden_state | + * \par + * In this way, the concatination is automatically done since (reset, input) and (input, history) + * are physically concatinated in memory. + * \par + * The ordering of the weight matrix should be adjusted accordingly. + * + * + * + * \par CMSIS DSP Software Library Functions Used: + * \par + * - arm_fully_connected_mat_q7_vec_q15_opt() + * - arm_nn_activations_direct_q15() + * - arm_mult_q15() + * - arm_offset_q15() + * - arm_sub_q15() + * - arm_copy_q15() + * + * Refer + * \link arm_nnexamples_gru.cpp \endlink + * + */ + +#include +#include +#include +#include "arm_nnexamples_gru_test_data.h" +#include "arm_math.h" +#include "arm_nnfunctions.h" + +#ifdef _RTE_ +#include "RTE_Components.h" +#ifdef RTE_Compiler_EventRecorder +#include "EventRecorder.h" +#endif +#endif + +#define DIM_HISTORY 32 +#define DIM_INPUT 32 +#define DIM_VEC 64 + +#define USE_X4 + +#ifndef USE_X4 +static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X2; +static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X2; +static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X2; +#else +static q7_t update_gate_weights[DIM_VEC * DIM_HISTORY] = UPDATE_GATE_WEIGHT_X4; +static q7_t reset_gate_weights[DIM_VEC * DIM_HISTORY] = RESET_GATE_WEIGHT_X4; +static q7_t hidden_state_weights[DIM_VEC * DIM_HISTORY] = HIDDEN_STATE_WEIGHT_X4; +#endif + +static q7_t update_gate_bias[DIM_HISTORY] = UPDATE_GATE_BIAS; +static q7_t reset_gate_bias[DIM_HISTORY] = RESET_GATE_BIAS; +static q7_t hidden_state_bias[DIM_HISTORY] = HIDDEN_STATE_BIAS; + +static q15_t test_input1[DIM_INPUT] = INPUT_DATA1; +static q15_t test_input2[DIM_INPUT] = INPUT_DATA2; +static q15_t test_history[DIM_HISTORY] = HISTORY_DATA; + +q15_t scratch_buffer[DIM_HISTORY * 4 + DIM_INPUT]; + +void gru_example(q15_t * scratch_input, uint16_t input_size, uint16_t history_size, + q7_t * weights_update, q7_t * weights_reset, q7_t * weights_hidden_state, + q7_t * bias_update, q7_t * bias_reset, q7_t * bias_hidden_state) +{ + q15_t *reset = scratch_input; + q15_t *input = scratch_input + history_size; + q15_t *history = scratch_input + history_size + input_size; + q15_t *update = scratch_input + 2 * history_size + input_size; + q15_t *hidden_state = scratch_input + 3 * history_size + input_size; + + // reset gate calculation + // the range of the output can be adjusted with bias_shift and output_shift +#ifndef USE_X4 + arm_fully_connected_mat_q7_vec_q15(input, weights_reset, input_size + history_size, history_size, 0, 15, bias_reset, + reset, NULL); +#else + arm_fully_connected_mat_q7_vec_q15_opt(input, weights_reset, input_size + history_size, history_size, 0, 15, + bias_reset, reset, NULL); +#endif + // sigmoid function, the size of the integer bit-width should be consistent with out_shift + arm_nn_activations_direct_q15(reset, history_size, 0, ARM_SIGMOID); + arm_mult_q15(history, reset, reset, history_size); + + // update gate calculation + // the range of the output can be adjusted with bias_shift and output_shift +#ifndef USE_X4 + arm_fully_connected_mat_q7_vec_q15(input, weights_update, input_size + history_size, history_size, 0, 15, + bias_update, update, NULL); +#else + arm_fully_connected_mat_q7_vec_q15_opt(input, weights_update, input_size + history_size, history_size, 0, 15, + bias_update, update, NULL); +#endif + + // sigmoid function, the size of the integer bit-width should be consistent with out_shift + arm_nn_activations_direct_q15(update, history_size, 0, ARM_SIGMOID); + + // hidden state calculation +#ifndef USE_X4 + arm_fully_connected_mat_q7_vec_q15(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15, + bias_hidden_state, hidden_state, NULL); +#else + arm_fully_connected_mat_q7_vec_q15_opt(reset, weights_hidden_state, input_size + history_size, history_size, 0, 15, + bias_hidden_state, hidden_state, NULL); +#endif + + // tanh function, the size of the integer bit-width should be consistent with out_shift + arm_nn_activations_direct_q15(hidden_state, history_size, 0, ARM_TANH); + arm_mult_q15(update, hidden_state, hidden_state, history_size); + + // we calculate z - 1 here + // so final addition becomes substraction + arm_offset_q15(update, 0x8000, update, history_size); + // multiply history + arm_mult_q15(history, update, update, history_size); + // calculate history_out + arm_sub_q15(hidden_state, update, history, history_size); + + return; +} + +int main() +{ + #ifdef RTE_Compiler_EventRecorder + EventRecorderInitialize (EventRecordAll, 1); // initialize and start Event Recorder + #endif + + printf("Start GRU execution\n"); + int input_size = DIM_INPUT; + int history_size = DIM_HISTORY; + + // copy over the input data + arm_copy_q15(test_input1, scratch_buffer + history_size, input_size); + arm_copy_q15(test_history, scratch_buffer + history_size + input_size, history_size); + + gru_example(scratch_buffer, input_size, history_size, + update_gate_weights, reset_gate_weights, hidden_state_weights, + update_gate_bias, reset_gate_bias, hidden_state_bias); + printf("Complete first iteration on GRU\n"); + + arm_copy_q15(test_input2, scratch_buffer + history_size, input_size); + gru_example(scratch_buffer, input_size, history_size, + update_gate_weights, reset_gate_weights, hidden_state_weights, + update_gate_bias, reset_gate_bias, hidden_state_bias); + printf("Complete second iteration on GRU\n"); + + return 0; +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru_test_data.h b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru_test_data.h new file mode 100644 index 0000000..e0ccbe1 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Examples/ARM/arm_nn_examples/gru/arm_nnexamples_gru_test_data.h @@ -0,0 +1,23 @@ +#define UPDATE_GATE_WEIGHT_X2 {-62,83,-58,-89,-80,1,-93,31,101,95,121,-83,71,18,-98,-5,44,-100,-16,-73,25,62,34,-22,-16,42,9,-125,60,-78,15,-76,-76,-63,71,-25,78,-66,38,-118,-71,-120,-80,28,33,51,82,-105,26,-47,38,86,-114,44,90,-98,105,-123,24,95,-12,11,49,-35,78,104,104,17,-116,-40,-83,4,88,-110,-111,-98,18,-89,120,-84,66,-69,-8,-22,-91,-29,-41,110,55,-124,-67,103,-40,-100,1,-25,-68,-62,-89,-75,-20,-78,101,-92,-51,-97,-54,59,-78,41,34,-102,-9,-53,56,103,-55,13,81,-75,-20,-37,29,36,110,84,-80,-127,-68,-33,-70,-16,-42,-9,-104,107,-81,-16,42,-74,-63,-4,-128,-109,-105,55,-51,-68,-88,19,-39,116,-7,66,52,-29,63,-94,71,-2,-127,31,-103,120,124,41,-13,-23,127,59,-22,54,-2,32,-87,-109,85,-31,-5,-59,-122,-97,-14,-88,-19,43,-30,115,42,14,10,121,28,-63,83,-85,101,40,23,-39,74,-99,73,50,-20,123,-88,-13,-126,-25,70,-11,16,-28,121,-29,20,-69,104,117,-40,-1,-97,-12,31,32,15,-32,77,31,16,40,107,-52,-52,-89,-17,124,-95,54,48,-40,37,24,-46,42,119,5,-118,-45,-10,106,83,57,-74,-10,-56,85,37,-25,83,-31,-54,111,-78,-96,-114,-65,-100,28,-31,-111,33,66,74,-43,112,119,-80,-26,74,-81,-123,55,-126,32,-66,110,-86,-118,-21,15,16,26,13,-109,41,-16,88,81,-82,-55,-89,109,-52,118,-39,57,-16,86,-68,-10,-19,110,-50,-17,-84,103,-3,94,-8,50,15,-44,-87,6,18,8,61,66,-108,-67,-6,107,-68,25,25,25,-82,71,62,121,-31,-4,17,-6,-60,-17,116,-67,45,117,-90,12,-68,20,121,-65,-43,74,-104,-42,-69,35,4,-17,5,95,-82,18,65,43,-57,89,1,-8,37,-51,10,67,4,-50,-18,81,-120,44,98,16,-98,25,127,88,-111,-49,114,111,-17,-74,40,-18,35,19,31,48,-23,53,102,41,89,-27,87,-54,-121,-113,97,125,125,-108,58,-17,8,70,-67,-55,59,42,-85,78,27,16,66,67,54,-74,33,-19,72,77,126,-122,-7,-109,58,78,-88,15,2,16,37,-34,-114,-88,-53,88,115,19,7,-67,93,80,-48,-11,-61,31,38,29,-59,-70,0,25,106,-7,-44,53,62,19,-64,109,70,-103,-114,97,57,112,24,-66,-127,29,29,-31,-87,-125,54,-98,101,-39,56,-88,-63,-113,-73,-91,80,112,-27,-75,-42,-5,79,60,-55,23,-61,66,51,39,-91,96,-60,-64,-1,75,55,-108,73,38,75,-113,-9,-92,-92,-3,-30,93,-27,-100,-55,125,52,72,110,12,84,-83,65,-79,92,11,87,-106,35,-38,-24,-79,15,-11,-109,-22,95,82,-1,-2,-113,116,-64,93,-62,-11,101,35,-91,51,-6,21,29,25,-16,68,-103,-111,-23,-123,-80,24,-17,-7,53,23,114,-13,-105,-88,120,13,-25,-40,29,-38,-43,3,2,-121,-110,54,-43,30,66,28,60,-81,-6,-8,126,-80,64,-42,126,75,-69,-116,-41,81,94,31,-116,5,-46,5,-21,-105,78,-20,-34,54,46,-124,120,-83,44,-17,-52,-23,-110,34,-35,31,61,88,-108,-38,31,117,-26,38,-57,65,9,0,59,124,14,-39,-95,-91,107,-34,85,-83,-31,-68,-78,-86,21,-118,56,60,-3,-116,33,53,-94,85,77,91,-94,100,-89,97,88,111,36,74,-110,7,-74,91,-112,21,32,-59,98,36,10,-41,44,-114,-88,92,111,72,43,58,42,-125,-11,96,126,25,96,-105,-128,-70,85,-82,-17,103,23,-37,76,58,108,16,-116,-44,22,89,0,6,-108,27,-34,88,-125,22,-45,-116,28,-29,-70,-3,-81,-80,42,119,105,-40,-109,105,64,5,72,-32,-95,90,60,6,-29,40,-19,57,89,-50,34,-123,-32,-18,20,9,-19,-81,-45,-120,-120,20,2,18,70,75,100,64,126,-9,63,-82,114,-62,106,-11,104,-9,-13,88,-40,101,73,108,52,33,116,-54,-114,-47,85,2,-117,-80,100,-20,98,-75,-83,-24,-125,-91,-97,95,-46,15,-94,-21,53,-27,-18,65,87,112,38,-115,-27,37,-84,1,103,85,-50,36,-49,-119,68,20,119,-113,43,-67,105,44,4,-48,16,-42,83,-39,106,31,-34,-76,-51,68,82,-111,-116,-104,-118,109,-29,-6,-91,81,-102,-76,-82,64,121,27,-98,-24,-88,36,115,59,-84,-121,4,29,45,73,110,-56,-12,109,-88,85,-30,87,18,118,23,21,106,40,115,78,-72,-103,11,83,44,117,-63,98,30,115,123,-39,25,15,84,52,46,77,64,-104,125,-13,34,125,65,6,57,-128,-2,115,7,-65,-73,82,72,-109,99,43,-94,-106,-39,-4,-127,58,123,-128,29,-80,4,51,109,-50,-38,25,-13,-52,-106,87,76,44,78,101,16,-102,-20,104,23,107,-88,18,-85,119,-21,-53,-84,-7,-8,-114,23,-54,74,80,77,-40,19,-75,-41,60,77,82,-96,-121,-43,114,-124,-1,-75,32,34,-117,21,64,-87,-100,-29,-36,-45,-46,-111,4,-44,-94,-117,100,-25,-27,105,95,15,88,25,-38,-88,122,62,-62,-28,95,-86,125,-83,-9,-100,101,-124,22,21,-91,50,-100,-27,-92,115,86,85,33,-112,-43,61,114,62,-31,-84,-7,5,-26,-10,-21,-89,60,-96,48,-34,88,-80,-91,92,12,118,-2,-38,83,-50,-109,-111,-26,-109,-78,-7,84,60,-95,15,-71,112,126,71,36,39,-42,-85,-126,-68,105,-18,-127,48,-41,57,-93,13,-25,-71,66,-43,-23,122,4,-70,123,115,124,-61,-32,18,-18,49,123,-101,37,-50,-111,-73,124,-18,54,-64,93,-69,16,112,21,-56,56,127,113,-48,-57,-4,85,-84,53,44,28,-126,-59,-11,94,58,-64,112,82,127,58,50,5,-6,-102,90,-18,-86,104,17,108,-64,-22,73,-102,-17,-31,-11,-105,-40,-49,84,-82,104,57,30,112,-119,-92,78,-92,35,90,-45,-13,-75,-125,-19,-83,-75,29,15,-33,127,-14,29,-80,61,41,67,-14,-18,101,101,108,-24,-61,-90,-59,-48,-114,1,-14,106,52,109,-45,-100,74,-33,-68,-94,-68,-22,-99,31,-86,85,-27,-70,69,127,92,125,-95,117,-87,-8,-71,18,94,-90,103,-31,-1,-50,-60,-2,96,31,-1,-98,75,104,-6,-38,-24,127,94,-48,97,-96,4,-108,106,76,-31,-7,-41,58,-13,-72,-81,-116,-24,-45,46,-20,114,97,-14,125,11,22,26,27,-2,-88,-28,-76,119,50,52,66,65,120,-42,-43,-59,-56,-28,-42,-87,-18,-47,-85,74,119,97,-6,-127,-86,30,18,-43,48,-73,22,-5,34,122,9,115,-32,-63,-13,61,119,18,-113,-12,80,26,-39,-76,-101,-104,-6,48,38,-82,-52,-91,-38,112,110,115,76,69,100,-116,109,3,-35,16,94,24,110,86,25,-5,84,2,62,57,-121,-28,-108,29,127,-25,89,16,-86,15,-68,97,-115,-73,-110,-13,41,16,-47,-74,75,-71,-52,-20,-29,3,-34,68,-2,-29,63,-5,95,-79,26,-42,-91,-109,-19,107,-102,62,111,-35,80,36,55,-65,26,76,-86,26,-88,-116,110,84,-62,-13,120,-31,-47,-32,84,-98,58,74,18,-22,5,-83,-3,11,53,114,32,-118,16,-91,-74,-67,-68,78,-34,102,88,-80,-5,63,-35,22,-87,-97,-30,-76,94,116,44,-109,-122,38,112,-103,99,-119,49,35,107,108,47,54,11,-50,-73,37,-56,71,-125,108,-47,15,-115,-65,-90,-13,-27,-16,-94,72,-101,-74,-58,27,121,-91,110,-101,45,-54,105,-8,-88,-66,-71,-128,-35,-53,-50,-51,-85,113,96,16,-72,-80,-54,78,47,75,-82,-115,-53,40,-39,54,-43,23,-35,43,81,125,-8,51,49,-91,122,123,-102,-65,-78,19,14,51,-68,60,43,-36,105,44,-100,36,89,-40,123,31,105,26,-128,63,-49,-115,48,96,-91,-73,99,37,2,3,-52,-103,-11,10,31,-106,-119,-67,118,-71,-67,-52,-12,43,-21,99,-64,-88,64,100,-62,-11,-32,23,-90,68,-102,116,-21,-78,1,108,-2,116,-122,114,53,-33,102,65,33,73,92,-79,-51,-50,-65,49,76,119,-51,15,-21,95,-109,80,17,7,115,115,-117,-77,-39,-115,-19,-83,-35,-122,56,94,1,-13,83,8,-84,72,-88,87,77,-82,-125,-18,75,10,-106,51,-59,120,-85,22,-45,-68,-44,-38,64,38,-75,-69,122,88,53,18,41,-108,48,38,-127,34,-85,36,-116,-96,56,105,38,76,92,-41,99,-101,-100,112,74,57,60,85,-14,95,0,-73,-46,12,-93,-14,-78,-1,-2,-10,34,111,115,-91,16,-79,76,-108,-8,-84,33,111,-98,2,-6,8,0,-77,1,52,18,-5,-77,-46,-80,-20,-61,-30,-81,-73,-7,49,-107,-25,-97,-125,69,-89,31,-124,-108,76,96,58,88,24,49,79,11,-43,-60,100,108,62,21,-72,-111,81,46,-108,-107,29,90,-13,55,-23,-63,-10,-128,-124,86,88,3,-39,-39,98,-57,-24,-97,-124,85,-84,-78,4,11,59,-73,120,66,21,-73,20,-95,91,-53,76,98,-29,49,-76,-74,-67,-80,-29,-106,111,60,32,-127,-87,104,30,95,-21,93,-23,-97,26,-46,63,12,-28,123,12,30,102,-115,36,74,-54,-54,-103,-57,-95,-72,-60,24,-14,-41,27,9,19,-74,-12,-65,-7,17,122,-85,123,16,-127,22,75,-85,-28,-50,125,-102,-28,24,120,-53,-128,-108,-65,-37,60,-53,-10,28,-38,-11,71,-45,21,-77,-108,-115,-24,103,-29,121,-23,11,-102,-115,-108,-78,-55,84,-17,-58,-8,-118,-119,-56,1,-109,42,-94,51,54,6,-30,56,12,23,-10,121,-113,-74,9,12,0,-93,67,51,-110,44,-69,-40,-72,49,-16,-31,-16,9,-43,7,90,96,-63,-24,-74,-26,35,-16,109,-101,38,87,-13,11,-18,-54,33,37,106,84,79,80,23,-76,-80,-45,-106,56,3,-103,-92,86,-81,68,90,-126,-125,102,-83,-36,83,97,-39,-44,-14,-14,79,-9,-31,119,114,29,-27,-29,55,-72,-3,54,49,-40,22,-37,54,68,71,66,-66,-23,49,69,-73,83,-14,-70,9,117,-63,111,65,66,92,58,-56,15,20,52,-72,-4,34,-94,119,-95} + +#define UPDATE_GATE_WEIGHT_X4 {-62,78,83,104,-68,28,-33,-63,-58,104,-89,17,-70,83,-16,-85,-80,-116,1,-40,-42,101,-9,40,-93,-83,31,4,-104,23,107,-39,101,88,95,-110,-81,74,-16,-99,121,-111,-83,-98,42,73,-74,50,71,18,18,-89,-63,-20,-4,123,-98,120,-5,-84,-128,-88,-109,-13,44,66,-100,-69,-105,-126,55,-25,-16,-8,-73,-22,-51,70,-68,-11,25,-91,62,-29,-88,16,19,-28,34,-41,-22,110,-39,121,116,-29,-16,55,42,-124,-7,20,66,-69,9,-67,-125,103,52,104,-29,117,60,-40,-78,-100,63,-40,-94,-1,15,1,-76,-25,71,-97,-2,-12,-76,-68,-63,-62,-127,31,31,32,71,-89,-25,-75,-103,15,120,-32,78,-20,-66,-78,124,77,41,31,38,101,-118,-92,-13,16,-23,40,-71,-51,-120,-97,127,107,59,-52,-80,-54,28,59,-22,-52,54,-89,33,-78,51,41,-2,-17,32,124,82,34,-105,-102,-87,-95,-109,54,26,-9,-47,-53,85,48,-31,-40,38,56,86,103,-5,37,-59,24,-114,-55,44,13,-122,-46,-97,42,90,81,-98,-75,-14,119,-88,5,105,-20,-123,-37,-19,-118,43,-45,24,29,95,36,-30,-10,115,106,-12,110,11,84,42,83,14,57,49,-80,-35,-127,10,-74,121,-10,-56,-8,85,50,-120,37,44,-34,37,15,-25,-44,98,-114,16,-88,83,-87,-31,6,-98,-53,25,88,-54,18,111,8,127,115,88,19,-78,61,-96,66,-111,7,-49,-67,-114,-108,-65,-67,114,93,111,80,-100,-6,28,107,-17,-48,-74,-11,-31,-68,-111,25,40,-61,-18,31,33,25,66,25,35,38,19,29,74,-82,-43,71,31,-59,48,-70,112,62,119,121,-23,0,53,25,-80,-31,-26,-4,102,106,41,-7,74,17,-81,-6,89,-44,-27,53,-123,-60,55,-17,87,62,-54,19,-126,116,32,-67,-121,-64,-113,109,-66,45,110,117,97,70,125,-103,-86,-90,-118,12,125,-114,-108,97,-21,-68,15,20,58,57,-17,112,16,121,26,-65,8,24,70,-66,13,-43,-109,74,-67,-127,-55,29,41,-104,-16,-42,59,29,42,-31,88,-69,81,35,-85,-87,78,-125,-82,4,-55,-17,27,54,16,-98,-89,5,109,95,66,101,67,-39,-52,-82,118,18,54,56,-74,-88,-39,65,57,43,33,-63,-19,-113,-16,-57,86,89,72,-73,77,-91,-68,1,-10,-8,126,80,-122,112,-19,37,110,-51,-7,-27,-109,-75,-50,10,-17,67,58,-42,78,-5,-84,4,103,-50,-88,79,15,60,-3,-18,94,81,2,-55,16,23,-61,-16,66,68,-52,44,-23,-114,51,-103,39,-111,-110,-88,34,92,-91,-23,96,-123,-35,111,31,72,-60,-80,-64,24,61,43,88,58,-1,-17,75,-7,-108,42,-38,-125,55,53,-108,23,31,-11,117,96,73,114,38,-13,-26,126,38,25,75,-105,-113,-88,-57,96,65,-105,-9,120,-92,13,9,-128,0,-70,-92,-25,-3,-40,59,85,124,-82,-30,29,93,-38,14,-17,-39,103,-27,-43,-100,3,-95,23,-91,-37,-55,2,125,-121,107,76,-34,58,52,-110,72,54,85,108,-83,16,110,-43,12,30,-31,-116,-68,-44,84,66,-83,28,-78,22,-86,89,65,60,-79,-81,21,0,-118,6,92,-6,11,-8,56,-108,60,27,87,126,-106,-80,-3,-34,-116,88,35,64,-38,-42,33,-125,53,22,-24,126,-79,75,-94,-45,85,-116,15,-69,-11,-116,77,28,91,-29,-109,-41,-22,81,-94,-70,100,-3,95,94,82,31,-89,-81,97,-80,-1,-116,-2,5,88,42,111,119,-113,-46,116,5,36,105,74,-40,-64,-21,93,-105,-110,-109,7,105,-62,78,-11,-20,-74,64,91,5,101,-34,35,54,-112,72,21,-32,-91,46,51,-124,32,-95,-59,90,-6,120,21,-83,98,60,36,6,29,44,25,-17,10,-29,-41,40,-19,-18,57,65,110,4,-56,51,89,87,-50,112,-12,109,109,-50,34,38,-123,-115,-88,-38,85,25,-32,-27,-18,37,-30,-13,87,-52,20,-84,9,1,18,-106,118,87,-19,103,-81,85,23,76,21,44,-45,-50,-120,36,106,78,40,101,-120,-49,20,-119,115,16,78,-102,2,68,18,20,-72,-20,-103,104,70,119,75,-113,11,23,83,107,100,43,64,-67,44,-88,117,18,126,105,-9,44,-63,-85,98,119,63,4,-82,-48,30,-21,115,-53,114,16,-62,-42,123,-84,-39,-7,106,83,-11,-39,25,-8,15,-114,104,106,-9,31,84,23,52,-54,-13,-34,88,-76,46,74,77,80,-40,-51,101,68,64,77,-104,-40,73,82,108,-111,125,19,-13,-75,52,-116,33,-104,34,-41,125,60,116,-118,-54,109,65,77,6,82,-114,-29,-47,-6,57,-96,-128,-121,85,-91,2,81,-2,-43,115,114,-117,-102,-80,-76,7,-124,-65,-1,100,-82,-20,64,-73,-75,82,32,98,121,-75,27,72,34,-109,-117,-83,-98,-24,-24,99,21,43,64,-125,-88,-91,36,-94,-87,-106,-100,-97,115,95,59,-39,-29,-4,-36,-46,-84,15,-121,-127,-45,58,-46,-94,4,-21,29,123,-111,-128,4,53,45,-27,73,29,-44,-80,-94,-117,-109,100,-78,-84,-18,53,101,-25,-7,-27,84,44,101,28,108,105,60,95,-95,-126,-24,-59,-61,15,15,88,-71,-11,-90,94,-59,25,112,-38,126,58,-48,-64,-114,-88,71,122,36,112,1,82,-14,62,39,-62,-42,127,106,58,52,-28,-85,95,-126,50,109,5,-45,-86,-68,125,105,-6,-100,-102,74,-83,-18,-9,-127,90,-33,-18,-68,-100,48,101,-41,-86,-94,104,-68,-124,57,22,-93,17,-22,108,-99,21,13,-91,-25,-64,31,-22,-86,50,-71,-100,66,73,85,-102,-27,-27,-43,-92,-23,-17,-70,-31,69,115,122,86,4,-11,127,-105,92,85,-70,33,123,-40,125,-49,-95,-112,115,-43,124,84,117,-82,-87,61,-61,114,-32,104,-8,57,-71,62,18,-31,-18,30,18,112,94,-84,49,-7,123,-119,-90,-92,103,5,-101,-26,37,78,-31,-92,-1,-10,-50,-21,-111,35,-50,90,-60,-89,-73,60,124,-45,-2,-13,96,-96,-18,48,54,-75,31,-125,-1,-34,-64,88,93,-19,-98,-83,75,-80,-69,-91,16,-75,104,29,-6,92,112,12,21,15,-38,-33,-24,118,-56,-2,56,127,127,-14,94,-38,127,83,113,29,-48,-80,97,-50,-48,-109,-57,61,-96,41,4,-111,-4,-26,85,67,-108,-14,106,76,-113,-31,-12,-2,-30,-29,-76,-7,80,-41,26,63,94,-5,116,58,-39,-13,-76,95,44,-79,-109,-72,-101,-81,-104,26,-122,-42,38,-116,-6,-24,48,-91,112,-109,-103,-45,38,46,-82,-19,99,107,-119,-20,-52,114,-91,-102,49,62,35,97,-38,-14,112,111,107,-35,108,125,110,11,115,80,47,36,54,22,76,26,69,55,11,-65,-50,27,100,-2,-116,26,-73,76,37,-88,109,-28,3,-86,-56,26,71,-76,-35,119,16,-88,-125,-116,108,50,94,52,24,110,-47,84,15,66,110,65,86,-62,-115,-13,-65,120,25,-42,-5,120,-90,-31,-13,-43,84,-59,2,-47,-27,-32,-16,-56,62,-28,57,84,-94,-98,72,-42,-121,-87,-28,58,-101,74,-74,-18,-108,-47,29,18,-58,-22,27,-85,127,74,-25,5,121,-83,-91,119,89,97,16,-3,110,11,-101,-6,-86,-127,15,53,45,114,-54,-86,-68,30,97,32,105,-118,-8,18,-115,-43,-73,16,-88,-91,-66,48,-110,-73,-13,-74,-71,-67,-128,22,41,-5,16,-68,-35,78,-53,34,-47,122,-74,-34,-50,102,-51,9,75,115,-71,88,-85,-80,113,-32,-52,-63,-20,-5,96,63,16,-13,-29,61,3,-35,-72,22,-80,119,-34,18,68,-87,-54,-97,78,47,-12,75,43,-88,115,87,-91,-82,-21,-115,99,77,16,-82,-79,-53,-64,40,-88,-125,76,-18,-108,-39,64,54,100,75,-8,10,-84,-43,-62,23,-11,-106,33,51,111,-35,-32,43,23,-59,-98,120,2,81,-90,125,68,-85,-6,22,8,-8,-102,51,116,-45,0,-68,-77,49,-21,-91,-78,-44,1,-38,52,122,1,123,108,64,18,38,-5,-102,-2,-65,116,-75,-77,-69,-46,-78,-122,19,114,122,-80,88,-20,14,53,51,-33,53,-61,18,-30,-68,102,60,65,41,-81,-108,-73,43,33,-36,73,48,-7,38,49,105,92,44,-79,-127,-107,34,-25,-100,-51,36,-50,-85,-97,36,-125,89,-65,-40,49,-116,69,-96,-89,123,76,31,119,56,31,105,-124,105,-51,26,15,38,-108,76,76,-128,-21,63,95,92,96,-41,58,-49,-109,-115,80,99,88,-101,24,48,17,96,7,-100,49,112,79,-91,115,-73,115,74,11,57,-43,99,-117,37,-77,60,-60,85,100,2,-39,3,-115,-14,108,95,62,-52,-19,-103,-83,0,21,-73,-72,-11,-35,10,-122,-46,-111,12,81,31,56,-106,94,-93,46,-14,-108,-119,1,-67,-13,-78,-107,-1,29,118,83,-71,8,-2,90,-10,-13,-67,-84,-52,72,34,55,111,-23,-63,-54,-10,-103,-118,3,-119,-103,-128,-57,-124,-95,-56,-92,1,86,86,-72,88,-60,-109,-81,42,68,3,24,-39,-14,-94,90,51,-126,-39,-41,98,27,54,-125,6,102,-57,9,-24,19,-30,-83,56,-36,-97,-74,-124,-12,12,83,23,97,85,-65,-84,-7,-10,-39,121,-44,-78,17,4,122,-113,-14,-74,-14,11,-85,59,123,9,79,12,-9,-73,16,120,-127,0,-31,-93,119,66,22,21,75,67,114,51,29,-73,-85,20,-28,-110,-27,44,-29,-95,-50,91,125,-69,55,-40,-72,-53,-102,76,-28,-72,-3,49,54,98,24,-29,120,-16,49,-31,-40,49,-53,-76,-128,-16,22,9,-37,-74,-108,-67,-65,-43,54,7,68,-80,-37,-29,60,90,71,96,66,-106,-53,111,-10,-63,-66,-24,-23,60,28,32,-38,-74,49,-26,69,-127,-11,-87,71,35,-73,-16,83,104,-45,30,21,109,-14,-101,-70,95,-77,-21,-108,38,9,87,117,93,-115,-23,-24,-13,-63,11,111,-97,103,26,-29,-18,65,-54,66,-46,121,63,-23,33,92,37,58,12,11,-28,-102,106,-56,84,15,123,-115,12,-108,79,20,80,52,30,-78,102,-55,23,-72,-76,-4,-115,84,36,-17,-80,34,-45,-94,74,-58,-54,-8,-106,119,56,-95} + +#define RESET_GATE_WEIGHT_X2 {65,-28,-36,70,67,55,86,-53,23,25,-19,59,67,43,-92,48,94,-113,60,-58,24,76,-15,-19,15,36,-74,115,-59,3,34,-43,21,-125,-45,127,92,-5,-65,-103,-83,51,42,109,-51,-39,-97,-64,-4,57,79,-42,88,-4,-108,83,-4,20,86,82,-87,95,12,-69,28,30,-97,-13,-33,-48,75,119,18,31,-83,-59,-114,-21,127,34,-27,-26,-47,86,-83,-49,8,29,-48,-31,-94,-59,-49,-36,0,28,-64,113,65,-8,47,-55,-49,112,-40,-39,-100,-42,32,82,27,-78,-105,3,19,88,15,-121,-120,7,-9,-107,-23,104,114,66,113,-102,-90,24,80,-34,106,48,-91,-11,22,-96,-82,75,26,-42,59,-45,23,78,79,-76,6,20,63,-118,-125,-42,111,-80,-79,-59,-121,-79,83,49,-95,-49,81,15,-11,-54,-45,64,-30,-49,81,-57,71,91,113,-46,-63,-4,-96,-95,-27,5,-52,35,67,112,58,-62,48,112,106,80,-19,103,4,-32,-118,-74,12,13,-126,-20,-5,115,-74,-30,123,-74,-66,11,-99,-16,-102,-100,-81,-20,-24,92,-79,-31,44,-24,-85,-123,5,-52,-111,73,29,28,-19,18,23,-112,-32,-52,-38,99,-59,-52,-31,87,124,28,-42,-39,81,-87,-24,16,47,20,36,1,-70,121,124,13,1,30,112,87,-86,11,36,-18,74,-104,-100,-14,0,-24,28,-53,53,66,-63,-109,-10,-50,-15,63,34,82,-59,85,-44,105,-10,-27,99,5,-105,-69,-75,2,-47,-66,71,-30,73,-11,-45,93,47,-37,-34,-8,90,-106,103,112,65,-100,-25,-13,38,74,54,27,-81,-8,19,49,94,118,-121,-116,120,-71,-87,36,-65,-112,8,-59,-106,-40,-16,68,87,-109,53,12,-7,9,6,67,78,8,-42,-123,79,-93,-102,-40,12,-66,-109,47,15,-8,-5,51,-62,111,8,-66,-82,-102,120,68,-67,9,-73,-69,-79,56,-36,-10,-69,-99,-2,-11,-66,76,37,4,92,1,-89,74,85,-124,-25,40,106,-102,42,-19,-30,0,-70,82,84,106,-84,48,16,37,33,-114,38,-29,-117,51,101,26,56,127,-81,-76,38,-124,103,-25,54,-21,-112,40,102,3,63,36,-54,16,-18,114,39,5,105,83,117,-92,-5,-14,-102,-87,-48,-77,-19,-82,-55,119,-95,-43,97,126,-48,-50,-97,-25,-102,-53,47,111,66,-82,-16,-38,76,-15,23,20,88,-19,125,-90,107,-31,102,107,30,-111,71,38,26,43,-85,82,29,-99,126,-109,21,-42,-107,-115,-123,30,-46,39,4,-19,-44,-69,86,41,4,33,57,-110,95,-22,123,71,1,119,77,90,105,81,-68,74,-38,-109,6,-82,-20,-115,-104,38,27,-44,82,-107,99,-41,-28,-55,100,10,-42,7,91,56,-91,113,-91,70,-66,-48,-18,109,-27,42,-89,-20,-63,-41,77,-13,73,10,-74,-51,88,28,50,-5,7,92,18,-98,-41,-14,8,-16,99,30,-109,7,52,110,-120,-17,33,53,1,106,-99,-14,-93,-46,-60,7,-54,100,91,93,89,-84,118,58,-84,38,57,-24,-25,22,-52,119,-85,-75,-79,60,-97,1,-13,54,-43,98,-92,65,37,-110,64,21,-18,-111,-9,86,90,42,-71,-29,86,-10,-15,-20,106,-45,-22,44,105,55,-61,-89,-119,31,93,-97,-35,9,-113,86,-113,22,-68,-29,-36,-123,98,79,34,-29,71,44,49,56,93,4,63,-3,45,12,54,-96,27,-55,-72,84,69,27,-28,-111,-57,-41,92,-106,-90,55,105,-60,94,34,94,-1,112,-86,-55,-58,68,-65,37,110,-107,-62,66,61,-69,-52,27,-61,70,-56,-116,-101,-103,127,-98,-79,25,-117,40,33,111,10,-3,-65,1,84,-41,5,-93,-85,-96,78,54,43,70,77,-53,-71,-38,48,103,-88,115,94,20,-5,-125,-7,-61,30,-25,-57,-42,-100,63,-114,40,-53,123,50,-7,121,75,67,75,3,-38,-101,-44,-46,54,38,-22,4,18,102,-126,44,86,-10,-1,118,98,102,-125,74,32,18,74,73,72,64,47,105,-72,5,73,98,9,39,18,10,-68,81,-128,-89,27,-51,51,16,119,-71,-53,51,-84,107,-116,7,73,106,20,52,-85,-74,-103,-18,29,-13,73,106,-92,107,-115,5,65,83,-79,-7,98,-42,-33,82,-64,75,-32,100,-67,-122,84,43,-111,114,-99,46,12,99,43,50,-24,-88,-60,111,68,64,54,-105,-120,119,68,5,51,63,89,-57,-75,-25,-35,-28,42,-64,101,-103,-35,-99,-96,-18,-64,-94,-46,89,-65,-38,-1,-97,127,-67,84,-18,86,115,60,-78,-109,-61,-93,-67,-87,-80,124,26,-9,111,115,-88,-71,-86,-71,-65,-15,108,-25,111,9,86,-115,-55,-23,57,27,103,108,-28,65,86,68,114,62,126,-4,33,-34,-123,87,-76,-104,-126,26,-13,44,108,105,12,-35,-58,3,-5,-32,91,49,89,88,37,38,119,-125,-48,37,53,85,-73,67,116,-116,-127,103,127,-115,92,-35,-83,-45,25,-96,-13,-90,41,-27,105,119,85,27,-3,-64,93,17,-53,104,-70,-43,65,45,-90,61,-31,-49,-99,84,46,93,-37,84,-79,13,-59,-76,62,19,-11,-96,-104,-3,-8,-78,92,98,50,-7,-39,-82,37,-126,127,-113,67,94,115,-9,-33,-57,26,-67,9,28,-8,81,-98,-10,84,34,111,-95,127,75,38,-7,-2,-71,-62,-72,99,-74,25,123,114,51,-28,103,-110,43,113,7,58,75,-95,-52,19,-112,101,26,65,-115,-91,85,-5,-45,110,-103,-34,-69,50,-15,-19,-110,-44,-7,-112,-93,29,50,-84,-55,-41,11,19,-31,-47,-62,-12,-105,-47,68,-124,-47,-113,-55,30,25,55,-14,85,-66,-5,-105,62,-27,-89,-124,-84,112,34,52,25,104,32,-30,84,-46,-38,60,-2,-107,-95,-86,-25,117,60,-121,32,84,8,-88,-1,91,-46,-76,81,44,79,105,-105,82,20,59,-115,96,21,-113,19,92,122,76,36,-112,78,16,38,73,69,54,97,41,-49,78,-71,-69,95,-85,117,10,-98,25,72,126,47,-17,4,-44,-32,-16,-12,105,76,4,-82,-91,-21,-117,30,-67,46,-8,-125,84,-51,94,0,-60,127,99,43,60,16,55,-16,-121,-61,-115,38,25,17,35,23,68,9,-107,-44,118,119,43,99,-95,40,42,-70,54,19,92,-36,82,-35,122,-96,54,-29,-50,100,-79,-71,-99,-60,-2,-100,41,97,-93,-58,-123,126,-102,81,-5,83,110,-50,58,-86,41,-126,43,-49,98,-59,94,-91,115,16,-3,-58,-30,-109,110,-114,124,22,-88,-79,-29,-100,54,-33,23,-1,-77,52,-126,114,70,-50,90,82,-13,-25,-125,16,48,101,-93,19,-103,67,-1,-32,28,-72,-26,73,45,-22,83,-68,-61,89,57,-37,90,16,-38,-124,47,-5,-113,81,71,-30,-46,-18,-52,-104,-40,49,-101,106,38,6,125,-70,25,-88,-50,-77,-12,53,110,-84,23,-109,-53,112,2,88,101,-55,-10,-72,123,-35,42,-15,98,-85,48,-100,-54,123,52,-105,7,-28,86,-125,85,12,86,-34,103,-8,-65,-24,88,-43,57,-16,114,-98,101,81,34,-83,-8,3,-27,5,110,-24,-80,9,85,-108,96,-93,-34,76,-107,71,84,-98,-10,-94,71,71,-38,-96,-112,100,127,52,-32,-127,102,61,-119,-46,-119,125,109,-23,-80,-11,-68,84,-53,35,-115,105,-88,72,110,109,17,-121,80,-87,-72,-123,-31,13,71,63,-126,107,115,-100,27,39,10,75,-128,58,103,-104,126,-59,31,89,-67,97,-96,-69,87,19,99,49,111,9,91,-98,-4,-118,103,-63,-92,-74,106,-53,52,122,12,24,123,-126,-105,104,38,107,118,10,74,-38,14,-11,76,-112,-112,30,-47,95,112,65,-94,120,21,85,33,52,55,-54,-57,-77,-16,52,88,-81,-77,52,0,90,-126,66,88,-81,83,50,81,-28,-56,-36,-8,50,4,115,58,-30,-53,-78,-114,-16,-100,33,-80,-6,96,108,4,-27,-90,8,48,-118,-112,22,-56,114,-66,4,-11,-48,118,61,104,118,-27,13,52,2,74,112,-127,48,27,59,-37,-58,18,85,-5,-41,-91,-32,-56,-5,-40,-117,-89,-48,-8,-32,43,-75,-118,-109,-92,-122,67,88,107,79,-90,30,-65,-102,-100,-112,-104,57,-33,-103,69,-26,15,-12,106,-17,50,-20,33,51,14,98,-118,-82,63,-65,-40,-89,-8,-75,-16,-1,-13,118,76,34,-100,83,-10,72,26,-13,50,92,69,12,-33,-66,76,62,-47,-10,-31,60,-52,52,74,77,30,59,-98,-78,-124,107,38,-121,97,-39,-12,-1,63,-112,71,-65,9,-66,-31,50,39,77,56,-81,-125,-109,-36,-62,-74,12,31,-128,64,62,86,-9,26,69,-45,-35,46,39,95,78,-22,81,-5,-22,90,-47,-36,58,65,88,-89,37,81,115,-3,-108,52,7,-32,80,-96,-24,-22,104,-95,-3,117,59,105,66,-113,28,55,-75,46,45,-118,79,-3,-113,119,-114,-3,-64,56,34,118,67,32,25,-8,1,-64,91,112,31,-88,91,-53,115,33,-3,14,-43,82,-42,-57,-128,-124,127,-69,-112,98,-40,-9,-35,29,-87,-74,27,120,77,-70,93,39,95,118,-39,82,83,-26,60,106,-116,43,8,-114,66,28,5,-95,111,-11,68,24,44,65,-93,26,50,13,100,-33,-93,99,6,0,77,98,5,-10,84,77,46,4,-13,-31,-83,84,-78,-97,-58,76,-71,-6,2,27,-73,81,100,-126,-7,117,-10,-6,118,52,-4,25,56,43,-26,-43,-64,23,-44,-108,-53,45,-117,91,-88,-45,-87,63,120,82,70,73,-108,89,-12,35,-81,-98,-124,-114,-126,86,21,-35,-32,-105,122,111,98,77,38,-18,-7,-48,69,22,74,-127,-62,-47,-20,-8,9,-48,-2,-53,-58,-37,51,27,-91,57,69,-27,-91,76,-127,78,76,-108,-1,13,-71,-41,38,46,60,-5,-73,-98,123,106,35,-38,-102,2,125,25,-63,-110,9,25,-106,-21,-113,-111,97,-33,33,83,55,123,72,-11,-78,-85,35,56,-110,-18,118,9,85,-100,-65,126,24,-18,50,-32,98,40,114,59,-60,-6,-72,-68,16,21,-10,-6,113,-23,-24,-27,-116,-126,119,6,-78,118,15,-53,7,113,3,83,52,44,-44,-53,-85,78,-108,-83,-128,63,-10,-122,-92,24,28,21,-87} + +#define RESET_GATE_WEIGHT_X4 {65,28,-28,30,-90,106,24,80,-36,-97,70,-13,80,-19,-34,103,67,-33,55,-48,106,4,48,-32,86,75,-53,119,-91,-118,-11,-74,23,18,25,31,22,12,-96,13,-19,-83,59,-59,-82,-126,75,-20,67,-114,43,-21,26,-5,-42,115,-92,127,48,34,59,-74,-45,-30,94,-27,-113,-26,23,123,78,-74,60,-47,-58,86,79,-66,-76,11,24,-83,76,-49,6,-99,20,-16,-15,8,-19,29,63,-102,-118,-100,15,-48,36,-31,-125,-81,-42,-20,-74,-94,115,-59,111,-24,-80,92,-59,-49,3,-36,-79,-79,-59,-31,34,0,-43,28,-121,44,-79,-24,21,-64,-125,113,83,-85,49,-123,-45,65,127,-8,-95,5,-49,-52,92,47,-5,-55,81,-111,15,73,-65,-49,-103,112,-11,29,-54,28,-83,-40,51,-39,-45,-19,64,18,42,-100,109,-42,-30,23,-49,-112,-51,32,-39,82,81,-32,-57,-52,-97,27,-64,-78,71,-38,91,99,-4,-105,57,3,113,-59,-46,-52,79,19,-42,88,-63,-31,-4,87,88,15,-4,-121,-96,124,-95,28,-108,-120,83,7,-27,-42,5,-39,-4,-9,20,-107,-52,81,35,-87,86,-23,82,104,67,-24,112,16,-87,114,95,66,58,47,-62,20,12,113,-69,-102,48,36,112,1,-70,54,121,27,-2,-102,-11,-87,124,-81,13,-8,-66,-48,76,-77,1,19,30,49,37,-19,4,-82,112,94,87,118,92,-55,1,119,-86,-121,11,-116,-89,-95,74,-43,36,120,-18,-71,85,97,-124,126,74,-87,-104,36,-25,-48,40,-50,-100,-65,-14,-112,106,-97,-102,-25,0,8,-24,-59,42,-102,-19,-53,28,-106,-53,-40,-30,47,0,111,53,-16,66,68,-70,66,82,-82,-63,87,-109,-109,84,-16,106,-38,-10,53,-50,12,-84,76,48,-15,-15,-7,63,9,16,23,37,20,34,6,82,67,33,88,-114,-19,-59,78,85,8,38,125,-29,-90,-44,-42,105,-123,-117,107,51,-31,-10,79,-27,-93,101,102,26,107,99,-102,5,-40,56,30,127,-111,-105,12,-69,-66,-81,71,-76,38,-75,-109,2,47,38,26,-124,43,-47,15,-66,-8,103,-85,-25,82,71,-5,-30,51,54,29,-21,-99,73,-62,-11,111,-112,126,40,-109,-45,8,93,-66,102,21,3,-42,47,-82,-37,-102,63,-107,36,-115,-34,120,-8,68,-54,-123,16,30,90,-67,-106,9,-18,-46,114,39,103,-73,112,-69,39,4,5,-19,65,-79,-100,56,105,-44,83,-69,-25,-36,-13,-10,117,86,-92,41,38,-69,74,-99,-5,4,-14,33,57,-41,-110,-14,-15,68,-20,-65,95,8,-22,-16,106,37,-45,110,123,99,71,30,-22,-107,44,-62,1,-109,119,7,105,66,55,61,77,52,90,110,-61,-69,-89,-52,105,-120,81,-17,-119,27,31,-61,-68,33,74,53,93,70,-97,-56,-38,1,-109,106,-35,-116,9,-101,6,-99,-82,-14,-113,-103,86,127,-20,-93,-115,-46,-113,-98,22,-79,-104,-60,38,7,-68,25,-29,-117,27,-54,-44,100,-36,40,-123,33,82,91,-107,93,98,111,79,10,99,89,-41,-84,34,-3,-29,-65,-28,118,-55,58,71,1,44,84,100,-84,10,38,49,-41,56,5,-42,57,7,-24,93,-93,4,-85,91,-25,56,22,63,-96,-3,78,-91,-52,113,119,45,54,12,43,-91,-85,70,-75,54,70,-96,77,-66,-79,-48,60,27,-53,-55,-71,-18,-97,109,1,-72,-38,84,48,-27,-13,42,54,69,103,27,-88,-89,-43,-20,98,-28,115,-111,94,-63,-92,-41,65,-57,20,-41,-5,77,37,-13,-110,92,-125,-106,-7,73,64,10,21,-90,-61,55,30,-74,-18,-51,-111,105,-25,-60,-57,88,-9,28,86,94,-42,34,-100,50,90,-5,42,94,63,-1,-114,7,-71,92,-29,112,40,-86,-53,18,86,-98,-10,-55,123,-58,50,-7,-103,121,-18,-46,-35,89,-58,75,29,67,-13,-65,3,-38,-5,75,73,3,106,-1,-32,-97,91,-38,-92,-101,107,127,49,-67,89,-44,-115,-46,5,84,88,-18,37,54,65,38,83,86,38,115,119,-22,-79,4,-7,60,-125,-78,-48,18,98,102,-42,-109,37,-61,53,-126,-33,44,82,-93,85,-67,-73,86,-64,-10,75,-87,67,-80,116,-1,-32,118,100,124,-116,26,-127,98,-67,102,-122,-9,103,111,127,-125,84,74,43,115,-115,-88,92,32,-111,18,114,-71,-35,-86,-83,74,-99,73,46,-71,-45,-65,25,72,12,64,99,-15,-96,108,-13,47,43,105,50,-25,-90,111,41,-72,-24,5,-88,9,-27,86,105,73,-60,98,111,-115,119,-55,85,9,68,39,64,-23,27,57,-3,18,54,10,-105,27,-64,103,93,-68,-120,81,119,108,17,-28,-53,-128,68,-89,5,65,104,86,-70,27,51,-51,63,68,-43,114,65,51,89,16,-57,62,45,126,-90,119,-75,-71,-25,-4,61,33,-31,-53,-35,51,-28,-34,-49,-123,-99,-84,42,107,-64,87,84,-76,46,-116,101,7,-103,-104,93,-126,-37,73,-35,106,-99,26,84,-13,-79,20,-96,52,-18,44,13,108,-59,-85,-64,-74,-94,105,-76,12,62,19,-115,-11,-91,117,-67,60,46,-96,85,-104,-5,-121,-8,32,-125,-3,-45,-8,110,84,84,8,-51,-78,-103,92,-34,-88,94,-1,0,98,-69,50,50,91,-60,-46,127,-7,-15,-39,-19,-76,99,81,43,-82,-110,37,-44,44,60,79,16,-126,-7,127,-112,105,55,-105,-16,-113,-93,67,29,82,-121,20,-61,94,50,115,-84,59,-115,-115,38,-9,-55,-33,-41,96,25,21,17,-57,11,26,19,-113,35,19,23,-67,-31,9,-47,92,68,122,9,28,-62,-8,-12,76,-107,36,-44,81,-105,-98,-47,-112,118,78,119,-10,68,84,-124,16,43,38,99,34,-47,111,-113,73,-95,69,40,-95,-55,127,30,54,42,97,-70,75,25,38,55,41,54,-49,19,-7,-14,-2,85,78,92,-71,-36,-71,-66,-62,-5,-69,82,95,-35,-72,-105,99,62,-85,122,117,-96,-74,-27,25,-89,10,54,-98,-29,123,-124,114,-84,25,-50,72,100,51,112,-28,34,126,-79,47,-71,103,52,-110,25,-17,-99,4,-60,43,104,113,32,-44,-2,-32,-100,7,-30,58,84,-16,41,-12,97,75,-46,-95,-38,105,-93,76,-58,-52,60,19,-2,4,-123,-82,126,-112,-107,101,-95,-91,-102,-21,81,26,-86,65,-25,-117,-5,30,83,110,-38,-50,-124,57,-31,-16,13,58,47,-86,-5,114,71,-98,63,41,-113,-126,81,101,-126,81,107,43,71,-49,-30,34,115,-83,-100,98,-46,-59,-18,-8,27,3,39,94,-52,-91,-104,-27,10,5,75,115,-40,16,49,110,-128,-24,58,-3,-101,-58,106,-80,103,9,-104,-30,38,-109,6,85,126,-108,-59,110,125,-114,-70,96,31,-93,89,124,25,22,-88,-34,-67,76,97,-88,-50,-79,-77,-107,-96,71,-69,-29,-12,-100,53,84,87,-98,19,54,110,-33,-84,-10,99,-94,49,23,23,-1,-109,71,111,71,9,-77,-53,52,112,-38,91,-96,-98,-126,2,114,88,-112,-4,100,-118,70,101,-50,-55,127,103,52,-63,90,-10,82,-72,-32,-92,-127,-74,-13,123,-25,-35,102,106,61,-53,-125,42,16,-15,-119,52,-46,122,48,98,101,-85,-119,12,125,24,-93,48,19,-100,109,123,-23,-126,-103,-54,67,123,-80,-105,-11,104,-1,52,-32,-105,-68,38,84,107,28,7,-72,-28,-53,118,35,10,-26,86,73,-125,-115,74,105,-38,45,85,-22,12,-88,14,72,-11,83,86,-68,-34,110,76,109,-112,-61,103,89,-8,17,-112,-121,30,57,-65,-37,-24,80,-47,-87,95,90,88,16,-43,-72,112,-123,65,-94,52,120,2,-16,26,-1,69,21,74,85,112,-13,-45,118,-35,33,-127,52,48,76,46,34,39,55,27,-54,59,-100,95,83,78,-57,-37,-77,-58,-10,-22,72,81,-16,18,52,85,26,-5,-13,-22,88,-5,-81,-41,50,90,92,-47,-77,-91,52,-32,69,-36,12,58,0,-56,90,-5,-33,65,-66,88,-126,-40,66,-117,76,-89,62,37,88,-89,-81,-48,-47,81,-10,115,83,-8,50,-32,-31,-3,60,-108,81,43,-28,-75,-52,52,52,7,-56,-118,-36,-109,74,-32,77,80,-8,-92,50,-122,30,-96,59,-24,4,67,115,88,-98,-22,-78,104,58,107,-30,79,-124,-95,107,-3,-53,-90,-78,30,38,117,-121,59,-114,-65,-16,-102,97,105,-39,66,-100,-100,33,-112,-12,-113,-1,28,-80,-104,-6,57,63,55,-112,-75,96,-33,108,-103,71,46,-65,45,4,69,-27,-26,9,-118,-66,79,-90,15,8,-12,-31,-3,50,-113,48,106,-118,-17,39,119,77,-114,-112,50,22,-20,56,-3,-81,-64,-56,33,114,51,-125,56,-109,34,-66,14,4,98,-36,118,-62,67,-11,-118,-48,-82,-74,32,12,25,118,63,61,-65,31,-8,-128,1,104,-40,118,-89,64,-64,62,91,-27,-8,13,-75,86,112,-9,31,-88,-10,91,84,111,123,98,72,-53,77,115,46,77,-11,38,-78,33,4,-3,-13,-18,-85,-7,35,14,-31,-43,-83,-48,56,69,-110,82,84,-42,-78,22,-18,74,118,-57,-97,-128,-58,-127,9,-62,85,-124,76,127,-71,-47,-100,-20,-65,-69,-6,-112,2,-8,126,9,24,98,27,-40,-73,-48,-18,-2,50,-9,81,-35,100,-53,-32,-58,98,29,-126,-87,-7,-37,40,51,114,-74,117,27,-10,27,59,-91,-60,120,-6,77,118,57,-6,69,-72,-70,52,93,-4,-27,-68,-91,16,39,25,95,56,76,21,-127,-10,118,43,-39,-26,78,-6,76,113,82,-43,83,-64,-108,-23,-1,-24,-26,23,60,-44,13,-27,-71,-116,106,-108,-116,-53,-41,-126,38,119,43,45,8,-117,46,6,60,-78,-114,91,66,-88,-5,118,-73,15,28,-45,5,-87,-98,-53,123,7,-95,63,111,120,106,113,35,3,-11,82,68,70,-38,83,-102,52,24,73,44,-108,2,44,125,-44,65,89,-93,-12,25,-53,-63,-85,26,35,50,-81,-110,78,9,-108,13,-98,100,-124,25,-83,-106,-128,-33,-114,-93,-126,-21,63,-113,-10,99,86,6,21,-111,-122,97,-92,0,-35,77,-32,-33,24,33,28,98,-105,5,122,83,21,55,-87} + +#define HIDDEN_STATE_WEIGHT_X2 {-3,-33,59,21,117,70,0,44,108,108,-47,-80,-118,34,88,-91,-123,-108,8,51,26,82,-80,107,-100,-69,97,-90,17,19,63,111,-40,-125,110,24,58,-69,26,-31,-65,-37,-47,-41,-109,106,-100,108,-99,108,116,104,86,-50,-45,10,-53,112,34,96,-10,-39,-32,-25,69,102,-2,-4,-25,121,-1,-28,-48,-100,0,-128,60,-73,42,-32,118,-88,-113,-112,-113,70,-98,118,95,77,-52,123,-99,72,26,-102,-32,120,113,22,6,-68,84,-33,103,66,111,60,-76,33,10,25,-43,93,41,-79,110,13,67,107,-113,90,58,64,-125,79,-85,-18,76,80,-59,11,-18,-74,15,-102,99,-19,117,99,65,-50,-108,-121,-9,-104,33,94,-95,110,-48,-97,76,36,1,-58,86,-115,45,-88,38,51,123,-23,-20,-43,-37,15,91,-85,-88,6,-96,58,78,13,23,1,-43,62,-70,-108,44,30,74,90,79,-80,-20,71,-21,0,60,19,-59,-52,44,-14,77,92,-69,121,-123,-27,119,-84,79,87,24,85,118,1,-51,-96,60,102,-6,15,96,120,-109,6,35,11,-119,-109,-18,16,-112,91,-126,71,-29,121,-21,-120,37,57,-117,-39,93,56,-73,-104,77,-107,-52,111,-61,-4,44,-119,67,72,-66,36,-127,-113,-124,123,21,98,84,86,76,23,78,7,-127,-4,1,-46,-107,59,-21,53,-65,-99,-15,-98,53,-31,7,64,7,105,51,-75,50,-52,48,101,-126,-120,5,34,3,81,-39,70,41,112,25,30,79,-6,107,-11,-97,92,-84,67,49,107,60,101,-37,27,-91,-61,-96,120,-113,87,-46,68,64,102,-86,-60,13,-71,56,-105,90,-9,-35,27,103,120,39,23,-39,-1,-85,-95,-6,119,-41,-2,-69,102,102,-119,-3,-11,-125,-111,40,-115,-41,-117,-44,-7,83,123,-21,23,99,-107,43,100,-99,-3,89,3,-113,103,47,-94,-69,-38,-28,-37,49,-117,-49,-126,17,-98,37,92,55,-116,-70,-50,77,120,47,124,78,114,67,-48,6,-42,-115,85,116,-114,-46,-50,-13,70,-101,110,-55,20,-51,125,-19,-9,-15,46,30,-27,-123,114,-50,-30,-72,76,-83,71,47,-45,74,102,44,108,-26,108,-113,-43,110,-91,37,-69,76,-33,106,-76,-96,20,-117,63,-33,-5,11,-121,-51,63,-56,59,-16,-33,114,74,124,73,99,-50,51,-71,118,106,30,-92,26,-40,119,-121,2,-45,9,0,-5,-2,-89,88,-11,-85,-60,19,81,-96,75,82,-40,124,89,-36,-117,-100,-2,-34,112,101,39,-101,-106,60,59,-126,-32,96,68,-53,87,20,54,-24,46,-95,65,-112,22,60,122,-22,-106,-124,97,-37,-86,95,-110,-8,44,58,-12,-120,-45,-86,-32,-86,-94,-14,15,29,-8,-114,71,70,-93,-69,100,-123,-18,-47,-12,127,104,-102,93,-11,-73,121,87,-79,-92,46,92,-108,-107,79,121,-71,-89,16,-11,-52,72,-114,-32,-60,-9,-57,-4,10,-81,-22,68,74,76,-68,-127,96,-84,69,-3,-26,-106,-3,-87,-65,105,109,122,-103,31,-108,-86,-5,-39,85,88,67,-82,0,-25,93,61,-62,5,-54,-114,-51,-9,-114,20,49,-26,38,19,39,-103,33,-120,37,-97,32,-89,119,111,-124,-99,78,-49,-128,76,-18,-12,-109,96,90,-73,-104,59,-59,-92,123,55,54,-120,-80,-48,-16,-95,96,36,118,-119,-58,93,45,-43,-75,64,38,-2,-72,-111,22,-89,-75,-120,-42,45,108,59,-105,40,27,32,-66,121,-22,-71,-9,118,124,60,-96,47,4,14,-27,64,70,47,-91,-70,1,-44,94,-46,53,4,23,-124,-92,-95,83,-49,-81,40,-80,48,0,39,1,-113,32,40,-21,-1,-110,102,1,-74,-51,40,108,-35,-36,89,84,123,-48,-115,-115,83,-61,114,-127,-61,114,100,-82,-45,60,87,60,19,86,97,-68,40,-66,75,86,-32,-128,88,-57,-27,77,3,-27,43,-39,-62,66,5,-82,45,-104,-78,34,57,96,89,-90,66,-10,37,-110,-30,82,-58,13,94,12,115,35,117,0,80,61,-7,107,-104,-21,21,-70,-93,-94,-51,-61,39,-62,64,-82,-109,76,84,58,-47,-100,52,46,-51,88,91,8,-47,108,-80,25,-58,111,-59,-83,-75,92,98,110,54,106,65,-47,-120,-5,90,-123,101,-61,-85,-93,109,88,0,8,59,86,56,126,17,-26,58,-101,-25,35,0,-123,-3,-56,112,-128,8,17,-52,88,31,-3,105,-56,68,-1,-94,96,-19,10,-22,-88,-10,119,-44,19,42,75,-86,18,-107,89,-82,-120,76,40,84,-122,29,33,-47,17,-50,-13,23,-66,-46,85,-29,-110,42,-68,8,99,-93,-29,101,16,52,-13,127,0,86,-117,-92,-70,-32,-27,127,-123,1,34,-13,92,114,-11,29,-103,-121,-54,20,73,16,74,108,16,-61,89,50,-30,-14,116,44,-31,16,96,24,-51,7,39,-87,-69,-61,-98,61,-46,113,85,-95,103,67,99,-66,-45,-42,-70,96,104,5,-111,69,-25,99,-118,23,109,11,4,-41,-94,73,100,96,6,90,-75,-25,79,-13,-43,-6,-12,51,12,40,124,-56,81,-8,59,-60,-26,-54,33,122,85,53,-99,125,19,-26,94,41,-5,46,-48,-70,-10,41,102,-1,-98,-9,15,29,46,-66,-118,-53,45,119,-127,94,53,-58,90,124,5,-110,-98,-80,-77,77,29,19,105,-121,92,9,-124,50,-119,59,40,67,104,-12,13,103,101,47,-51,34,-66,-101,-117,112,-5,118,-48,-60,-114,38,-71,2,51,114,80,115,-5,116,20,16,-47,-19,30,24,-68,7,-30,-3,-64,-7,-34,-12,44,34,-91,-97,116,112,-99,108,-75,17,26,-14,-61,80,22,-7,34,47,-93,45,106,121,78,43,-97,39,-99,-68,-72,-7,64,-49,-82,-127,78,-64,48,18,15,126,-125,-111,-69,-111,10,-46,111,-75,123,-44,-67,-31,-96,-67,-53,-53,-106,67,-101,23,62,30,9,-114,-12,-57,-38,-78,95,-10,-3,110,88,123,-26,78,-125,114,53,10,-57,26,38,-51,73,92,-124,79,15,75,-62,109,-113,-67,1,35,52,-36,55,7,111,-43,109,101,88,122,-21,-32,-87,59,16,-122,-109,-118,17,-22,-39,53,-105,77,90,-24,-65,43,-27,113,30,-117,-30,106,37,55,59,54,-70,99,99,-73,120,97,-39,-88,-54,101,51,-76,70,-121,-68,23,-73,-31,75,-8,-63,-123,-93,96,-81,99,-95,28,-36,55,-104,32,-64,41,-97,95,-89,126,-26,-25,126,2,-26,-54,110,-86,110,74,-3,-110,56,-60,-49,117,-82,-55,-103,-112,70,-85,85,-63,82,7,75,-61,90,32,35,-115,72,73,-121,63,-84,-52,-29,-59,-4,29,64,119,127,58,-117,48,126,120,-115,-15,-10,27,27,-81,117,-5,121,-72,113,31,-13,10,27,-106,-51,81,-96,-22,19,-78,6,71,-34,123,118,75,-23,-72,-97,111,-121,0,80,28,52,95,59,-116,72,80,-75,-62,88,23,-102,13,6,113,-85,98,45,-96,-32,94,-7,12,-9,86,18,59,-15,75,13,-70,50,-93,52,67,53,-31,19,45,-111,36,39,-91,-77,104,71,7,-44,-76,3,-62,121,43,37,-7,-96,-6,57,-104,30,-126,-94,118,-44,91,29,124,-86,-13,55,41,-41,91,-112,-25,103,81,-70,-112,113,-25,-73,-82,16,67,-5,104,56,66,-115,-90,-126,106,80,-78,-51,-15,-68,-3,102,-10,-123,-10,-71,-111,86,48,-45,101,81,-114,-94,77,-127,-96,-100,86,109,-33,15,-34,60,88,-86,-63,-103,-46,101,-127,-88,90,-37,82,-125,-28,-6,61,-104,77,0,-52,59,-9,-82,59,-78,79,80,-77,-125,-95,16,26,-55,-16,15,-76,-9,56,110,85,-102,-23,-12,-6,-97,-34,32,-79,-95,71,126,127,30,-112,-115,75,-8,125,103,-118,65,-43,107,46,96,-41,-87,-64,-18,126,82,10,81,45,95,61,9,28,-113,-71,47,117,26,-81,73,49,-55,-126,-33,62,-84,-87,-56,-71,97,49,-124,-76,-9,97,119,-23,127,-29,20,-66,-80,-122,40,-2,116,126,-120,-48,124,57,-107,104,80,-13,81,118,33,88,119,-110,33,-35,-75,-6,89,-41,99,46,127,-36,54,-55,50,24,51,49,-71,37,-117,114,6,110,88,84,-30,-45,-50,113,-12,-57,59,-18,49,99,-124,46,-48,88,-82,-121,-97,15,-73,-128,-121,46,30,-93,-109,-15,-86,-2,75,1,-32,-27,-86,-13,-38,48,10,-36,-107,-27,-48,88,-7,-88,98,-83,61,-81,20,-123,18,-41,-127,-55,-66,24,-107,73,30,-42,-74,124,-43,-125,102,98,6,32,24,-123,32,113,105,-81,117,-41,-54,-113,-126,-28,31,-56,-64,-6,-103,-36,-2,-59,34,-40,-64,-39,-64,-74,-105,50,-86,-66,-14,-71,35,-116,-20,15,-119,-12,90,-117,-29,13,-8,-75,57,67,124,-38,66,113,-80,113,105,45,-74,-80,108,-24,-3,36,62,-8,109,-40,-101,106,12,-47,-113,-118,-12,-3,-86,-52,-93,-24,-62,-119,-93,67,39,4,-18,-103,24,1,71,93,95,-113,-7,34,-10,-77,-74,96,86,52,-2,-45,-71,-48,124,-97,1,23,-59,-117,-74,58,-31,-115,114,-14,-115,77,82,100,67,117,-16,-64,105,-19,59,124,124,-116,-33,22,-115,30,102,91,98,-124,38,12,-38,-23,-106,52,75,-45,74,-6,-29,31,117,20,99,66,27,-92,127,-67,-53,68,-66,-26,35,114,-84,-74,-94,-14,-43,-106,-32,-67,-27,28,29,-32,-101,-60,-55,-6,-101,-42,61,111,107,-87,-67,102,-36,119,-81,-54,52,-114,5,-26,115,-7,44,-30,-21,-67,33,-92,29,-30,3,7,-101,-83,-115,29,68,49,-70,-40,-116,63,-49,115,97,123,119,22,-13,47,-4,-14,-94,94,-122,56,58,57,-127,-60,-46,29,94,-105,49,-72,94,20,-8,104,35,-90,19,-26,24,-7,109,10,-9,80,-105,0,126,94,105,63,85,43,-63,-2,-32,39,-119,-12,-108,33,-67,127,-66,-23,-123,8,41,-21,-30,117,20,-85,-39,-87,2,96,-12,-128,83,67,-53,-101,3,-3,-22,-16,51,125,-125,-76,25,42,101,101,35,-36,103,85,-71,-24,6,26,105,60,112,-91,69,13,21,10,-93,22,-111,0,-38,4,-34,45,-86,121,-42,-54,7} + +#define HIDDEN_STATE_WEIGHT_X4 {-3,69,-33,102,76,60,80,19,59,-2,21,-4,-59,-59,11,-52,117,-25,70,121,-18,44,-74,-14,0,-1,44,-28,15,77,-102,92,108,-48,108,-100,99,-69,-19,121,-47,0,-80,-128,117,-123,99,-27,-118,60,34,-73,65,119,-50,-84,88,42,-91,-32,-108,79,-121,87,-123,118,-108,-88,-9,24,-104,85,8,-113,51,-112,33,118,94,1,26,-113,82,70,-95,-51,110,-96,-80,-98,107,118,-48,60,-97,102,-100,95,-69,77,76,-6,36,15,97,-52,-90,123,1,96,-58,120,17,-99,19,72,86,-109,-115,6,63,26,111,-102,45,35,-88,11,-40,-32,-125,120,38,-119,51,-109,110,113,24,22,123,-18,-23,16,58,6,-69,-68,-20,-112,-43,91,26,84,-31,-33,-37,-126,15,71,-65,103,-37,66,91,-29,-85,121,-47,111,-41,60,-88,-21,6,-120,-109,-76,106,33,-96,37,58,57,-100,10,108,25,78,-117,13,-39,-99,-43,108,93,23,93,1,56,116,41,104,-79,-43,-73,62,-104,86,110,-50,13,-70,77,-108,-107,-45,67,10,107,44,-52,30,111,-53,-113,112,90,74,-61,90,-4,34,58,96,64,79,44,-80,-119,-10,-125,-39,79,-20,67,71,72,-32,-85,-25,-18,-21,-66,0,36,-127,-96,-113,120,49,76,-117,-33,-124,-113,123,87,-49,106,-126,-76,21,-46,98,68,17,-96,-98,20,84,64,86,102,37,-117,92,63,76,-86,23,-60,55,-33,-116,-5,78,13,7,-71,-70,11,-50,-121,-127,56,-4,-105,77,-51,120,63,1,90,-46,-9,47,-56,124,59,-107,-35,59,27,78,-16,114,-33,-21,103,53,120,67,114,-48,74,-65,39,-99,23,6,124,-42,73,-15,-39,-98,-1,-115,99,85,-50,53,-85,-31,-95,116,51,-114,-71,7,-6,64,119,-46,118,-50,106,7,-41,105,-2,-13,30,70,-92,51,-69,-75,102,-101,26,110,-40,50,102,-52,-119,-55,119,20,-121,48,-3,101,-11,-51,2,125,-45,-126,-125,-120,-111,-19,9,-9,0,5,40,34,-115,-15,-5,46,-2,3,-41,81,-117,30,-89,-27,88,-39,-44,70,-7,-123,-11,114,-85,41,83,112,123,-50,-60,-30,19,25,-21,30,23,-72,81,76,-96,79,99,-6,-107,-83,75,71,82,107,43,-11,100,47,-40,-45,124,-97,-99,92,-3,74,89,102,-36,-84,89,67,3,44,-117,108,-100,49,-113,107,103,-26,-2,108,-34,60,47,101,-94,-113,112,-43,101,-37,-69,27,-38,110,39,-91,-101,-91,-28,-61,-37,37,-106,-69,60,59,121,-126,-71,-97,47,32,4,-32,-89,96,16,-89,14,119,-27,68,-11,-53,-52,111,64,-124,70,87,72,20,-114,-99,47,78,-91,54,-32,-24,-60,-49,-70,-128,1,46,-9,-95,-57,76,-44,-18,94,65,-4,-112,10,-12,-46,-109,53,22,-81,60,-22,96,4,90,23,122,68,-22,74,-73,-124,-104,-92,-106,76,-124,-68,59,-95,-59,83,97,-127,-37,96,-92,-49,123,-81,-86,-84,95,69,55,40,54,-80,-110,-3,-8,-26,-120,48,-80,0,44,-106,58,-3,-48,39,-16,1,-12,-87,-120,-65,-95,-113,96,32,-45,105,-86,109,36,40,118,-21,-32,122,-86,-103,-119,-1,-58,-110,-94,31,-14,-108,93,102,45,1,15,-86,29,-5,-43,-74,-75,-51,-8,-39,-114,85,64,40,38,108,71,88,70,67,-2,-35,-72,-36,-93,-82,-69,0,-111,89,22,84,100,-25,-123,93,-89,123,-75,-48,-18,61,-47,-62,-120,-115,-42,-115,-12,5,127,-54,45,83,108,-61,104,-114,-102,-51,59,114,-105,-127,93,-9,-11,-114,40,-61,27,114,-73,20,121,49,32,100,-66,-82,87,-26,-79,38,121,-45,-22,60,-92,19,46,39,-71,87,-9,60,92,-103,-108,33,118,19,124,86,-107,-120,79,37,60,97,-96,-68,40,-51,-66,88,-10,-61,119,89,75,91,86,8,-44,50,19,-30,-32,-47,-128,108,42,-14,75,116,88,-80,-57,25,-86,44,18,-31,-27,-58,77,111,-107,16,89,96,3,-59,-27,-83,-82,24,-120,-51,43,-75,-39,92,76,7,40,39,-62,98,66,110,84,-87,-122,-69,5,54,-82,106,29,-61,33,-98,45,65,-104,-47,-47,61,17,-46,-78,-120,34,-5,-50,113,-13,85,57,90,96,-123,23,-95,-66,103,89,101,-90,-61,-46,67,85,99,66,-85,-10,-93,-29,-66,-110,-45,37,109,-110,88,42,-42,-68,-70,-30,0,82,8,8,96,99,104,-58,59,13,86,-93,5,-29,-111,94,56,12,126,101,69,16,-25,115,17,35,-26,52,99,-13,-118,117,58,0,-101,127,23,0,109,80,-25,61,35,86,11,-117,4,-7,0,107,-123,-92,-41,-70,-94,-104,-3,-21,-56,-32,73,-27,100,21,112,-70,-128,127,96,-123,6,-93,8,-94,17,1,90,34,-75,-51,-52,-61,88,-13,-25,92,79,39,31,-62,-3,114,-13,-11,-43,64,105,-82,-56,29,-6,-103,-12,-109,68,76,-1,-121,51,-54,12,84,-94,58,96,20,40,73,124,-47,-19,-100,10,16,-56,74,81,52,-22,46,-88,108,-8,16,59,-60,-101,-26,-117,-127,-36,78,55,-54,112,33,-5,-64,7,48,111,122,118,85,-48,18,-43,15,109,53,-60,-99,-114,126,101,-125,88,125,38,19,-71,-111,122,-69,-21,-26,2,94,51,-111,-32,10,-87,41,114,-5,80,-46,59,111,16,46,115,-48,-5,-75,-122,123,-109,-70,116,-10,20,-44,-118,-67,17,41,16,102,-47,-31,-22,-96,-39,-1,-19,-98,30,-67,53,-53,-105,-9,24,15,-68,-53,77,-106,90,29,7,46,-30,67,-24,-101,-65,-66,-3,-118,-64,23,43,62,-27,-53,-7,45,-34,30,113,9,30,119,-12,-127,44,-114,-117,-12,-30,94,34,53,-91,-57,106,-38,37,-58,-97,90,116,-78,55,95,59,124,112,5,-99,-10,54,-3,-70,-110,108,-98,-75,110,99,88,99,-80,17,-77,26,123,-73,-26,120,77,-14,29,-61,78,97,-125,-39,19,80,105,22,114,-88,53,-54,-121,-7,92,34,10,101,-57,51,9,47,-124,-93,26,-76,38,70,50,45,-119,106,-51,-121,73,-68,59,121,40,78,92,23,-124,-73,67,43,104,-97,79,-31,15,75,-12,39,13,-99,75,-8,-62,-63,103,-68,101,-72,109,-123,-113,-93,47,-7,-51,64,-67,96,1,-81,34,-49,-66,-82,35,99,52,-95,28,27,-36,27,-93,-15,52,-68,55,-81,-104,117,67,-3,53,102,32,-5,-64,121,-31,-10,19,-123,41,-72,-97,113,45,-10,-111,-71,95,31,-89,-13,36,-111,39,86,126,10,-26,27,-91,48,-77,-45,-25,-106,126,-51,104,101,71,81,2,81,-26,-96,7,-114,-44,-94,-54,-22,110,19,-76,77,3,-127,-86,-78,110,6,-62,-96,121,-100,74,71,-3,-34,43,86,37,109,-110,123,56,118,-7,-33,-96,15,-60,75,-49,-23,-6,-34,57,60,117,-72,-82,-97,-104,88,30,-86,-55,111,-103,-121,-126,-63,-94,-103,-112,0,70,80,118,-46,-44,101,-85,28,85,52,91,-127,29,-88,-63,95,82,59,124,90,-86,-37,7,-116,75,72,-13,82,55,-125,-61,80,90,-75,41,-28,-41,-6,32,-62,35,88,91,61,-112,-104,-115,23,72,-102,-25,77,103,0,73,13,-121,6,81,-52,-70,59,63,113,-84,-85,-112,-9,113,-82,-52,98,-29,45,-25,59,-73,-78,-59,-96,-4,-32,-82,79,16,80,29,94,64,-7,67,-77,-5,-125,119,12,127,-9,104,-95,56,16,58,86,-117,18,66,26,-115,-55,48,59,126,-15,-90,-16,-126,15,120,75,-115,13,106,-76,80,-9,-15,-70,-10,50,-78,56,-51,110,85,-29,-102,20,15,-56,-73,-64,-23,-66,-12,-80,-128,-6,-121,-103,-6,-122,-97,40,46,-36,30,-2,-34,-2,32,116,-93,-59,-109,34,-79,126,-95,-120,-15,-40,-86,-64,71,-48,126,124,-2,-39,75,-64,127,57,30,-107,1,-74,-32,-105,-112,104,-115,80,-27,50,-86,-86,75,-13,-8,81,-13,-66,-38,-14,125,118,103,33,48,-71,10,35,-118,88,65,119,-36,-116,-107,-20,-43,-110,107,33,-27,15,-48,-119,46,-35,96,-75,88,-12,-7,90,-41,-6,-87,89,-88,-117,98,-29,-64,-41,-18,99,-83,13,61,-8,126,46,82,127,-81,-75,20,57,10,-36,81,54,-123,67,18,124,45,-55,95,50,-41,-38,-127,66,61,24,9,51,-55,113,-66,-80,28,49,-113,-71,24,113,-107,105,-71,37,47,-117,73,45,30,-74,117,114,26,6,-42,-80,-74,108,-81,110,73,88,124,-24,-43,-3,49,84,-55,-30,-125,36,102,62,-126,-45,-33,-50,98,-8,6,109,62,113,-84,-12,32,-40,24,-101,-87,-57,-56,59,-123,106,32,12,-71,-18,97,49,113,-47,105,-113,49,99,-124,-124,-81,-118,117,-12,-76,46,-9,-48,-41,-3,-54,-86,97,88,119,-82,-113,-52,-126,-93,-23,-121,127,-97,-28,-24,31,-62,-119,52,-93,75,7,33,-101,-67,67,-45,39,74,-83,127,-115,-66,4,-6,-18,-29,29,-23,68,-123,-103,31,24,117,49,8,-70,41,1,20,71,99,-40,-21,-116,-30,93,66,95,27,63,117,-49,20,-113,-92,-7,127,115,-85,97,-39,34,-67,-10,-53,123,-87,119,2,-77,68,-74,-66,22,96,-13,-12,96,-26,86,35,47,-128,-4,83,52,114,-2,-84,-14,67,-94,-53,-45,-74,-71,-94,94,-101,-122,3,-48,-14,124,-43,56,-3,58,-22,-97,-106,1,-32,57,-16,-127,51,23,-67,-59,-27,-60,125,-46,-125,-117,28,-74,29,29,-76,94,25,58,-32,-31,-101,-105,42,49,101,-115,-60,114,-55,-72,101,94,35,-14,-6,-115,-101,20,-36,-8,103,77,-42,82,61,104,85,35,-71,100,111,67,107,-90,-24,19,6,117,-87,-16,-67,-26,26,24,105,-64,102,105,-36,-7,60,109,112,-19,119,59,-81,10,-91,-9,69,124,-54,124,52,80,13,-105,21,-116,-114,-33,5,0,10,126,-93,22,-26,-115,115,94,22,105,-111,30,-7,102,44,63,0,85,-38,91,-30,98,-21,43,4,-63,-34,-124,-67,38,33,-2,45,-32,-86,12,-92,-38,29,39,121,-119,-42,-23,-30,-106,3,-12,-54,-108,7} + +#define UPDATE_GATE_BIAS {-85,78,113,70,33,38,8,114,70,-35,-67,65,31,-24,-70,-124,-89,104,124,-122,111,61,-87,75,-61,-98,83,-69,-63,45,-11,103} + +#define RESET_GATE_BIAS {-77,67,-93,-3,98,59,-121,33,49,50,41,91,-115,-33,71,47,-70,45,89,-115,72,106,-22,100,97,-100,-95,108,-33,3,14,30} + +#define HIDDEN_STATE_BIAS {-85,78,113,70,33,38,8,114,70,-35,-67,65,31,-24,-70,-124,-89,104,124,-122,111,61,-87,75,-61,-98,83,-69,-63,45,-11,103} + +#define INPUT_DATA1 {-367,-338,0,-89,453,-413,-343,-16,42,418,201,274,-352,477,-290,-92,266,-49,342,453,-398,247,-153,328,217,342,85,69,-38,351,73,128} + +#define INPUT_DATA2 {280,41,-322,61,315,350,504,-227,-221,-483,352,252,455,-236,344,364,-378,229,-187,-498,295,357,-511,58,-349,-458,-420,-66,-400,-379,477,-60} + +#define HISTORY_DATA {-38,53,105,-79,-463,51,-343,-226,-435,-282,218,441,-299,-215,-109,335,340,-471,-109,273,33,-245,-469,170,-26,-59,192,-119,76,-6,236,-145} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nn_tables.h b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nn_tables.h new file mode 100644 index 0000000..9357424 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nn_tables.h @@ -0,0 +1,59 @@ +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_tables.h + * Description: Extern declaration for NN tables + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ARM_NN_TABLES_H +#define _ARM_NN_TABLES_H + +#include "arm_math.h" + +/** +* @brief tables for various activation functions +* +*/ + +extern const q15_t sigmoidTable_q15[256]; +extern const q7_t sigmoidTable_q7[256]; + +extern const q7_t tanhTable_q7[256]; +extern const q15_t tanhTable_q15[256]; + + /** + * @brief 2-way tables for various activation functions + * + * 2-way table, H table for value larger than 1/4 + * L table for value smaller than 1/4, H table for remaining + * We have this only for the q15_t version. It does not make + * sense to have it for q7_t type + */ +extern const q15_t sigmoidHTable_q15[192]; +extern const q15_t sigmoidLTable_q15[128]; + +extern const q15_t sigmoidLTable_q15[128]; +extern const q15_t sigmoidHTable_q15[192]; + +#endif /* ARM_NN_TABLES_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnfunctions.h b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnfunctions.h new file mode 100644 index 0000000..96c59c2 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnfunctions.h @@ -0,0 +1,1010 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nnfunctions.h + * Description: Public header file for CMSIS NN Library + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS NN Software Library + * + * Introduction + * ------------ + * + * This user manual describes the CMSIS NN software library, + * a collection of efficient neural network kernels developed to maximize the + * performance and minimize the memory footprint of neural networks on Cortex-M processor cores. + * + * The library is divided into a number of functions each covering a specific category: + * - Neural Network Convolution Functions + * - Neural Network Activation Functions + * - Fully-connected Layer Functions + * - Neural Network Pooling Functions + * - Softmax Functions + * - Neural Network Support Functions + * + * The library has separate functions for operating on different weight and activation data + * types including 8-bit integers (q7_t) and 16-bit integers (q15_t). The descrition of the + * kernels are included in the function description. The implementation details are also + * described in this paper [1]. + * + * Block Diagram + * -------- + * \image html CMSIS-NN-OVERVIEW.PNG + * + * Examples + * -------- + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Pre-processor Macros + * ------------ + * + * Each library project have differant pre-processor macros. + * + * - ARM_MATH_DSP: + * + * Define macro ARM_MATH_DSP, If the silicon supports DSP instructions. + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_NN_TRUNCATE: + * + * Define macro ARM_NN_TRUNCATE to use floor instead of round-to-the-nearest-int for the computation. + * + * Copyright Notice + * ------------ + * + * Copyright (C) 2010-2018 Arm Limited. All rights reserved. + * + * [1] CMSIS-NN: Efficient Neural Network Kernels for Arm Cortex-M CPUs https://arxiv.org/abs/1801.06601 + */ + +/** + * @defgroup groupNN Neural Network Functions + * These functions perform basic operations for neural network layers. + */ + +#ifndef _ARM_NNFUNCTIONS_H +#define _ARM_NNFUNCTIONS_H + +#include "arm_nnsupportfunctions.h" +#include "arm_nn_tables.h" + +#define USE_INTRINSIC + +//#define ARM_NN_TRUNCATE /* This config the rounding model to floor or round to the nearest int */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup NNConv Neural Network Convolution Functions + * + * Perform convolution layer + * + * The convolution is implemented in 2 steps: im2col and GEMM + * + * im2col is a process of converting each patch of image data into + * a column. After im2col, the convolution is computed as matrix-matrix + * multiplication. + * + * To reduce the memory footprint, the im2col is performed partially. + * Each iteration, only a few column (i.e., patches) are generated and + * computed with GEMM kernels similar to CMSIS-DSP arm_mat_mult functions. + * + */ + + /** + * @brief Basic Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_convolve_HWC_q7_basic(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Basic Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + */ + + arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Basic Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_convolve_HWC_q15_basic(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + + arm_status arm_convolve_HWC_q7_fast(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + + arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q7 version of 1x1 convolution (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function implement convolution with 1x1 kernel size (i.e., dim_kernel_x=1 + * and dim_kernel_y=1). It can be used for + * second half of MobileNets after depthwise separable convolution. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Q7 version of convolution for RGB image + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This kernel is written exclusively for convolution with ch_im_in + * equals 3. This applies on the first layer of CNNs which has input + * image with RGB format. + */ + + arm_status arm_convolve_HWC_q7_RGB(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + + arm_status arm_convolve_HWC_q15_fast(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Fast Q15 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + + arm_status + arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Q7 depthwise separable convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + + arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB); + + /** + * @brief Q7 depthwise separable convolution function (non-square shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding sizes x + * @param[in] padding_y padding sizes y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + +/** + * @defgroup FC Fully-connected Layer Functions + * + * Perform fully-connected layer + * + * Fully-connected layer is basically a matrix-vector multiplication + * with bias. The matrix is the weights and the input/output vectors + * are the activation values. Supported {weight, activation} precisions + * include {8-bit, 8-bit}, {16-bit, 16-bit}, and {8-bit, 16-bit}. + * + * Here we have two types of kernel functions. The basic function + * implements the function using regular GEMV approach. The opt functions + * operates with weights in interleaved formats. + * + */ + + /** + * @brief Q7 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q7(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q7_opt(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Q15 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q15(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_q15_opt(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Mixed Q15-Q7 fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_mat_q7_vec_q15(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + + /** + * @brief Mixed Q15-Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + */ + + arm_status arm_fully_connected_mat_q7_vec_q15_opt(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer); + +/** + * @brief Matrix-Multiplication Kernels for Convolution + * + * These functions are used within convolution layer functions for + * matrix multiplication. + * + * The implementation is similar to CMSIS-DSP arm_mat_mult functions + * with one Q7 and one Q15 operands. The Q15 operand is the im2col + * output which is always with 2 columns. + * + */ + + /** + * @brief Matrix-multiplication function for convolution + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + */ + + q7_t *arm_nn_mat_mult_kernel_q7_q15(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut); + + /** + * @brief Matrix-multiplication function for convolution with reordered columns + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + */ + + q7_t *arm_nn_mat_mult_kernel_q7_q15_reordered(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut); + +#ifdef __cplusplus +} +#endif + +/* + * Other functions + * These layers are typically not timing critical + * Basic implementation is supported here + */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @defgroup Acti Neural Network Activation Functions + * + * Perform activation layers, including ReLU (Rectified Linear Unit), + * sigmoid and tanh + * + */ + + /** + * @brief Q7 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + */ + + void arm_relu_q7(q7_t * data, uint16_t size); + + /** + * @brief Q15 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + */ + + void arm_relu_q15(q15_t * data, uint16_t size); + + /** + * @brief Q7 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + */ + + void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width, + arm_nn_activation_type type); + + /** + * @brief Q15 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + */ + + void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width, + arm_nn_activation_type type); + +/** + * @defgroup Pooling Neural Network Pooling Functions + * + * Perform pooling functions, including max pooling and average pooling + * + */ + + /** + * @brief Q7 max pooling function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + */ + + void arm_maxpool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const uint16_t dim_im_out, + q7_t * bufferA, + q7_t * Im_out); + + /** + * @brief Q7 average pooling function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + */ + + void arm_avepool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const uint16_t dim_im_out, + q7_t * bufferA, + q7_t * Im_out); + +/** + * @defgroup Softmax Softmax Functions + * + * EXP(2) based softmax function + * + */ + + /** + * @brief Q7 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * @return none. + * + */ + + void arm_softmax_q7(const q7_t * vec_in, const uint16_t dim_vec, q7_t * p_out); + + /** + * @brief Q15 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * @return none. + * + */ + + void arm_softmax_q15(const q15_t * vec_in, const uint16_t dim_vec, q15_t * p_out); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h new file mode 100644 index 0000000..05a239d --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Include/arm_nnsupportfunctions.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nnsupportfunctions.h + * Description: Public header file of support functions for CMSIS NN Library + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#ifndef _ARM_NNSUPPORTFUNCTIONS_H_ +#define _ARM_NNSUPPORTFUNCTIONS_H_ + +#include "arm_math.h" +#include "arm_common_tables.h" +//#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Union for SIMD access of Q31/Q15/Q7 types + */ +union arm_nnword +{ + q31_t word; + /**< Q31 type */ + q15_t half_words[2]; + /**< Q15 type */ + q7_t bytes[4]; + /**< Q7 type */ +}; + +/** + * @brief Struct for specifying activation function types + * + */ +typedef enum +{ + ARM_SIGMOID = 0, + /**< Sigmoid activation function */ + ARM_TANH = 1, + /**< Tanh activation function */ +} arm_nn_activation_type; + +/** + * @defgroup nndata_convert Neural Network Data Conversion Functions + * + * Perform data type conversion in-between neural network operations + * + */ + +/** + * @brief Converts the elements of the Q7 vector to Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none. + * + */ + +void arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize); + +/** + * @brief Converts the elements of the Q7 vector to reordered Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none. + * + */ + +void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize); + +#if defined (ARM_MATH_DSP) + +/** + * @brief read and expand one Q7 word into two Q15 words + */ + +__STATIC_FORCEINLINE void *read_and_pad(void *source, q31_t * out1, q31_t * out2) +{ + q31_t inA = *__SIMD32(source)++; + q31_t inAbuf1 = __SXTB16(__ROR(inA, 8)); + q31_t inAbuf2 = __SXTB16(inA); + +#ifndef ARM_MATH_BIG_ENDIAN + *out2 = __PKHTB(inAbuf1, inAbuf2, 16); + *out1 = __PKHBT(inAbuf2, inAbuf1, 16); +#else + *out1 = __PKHTB(inAbuf1, inAbuf2, 16); + *out2 = __PKHBT(inAbuf2, inAbuf1, 16); +#endif + + return source; +} + +/** + * @brief read and expand one Q7 word into two Q15 words with reordering + */ + +__STATIC_FORCEINLINE void *read_and_pad_reordered(void *source, q31_t * out1, q31_t * out2) +{ + q31_t inA = *__SIMD32(source)++; +#ifndef ARM_MATH_BIG_ENDIAN + *out2 = __SXTB16(__ROR(inA, 8)); + *out1 = __SXTB16(inA); +#else + *out1 = __SXTB16(__ROR(inA, 8)); + *out2 = __SXTB16(inA); +#endif + + return source; +} +#endif + +/** + * @defgroup NNBasicMath Basic Math Functions for Neural Network Computation + * + * Basic Math Functions for Neural Network Computation + * + */ + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated. + */ + +void arm_nn_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + const uint16_t out_shift, + uint32_t blockSize); + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated. + */ + +void arm_nn_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + const uint16_t out_shift, + uint32_t blockSize); + +/** + * @brief defition to adding rouding offset + */ +#ifndef ARM_NN_TRUNCATE + #define NN_ROUND(out_shift) ( 0x1 << (out_shift - 1) ) +#else + #define NN_ROUND(out_shift) 0 +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM0/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM0/RTE_Components.h new file mode 100644 index 0000000..bf1d6d1 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM0/RTE_Components.h @@ -0,0 +1,20 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_cifar10' + * Target: 'ARMCM0' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM0.h" + + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM3/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM3/RTE_Components.h new file mode 100644 index 0000000..6993e2a --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM3/RTE_Components.h @@ -0,0 +1,26 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_nn_test' + * Target: 'ARMCM3' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM3.h" + +#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */ + #define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */ +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ +#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */ + #define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM4_FP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM4_FP/RTE_Components.h new file mode 100644 index 0000000..374579e --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM4_FP/RTE_Components.h @@ -0,0 +1,26 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_nn_test' + * Target: 'ARMCM4_FP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM4_FP.h" + +#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */ + #define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */ +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ +#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */ + #define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM7_SP/RTE_Components.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM7_SP/RTE_Components.h new file mode 100644 index 0000000..40dfc78 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/RTE/_ARMCM7_SP/RTE_Components.h @@ -0,0 +1,26 @@ + +/* + * Auto generated Run-Time-Environment Component Configuration File + * *** Do not modify ! *** + * + * Project: 'arm_nnexamples_nn_test' + * Target: 'ARMCM7_SP' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM7_SP.h" + +#define RTE_Compiler_IO_STDERR /* Compiler I/O: STDERR */ + #define RTE_Compiler_IO_STDERR_ITM /* Compiler I/O: STDERR ITM */ +#define RTE_Compiler_IO_STDOUT /* Compiler I/O: STDOUT */ + #define RTE_Compiler_IO_STDOUT_ITM /* Compiler I/O: STDOUT ITM */ +#define RTE_Compiler_IO_TTY /* Compiler I/O: TTY */ + #define RTE_Compiler_IO_TTY_ITM /* Compiler I/O: TTY ITM */ + +#endif /* RTE_COMPONENTS_H */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref.c new file mode 100644 index 0000000..4aa6077 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_convolve_HWC_q15_ref(const q15_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q15_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q15_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q15_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ) +{ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { +#ifndef ARM_NN_TRUNCATE + conv_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1)); +#else + conv_out = bias[i] << bias_shift; +#endif + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref_nonsquare.c new file mode 100644 index 0000000..69efcb2 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q15_ref_nonsquare.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void +arm_convolve_HWC_q15_nonsquare_ref(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) + +{ + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { +#ifndef ARM_NN_TRUNCATE + conv_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1)); +#else + conv_out = bias[i] << bias_shift; +#endif + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel_x * dim_kernel_y + (m * dim_kernel_x + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } +} + + diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref.c new file mode 100644 index 0000000..aaf25ba --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_convolve_HWC_q7_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q7_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ) +{ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { +#ifndef ARM_NN_TRUNCATE + conv_out = ((q31_t) (bias[i]) << bias_shift) + (0x1 << (out_shift - 1)); +#else + conv_out = bias[i] << bias_shift; +#endif + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + // if-for implementation + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref_nonsquare.c new file mode 100644 index 0000000..e731d07 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_convolve_HWC_q7_ref_nonsquare.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_convolve_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const q7_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y, // output image dimension y + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ) +{ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { +#ifndef ARM_NN_TRUNCATE + conv_out = ((q31_t) (bias[i]) << bias_shift) + (0x1 << (out_shift - 1)); +#else + conv_out = bias[i] << bias_shift; +#endif + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in + + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref.c new file mode 100644 index 0000000..970effc --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_depthwise_separable_conv_HWC_q7_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q7_t * bias, // bias + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + q7_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ) +{ + int i_out_y, i_out_x, i_ch_out; + int i_ker_y, i_ker_x; + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output +#ifndef ARM_NN_TRUNCATE + int conv_out = (bias[i_ch_out] << bias_shift) + (0x1 << (out_shift - 1)); +#else + int conv_out = bias[i_ch_out] << bias_shift; +#endif + for (i_ker_y = 0; i_ker_y < dim_kernel; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel; i_ker_x++) + { + int in_row = stride * i_out_y + i_ker_y - padding; + int in_col = stride * i_out_x + i_ker_x - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + i_ch_out] * + wt[(i_ker_y * dim_kernel + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out + i_out_x) * ch_im_out + i_ch_out] = + (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref_nonsquare.c new file mode 100644 index 0000000..8fa4147 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_depthwise_separable_conv_HWC_q7_ref_nonsquare.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const q7_t * bias, // bias + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + q7_t * Im_out, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y, // output image dimension y + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ) +{ + int i_out_y, i_out_x, i_ch_out; + int i_ker_y, i_ker_x; + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output +#ifndef ARM_NN_TRUNCATE + int conv_out = (bias[i_ch_out] << bias_shift) + (0x1 << (out_shift - 1)); +#else + int conv_out = bias[i_ch_out] << bias_shift; +#endif + for (i_ker_y = 0; i_ker_y < dim_kernel_y; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel_x; i_ker_x++) + { + int in_row = stride_y * i_out_y + i_ker_y - padding_y; + int in_col = stride_x * i_out_x + i_ker_x - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + i_ch_out] * + wt[(i_ker_y * dim_kernel_x + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out_x + i_out_x) * ch_im_out + i_ch_out] = + (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_opt_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_opt_ref.c new file mode 100644 index 0000000..6fe5e2b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_opt_ref.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_mat_q7_vec_q15_opt_ref(const q15_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer) +{ + + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + q31_t sum = *pBias++ << bias_shift; + q31_t sum2 = *pBias++ << bias_shift; + q31_t sum3 = *pBias++ << bias_shift; + q31_t sum4 = *pBias++ << bias_shift; +#endif + + uint16_t colCnt = dim_vec >> 1; + + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + colCnt--; + } + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = *pBias++ << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_ref.c new file mode 100644 index 0000000..6a4d385 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_mat_q7_vec_q15_ref.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_mat_q7_vec_q15_ref(const q15_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer) +{ + for (int i = 0; i < num_of_rows; i++) + { +#ifndef ARM_NN_TRUNCATE + int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = bias[i] << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_opt_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_opt_ref.c new file mode 100644 index 0000000..475c757 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_opt_ref.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_q15_opt_ref(const q15_t * pV, // pointer to vector + const q15_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q15_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer) +{ + + uint16_t rowCnt = num_of_rows >> 2; + const q15_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q15_t *pBias = bias; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + q31_t sum = *pBias++ << bias_shift; + q31_t sum2 = *pBias++ << bias_shift; + q31_t sum3 = *pBias++ << bias_shift; + q31_t sum4 = *pBias++ << bias_shift; +#endif + + uint16_t colCnt = dim_vec >> 1; + + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q15_t inB1 = *pB++; + q15_t inB2 = *pB++; + sum += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum2 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum3 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum4 += inA1 * inB1 + inA2 * inB2; + + colCnt--; + } + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = *pBias++ << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_ref.c new file mode 100644 index 0000000..3fd0bc0 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q15_ref.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_q15_ref(const q15_t * pV, // pointer to vector + const q15_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q15_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer) +{ + for (int i = 0; i < num_of_rows; i++) + { +#ifndef ARM_NN_TRUNCATE + int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = bias[i] << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_opt_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_opt_ref.c new file mode 100644 index 0000000..cee8faa --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_opt_ref.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_q7_opt_ref(const q7_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q7_t * pOut, // output operand + q15_t * vec_buffer) +{ + + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q7_t *pA; + q7_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + q31_t sum = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum2 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum3 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); + q31_t sum4 = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + q31_t sum = *pBias++ << bias_shift; + q31_t sum2 = *pBias++ << bias_shift; + q31_t sum3 = *pBias++ << bias_shift; + q31_t sum4 = *pBias++ << bias_shift; +#endif + + uint16_t colCnt = dim_vec >> 2; + + while (colCnt) + { + q7_t inA1 = *pA++; + q7_t inA3 = *pA++; + q7_t inA2 = *pA++; + q7_t inA4 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum += inA3 * inB1 + inA4 * inB2; + sum2 += inA3 * inB3 + inA4 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA3 * inB1 + inA4 * inB2; + sum4 += inA3 * inB3 + inA4 * inB4; + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + pA = pV; +#ifndef ARM_NN_TRUNCATE + int ip_out = (*pBias++ << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = *pBias++ << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q7_t) __SSAT((ip_out >> out_shift), 8); + + rowCnt--; + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_ref.c new file mode 100644 index 0000000..78c891c --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_fully_connected_q7_ref.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_fully_connected_q7_ref(const q7_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q7_t * pOut, // output operand + q15_t * vec_buffer) +{ + for (int i = 0; i < num_of_rows; i++) + { +#ifndef ARM_NN_TRUNCATE + int ip_out = (bias[i] << bias_shift) + (0x1 << (out_shift - 1)); +#else + int ip_out = bias[i] << bias_shift; +#endif + for (int j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q7_t) __SSAT((ip_out >> out_shift), 8); + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_nn_mult_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_nn_mult_ref.c new file mode 100644 index 0000000..e78850f --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_nn_mult_ref.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +void arm_nn_mult_q7_ref(q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) { + uint16_t i; + +for (i = 0; i < blockSize; i++) + { + q31_t product = pSrcA[i] * pSrcB[i]; +#ifndef ARM_NN_TRUNCATE + pDst[i] = (q7_t)__SSAT((product + (0x1 << (out_shift - 1)))>>out_shift, 8); +#else + pDst[i] = (q7_t)__SSAT(product >> out_shift, 8); +#endif + } +} + +void arm_nn_mult_q15_ref(q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) { + uint16_t i; + +for (i = 0; i < blockSize; i++) + { + q31_t product = pSrcA[i] * pSrcB[i]; +#ifndef ARM_NN_TRUNCATE + pDst[i] = (q15_t)__SSAT((product + (0x1 << (out_shift - 1)))>>out_shift, 16); +#else + pDst[i] = (q15_t)__SSAT(product >> out_shift, 16); +#endif + + + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_pool_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_pool_ref.c new file mode 100644 index 0000000..b75a0a2 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_pool_ref.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ref_functions.h" + +void arm_avepool_q7_HWC_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimension + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel, // window kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const uint16_t dim_im_out, // output image dimension + q7_t * bufferA, // a buffer for local storage + q7_t * Im_out) +{ + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int sum = 0; + int count = 0; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + sum += Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + count++; + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = sum / count; + } + } + } +} + +void arm_maxpool_q7_HWC_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimension + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel, // window kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const uint16_t dim_im_out, // output image dimension + q7_t * bufferA, // a buffer for local storage + q7_t * Im_out) +{ + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int max = -129; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + if (Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)] > max) + { + max = Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + } + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = max; + } + } + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_relu_ref.c b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_relu_ref.c new file mode 100644 index 0000000..9397ef1 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/arm_relu_ref.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +void arm_relu_q7_ref(q7_t * data, uint16_t size) +{ + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } +} + +void arm_relu_q15_ref(q15_t * data, uint16_t size) +{ + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/fully_connected_testing_weights.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/fully_connected_testing_weights.h new file mode 100644 index 0000000..31cdcb0 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/fully_connected_testing_weights.h @@ -0,0 +1,7 @@ +#define IP2_WEIGHT {18,-12,-120,-75,60,-92,62,106,43,43,-108,-80,78,76,94,13,-125,63,54,-121,-61,26,60,-125,-79,112,-45,-97,-59,-100,28,35,-15,26,-41,-65,-99,106,115,109,-20,-75,83,-106,51,-55,25,-126,15,-46,-73,62,-89,-15,-37,-79,-12,43,-30,120,46,116,113,11,-57,-81,113,-53,4,117,18,-31,101,65,125,60,76,91,-53,-63,-74,73,-47,-51,-87,-27,-126,-12,107,103,79,113,-41,93,124,122,-72,67,93,-103,-97,-61,62,-17,10,30,124,-119,-17,31,-60,4,88,-76,18,25,-109,-47,19,33,102,71,66,-42,-111,8,-4,-44,78,40,-19,107,-118,11,-105,-116,48,0,-73,-101,-55,-20,-81,71,-121,60,107,110,103,-28,88,-85,34,-90,12,-105,-21,-10,-115,118,-84,97,86,-67,-80,-43,-107,115,108,-49,-59,22,19,122,-76,82,-16,93,67,-100,-57,-41,-43,99,-1,-69,-79,54,-46,24,-59,-1,77,-94,111,-20,-35,108,54,3,107,-59,17,-112,106,-108,95,37,63,60,9,-65,-63,7,-118,-69,-48,111,120,40,44,63,-67,108,26,-37,127,96,-54,-1,21,88,-24,-112,-115,-27,-9,59,-89,22,109,45,47,-42,68,-72,94,55,-121,-23,-2,83,105,-18,104,-34,29,-80,58,-104,-6,-20,53,-86,-5,115,94,39,100,70,-70,-69,-121,-106,-43,94,83,120,121,-93,-97,90,0,-26,-87,6,-26,1,94,67,-26,-71,-21,64,53,35,-46,-102,-58,-103,-7,-34,15,-19,117,-27,59,20,111,-31,-31,43,-36,-19,49,94,-17,119,32,118,110,-19,121,24,30,-74,-12,-38,52,21,-38,98,-58,63,-115,-84,29,22,-93,63,-127,-113,56,25,-2,43,88,107,29,14,116,88,-24,115,-22,-14,-65,116,-119,-95,88,57,-64,18,-127,8,-123,-51,-80,75,-8,-98,2,-109,19,76,40,3,117,121,-4,61,92,-56,21,94,47,-32,24,-50,-38,-26,111,-61,118,-111,94,-14,-74,51,-38,-116,111,62,-39,-121,97,109,-45,-122,-37,-62,108,-74,73,34,59,-21,-20,37,-2,-102,45,121,-41,-116,80,-2,110,-52,-39,62,-12,-127,52,99,13,124,-15,-89,89,85,67,-119,110,-38,-13,-14,-53,-97,119,-121,16,14,-53,-65,-118,26,-4,19,111,-44,22,-57,81,110,-26,-70,45,55,-55,108,-122,-78,-34,24,-69,90,-48,-76,-80,-123,-49,10,113,89,58,119,68,-26,109,-35,-90,88,-90,-66,-24,78,-122,-84,82,76,93,106,123,-52,2,-19,-125,38,36,105,31,3,-99,-27,74,54,-29,8,40,30,-111,21,-118,87,95,58,-29,-117,84,-83,114,-75,96,64,94,-23,-44,46,-77,-82,62,104,74,26,-91,7,63,81,14,-27,33,41,31,-9,64,-19,60,-79,21,-120,49,26,63,-8,105,-116,-58,65,87,-38,-27,109,-97,-50,63,83,-70,111,32,-70,104,22,-123,74,-61,98,60,58,-13,-80,-37,-62,76,-82,-26,76,109,25,81,78,-104,96,-29,-9,-6,-46,-120,54,-33,-30,-108,41,22,110,-54,78,52,14,-40,-70,59,-101,-38,61,-122,77,46,116,-3,-21,-124,-23,41,80,83,29,-71,-43,9,101,77,35,-119,2,93,-30,22,-62,97,-12,29,40,41,36,106,-87,21,93,-41,-112,60,-100,81,91,-89,-10,79,-69,-7,-113,111,-47,51,-23,14,16,-56,98,26,-50,121,127,-104,39,-38,44,-22,-73,-69,125,61,15,-78,-119,-47,-15,-44,-90,-72,29,61,92,109,-10,25,-16,-49,-31,-109,121,5,-2,-125,10,53,80,-13,46,38,1,73,116,66,75,-18,-50,99,-44,-126,-60,-126,-26,-57,-121,-35,105,57,77,112,44,56,83,66,-94,106,60,-119,-124,-25,57,104,106,122,-52,-51,-38,68,47,64,-50,25,-64,-72,-127,73,124,-51,-96,116,53,75,-18,97,97,-96,-12,-16,46,29,105,-118,11,53,-31,-127,-98,-126,2,-115,-116,12,-47,-70,-106,-41,73,-115,-55,-96,126,-124,-41,-48,-43,-6,18,-107,-106,-59,86,-5,85,89,-17,91,-71,103,-116,-122,-80,99,-26,-87,-14,-4,-110,52,-44,-124,-47,15,104,-52,-16,18,62,92,-92,-81,101,94,38,45,-77,-103,-124,74,67,70,-113,25,25,-53,-125,124,33,-84,-119,118,105,-70,-101,-108,-48,111,118,-91,-49,38,102,105,24,56,-95,-119,-45,-96,88,33,126,-101,74,-30,17,-35,24,-23,123,47,-41,-82,91,-3,60,15,-4,46,38,49,-8,-35,82,28,110,8,-58,-108,-124,60,125,-5,49,31,69,-73,94,-25,75,107,75,-1,53,-32,66,20,121,-75,-39,-13,-84,120,15,8,-33,-46,-30,-121,-119,-17,73,-102,-36,103,-20,11,-62,-80,-111,69,-84,-37,38,82,-87,8,69,-110,80,66,-41,122,102,125,-90,72,109,-120,-25,-56,-43,-44,-93,48,63,-59,-30,106,85,-83,-68,44,112,-75,-61,-127,-4,21,-124,-79,-111,-65,68,0,-111,62,-14,41,27,53,68,69,102,-55,122,99,-5,-74,74,2,96,71,107,49,88,19,55,10,84,-124,2,10,-47,-66,-1,-61,-70,3,-101,37,113,120,33,3,18,3,52,-86,38,91,-88,-48,-115,104,-20,49,-25,26,-108,-82,86,80,-125,-86,-73,-109,-72,-49,108,56,-8,-103,-10,-115,-99,97,-120,15,-94,-52,90,-1,-39,-1,-2,89,-103,-69,-82,-63,-32,59,101,-23,-83,-67,-112,-23,-12,-47,-105,-85,-117,-9,-80,-34,-38,108,-77,89,112,-63,28,-69,70,-99,47,59,82,16,-89,47,-78,-21,-101,23,115,-98,-89,23,83,-113,-26,6,-15,101,-72,95,15,-116,46,107,117,67,-98,45,21,-30,10,108,120,99,-30,-91,-96,100,53,-62,-126,54,103,96,-20,-57,14,-128,123,-104,-7,-62,-49,-94,105,108,-104,52,5,-91,114,62,102,-103,10,84,1,30,-102,-17,-112,91,-115,14,1,54,-110,4,99,-10,-35,78,84,78,-66,120,-110,-29,-92,105,-96,118,64,81,48,-127,-32,-9,51,69,-31,40,-84,111,4,-123,-43,54,55,100,-61,19,33,-65,-50,-27,42,120,-66,-126,-17,36,107,2,53,80,95,-94,17,64,50,-25,29,9,-67,-101,-24,82,97,-53,-58,-119,-40,-10,8,-99,60,-29,79,-79,-43,-127,-73,26,-60,-26,114,-82,-19,-111,49,3,-54,100,67,45,72,-84,-50,-17,123,54,-94,-86,80,-9,-87,-51,-57,-32,-92,123,40,-93,-44,-61,-24,-128,-85,-52,-56,-52,51,32,-23,-108,-32,8,-69,9,-2,84,-36,24,126,-80,-73,3,42,20,30,-46,-29,25,89,-30,48,115,37,57,-47,-95,-100,-77,-38,-8,26,-37,-23,-31,124,65,67,-87,35,19,-80,107,-71,120,106,21,-28,69,24,-110,103,-43,-68,94,95,-105,28,-16,-49,-6,88,121,-36,-83,28,-101,102,-28,40,-7,-108,28,97,11,-98,117,80,2,-92,-62,-43,-67,113,74,59,18,-72,-124,-126,-52,102,-128,-14,125,-116,-40,21,82,13,-2,59,-111,-110,-125,-44,-94,109,111,49,-71,40,-52,1,2,-73,-62,-40,-30,-93,-43,25,-103,-94,-110,126,-112,78,32,24,-95,-121,101,25,95,66,-63,5,72,-61,-83,-66,-88,-57,118,113,-110,92,-44,-3,15,24,-14,-114,14,33,-76,-75,80,76,-110,122,-56,101,12,66,-89,21,-76,42,86,-49,77,65,97,127,-20,43,0,-117,115,9,-83,-27,119,15,-122,4,21,-47,72,-113,-68,-98,-124,-89,125,-90,-83,35,-74,79,101,-65,127,60,-118,104,73,44,-41,-111,79,54,-70,-52,-97,10,18,-17,91,-46,-72,3,-35,-23,44,84,-11,-17,-11,-45,-38,67,75,-100,3,54,-16,-22,66,-98,-79,41,-110,-49,-76,-6,-33,-109,30,6,-18,84,63,50,-119,64,-127,-79,101,-91,59,-87,-51,0,-18,-23,-102,-99,120,-28,123,-86,59,-81,-22,-13,43,107,-13,-92,78,95,-10,26,-108,36,-57,-44,-118,-93,-62,-77,-33,-6,-50,-122,-103,-20,57,24,3,-25,-95,-91,-47,74,14,20,16,23,52,78,-15,-17,69,13,-98,126,84,115,74,-125,23,62,110,34,124,-38,111,6,106,-24,82,53,-102,-53,-36,7,60,1,19,80,-26,-111,58,83,-76,-19,112,121,41,-45,69,112,-95,98,-126,68,-37,-109,-55,-70,77,-97,35,-61,12,-58,54,-36,93,-48,4,10,104,102,37,70,4,10,-18,33,26,0,60,69,-49,26,66,-114,-22,-72,-96,124,16,-6,-92,-52,83,103,96,77,-99,4,80,10,-119,-108,-117,122,39,-13,-72,-7,77,-91,58,111,3,29,52,93,116,-123,-16,44,-60,107,60,-57,83,15,42,33,-93,-16,60,-97,53,86,5,-76,120,-42,-88,-35,18,12,110,-4,-62,84,2,-46,-14,-99,27,96,96,-69,15,102,79,-84,-24,-7,-64,-49,107,-51,17,108,-3,-41,-104,122,-123,-2,-58,-69,-36,-69,-33,81,-78,12,0,11,-63,125,97,58,-43,-63,-49,48,73,-78,-87,-88,-94,94,97,56,-31,-27,-113,125,-128,-25,-65,5,67,71,-26,7,40,-115,-55,-119,74,-34,-111,-42,-77,-15,-80,41,71,-121,-62,54,-95,-76,122,-115,101,-80,36,82,-55,-25,11,11,105,39,-98,-80,-77,-45,-58,93,-118,64,126,124,-46,1,26,113,37,107,108,-117,-127,123,-17,-120,-64,-35,-99,10,81,2,55,-110,-122,-120,-3,-24,-11,109,126,72,60,-18,92,-79,32,84,2,103,-7,-22,-7,-2,-108,-40,-55,45,47,14,-77,-60,50,43,-98,67,-52,51,101,107,105,45,-24,52,93,46,-61,-45,-36,-63,-33,-33,50,-81,-30,38,-124,73,-106,-90,54,-116,-86,-77,76,-63,-5,121,-22,-79,-73,-87,29,69,68,5,87,-85,-36,43,124,0,-62,104,72,-98,-63,-90,76,88,52,12,107,63,119,-54,102,-30,80,-63,-50,51,-5,79,110,-101,-11,32,80,-90,-22,-28,78,42,-76,89,-22,74,111,9,-78,28,-76,-17,20,-113,44,99,-82,31,-94,40,42,-75,-10,57,27,41,-29,42,-104,127,-70,-119,115,-77,54,114,-5,89,-63,9,-51,-68,-117,99,13,-23,103,-30,-117,76,78,112,-118,-16,-87,41,-23,72,67,-4,-69,30,-16,-18,-97,-111,-93,-68,-104,-112,55,-92,123,52,-14,-78,3,69,61,-35,-108,68,88,87,-114,-81,-126,26,-94,-111,80,10,47,43,98,28,-115,-122,103,-88,20,-58,79,33,103,-48,118,102,6,86,35,52,126,123,-62,62,-37,-126,-52,65,84,28,127,49,120,-67,-80,-8,96,-60,-25,100,-47,-14,103,-79,-29,-11,75,-77,-29,-56,1,-88,75,39,-36,-12,-71,-77,34,-98,-35,-103,-89,-41,-106,-86,-56,-36,-119,113,-17,-1,118,48,-59,101,-9,-51,-117,4,-71,31,23,6,80,3,40,-52,18,103,-127,50,75,-102,-56,0,47,-16,29,-15,-38,-32,-10,97,60,-4,-77,-105,-38,115,32,-14,5,-57,34,-22,-125,107,-32,99,115,64,-114,-90,118,-101,-25,125,33,-98,105,-88,85,-121,-66,-62,-46,-108,49,-19,-15,86,-83,49,50,42,-25,-128,-3,-89,-107,99,-116,-101,-45,-44,5,-53,57,-96,107,-77,-119,127,-76,99,-94,45,59,-6,-1,6,108,-71,-46,-35,-3,-26,4,104,-106,23,-51,52,104,-67,-74,-38,-125,-107,-9,-24,-93,75,-123,80,-68,28,-98,-119,-69,15,91,105,-17,46,-110,4,76,39,106,18,23,-55,69,-77,7,105,-16,-19,53,38,-95,100,46,73,23,44,86,19,64,87,-28,76,-1,81,-59,-123,-39,70,127,-120,81,89,110,-27,-54,-92,36,70,-45,-3,-12,-72,88,-109,96,123,-80,26,101,87,-113,-100,-45,0,29,122,111,-86,-67,-104,-87,-6,-109,-49,94,110,-85,113,93,-49,-110,-48,67,-85,34,-60,50,89,-34,-1,-46,12,3,-74,-25,0,-23,-48,-100,-98,54,-126,101,95,68,127,-118,-22,9,-106,84,95,-124,-31,-90,-39,18,23,10,7,45,35,52,6,-102,37,40,-31,-9,-33,69,-95,119,-36,6,-124,-3,-100,75,-91,126,106,77,126,112,-72,-60,53,-127,90,-112,45,115,69,32,61,69,-82,56,80,-40,-115,50,-124,34,-13,109,35,-21,-19,-82,90,65,-93,10,-121,106,39,114,-81,10,-43,-58,91,-26,-88,125,-36,93,-19,70,40,121,-26,-124,-28,-28,-70,18,-94,-120,109,10,100,-19,96,-78,-26,62,127,60,91,-6,-52,-64,-52,34,-47,47,-85,-49,-2,-44,91,56,-100,90,-62,124,-113,-67,-127,-15,-67,-39,10,53,87,38,41,3,-58,83,14,36,109,13,57,32,-37,-97,-18,-4,3,5,-33,-31,-7,46,73,-1,-120,-117,33,-82,91,76,84,-35,-128,100,41,117,-102,126,71,-50,18,41,16,-109,117,-86,102,-36,56,-66,-77,-92,-67,-70,-66,75,49,98,53,-36,50,103,62,61,-15,61,11,-19,-51,126,79,14,76,32,-120,35,-21,106,93,66,-74,4,13,19,-18,68,-90,-91,55,93,27,68,70,-64,-97,13,-32,-112,65,-116,91,3,37,13,-77,21,-17,83,53,-56,69,-86,55,-107,-116,106,-49,2,-5,-59,63,124,16,30,-81,-27,-61,-60,65,92,103,72,39,-88,113,112,-31,-52,55,-46,53,-58,-50,50,51,57,-71,-112,-99,42,76,-33,58,2,115,-111,15,27,-49,114,74,-63,5,123,-108,-73,-56,8,-26,-122,-35,88,40,18,51,52,20,65,-35,-24,-41,-7,67,65,-47,20,8,-118,51,107,36,17,96,-108,-69,-40,-72,-61,-67,-17,-109,61,-26,59,-83,-31,10,-25,-62,-47,-113,65,46,25,13,86,-61,-14,113,-52,64,-100,0,110,34,-64,-35,-88,121,-84,81,46,33,-19,22,-23,106,49,40,4,-76,-89,53,110,86,-50,-71,-67,28,14,49,-123,-66,-18,66,-100,-83,111,101,54,18,-70,63,9,-48,-70,-115,-22,21,-71,-14,-74,65,-71,-2,-77,53,-62,-35,-127,-100,33,24,-5,-87,65,82,52,0,87,-37,20,104,-62,-52,31,11,29,-45,-58,-54,107,126,-119,-113,-47,-9,-72,-77,43,102,-116,-4,-79,-120,-90,79,-117,39,1,53,-91,127,123,41,-70,-104,38,31,-53,-85,-18,-127,45,18,13,-59,-5,-75,-110,1,24,-60,28,-110,58,-9,0,43,-104,92,-125,106,-91,-16,-75,-1,113,-115,-83,-95,66,-25,63,-120,-96,-26,101,51,83,27,47,-75,60,83,63,-58,-26,42,-88,-22,111,116,-72,-5,-65,-44,-78,-70,12,-109,95,-71,-27,125,9,-6,-72,104,-39,70,98,-38,48,117,67,-66,-117,-125,-89,49,-72,-71,127,-67,8,8,36,-76,-71,-105,-127,70,-100,-78,115,-84,32,38,78,26,85,43,62,-79,56,-78,113,-2,-12,-37,4,49,-17,123,-87,51,36,-90,-62,-27,11,47,73,-1,-37,18,75,18,19,-109,30,44,-96,91,-21,-115,-88,85,108,-17,-18,52,111,32,-88,108,66,-9,113,13,-117,-44,-49,15,-37,27,28,-57,-15,125,106,43,60,98,-21,-119,36,42,52,6,65,52,23,-39,60,-46,-61,100,50,116,111,8,-128,87,29,-27,-42,93,122,125,50,-82,45,95,-86,6,-10,21,-23,87,21,61,-14,-102,27,-64,43,8,3,-118,-97,-82,-66,-119,-82,56,-13,90,-109,-36,-116,-21,-42,64,-38,-55,-77,-14,-97,93,126,-10,77,39,-78,64,-39,46,-17,27,114,114,-88,80,-86,-88,-20,-121,-7,97,-20,100,82,-3,81,-108,-10,-40,53,-54,59,-103,31,-58,96,85,87,-76,118,-60,24,-41,78,84,38,-56,121,39,-101,55,6,103,40,-39,117,44,-26,-67,14,-33,-71,36,-38,-88,73,-5,28,-41,-21,-31,33,-53,82,93,54,-28,-63,31,-17,94,-48,-128,115,-62,-89,36,-28,-4,-48,75,-104,25,113,-76,-52,103,24,-96,-24,-44,107,-17,124,-95,-75,122,-64,122,51,74,121,106,-45,41,-77,-91,97,-17,87,111,106,-25,-38,-109,-87,-91,42,-71,-97,-111,-69,18,77,66,46,96,10,24,-89,16,-25,10,-1,-114,26,123,68,46,75,-115,44,-125,-121,-60,112,48,-110,-50,-10,-55,-10,75,4,-79,53,-84,99,98,-36,56,52,-66,67,-126,-77,29,-31,-88,-35,26,62,79,-79,-10,-114,-52,110,-21,-22,124,47,-114,-18,-101,-105,-44,-50,-114,-12,-104,-77,-38,-128,60,-81,-110,30,101,13,107,-57,-69,-40,14,-97,-50,-54,92,-60,59,127,-128,-95,95,-8,0,-119,83,24,-96,-106,-84,96,-29,14,-80,82,-120,-28,-116,-55,-78,-31,95,112,-82,68,92,-121,74,75,-62,24,-5,97,6,42,-123,-99,82,-82,-70,56,16,118,-84,66,111,80,-82,-15,-104,69,-12,-76,-23,-69,-55,-46,-48,22,79,16,-51,34,-115,64,23,-106,-77,71,-8,107,46,-22,34,-14,60,-80,117,-8,89,-108,123,25,-58,15,-25,64,-114,-19,69,50,95,-7,-95,120,98,106,-41,-31,-120,-127,88,71,53,41,-50,-68,-80,40,55,96,26,-8,-6,54,96,106,98,-60,-71,90,60,-17,48,24,17,-36,10,95,74,126,-123,51,79,118,115,69,-106,-78,65,121,77,96,78,-70,-49,91,27,-91,-51,62,53,-68,5,-96,-108,12,-45,79,-19,-80,-61,-30,-40,127,-117,77,83,22,116,19,-70,70,-95,95,-77,-120,59,24,-41,79,-100,95,-112,-22,89,-99,77,94,60,84,-5,112,55,-33,-92,63,88,-89,-88,-23,123,-20,-6,115,22,29,125,-46,65,-118,77,-50,94,-31,24,111,-107,63,19,-71,22,-69,-102,-26,-26,22,85,111,126,-55,46,90,-13,34,77,-5,61,43,-29,-60,13,114,107,19,-64,-107,108,-101,-63,103,51,32,-26,79,-115,-91,22,-120,-58,33,-83,-114,95,-48,-126,84,-112,-38,-38,54,-52,-113,46,111,-38,-111,-69,55,26,-43,-88,-81,94,-96,120,102,54,80,-68,-10,11,53,-68,102,32,-50,-60,50,20,124,-27,-57,15,87,-92,57,-50,51,49,-70,-124,32,-76,-51,-3,-38,22,-9,-18,102,-78,49,27,-96,-47,-9,89,-81,-39,37,-82,-70,-88,-104,46,95,31,-17,10,-62,-66,68,26,118,-104,-50,-50,-17,-108,24,-120,-88,22,-31,59,-7,-5,-15,75,101,-102,-17,106,57,12,93,-99,-105,24,51,-14,-7,107,-111,46,98,75,-8,-101,121,42,5,4,89,-110,-42,21,-14,-110,-46,49,-67,-64,-20,-85,72,41,-89,95,79,89,-97,43,48,14,121,109,-53,-50,35,-35,-103,12,-97,-111,-17,2,-89,28,-126,-36,-96,-98,71,-98,-9,74,-59,112,81,-89,-123,31,115,28,110,-20,-109,101,-107,-98,122,-101,15,47,27,-63,-19,85,-113,99,-67,109,-45,55,5,18,-97,31,117,-3,104,-8,11,24,-63,34,-86,42,-65,55,16,103,51,-82,-121,73,-61,104,76,-115,-92,30,86,-30,-110,-51,-115,-43,-108,-13,114,-89,-104,-51,-26,-112,-83,-29,79,8,112,-30,-47,94,71,-21,89,-38,7,-57,-70,105,62,-116,76,-12,95,-94,114,9,55,7,-46,-95,-105,96,61,24,88,25,-126,42,31,69,20,-93,-86,126,-79,97,39,87,-74,-104,-71,66,-83,87,-81,108,75,8,1,-121,120,-10,-1,-29,-47,-20,38,-73,67,7,52,-89,100,-57,92,9,-38,-58,-71,-112,-57,108,-121,-17,-127,-59,40,0,-69,-45,-98,115,-67,49,55,-76,-97,57,-94,-67,-60,97,-25,-13,-77,91,-54,118,36,-122,14,63,29,-66,-41,-87,2,9,-83,14,-42,34,25,-36,54,19,93,95,69,77,115,115,-67,-20,90,110,70,-83,-68,65,28,122,-51,102,-112,123,-55,-6,-88,42,76,-8,-96,127,117,-121,-97,36,62,120,90,-58,-89,79,56,-114,-1,62,69,-44,-96,-49,-18,102,6,-43,-9,-26,34,-127,83,-97,-74,-48,0,118,52,-66,42,-74,126,-89,-107,-37,-72,-114,64,-109,51,-2,34,-104,47,-122,-20,65,-48,24,81,2,-29,122,44,-11,61,27,11,114,75,21,18,22,39,114,-46,-109,124,-41,59,-99,-28,55,53,24,77,-63,51,118,122,101,-48,11,71,91,18,37,-41,-86,65,-69,-48,15,-101,-2,-43,122,20,-102,-58,-97,-88,25,3,47,22,-91,51,37,-14,70,118,-2,-47,25,49,111,45,83,15,-70,-96,8,23,112,-8,-79,-89,49,68,-35,118,101,-1,39,11,-51,98,-5,-67,-64,52,-41,-128,-128,30,-128,74,113,-85,-25,30,-22,2,127,-20,13,-85,-92,-32,-4,-21,31,-105,3,-47,22,35,5,29,-82,126,62,83,-28,-4,-94,93,-93,-120,44,16,19,-67,-70,5,-31,-100,85,80,30,123,-89,-9,52,2,87,79,105,45,82,-93,-46,99,-110,87,-13,-4,-52,19,7,17,54,-92,-118,-127,-24,71,-79,55,-102,0,30,-71,-42,-6,-112,-78,-55,85,29,-32,-103,-54,72,27,-76,-95,30,-7,-6,67,112,76,-79,84,-56,7,-84,85,33,-86,-39,-77,-27,103,100,99,-43,105,68,12,85,44,-92,76,-109,31,20,27,-28,-39,78,30,94,46,-28,-79,76,-103,-26,25,52,-21,-79,9,26,-26,-84,-17,-102,15,-120,70,-100,89,55,-3,-125,-80,-65,-27,89,-41,74,-8,-63,77,99,-9,-9,89,87,74,-101,-44,-16,112,100,102,9,-47,-40,-41,15,-53,-88,59,-44,93,-8,-51,26,76,-54,21,102,94,23,-81,9,110,-125,-76,59,-45,22,-78,72,19,98,127,21,-113,12,62,-80,-27,-21,58,-38,7,-112,-109,-111,-123,32,73,-29,-65,8,23,20,-58,106,-101,-30,20,-93,-36,-38,48,31,57,-26,-76,-93,93,-33,-99,12,25,-68,64,-90,120,-86,82,-102,103,-11,56,-96,104,3,101,83,-82,8,36,-38,-72,98,-94,112,-112,-83,-60,-123,125,86,96,64,17,89,113,34,2,68,51,-85,109,-92,102,50,64,-57,-64,114,66,-37,-120,-32,-102,96,-38,-90,-114,-81,46,-15,108,72,19,118,-98,64,33,-58,-93,-13,70,-93,41,67,93,-61,99,-53,88,-79,-64,-85,48,-67,56,-54,-46,58,2,-14,58,-127,-72,73,34,-12,-50,-50,31,48,-75,33,-89,-7,-93,-76,-95,-96,-52,85,122,35,-14,73,-30,-107,-112,127,-22,74,85,-127,44,13,-78,-85,-63,-86,-121,-58,126,-117,71,113,59,-95,117,41,48,-73,2,-89,34,18,-3,90,112,15,-26,-5,69,46,-24,99,-6,35,38,-33,-55,52,104,53,77,-114,-37,43,-36,-70,114,36,88,-43,-81,53,-99,75,108,-70,92,99,-6,102,-80,-128,-112,119,-107,-22,36,27,123,105,-80,76,-103,83,127,20,-7,14,-52,76,-23,-128,123,63,-65,-111,-53,25,100,-6,40,40,34,-42,-25,-44,-40,8,-36,-46,84,41,-123,106,117,-89,69,-53,-33,-58,-41,90,-114,-68,26,-80,-124,8,-77,92,-49,103,-48,-27,-77,-50,-96,-113,-6,55,-5,-60,106,112,-6,-111,-89,-127,-38,-33,99,83,-88,113,-2,-23,-73,-7,-88,-49,76,69,-42,35,46,58,-96,67,29,84,117,52,-97,93,-113,64,123,-90,-104,109,-41,-26,-50,-48,85,-52,41,104,-20,38,45,25,-105,37,85,15,-92,79,-23,81,-125,-40,-49,18,1,-124,-34,-125,59,-97,65,68,93,64,38,-5,-31,-59,-74,43,-104,-62,-100,95,14,-85,-60,-56,-37,37,116,27,41,106,63,124,64,75,109,72,47,44,-128,-119,60,28,105,58,20,-104,-35,-98,63,118,-61,-11,-28,32,-97,92,57,114,99,47,-80,92,39,-115,-55,-35,-57,-79,4,-113,28,43,124,-31,-119,-83,56,101,-114,-53,116,-102,-126,-73,-124,-97,46,83,-17,49,-17,-13,96,23,3,-60,-93,-73,23,4,-35,-119,-71,5,-118,30,-51,71,112,121,-95,97,23,-37,47,55,102,-6,17,107,-16,-70,124,-81,28,-5,71,77,-70,43,20,71,44,-72,-125,88,123,32,40,-27,98,62,-6,35,47,49,-74,20,-56,-112,82,-50,22,113,82,-11,102,-67,114,-6,-41,123,41,-73,-102,-65,-97,-39,-41,70,-25,-21,96,58,74,119,-125,-112,-101,-57,87,116,-29,-25,-79,24,8,-83,17,76,-28,40,25,80,-59,-77,61,-50,41,69,-21,38,-56,61,26,114,32,49,50,-47,5,-53,29,-43,41,-5,-80,38,-112,49,49,-26,-34,-54,-95,50,103,16,95,28,-31,-126,-31,-2,-48,74,122,-83,-73,-22,-122,89,52,-12,13,18,117,-80,52,-36,88,-57,-37,32,-107,33,-55,15,78,80,23,-30,-44,126,125,124,12,125,73,-3,-8,37,-15,8,29,70,73,92,19,63,-5,24,-123,60,53,-14,-27,-92,20,-12,-38,49,-43,9,-118,111,39,110,50,-16,98,-85,21,23,30,-9,93,-96,77,52,-107,-58,-19,-72,69,21,-127,-43,-43,19,-39,121,-103,-125,58,-105,2,90,92,-49,-74,-95,-52,119,81,38,-13,-63,11,112,-2,125,-34,-82,81,13,65,-43,-88,-74,5,17,-112,-41,26,60,-71,58,-93,-92,-75,-65,-24,-49,119,55,-118,-4,125,34,7,97,20,60,-3,105,-44,-111,-96,-73,53,-79,-83,-53,59,33,-20,-3,-89,117,59,98,-104,-43,-48,19,100,60,-125,76,58,-125,94,78,-40,23,-49,46,85,45,-108,-126,-108,-19,-101,-27,-68,-111,-16,-62,-4,123,18,98,-82,110,-81,-41,-120,76,-41,-76,123,21,-55,58,-24,-86,-125,-94,-37,-127,-77,31,108,-2,30,-24,123,116,10,-16,104,-111,-68,80,-113,62,-64,64,-78,-81,127,101,125,-15,-54,87,-48,-108,86,-119,-55,52,122,-118,47,-121,59,-84,-45,54,-97,-72,94,-38,114,-105,8,-53,-61,69,-113,-27,-30,75,-37,13,-51,24,-49,-122,12,97,111,29,68,-111,-35,21,50,-9,-105,-94,90,43,52,-80,0,-100,61,100,-68,-89,103,-52,-105,29,-128,109,-32,52,-88,77,59,6,38,69,-31,-110,-85,102,112,93,-64,-79,-51,-117,70,11,-51,100,102,-120,-48,79,123,-86,-32,5,5,-108,116,111,-34,-47,-90,79,-17,40,-59,-85,95,-69,-9,42,12,-77,54,-75,-3,68,-128,-88,-32,118,-126,19,20,56,118,-84,-30,-87,87,99,-19,-125,-62,-31,123,-19,-56,-83,21,87,1,-38,-96,73,-30,20,22,95,35,45,87,-61,48,10,80,125,122,24,33,27,37,85,-30,-54,-99,-7,-75,68,-63,-28,-22,14,-84,82,-89,-17,-82,-63,123,-76,77,107,89,-46,49,-69,-88,96,48,5,73,122,33,-16,67,-67,-92,-33,87,-68,113,-23,-45,93,69,-128,-8,-39,87,-91,-104,-76,13,71,-17,-20,-128,111,80,-43,55,34,110,85,-128,-111,48,-109,102,-52,-93,-26,-25,-88,90,81,123,88,-119,-54,63,-96,3,-13,-40,-48,-41,-79,-10,86,69,-62,65,105,-116,49,-107,-98,-38,23,-76,120,86,-74,-69,119,19,-58,-13,100,23,-121,-4,-85,-85,-41,93,117,-52,-75,89,119,55,-13,31,98,-51,110,18,-17,4,73,90,106,99,86,74,-80,45,-18,102,74,-83,-119,124,75,-72,-18,-27,93,-9,-77,-65,-33,86,-76,-94,-11,29,63,-69,-106,-115,107,81,9,-117,44,77,-4,-36,-109,-78,-40,-94,-79,15,-59,40,42,117,44,-44,-51,71,124,-65,73,-46,59,-61,59,45,-56,-95,-96,16,10,-28,-94,120,67,-92,86,-86,-43,-7,-95,112,-37,74,55,-21,-75,-112,97,-20,73,52,-53,-59,-120,71,-40,58,91,85,77,49,-15,-82,-86,-39,-67,-122,-91,-118,-30,-36,-7,50,-89,93,30,17,-99,-104,107,-76,8,-37,-14,101,-15,83,92,101,-82,-46,-91,45,-74,-122,-70,-93,-41,-50,-38,120,-17,-106,-118,98,80,-49,-70,-52,13,-29,39,-119,55,62,-43,-82,-40,-89,-59,112,-120,40,8,9,-81,-62,-6,84,-63,80,-2,-82,-17,-47,100,-64,100,5,13,-128,-81,-122,100,87,29,-100,-49,6,53,-103,52,86,4,-41,17,-126,63,16,79,-89,92,-123,120,34,-102,77,90,-65,-62,101,-36,63,-19,-125,113,-18,-120,-85,-50,55,-34,-69,101,-108,-46,106,-31,12,37,21,-53,-64,122,121,-73,109,-74,-74,-110,-122,54,6,31,114,-20,-63,-25,111,69,119,80,-24,-25,87,-11,-113,-76,-103,111,10,2,94,-22,124,-117,90,52,-85,92,15,-76,-24,-74,102,-57,-47,86,-77,67,-110,95,64,-118,-84,-113,-1,-123,5,5,-108,-28,-33,47,20,-126,58,-45,34,-128,57,-44,-23,-124,123,-13,-125,-87,-75,-60,-124,125,-127,-105,-77,63,-103,122,-3,-106,-99,51,4,65,-115,105,-115,98,-36,32,110,-24,-33,84,76,10,29,22,-85,45,-126,-108,30,-56,-121,47,-121,-114,82,-34,-21,-107,-46,60,-78,29,2,-87,109,-68,-25,-84,80,106,-62,-64,-73,-72,42,29,-46,10,-43,76,-12,-121,-5,39,86,73,74,-32,-115,-99,112,-10,-68,-38,-18,103,22,-122,-119,-52,-76,-124,13,127,47,1,-29,26,-108,-17,-86,52,-28,-81,-35,-1,-99,68,94,12,97,-24,-98,70,63,-96,-58,-37,105,-48,-62,107,-113,12,121,42,105,-7,112,86,-18,116,117,82,123,-54,2,-110,76,-118,54,57,82,68,92,22,76,-109,96,-71,-88,56,81,108,-8,76,-98,-104,-80,-116,77,-44,16,1,-103,-127,32,-25,-109,-127,-6,83,123,33,56,38,8,4,89,40,-116,77,-109,28,12,-88,89,-65,-27,-87,22,-37,62,23,68,15,30,-43,-49,-42,-32,-74,-11,104,-24,-78,-20,50,-9,96,-73,90,116,-68,-43,47,2,-84,-115,2,-39,3,-17,-21,-114,-104,38,114,-68,23,-97,-96,-25,68,-39,93,80,-117,-27,-96,-21,23,-50,-109,44,75,38,-8,-16,-99,-110,-29,34,-128,117,-4,53,-77,-110,-35,77,100,-117,-4,-101,-40,108,-86,65,-44,15,-63,-83,80,-50,34,-61,113,18,-29,-31,25,-128,-4,-105,89,120,3,-107,-29,31,-38,26,102,-7,-6,-34,-44,-2,25,-23,-30,108,25,124,100,-48,-46,-60,-71,62,-118,-89,58,-73,96,-128,73,-87,-99,63,-24,124,-86,38,34,-51,27,-71,53,117,99,-7,121,-9,-35,-108,-64,-105,99,-42,-6,72,-22,-19,36,107,-109,90,-27,32,-112,76,106,-81,-63,-57,-29,-11,-24,-118,77,-80,111,-52,48,-37,123,67,-124,-64,-101,34,100,-62,-37,113,-68,122,43,112,-86,-110,64,-33,-17,29,38,-90,107,40,-58,91,23,64,58,-101,94,-22,78,-36,48,-8,-49,28,15,-90,36,103,45,127,-89,-84,-56,-27,103,45,-112,121,104,-13,118,24,-84,-66,122,121,12,-78,-2,22,-59,92,7,116,92,-115,62,-3,-126,-24,113,122,-71,0,-68,-105,59,-62,18,110,-24,13,48,50,8,19,64,-127,74,-46,-86,-99,14,-115,-18,-124,-42,51,-27,-26,-119,-99,97,82,-47,47,117,78,-59,-109,-13,-61,-49,12,-86,-91,47,-64,-71,-79,67,-33,56,6,-33,-29,-76,-16,95,94,-76,-72,45,27,-117,-99,27,-37,47,-58,69,-90,100,107,23,-44,-76,-50,-9,113,20,44,121,-125,100,43,81,45,-66,104,-65,-31,-54,-81,-13,20,-54,-23,-35,37,44,78,61,-102,-106,46,-79,-52,-59,57,-18,28,81,-110,-94,44,83,-43,-51,19,-78,7,80,99,59,-61,100,21,96,100,-55,-108,-90,-41,94,-37,53,14,48,116,-4,111,-9,-32,88,-61,-15,79,36,-55,67,-35,38,13,-82,-61,-61,-70,14,34,30,-99,4,-29,41,-94,14,-58,45,90,-24,-63,54,3,110,113,-18,36,-5,39,82,121,-101,-81,107,-57,-4,-51,114,-77,105,-82,-15,83,-53,44,14,51,-58,-44,106,-79,-21,-106,-47,114,-91,-76,-55,81,-128,94,118,90,2,116,-69,103,14,-62,-35,-32,127,117,77,87,-115,-16,-3,-104,-67,-39,-91,61,-5,-34,-62,102,-123,89,-38,111,-2,92,-29,-2,-66,124,107,98,-74,-93,-58,-65,-103,-38,-23,88,82,99,76,67,56,-62,-121,-17,-80,-77,-4,-45,77,-85,-75,116,7,0,76,71,-104,-70,98,-66,26,44,27,63,-44,-97,-13,37,-7,8,-125,11,100,47,77,112,73,67,68,-96,23,-35,48,-56,-11,29,-78,116,-72,123,39,-21,10,-21,47,18,40,-7,-8,1,-50,18,35,-103,-99,-49,7,-10,84,34,-11,-62,-105,38,-55,-101,-46,-103,-3,44,-90,-78,-71,-103,70,-60,-93,59,48,3,60,11,-112,-44,88,102,52,-77,-90,46,101,47,32,-19,-78,8,-36,-66,60,-71,39,-100,103,127,-95,109,11,87,-71,-106,-118,72,73,119,37,-41,68,-41,38,-84,110,-63,77,112,72,-90,63,125,76,46,95,101,95,8,18,77,2,2,114,99,-88,65,13,48,11,28,99,32,101,-94,84,19,-48,4,5,-26,105,-14,-36,68,-20,-43,8,28,-98,97,-89,-47,102,-67,-41,49,20,50,-118,-121,-74,82,-68,81,102,7,99,-89,85,2,71,9,-104,124,81,-110,17,73,-32,81,-15,7,119,116,-26,-12,39,-43,96,-68,3,-88,-93,-56,-36,66,77,102,-80,1,-44,-81,63,83,-80,29,56,-124,-60,80,96,126,-74,53,-16,-117,6,52,-57,45,20,2,-33,34,27,-16,21,127,76,-105,56,68,6,-26,-21,35,-108,46,10,-58,80,-100,-77,63,-10,111,71,-22,-3,95,104,-90,-38,-11,-104,-31,111,-113,26,-4,-2,-30,-2,58,100,-112,49,-76,101,-40,-106,-45,-126,39,-24,5,-97,-90,-84,-113,-77,-18,41,63,-25,42,16,-85,90,-4,-80,-2,-117,21,-75,-35,28,-118,-20,45,83,88,122,30,-78,-127,54,-13,96,34,9,103,-88,92,120,-59,-87,48,86,116,-36,-38,-65,103,104,-70,-1,90,66,-35,71,-54,-7,-107,-3,-78,-49,-105,-87,82,22,29,-3,-13,23,108,87,-65,-39,78,37,-13,-19,59,6,83,118,85,3,58,5,-113,-23,-47,58,83,25,-85,-80,87,86,84,-75,-111,106,-89,-17,71,32,-81,106,-30,-125,-50,95,-74,-14,-86,-78,102,53,-66,89,95,-35,39,-83,32,-86,-56,103,71,110,-79,-97,-107,-24,29,-19,84,103,87,48,-13,-14,-40,17,-64,-74,21,74,-29,2,53,-84,4,-113,50,66,92,26,5,34,9,-126,109,67,19,116,85,-87,-53,12,-99,87,63,100,-80,-62,85,-99,60,-6,-80,-59,17,-56,-111,-7,-114,21,-13,-110,-115,112,70,-70,-40,-47,64,87,74,59,52,-96,-79,-61,12,32,-119,57,80,27,89,16,-95,-78,23,90,-14,-42,-117,-49,40,-2,-122,-94,-47,101,-47,43,-94,22,96,7,-7,30,78,-110,-19,-66,-86,4,-83,118,-105,83,46,-104,75,88,20,-82,-106,-80,-71,52,121,117,-39,77,3,105,-112,49,54,15,33,61,-48,6,-76,2,-101,-54,8,-50,-36,-105,-55,126,2,76,10,95,44,-85,-53,3,-75,-42,-102,6,-70,-9,88,91,33,84,-18,-28,21,33,-65,-97,-87,73,103,-96,-67,93,39,-58,-49,92,-48,-75,54,61,123,-29,-68,16,-84,-90,14,-84,-100,-37,82,57,-61,84,63,101,9,-97,-124,-31,102,98,-57,-77,26,-110,-16,102,119,80,-38,-54,-35,-45,-115,-114,123,-35,-99,111,-52,10,-99,-112,-16,99,30,-50,109,-66,70,48,-62,-45,37,-25,125,22,19,54,61,116,-52,108,70,120,9,-56,71,-8,-64,-5,-99,-7,65,-60,23,13,79,-63,-79,96,22,89,61,-41,-51,51,88,-61,-12,45,15,-71,-9,51,29,-105,-82,33,13,-29,-73,43,123,33,-86,-90,41,106,10,-124,52,11,114,82,-60,30,-47,-118,-6,117,-33,-5,1,-57,0,-60,27,-17,21,46,-83,-121,98,-59,92,4,-21,-109,-88,75,-40,80,97,-32,9,127,-2,-15,109,17,-55,-53,-94,65,79,64,-29,-24,-123,-121,-109,-99,-43,10,-111,-79,-124,68,-55,-83,-85,103,112,-122,-101,29,0,97,-61,-67,95,10,-86,53,-42,-119,12,-42,-24,20,3,123,87,74,-12,-102,105,-6,85,10,116,24,40,96,-5,-7,19,43,-104,121,32,7,-6,16,91,-70,80,39,62,44,29,-114,68,51,50,-51,17,-120,27,-52,-43,109,49,0,-13,74,26,83,-44,-108,96,99,5,-33,-69,-35,-80,47,-13,-117,-65,-78,110,61,-75,107,88,-100,-55,-64,-73,-29,65,26,-86,77,-54,127,-56,-77,61,65,10,-18,-57,28,2,-63,125,-116,88,12,-112,106,78,-36,4,-98,63,-57,83,-32,40,-19,-72,36,-59,3,10,-114,26,-1,-87,32,-36,13,8,-112,124,-50,-1,-28,-47,63,10,-28,69,-42,-101,15,-89,19,59,-76,115,14,68,-83,68,-2,-19,19,-93,31,61,29,116,121,-80,-84,115,69,75,-22,68,-51,-27,-106,105,-109,-48,-65,54,123,100,-13,-110,-79,103,-28,10,124,91,114,95,13,39,-34,-101,-128,-121,-18,-35,-102,101,-127,74,-107,-100,-19,-84,-56,-33,109,-48,29,-65,-86,-26,-111,-119,113,-35,-95,-24,125,-85,-105,9,-76,2,11,90,22,48,44,-2,76,-11,72,91,-93,79,-28,92,-39,-23,50,-34,91,56,-101,-86,3,-113,53,46,52,-108,25,57,117,-108,-59,105,-127,-108,65,-92,15,-71,-23,114,108,120,-36,77,-23,54,-100,-65,112,118,69,-118,-78,-43,-56,94,-47,30,-49,-111,-17,-109,-105,-41,-25,-80,-38,111,40,11,112,-95,-68,-13,-103,-46,-91,108,32,52,-76,-30,39,-52,-57,-15,-63,-48,-23,-57,27,29,117,-74,-112,20,109,24,4,25,-64,125,-1,-63,-29,-25,-89,83,-3,28,-63,30,47,1,-1,-29,22,24,43,-18,69,19,90,-37,27,-51,69,98,-13,-96,72,61,44,-103,72,74,92,83,98,94,92,79,-26,115,60,-73,-73,-98,34,-90,58,51,-77,-51,67,-124,-50,28,-54,-43,-111,35,-97,-50,22,83,98,29,13,-44,56,65,66,-31,-111,79,124,-28,-72,118,-88,116,-125,-66,-120,78,-79,-42,90,-115,-123,-19,-98,-86,68,40,-91,125,65,91,-111,114,90,5,-68,-52,97,59,64,102,107,1,25,-64,64,-21,29,115,15,-8,74,10,-104,-99,35,-94,20,43,-22,-44,23,-106,104,54,72,49,-12,40,33,-12,-108,-85,-48,-123,-111,-105,-107,-116,54,-25,-17,46,26,32,-31,42,-21,30,20,94,-33,35,-30,33,15,28,40,98,83,-102,-88,11,-8,95,-73,-109,81,77,-44,115,-36,86,43,-16,-98,-72,-33,6,-18,-27,-116,-113,14,-91,-17,28,-64,-1,-58,119,-16,109,-8,-17,108,-58,43,-54,-80,-75,117,-58,-72,-51,4,-33,20,123,-97,-15,41,93,24,-86,-87,-123,-40,2,-111,57,60,11,-45,83,-43,-62,-125,-97,-51,-12,94,-74,-37,-123,-31,2,18,8,37,-1,-105,40,43,40,-63,77,-53,86,-95,-96,120,107,-67,18,38,-70,111,14,-109,98,-72,60,7,-121,-10,-128,36,101,20,126,-72,-29,-11,95,27,-74,-51,-115,18,-101,16,-59,-43,68,38,106,-110,38,-122,-46,-61,77,-110,-23,62,-33,32,-96,38,53,84,-80,34,-115,91,-19,106,35,7,18,-51,88,109,-114,-121,51,-76,-43,-87,-46,15,-55,83,74,-38,-3,43,82,-5,85,-100,-55,127,117,-75,90,92,106,-41,-39,-120,-41,35,5,83,126,62,-105,-33,117,-81,69,110,43,-122,43,100,45,-46,-104,-2,21,75,27,90,-82,80,110,24,-40,113,64,-79,110,97,-121,-14,-128,-60,-30,-91,7,-89,36,85,57,-17,15,11,91,-98,64,38,-96,67,-71,0,44,-8,119,123,38,-122,45,7,-6,-92,-111,-67,27,-95,-126,86,40,46,30,90,-123,105,127,81,-70,4,-123,86,21,-125,-12,-25,-119,42,22,46,78,50,-123,-112,-83,-19,86,-33,-109,104,-28,111,69,-48,61,53,-80,-102,56,105,88,74,6,-49,123,88,60,9,122,-32,94,-60,-80,73,-27,-9,113,34,-66,-93,-117,-35,51,36,45,-95,88,95,4,-22,98,-38,102,119,-40,-115,82,-80,88,77,-97,-49,99,10,-71,-3,-82,-124,-27,25,74,-9,21,-33,77,-43,44,-15,112,100,85,-124,90,-10,83,59,64,-108,-89,-1,77,-14,-74,84,-128,-11,41,74,80,95,-69,3,-86,-111,-26,-34,-54,-37,81,112,-40,-44,32,-83,-55,-62,52,-33,127,106,-69,17,-70,48,-34,0,-92,44,-110,22,113,-51,30,73,30,86,89,-90,-95,69,30,125,54,4,6,3,-80,-76,16,53,-67,-27,-42,-105,-98,-32,-66,-93,126,107,45,-110,19,125,54,121,102,52,-121,119,103,49,-32,90,-115,60,54,-77,-94,59,-119,42,-42,-6,106,-5,-90,-6,-74,-32,-81,113,-103,-69,-126,119,-90,7,24,52,115,-52,-96,59,74,-113,32,69,5,127,-38,-91,126,-126,74,-90,94,50,-39,-117,-22,-102,-106,-98,109,52,122,12,-111,123,-100,-87,35,-54,14,-89,126,-119,88,-107,62,-88,56,95,9,-95,-106,-25,69,84,-67,35,-42,-76,-61,-99,-88,-82,-24,-20,-26,75,109,74,27,-100,-55,-77,72,-6,52,76,96,-100,67,53,5,111,48,-16,38,89,3,-1,-115,59,-19,-16,-34,-61,-94,-115,-16,90,-110,116,65,-121,-117,104,109,-107,-26,-72,123,108,-49,55,36,-100,91,59,-93,-7,40,77,-91,84,80,102,-108,-113,-104,-22,-64,-90,-57,-37,-63,78,33,-95,-78,102,20,-105,94,24,59,-81,-39,120,54,-40,-56,-45,9,-107,-104,74,72,29,-45,91,-18,-106,11,91,-51,62,-87,-109,70,126,-49,-117,119,-89,-117,79,-124,-95,-93,21,108,122,39,18,48,3,-107,30,-99,-19,103,-91,83,-110,41,107,-78,99,-23,58,-99,39,50,-47,89,126,-119,58,123,31,7,23,43,-17,64,65,93,7,-26,-107,50,-11,-63,-24,-39,2,-55,-119,68,6,119,-90,-16,-92,93,111,-79,-89,78,-4,95,-7,-65,32,-100,35,-20,76,114,-126,-69,-13,-127,-43,-11,62,-107,77,10,114,-76,94,85,-97,99,50,-76,-57,-72,-117,86,9,28,124,14,-108,26,19,37,83,38,-125,21,-56,-42,51,-69,-3,-108,51,70,15,33,-125,-36,-122,-34,126,29,25,103,9,66,-126,54,-54,105,-9,-124,59,-105,78,76,3,101,-94,-67,-71,90,-7,62,-77,94,26,49,-14,-112,55,67,92,-26,97,80,-36,-13,106,33,-111,-110,51,-12,118,21,-75,-25,14,75,2,-109,123,-11,98,77,109,-47,6,22,-38,124,-100,61,27,-124,89,-54,-108,-28,123,-99,-24,-77,115,70,105,-32,49,-83,-99,-29,87,-11,79,26,77,-83,-22,-38,-13,-56,-82,10,-66,4,-69,-26,-19,-7,91,-58,35,101,-31,80,-5,-37,53,-73,-126,90,-76,20,-51,-1,55,51,-93,96,-39,-81,-64,-111,65,-47,46,-87,-65,-89,100,-36,-5,-9,-2,81,-37,-97,98,-25,117,-75,79,-81,-118,112,76,-105,120,34,-116,23,-125,-13,77,-73,87,-115,-108,-44,19,-96,-103,89,-56,-60,52,-3,-105,-59,37,-43,124,76,-2,25,57,92,-57,113,-20,22,79,32,122,48,115,-85,-6,-35,-103,9,13,93,-26,-123,-98,109,7,29,4,92,-54,-89,52,-92,74,8,55,13,97,-49,87,-26,-28,-11,14,72,-29,112,-82,12,4,50,-24,63,-112,84,74,122,23,57,-58,-125,20,-85,104,-32,125,126,-86,50,-83,14,-82,107,-124,26,101,-55,-118,-72,-100,-105,102,-111,-76,123,47,103,10,-14,-109,56,-70,104,27,-18,-33,30,41,-56,122,-117,-56,-76,-45,49,41,-34,-45,-35,100,77,-36,-24,0,102,88,123,11,116,47,-1,-9,-3,78,127,-108,33,64,27,-115,30,110,-105,-92,-15,56,21,20,-70,15,47,127,9,-21,122,83,105,117,21,10,-5,31,-91,-126,63,-7,-128,-20,46,106,22,3,-102,96,110,-106,71,-93,-52,112,121,-117,-74,-49,-7,118,121,78,76,-94,93,108,52,-67,-10,-103,54,62,109,5,81,-90,-100,24,109,22,30,-48,-36,-61,-36,119,120,-47,-92,112,-125,-41,-7,-11,-106,50,-23,32,84,-125,79,-36,-6,68,41,-97,-102,-51,-72,114,-105,126,-127,-13,53,-112,-71,38,44,-98,0,93,123,-60,-19,69,108,-68,-106,-68,-53,-55,-21,-37,118,-117,-121,52,-52,88,-36,63,-82,-72,-77,-25,68,115,112,62,-124,-71,122,-68,30,42,110,98,-42,27,22,-112,22,-56,-64,74,72,-92,32,-119,-50,-69,-64,-106,-59,83,9,125,20,49,-65,-128,-33,102,-28,46,97,28,74,-47,-59,-32,-113,-96,33,-54,20,-18,7,107,-61,51,6,104,23,15,-128,123,-92,-12,-75,0,-37,-89,-17,-14,-106,126,-5,-25,57,39,-66,102,82,32,28,97,-78,33,93,125,53,4,-74,-102,121,-51,-126,84,57,34,127,22,97,4,-24,88,-23,-65,-63,89,85,119,-99,97,6,94,-107,-69,18,107,-79,-25,-71,68,14,-16,-75,-21,30,-20,106,98,71,38,105,48,-41,110,-45,-70,68,8,-42,-82,110,29,-32,71,60,-77,-53,-20,6,-94,-90,88,107,28,74,58,-95,-19,26,-63,-73,88,4,21,125,82,-71,16,85,107,-67,-48,119,-17,27,-63,49,102,-78,-20,31,98,125,64,56,-100,23,-82,-89,-65,10,49,-105,-38,18,48,-50,-114,-23,87,71,-84,-28,-101,-65,34,-112,-18,38,-80,-120,-95,90,-79,-27,92,28,8,63,49,30,3,-85,-111,-114,52,-111,-53,42,-118,22,119,35,65,21,-8,3,72,-89,-111,-121,-29,45,-125,53,-122,-24,49,-64,-80,-107,-23,125,-84,-91,-115,102,26,124,-9,-72,67,-57,29,-34,57,15,-2,-14,16,-84,5,-95,115,-97,15,-58,39,2,-24,80,-37,55,-62,-43,24,38,11,-110,-76,54,-58,-109,112,24,-65,6,-127,-94,78,107,-67,21,-23,16,-29,62,48,-53,46,41,-123,-39,51,-82,114,83,14,93,41,-59,69,-23,-17,50,-113,-41,-117,40,-95,2,4,45,23,75,-110,-90,74,-18,77,9,113,97,66,-102,-76,-16,78,2,49,-105,71,-105,94,-43,74,-86,-89,71,126,117,-51,-72,73,-27,-100,116,17,-60,-83,-55,42,-45,-37,91,-100,-75,-51,-11,90,41,102,-99,-108,-8,28,114,-24,-41,127,36,-23,118,-44,8,-41,48,-62,-127,-89,124,3,89,-1,19,38,-64,-128,123,121,14,-99,-79,-19,23,88,-53,-80,-35,119,38,51,84,-104,-50,-103,10,-41,-39,-88,-118,-37,-55,46,-41,123,1,-94,-50,-24,119,-86,-110,93,59,51,-56,71,-48,0,-110,4,-4,-56,-99,-99,-31,29,-21,-65,-23,116,1,93,3,25,-29,95,-1,-109,33,77,21,-116,78,40,-124,14,-114,-50,35,116,-19,-52,112,26,-110,47,-120,72,-36,19,-97,-53,-28,-64,71,4,104,101,-2,44,-26,-102,-4,-18,8,30,-35,6,39,-93,-39,44,-3,-92,16,-87,-38,51,-87,-82,79,17,-20,28,-18,-118,-21,-19,-18,127,-48,19,-43,36,93,42,-46,-34,-70,-121,-51,-128,83,20,-19,120,37,-8,118,58,30,-95,63,-108,-55,-1,-80,78,1,34,37,71,-16,8,20,-55,8,-15,122,107,-125,-21,111,38,75,87,12,-20,-77,115,26,-102,-86,94,-85,-97,-109,29,95,-48,-22,-117,-104,-28,-94,91,-65,51,-79,-51,-90,97,112,3,59,73,16,-119,-88,-21,52,4,-66,-107,85,-114,71,87,-68,116,11,-3,-123,-22,81,-77,-72,108,19,118,-18,-54,21,-35,24,1,76,9,72,-58,-31,-1,-124,-19,121,-47,71,118,-83,-12,54,40,-125,45,23,-121,-46,81,-16,-73,-127,56,-117,-112,-99,-128,-81,51,52,10,27,97,67,112,67,-1,-97,-94,-42,27,91,-28,-9,-82,-112,50,12,108,3,-42,86,22,115,-72,74,3,-17,28,38,79,-29,113,32,-27,-61,-87,-99,119,-53,112,-82,-17,100,-111,80,112,-106,72,94,-124,12,-29,-88,95,54,-107,-123,64,-3,124,-83,-63,120,-91,-46,-117,123,-21,-108,-65,-26,-63,-115,-54,126,81,27,80,-6,-56,71,-91,-22,46,23,-39,26,42,61,74,46,0,-56,28,28,-75,66,-20,45,-72,-86,36,-73,-41,14,115,97,102,20,55,46,-120,-26,-18,-24,-46,99,47,-2,10,-57,24,10,90,43,123,10,-90,112,99,-16,54,-3,107,-72,-84,-125,30,112,127,76,-107,114,-120,49,-117,-9,-109,116,-103,52,-108,-37,-68,-2,-107,24,-110,6,-53,-6,44,13,66,-92,29,34,-57,-41,-49,45,47,99,-15,-11,-104,127,-110,3,68,24,-97,-97,49,89,-9,-1,-53,-6,-18,-36,-18,-108,-97,-118,-104,21,-11,-55,-16,59,-72,-118,-23,87,-79,-118,-49,31,116,-62,40,88,-7,-18,-91,-36,54,28,103,44,-16,-121,-2,-122,17,38,44,91,-70,52,110,29,-53,-88,-102,-101,-91,85,115,-50,33,-24,-66,-43,-14,126,-30,81,34,88,51,-85,-37,123,64,-74,25,-82,-17,124,40,-74,63,14,-41,52,-65,-118,78,24,-15,-91,-115,-89,121,93,-28,49,-28,14,-37,-49,-100,93,-7,98,-99,86,23,-111,114,58,-26,5,22,-20,-51,-29,21,-67,57,39,5,-79,-87,94,26,-36,77,-69,127,114,31,-69,62,-44,127,-26,-84,-119,34,70,-108,53,-125,7,-12,-76,121,-125,-85,-19,-43,-121,34,-59,-4,-54,12,-89,67,-38,15,100,-44,-92,34,-7,38,-19,110,-45,6,-45,17,121,-71,36,-46,-32,53,117,82,36,101,-47,7,-108,-71,-25,117,-112,104,93,115,-116,-90,55,8,-4,109,-83,104,-54,64,14,60,89,6,-70,109,115,27,26,-74,77,48,1,-26,-21,82,-50,-39,-87,-115,-26,-41,11,17,46,-84,102,65,-5,67,24,19,-43,-105,-11,77,-44,-30,20,-11,44,-71,-84,2,98,95,-9,40,-111,-95,112,-96,85,-102,-53,113,-73,68,12,84,75,72,-59,63,-35,-81,-58,0,-67,-13,5,-14,-37,-45,72,-90,89,49,12,120,34,-37,123,-104,113,-75,25,-100,-113,58,-99,11,-58,41,64,-93,43,53,-90,-75,92,122,-39,-26,14,-108,-81,18,-125,33,41,10,53,-74,-77,69,89,65,72,-12,13,40,105,44,-20,-109,-37,-64,-47,36,-98,-62,-38,-56,-112,-53,-96,60,29,58,-84,104,36,-103,37,-93,38,19,107,-120,24,-122,38,35,-8,-4,-65,7,9,-61,-33,48,0,-99,10,-61,104,108,-83,122,14,23,89,104,107,-100,31,-111,-45,-5,16,-6,84,-15,-105,-27,-28,-31,-86,-119,35,-106,-19,-45,-5,38,113,-14,70,-100,118,39,102,59,44,90,-47,59,-28,-94,-85,75,1,-124,-45,-90,36,86,-45,-16,19,122,-57,-111,11,-53,19,-36,-32,79,123,114,-124,-116,67,-110,-3,47,-19,-21,-33,63,-121,14,50,30,-11,-94,-10,-41,65,7,18,13,-3,106,73,116,2,-7,31,-6,113,-15,117,-121,60,68,117,-101,-57,-15,-27,114,36,-27,-34,29,-100,79,19,12,-27,-14,-4,-120,116,-83,124,2,110,-37,67,99,-43,-103,-64,-31,-30,-100,-25,-94,-16,-62,-80,12,-128,-64,-3,0,95,102,-61,-42,51,93,-74,18,70,98,-60,-67,-2,-89,52,-35,0,-80,-70,39,16,-115,69,-115,127,39,65,-4,-67,-43,22,127,-83,59,99,91,-33,115,-86,4,-5,107,-68,-40,-56,20,37,94,31,-62,-100,-85,83,14,-65,-7,106,61,-70,-77,87,104,-59,-23,-108,125,-119,-39,-102,-126,96,6,72,61,-127,88,-57,111,-62,65,68,-32,-78,5,-65,61,46,97,125,-47,16,81,-20,-77,66,44,116,-80,-18,14,-77,-88,60,111,1,93,-64,-55,97,53,26,80,-23,20,-52,73,55,42,-13,-85,-17,-11,-54,-31,-109,-102,64,-87,104,-105,-121,86,67,32,44,72,-84,-67,-62,-54,28,-61,-46,-124,-100,-120,-49,53,-102,-113,-19,-54,-114,-115,127,27,-21,-27,-44,-86,-126,108,110,-120,85,67,-58,-91,-128,-68,10,-64,-65,-33,67,-32,41,-17,45,-121,-78,-114,74,117,26,56,-125,69,-117,43,52,-38,-19,-42,-4,110,95,-89,35,82,-83,54,-37,-39,-24,103,37,-65,-5,120,4,64,-88,69,54,-23,104,-100,-73,-80,-126,77,-18,-15,27,45,1,-40,51,108,-74,-69,121,-45,27,110,-74,43,60,68,-79,-7,-111,-1,-63,-59,0,-90,96,-12,103,58,39,-18,88,-62,-26,-19,-111,51,73,-82,50,-84,-126,-23,-110,11,4,-11,49,-54,-69,-50,-27,65,20,-19,-27,75,-46,-98,-42,-74,53,-23,10,-59,-99,106,-87,-83,-4,-2,95,-12,85,58,-12,-9,88,-2,86,35,-81,5,-120,-87,-9,-40,78,-9,76,-32,-101,80,-98,97,24,-56,25,109,74,99,15,-78,-15,98,-17,-102,-79,69,74,123,94,59,104,-85,-80,-123,-19,84,-124,44,-87,95,-64,-120,105,-27,-71,-92,116,-110,-26,-101,-123,87,11,62,-79,-79,-91,98,9,-36,-112,-113,94,87,-29,108,38,47,116,-110,-6,-11,-118,-67,93,-31,-36,46,-53,117,-24,82,-76,121,7,108,-107,84,-39,-82,75,-31,51,78,-92,-69,61,26,-67,-127,-49,-37,-67,17,78,-47,-31,68,77,116,105,-74,45,42,-59,-109,-89,-10,-26,64,-28,109,114,80,-71,-64,56,-75,16,-50,-20,96,-23,-39,42,-84,46,94,61,-100,-43,-63,35,54,110,37,48,54,9,32,-40,17,-100,33,-33,-103,-90,-86,5,21,45,-75,89,45,-78,-18,-55,-97,23,-15,-5,-108,-41,-102,-9,10,42,-36,-28,-17,-84,-53,-76,117,104,80,-112,-10,87,51,32,96,-87,-15,47,-44,-16,44,-55,-34,-122,-65,89,-59,61,93,-70,-10,-124,-64,-65,-118,64,-88,-100,-68,26,-44,51,-51,-112,53,-38,43,48,-60,-55,-101,116,-42,-89,-59,-47,-41,37,-122,61,109,-97,-94,-99,85,-128,11,120,-32,-71,59,-84,50,-26,-111,118,-10,-74,-105,85,-63,75,-73,96,-122,108,12,-2,122,2,22,-128,-8,15,-50,20,14,-58,-99,-91,62,66,32,19,112,-38,-9,-101,-40,50,68,58,-117,51,94,-18,112,19,88,-47,73,-109,81,67,-49,121,-67,-113,52,-116,-38,-53,18,83,124,34,-116,66,74,-47,-96,-64,76,-125,74,97,36,-53,-30,118,14,-23,97,-10,-87,-54,-103,-22,-122,-6,80,-82,-44,-59,-56,65,-66,-65,-73,-84,82,-66,127,-63,24,-26,38,105,-109,110,62,-17,-51,15,-123,-96,-122,-111,114,-52,122,120,-49,-51,-19,28,-11,-22,-55,77,54,99,-121,30,36,19,-84,-53,59,-118,-127,-18,81,-94,-75,101,106,94,5,35,87,-114,84,-93,112,-55,34,84,82,-100,102,114,38,-66,41,89,-73,-107,-67,16,-119,61,22,119,7,-103,-84,34,-116,20,67,-57,61,-38,-94,-96,-51,-44,54,10,-62,15,108,-68,-123,25,-122,67,-41,1,-77,67,-4,3,-120,8,106,86,-26,71,10,-19,121,52,29,84,52,-27,73,81,9,35,-73,-15,-62,100,-19,93,5,-30,31,-71,-43,-63,10,3,-103,-41,10,-16,94,101,-8,-11,44,105,-113,87,21,-75,30,-79,-44,55,-113,-105,36,42,-100,-128,93,-122,-99,-72,-86,90,-9,-106,29,-58,33,85,45,-49,-115,38,-114,-76,115,-13,43,77,-82,23,-3,117,93,101,-1,-89,-71,-113,123,5,3,-64,36,69,-124,97,65,-109,-62,106,33,81,-46,-40,-33,28,-89,-67,117,29,-110,98,-36,102,47,91,55,-67,-34,57,31,-124,13,99,108,-9,105,99,40,-95,-64,114,-108,-60,-4,-28,-1,-126,-1,121,-80,103,-4,-104,-78,-92,20,120,113,-19,-46,-13,11,-105,110,19,-82,76,-85,89,-103,107,-35,-14,-56,-92,-95,83,10,123,-73,113,-82,-53,-128,-6,44,-64,126,44,-63,67,-25,45,-69,48,-76,47,6,89,115,-17,-100,-92,-106,33,-79,-60,44,74,106,-90,-120,-107,-59,89,33,96,66,70,-104,102,-35,-4,14,101,99,-3,-120,105,122,35,48,-125,7,101,-95,86,-39,-8,90,-112,127,-77,13,-36,27,-83,48,-10,-40,102,97,50,-48,-111,110,45,-72,-4,-86,33,-13,126,95,67,-1,-4,-66,-91,119,67,-32,35,-124,-36,31,25,118,21,-2,-24,126,49,-102,74,100,-127,-15,89,84,-83,-17,-25,-54,35,-123,28,-98,52,-27,75,-45,-116,85,-112,-43,104,51,36,-84,82,-122,35,98,-20,-17,-62,-99,92,92,-26,85,108,-70,-118,-78,-85,-56,-2,-60,-115,54,-77,-8,-28,-57,-81,-16,-57,-92,40,89,-58,-19,-125,-31,-90,44,-117,-88,46,-12,96,-93,112,-67,50,-41,0,81,-26,-128,117,-53,65,-85,54,105,-124,-84,-5,-16,13,101,92,-51,-115,98,109,40,-23,43,-41,-28,-45,-10,18,5,-125,48,-116,111,-54,19,20,33,82,30,-123,55,120,3,79,-32,-55,70,90,-33,60,121,1,-28,77,-64,22,-95,37,-40,83,33,-107,-72,-96,-47,59,-76,117,-34,-13,-81,-38,117,36,-106,93,33,-86,-118,81,-71,-49,-126,-74,-61,66,73,-91,80,-98,-56,-31,60,4,36,-104,24,-53,-106,44,-120,5,90,79,83,-88,34,71,-32,-78,-50,-39,-42,-21,98,60,86,79,6,43,-27,32,-6,57,-54,-98,71,23,-60,22,-126,-86,64,-28,-128,-40,63,53,-31,-124,-98,13,-98,-81,-52,107,-46,71,34,-9,108,-50,9,16,64,93,-6,11,125,2,45,18,15,-15,116,111,109,-47,-107,-17,127,-19,125,-95,97,-79,41,56,44,46,-8,-12,86,36,-56,-92,4,-111,127,76,95,77,75,87,67,91,5,-35,89,43,-80,47,-84,11,0,-33,-44,-73,-104,46,-48,-28,-38,49,105,-30,-95,102,-112,-62,-1,72,-54,-56,49,85,47,41,114,42,-67,-97,9,7,113,-85,-22,58,90,25,118,-111,-62,-47,-81,-5,42,65,-111,89,-126,-46,-22,45,118,25,-29,74,-62,-77,124,-1,123,123,-46,-74,-24,-115,-5,-111,-82,24,-1,109,-70,-13,-1,37,121,-66,-119,-36,19,-61,-62,-6,82,-103,48,94,-24,15,-106,90,13,124,-94,16,83,-38,98,-30,-101,52,105,-13,3,-98,58,111,-61,-16,-32,-47,5,41,28,-126,86,5,22,77,-34,-55,64,100,-104,44,59,121,70,-7,110,-12,-19,68,-124,30,-97,105,17,14,-100,-48,56,26,108,-78,-56,-3,81,58,-14,-73,-83,51,-51,-116,-20,114,55,49,106,-64,-75,24,57,18,-113,74,-86,-14,109,-124,-21,-121,-78,46,-104,62,-39,34,-47,-110,77,-107,-23,43,-82,32,-111,-75,1,33,78,60,56,-6,120,-90,-92,-35,77,11,-42,-81,-123,64,-78,-43,118,52,-62,-96,53,8,70,-64,41,6,80,-20,-104,-124,-101,90,-24,-17,-11,99,105,88,122,-114,67,-122,69,7,56,23,67,61,74,-65,0,-50,-29,21,-76,84,85,-42,-60,103,-102,107,-24,-110,61,-102,102,-27,-81,-110,4,-79,-9,0,58,-38,62,94,-99,-44,64,76,8,-74,-118,-96,102,-40,112,-81,83,-72,97,-9,-102,-126,101,62,-44,-122,-107,25,-35,107,-100,-124,-65,1,109,-102,0,-96,37,-84,26,-67,91,46,83,-23,16,57,-70,75,-14,-123,-72,-102,38,79,-78,25,-121,-112,58,-9,-128,-70,30,-40,-51,122,27,-92,-8,119,-115,-125,71,-40,115,54,104,71,65,120,-95,14,-96,-69,-89,13,-56,2,26,71,-70,87,126,11,-6,94,-31,110,43,97,-22,-83,-93,-79,34,-116,-102,44,43,-54,-65,81,89,51,76,42,-28,18,115,-33,108,-17,88,61,101,-42,27,39,-20,120,-2,-83,26,-100,67,-13,27,-60,-120,-15,-7,59,-39,-53,107,-54,-44,-123,-110,104,-119,122,-90,102,-51,1,-85,30,-75,82,-94,6,39,-92,3,60,-2,2,43,-71,-110,-55,-102,116,116,-128,-85,70,48,93,-83,-127,82,-35,119,109,-107,48,-23,-8,-127,95,81,88,-109,-45,73,46,89,-107,15,-11,-108,-67,66,108,59,-80,25,-64,108,-29,53,72,75,23,-29,-9,7,-30,103,-6,29,-63,57,54,74,-115,-3,116,-54,68,-31,-13,-115,85,120,-69,-79,-44,75,117,-28,-67,121,-46,56,-83,114,-86,11,7,121,119,-49,7,87,-117,-105,21,50,9,65,-122,-13,16,127,100,121,-43,56,45,59,18,-70,-17,43,-40,-19,123,-22,56,35,-16,55,67,-23,-60,12,101,48,68,25,118,103,-85,-7,42,-52,-32,-11,-44,31,71,-72,-15,114,75,112,-37,8,-32,69,-21,-30,-78,106,9,-109,-15,37,-106,65,127,47,115,24,-119,-103,-20,-8,95,90,-7,113,37,-103,-113,87,-79,92,-11,31,-49,-21,-64,89,62,91,-109,65,-2,62,-48,-55,-25,86,29,-81,0,-23,-5,-4,58,65,123,-121,-108,119,-104,117,-68,52,118,75,-19,-64,-126,72,73,-121,-91,42,-104,0,-1,-103,-104,16,-109,-50,-29,-32,109,-9,-19,-105,-103,-50,77,-123,-23,-99,-95,58,-14,-90,-21,-38,24,-74,94,-121,-98,110,95,4,-48,122,-69,21,23,57,-50,76,-112,32,48,-38,116,-62,-54,-57,-39,-32,121,60,-67,-41,-107,31,29,65,122,90,107,-128,126,101,115,76,-109,-59,-58,-52,56,-114,-115,102,19,55,-53,-83,-61,-103,-26,-63,123,113,14,-83,-59,59,-104,3,7,-1,-39,-51,61,25,36,-84,-30,65,69,-66,-75,66,29,9,-128,99,-70,-18,1,-68,-22,-96,41,14,-54,11,-5,62,-115,-87,-40,57,-53,-117,70,-12,32,-123,31,-44,-63,16,-43,-34,126,-82,-115,68,-121,98,-68,4,-80,5,35,35,-53,17,70,34,14,125,-122,80,80,50,113,-39,52,-34,7,89,-87,-118,-25,-94,58,118,-69,-112,55,17,116,53,33,-84,22,-49,55,48,48,-102,78,76,-55,112,101,-75,-55,63,32,98,19,79,95,-13,67,113,15,-22,-123,51,34,114,-10,88,-62,59,88,23,53,109,-42,24,-21,61,25,-34,24,50,24,6,-95,-102,-85,65,127,62,-59,41,55,-67,-99,11,78,61,-108,64,58,-54,21,-119,76,-9,64,23,-48,-82,54,6,52,103,59,123,-35,55,24,35,-68,-56,-39,-74,32,17,-29,-7,37,62,-103,-58,19,-37,-123,28,-53,30,101,46,88,-127,14,72,27,-124,8,94,-56,-90,-97,-80,-17,90,-32,-12,107,92,-110,0,54,-36,-69,37,-95,-74,98,-57,-72,-38,79,-8,-31,77,122,-62,-118,68,-6,90,109,-1,121,114,91,-51,-58,73,13,-110,40,59,-25,-121,-65,31,-87,25,35,-72,-22,52,-60,15,-117,-37,26,-15,-32,99,94,-94,-53,117,-7,-108,10,-82,-55,-58,-28,-6,122,103,121,31,-68,11,-26,60,-66,-97,81,117,65,90,73,-11,102,-56,104,12,-75,20,-116,76,-116,-115,32,74,-46,94,105,53,74,-8,-21,45,-2,-65,108,-5,39,94,62,20,-61,36,-97,10,8,54,-117,61,40,-123,24,-16,63,24,-4,11,28,61,-104,127,-46,-90,114,72,-70,-105,-7,60,-51,-35,-5,71,-113,102,-66,-83,111,52,-128,6,100,114,84,-77,-52,50,-94,-33,56,55,-114,44,91,63,113,-5,127,66,-73,55,68,13,-76,10,-95,94,93,-124,28,-82,-117,37,31,-27,-36,-72,-31,-66,69,56,-8,-123,-102,76,-113,40,18,95,47,76,-90,73,-84,-46,-75,55,25,7,-95,38,-34,72,18,-84,-104,62,-92,-5,-77,-67,85,16,122,63,-31,64,97,-23,-55,-63,11,-90,-105,-80,57,5,-60,10,34,56,-39,-102,-104,-87,-85,23,-96,121,75,32,10,7,61,45,19,-110,106,58,-50,67,49,76,19,81,19,-65,-25,16,-79,80,96,125,107,93,-119,-43,13,15,-76,-127,-29,38,-29,-95,-43,-92,-120,-126,22,-39,-34,-81,-91,43,113,-13,-7,105,94,126,100,-79,77,7,25,-99,113,115,-125,26,2,-5,106,-89,76,-106,-70,-92,-71,-104,48,-16,88,-21,123,82,-58,109,7,-47,-62,-62,121,-75,122,-100,-103,51,86,95,101,-99,115,27,-8,-97,-109,50,-68,-15,64,126,76,-94,-94,87,-13,-45,11,62,-27,35,126,-56,-115,12,39,54,108,-127,-17,-76,-95,61,-98,-10,-14,-65,-52,87,9,45,-66,-110,114,-65,-54,-7,-115,-126,86,32,-21,24,97,-117,-50,-52,49,-106,-116,53,-39,15,112,99,90,111,34,24,-70,16,80,-85,-29,113,-90,-21,69,120,-111,47,73,110,-36,108,21,-117,-72,-63,-15,84,-65,13,-40,-96,57,-15,44,126,-114,51,1,105,40,-20,77,76,44,34,-115,-28,-114,22,-108,-96,110,-128,42,69,87,-68,-96,-57,89,66,-86,-32,43,-14,41,-114,16,106,-27,-22,23,23,16,-57,72,-53,116,9,59,44,20,46,29,77,-42,-17,-119,-66,1,-75,-88,33,-94,107,78,-28,-125,-96,-27,-71,-43,-52,-74,-126,-86,-77,33,37,22,-105,124,-5,80,-124,65,29,14,-23,2,13,102,-11,-86,0,24,76,-18,63,-66,111,5,-15,76,-125,126,-82,-92,43,-3,-59,-126,-99,-46,37,-76,10,-127,-80,21,98,24,-62,-99,62,-51,85,70,43,-112,-97,111,-111,120,-54,-56,-52,-93,-30,53,-107,53,53,21,-104,-97,-30,89,25,-54,-62,54,88,-83,74,109,120,85,15,48,76,76,-74,50,-36,-52,-99,-112,121,54,18,-75,-40,30,-64,-72,110,28,-7,45,-91,-65,115,-67,-20,22,107,14,103,-71,-102,92,-33,33,-72,-4,92,100,110,-70,91,-27,-52,-63,116,64,-124,50,-37,-48,-93,-23,51,56,-77,87,55,61,-37,-23,-96,19,-73,79,119,3,-34,31,65,86,-127,-120,21,-39,-117,-78,-18,109,89,-33,-42,49,5,-28,65,40,52,-99,-27,114,-28,42,36,38,-46,-36,-88,-8,-94,45,116,-120,48,-109,78,-22,-20,50,74,11,-11,-16,-73,-127,45,109,24,28,-113,102,-33,109,111,-70,-40,33,-112,81,19,40,6,9,65,-25,-38,45,122,-57,-69,-65,-28,37,86,42,-113,119,11,60,-114,4,69,125,93,-60,-52,-58,-72,76,-8,93,77,69,107,-42,-84,-28,100,38,41,-119,-115,-114,-80,-111,95,-113,-122,37,-10,-118,-21,-6,-45,87,-30,88,44,54,101,95,-29,122,124,-101,-72,92,28,-74,6,-29,83,-48,67,43,-92,94,-69,-99,20,124,22,13,-76,-104,-46,-74,-83,-61,48,-81,-115,93,7,-85,-125,-81,-37,81,-28,-85,-14,-79,10,74,86,91,65,127,-66,87,-30,24,126,45,114,-32,-7,-25,-9,-45,-113,28,-53,-106,19,53,85,65,91,-67,-107,-106,-103,-31,49,27,59,-52,113,119,90,125,126,-13,90,7,58,-93,78,-124,-59,80,-59,34,105,-49,-100,-119,-126,-86,73,-54,22,-71,88,112,36,60,-9,88,-96,-113,-70,-83,-105,126,36,-9,118,-33,58,-47,-17,29,-86,98,13,-103,-106,79,69,-102,37,-104,-35,97,53,-99,38,72,100,-88,121,112,116,26,-32,-105,-98,97,82,-125,64,81,-81,12,68,-86,-56,-80,5,123,21,48,-122,-99,50,10,-98,94,-30,51,-86,-97,-24,-95,109,-11,61,-1,-24,-103,-125,-28,-101,73,-111,-32,-41,75,117,96,-9,36,68,-34,121,-122,-83,-42,84,41,-116,-101,-29,-51,-104,-32,65,-37,-49,-117,-22,106,110,-20,73,-5,-105,59,-96,-79,-47,-115,-115,-103,83,5,-104,-126,97,94,39,107,1,-105,-91,-103,-70,-92,121,82,89,-85,-103,-5,122,-43,-10,94,-59,-116,-12,72,-73,54,17,-43,71,127,-7,-125,-31,-57,126,56,-96,-37,36,112,-80,-42,26,-118,81,124,59,96,-36,-31,8,-49,-80,83,62,-52,38,-106,122,-112,93,32,-47,-67,56,41,-120,110,43,-44,-31,119,-64,98,54,76,64,-28,122,95,-7,63,-41,-48,-95,76,71,-94,125,-82,-91,59,65,125,20,109,-42,23,78,3,-91,-29,-19,-84,37,-21,59,-80,-84,-50,-77,-46,-42,75,6,-14,-46,-102,-81,-94,-102,-68,91,-26,-85,-61,-43,-128,-84,-55,87,-45,-67,90,-24,91,-20,117,81,-2,124,65,-113,124,54,-116,-106,41,106,-12,55,6,-93,7,31,-44,54,-50,-16,-119,-17,-23,14,88,22,-41,-9,-3,52,78,-33,-61,-16,114,-101,-57,46,-113,-76,112,121,-82,2,-3,-50,117,-74,104,67,64,-45,84,-36,125,30,11,-16,40,-69,83,-80,115,-127,-72,-41,103,-16,71,-33,-38,22,-39,-81,54,72,-73,20,-105,65,61,97,57,-122,23,106,-111,-87,-72,-97,115,89,113,57,38,-67,-25,-29,-93,116,-123,113,-68,-111,92,46,-25,27,-44,-11,79,101,-30,12,-89,-29,82,68,22,-17,-52,71,105,52,85,-112,-72,34,-109,17,86,-55,42,-90,22,67,119,43,-80,-14,51,40,-73,85,-51,102,95,28,-44,82,-28,-74,127,-104,31,58,-27,92,-125,-125,80,47,-47,24,-24,37,-71,123,91,49,102,67,-42,-111,97,41,48,-111,-45,81,-31,72,-64,38,-118,70,-114,-102,42,7,-87,-41,-9,-54,118,-48,121,-105,19,-28,-109,-84,-108,110,-55,-107,122,-74,99,69,100,85,-105,83,-66,-78,-8,-51,-88,-102,40,-5,-9,-110,3,-36,-20,120,-121,-97,-53,-37,-80,-46,-101,85,-61,-46,-22,117,-80,-120,64,-3,120,-46,-117,-121,-122,-53,-9,15,127,-29,11,-32,9,11,-87,86,15,57,-59,100,-90,64,-47,121,-34,-43,52,91,-116,-35,122,117,122,-90,115,-128,112,29,66,-73,39,95,-107,44,124,-31,18,-104,102,59,78,-14,-47,-30,41,-21,26,18,122,-19,43,-66,59,28,105,45,-3,98,-77,60,100,81,-22,8,3,80,105,-87,62,116,-21,83,31,-95,112,-114,-126,-58,8,121,-65,46,-112,-94,79,-128,112,24,99,-114,83,28,-104,89,-18,-121,-10,16,-73,-18,-97,69,-94,-81,-18,108,-86,53,-87,-17,-30,99,-23,54,1,-111,11,-52,-63,112,-55,-125,60,56,70,4,-103,114,89,114,-80,53,-50,49,90,-97,-54,-89,126,-17,110,-99,-30,-9,-71,95,74,63,92,-38,26,111,61,37,53,-76,27,110,-96,101,63,21,-99,121,68,-10,-124,-17,32,-83,-19,-92,-72,-26,-78,108,105,-80,115,60,-10,52,-74,-46,-77,-70,123,109,-77,-48,57,-54,-30,-37,22,-90,66,-41,112,-125,-1,89,120,-93,68,-103,-97,1,7,94,116,-108,39,-102,-7,-113,79,-90,56,-76,-8,38,27,123,-40,-111,87,-47,105,114,77,-9,-69,54,-109,34,-25,85,-65,-16,106,-94,-75,-103,87,12,-123,101,-41,-3,-1,-7,48,-46,56,-1,92,-18,-4,120,-46,110,96,81,21,92,-37,-54,36,121,-18,86,-55,118,101,87,55,49,79,-96,-28,19,56,71,-27,-127,110,104,107,30,65,-128,-107,110,-20,-57,112,-103,-41,88,12,113,117,-5,46,33,-20,-115,-113,-106,-19,101,-120,5,-125,-89,-107,-33,-116,-69,107,-85,-101,-39,44,31,-69,108,-124,-2,67,15,37,32,41,0,-20,78,59,79,-8,-80,-50,-82,-115,-6,12,1,-30,-85,-90,7,-61,96,-81,99,97,51,123,-107,-68,-102,127,-82,58,23,11,42,62,-82,-51,-59,-40,73,76,0,66,-42,103,-104,59,25,-48,-25,-99,55,-9,43,123,82,-108,53,-32,-20,-4,-36,39,23,-48,100,-1,-114,20,-108,74,114,-12,83,111,-77,89,-14,-37,74,6,126,-52,29,109,62,110,-108,38,-32,55,36,-92,-16,88,60,-84,0,-3,96,-50,36,3,-111,92,-3,-13,-23,19,-122,-32,-35,43,-48,52,5,62,78,27,-86,-59,-114,-19,60,-111,-75,0,-120,122,125,77,-128,-124,11,-112,29,74,18,15,43,82,58,63,-69,-26,-90,63,125,25,122,39,48,-64,-103,-107,41,-105,-122,84,46,-95,-57,39,36,76,-3,19,-21,-57,-56,-47,34,-30,-41,-128,-47,-10,66,118,37,119,48,76,97,95,-119,-71,17,66,-128,47,96,15,83,-48,117,-22,-43,-68,-44,-128,102,17,-16,62,-34,85,79,80,-11,-2,123,-123,-68,-36,126,98,-5,99,-56,71,76,23,45,69,38,28,-9,-96,-80,-107,-9,-87,1,53,69,-10,-69,-74,-107,-38,83,-7,-46,105,-117,-30,49,-126,-29,-55,35,56,-18,-4,95,119,-9,-114,9,29,-32,-19,-55,-123,72,-30,-17,-56,-117,121,-92,-18,-11,67,-71,33,28,-9,92,48,-100,-7,-120,-18,-37,16,-105,-18,106,98,124,45,-45,46,90,-39,-120,-67,120,125,88,-12,125,-42,114,-84,-8,-63,-17,-109,41,80,-57,19,82,9,-87,-4,-58,-52,-60,-76,20,41,43,126,-19,-110,-26,32,-107,126,8,-74,29,108,59,28,71,-39,-12,100,-82,89,118,97,-96,-77,-41,31,4,-119,-38,85,-23,7,116,53,-115,-35,117,-67,-122,75,109,18,50,115,99,97,-72,-94,-48,-22,-122,-21,-22,81,47,108,51,-68,-115,109,7,91,-56,11,-6,12,-15,-62,2,26,-100,52,111,5,60,-52,82,110,93,-116,-31,-62,-2,83,113,10,20,-82,-58,-78,0,52,-108,-67,121,20,-18,79,90,79,94,35,88,68,92,20,46,67,79,-21,-23,27,68,-50,-9,-16,-113,-76,30,-35,-86,-10,17,-102,-88,-89,-112,-99,-67,-123,-108,84,110,-9,-92,-57,73,31,-107,98,60,111,-82,-127,88,45,64,116,-125,29,-115,-33,-81,-127,-121,109,112,126,126,-76,37,56,39,-45,-35,-53,69,-74,94,58,62,35,-120,-17,9,29,-92,-66,-110,-71,-96,-52,-25,-55,-98,23,102,115,-84,-115,3,29,83,61,27,-40,38,-8,-102,95,-83,-115,96,-2,-90,74,0,-13,-39,98,-119,117,-78,-87,36,98,-30,-96,-110,-122,-105,0,-113,-23,-115,86,31,-86,21,-91,54,15,-29,112,120,-128,18,-35,-67,15,77,33,115,-18,74,-51,126,99,-6,46,37,-13,-33,-47,92,-88,-108,-43,-25,-74,59,-67,-89,9,8,92,-126,-82,22,88,-51,-48,41,-111,-55,103,-36,-41,29,-11,-6,30,67,25,-109,-47,-43,-120,-15,-40,-69,-120,19,-113,-61,78,-21,-121,-127,125,30,-20,95,16,122,10,111,-37,107,-77,43,-97,-98,106,-121,-86,-94,-104,-39,86,10,-44,99,-14,37,-52,113,-37,-49,-44,10,-61,-55,2,-107,36,78,52,115,76,83,54,125,86,20,97,36,55,18,-114,-49,83,-48,-23,-90,83,69,-73,57,-128,-85,-16,-11,49,84,-15,9,83,4,-60,100,126,-41,-81,80,-16,114,-2,-92,60,28,77,118,102,45,86,50,79,29,1,81,126,53,15,79,-110,-113,-87,-55,-95,-46,75,-29,-56,88,-90,-17,-4,-24,-57,4,-101,-38,-86,54,-80,26,70,-97,-112,-53,-57,-58,-97,-38,2,-30,30,-53,60,102,-113,-78,9,39,-9,28,-37,69,-11,98,-78,11,-9,-38,54,-27,65,-86,101,-82,102,-36,-66,-55,-123,-1,107,94,41,-103,-47,-21,26,-40,-57,43,127,127,121,124,-126,-104,105,-121,-39,9,-107,121,125,-67,-79,64,-77,88,-47,-96,-78,27,-19,41,-57,36,39,-54,101,46,-27,-48,-95,-60,27,77,-26,-23,-52,122,-101,101,-96,44,-48,-7,-109,23,53,65,17,-119,52,-15,110,-49,-124,-17,62,-122,-91,95,-56,-100,-81,77,-10,30,-124,34,79,-9,117,85,-70,3,-64,24,-29,-78,-106,97,46,-16,35,54,-44,117,52,-29,54,68,-120,-11,111,81,0,-123,-4,-42,5,-69,34,51,-113,-116,-108,-91,34,126,-56,126,74,-20,-98,20,75,87,-63,-123,-85,6,-70,8,72,-60,-25,-78,19,62,-32,13,6,-48,-83,20,-20,70,-30,-114,48,-107,-60,99,-10,101,-50,7,116,-33,15,-73,41,27,-82,-117,-56,-25,10,9,85,108,44,20,-69,92,28,-61,116,-55,1,-25,31,75,-68,-21,21,-3,22,41,-111,-22,25,25,12,-32,-10,84,41,-3,-11,96,-83,85,-33,-59,74,107,-80,-40,-102,123,-28,18,-93,115,-66,117,-128,-88,-10,-99,101,58,-3,-51,-47,40,4,-36,50,28,-57,-126,-91,100,44,-47,36,-124,117,-46,-47,109,-65,112,-43,51,-48,-116,51,-113,-106,71,115,-123,-111,-82,-18,-126,10,94,98,-39,-50,-60,-58,-14,43,-124,18,25,98,-99,86,77,35,-85,-58,-127,10,-23,79,60,119,28,3,-11,-44,7,-70,108,115,-122,58,66,-96,55,76,-2,-1,15,98,-121,84,-120,94,121,-80,-58,84,110,92,107,-125,-61,75,-4,-94,-52,-7,3,84,96,12,-48,-16,-25,-36,6,-91,70,-80,-22,91,61,-82,-77,83,111,-47,22,-82,65,28,119,63,-71,94,-53,-74,-119,57,-103,-81,12,-26,-73,-113,124,100,-91,-102,-90,24,113,11,3,-18,-4,-50,-73,72,-2,-16,121,94,-70,106,-62,-105,-50,4,-46,-34,-52,-31,-15,-89,62,-11,-78,43,-36,-104,-118,-68,87,-106,-2,-86,112,-51,3,-24,120,-78,-20,14,44,-58,103,-70,-15,10,93,9,15,-66,-75,74,-106,-117,-65,-8,16,-10,-31,107,-114,125,-44,-84,-75,26,-97,2,12,-27,-117,80,45,-115,-29,8,97,-74,108,75,-60,17,-119,1,-14,10,-14,-18,81,-81,11,8,29,-110,122,122,-24,-35,-120,113,-78,86,27,-31,87,-89,76,9,-114,-29,-75,-43,-12,-70,-118,-94,-1,70,62,-56,34,-32,-99,-126,-15,97,-38,-86,88,-37,20,94,119,103,64,41,-44,-66,-78,33,22,-67,120,-109,84,-106,-62,-34,12,104,36,-88,21,-35,52,-78,74,37,6,121,70,-78,-109,26,8,-18,42,102,-104,22,25,87,120,-8,125,-90,-82,127,-100,1,6,102,-72,78,-42,-100,-59,-87,-125,-13,-86,34,43,-12,-109,-61,13,36,87,-108,29,33,24,-124,-36,-114,34,-88,114,-41,21,-115,-71,-3,-108,36,-31,19,57,-95,97,-114,46,-121,-102,114,77,76,82,79,11,124,-82,-124,-50,31,92,113,-100,-102,27,-88,122,4,-87,7,102,118,30,-98,-84,72,-73,24,-112,-97,-125,-29,58,-101,52,48,82,111,78,71,88,-40,-58,-28,11,-94,125,-6,12,-18,50,-62,78,-18,-62,102,29,127,80,-31,-126,7,114,-25,-100,-116,120,-75,69,25,26,124,-23,-68,-15,-79,-5,-14,108,4,11,-69,-41,75,59,-72,113,26,-66,48,-4,103,57,71,-94,-2,14,-28,-36,22,-8,-25,39,-51,25,99,91,70,63,11,-124,69,46,-34,-21,99,-70,-110,-90,32,116,34,-74,82,43,-104,-56,31,-117,-43,67,12,-72,115,-84,-62,-9,21,-30,105,82,94,86,12,40,-47,-39,40,-114,-67,-89,-72,-64,-62,-124,-105,32,95,-124,-41,-14,48,26,8,-116,-57,24,-45,-45,-75,-40,-111,-118,107,116,66,-97,-57,-79,-96,-85,-55,49,-55,-32,-87,-76,-12,42,-85,85,-16,75,-41,-112,49,-29,-28,-124,-10,-60,62,-2,-112,15,-36,-33,81,-95,117,120,51,99,-64,30,11,106,-21,-42,43,-59,51,117,12,45,3,-116,110,88,104,60,67,102,-74,108,80,-58,-108,28,38,-108,16,63,100,-24,-36,-1,70,97,7,32,118,-112,-122,-31,-36,106,10,115,-89,35,58,-15,-5,63,19,-123,-99,-11,-94,108,-18,-13,70,-12,-1,126,-15,-9,-25,113,111,66,-59,81,-88,-114,97,-121,-76,16,8,72,62,3,-107,106,-43,92,-91,63,60,-90,-61,96,-9,93,-24,-17,-22,38,-24,29,-27,-36,-25,117,99,-10,76,66,-77,-71,33,-87,100,48,-13,-122,-49,56,-104,72,72,-84,103,72,115,-10,45,19,-22,52,-97,-77,-107,50,-81,-93,-79,102,-71,46,73,6,-21,-52,5,-96,32,112,15,-44,-4,110,5,-26,-85,89,-87,35,73,-17,59,-95,-5,-123,94,127,-83,9,-122,-64,-58,-72,-111,33,-91,-82,56,63,1,6,-67,-106,-55,26,-12,-105,-32,115,-38,-95,118,117,67,-17,95,99,120,-75,2,28,-113,-105,117,-15,111,22,-46,116,25,-91,40,44,84,37,-4,-66,-125,15,69,-14,49,-12,-11,87,-68,20,91,110,117,125,-65,-34,-36,84,-29,-87,-27,60,-66,-118,-125,49,69,81,54,7,-119,53,-23,-60,-9,22,-116,-125,-58} + +#define IP4_WEIGHT {18,-44,-120,40,104,61,29,-56,-12,78,-75,-19,-34,92,-80,21,60,107,62,11,58,94,-6,-32,-92,-118,106,-105,-104,47,-20,24,43,-116,-108,0,53,-50,-5,-26,43,48,-80,-73,-86,-38,115,111,78,-101,94,-20,94,-61,100,-111,76,-55,13,-81,39,118,70,94,-125,71,54,60,-70,-14,-121,51,63,-121,-121,107,-69,-74,-106,-38,-61,110,60,-28,-43,-116,83,62,26,103,-125,88,94,111,120,-39,-79,-85,-45,-90,121,-121,-97,109,112,34,-97,12,-93,97,90,-45,-59,-105,28,-10,0,-122,-87,-62,-100,-21,35,-115,-26,-37,6,108,-15,118,-41,97,-26,-74,94,34,26,-84,-65,86,1,73,67,59,-99,-67,115,-43,-26,-21,-21,37,106,-80,109,-107,-71,-20,64,-2,-20,115,83,-49,53,-102,-46,121,-75,108,-106,-59,35,45,-102,-41,51,22,25,122,-58,-116,-7,-2,-55,19,-126,-76,-103,80,-34,110,15,82,-73,93,15,-52,117,62,-46,-16,62,67,-19,-39,-27,-12,-89,-100,-37,-41,59,-127,111,99,-15,-57,-79,-43,20,52,-31,13,-12,99,-30,-69,-31,124,-36,-89,43,-1,120,-79,43,-15,-19,89,46,54,113,24,49,85,-17,-119,116,-46,11,-59,94,67,119,110,-57,-1,113,-94,32,-38,110,-14,-81,77,-53,111,118,-13,-19,-53,4,-20,18,108,121,-97,30,-121,117,-35,-31,54,24,119,-74,16,101,3,125,-59,-12,14,52,-65,65,107,60,17,-38,-53,21,-118,76,-112,-53,-108,-38,26,-58,19,91,106,-63,95,98,-4,63,111,-74,37,-47,60,-115,-44,29,-57,73,63,-51,9,-84,22,22,81,-87,-65,-126,7,-93,110,-127,-70,-27,-63,-12,-118,63,-26,-113,45,107,-69,79,111,56,55,-2,108,103,-48,113,120,25,-55,43,-122,-41,40,124,63,88,-78,29,24,93,44,122,-67,107,-34,14,-69,-72,108,93,-37,116,90,-24,-76,67,26,-103,127,88,-48,115,-80,-97,96,62,-1,-22,-123,-65,10,-61,-54,-17,21,-14,-49,116,113,10,88,124,-112,-119,89,88,119,30,-24,-119,-115,-95,58,57,68,-17,-27,-60,59,-64,-26,-127,-35,31,-9,4,-89,18,109,8,-90,88,22,18,45,-123,88,-80,-66,-76,109,25,47,-51,-90,75,-24,-109,-42,19,-72,-8,78,2,-84,-47,68,33,94,-98,-122,-109,82,102,55,66,-23,19,76,40,106,71,-121,-42,-2,76,93,3,123,-111,83,117,-52,8,105,121,2,-4,-18,-4,-19,-125,80,36,29,25,123,-72,-41,38,83,105,-71,-64,47,-127,-82,31,-43,-99,101,73,91,-51,60,3,9,-27,77,124,-3,-96,15,74,35,-29,2,116,-4,75,38,54,-119,8,93,53,46,-18,49,40,-30,-111,-62,97,-8,-96,82,30,22,21,97,97,-35,-12,28,-118,-12,95,40,-16,110,29,-58,87,29,58,41,46,8,105,-108,-29,36,84,-87,-118,-124,53,125,-117,106,-83,21,11,60,-31,-5,114,93,96,-112,-127,49,-126,69,-75,-41,64,60,-98,31,2,-73,94,-100,-44,91,-115,94,12,75,-23,81,46,-89,-116,-25,-47,107,-77,-10,62,-69,-70,75,-41,53,-82,79,104,-7,-106,-1,73,-32,74,-113,-91,-47,-115,66,-96,121,26,111,7,51,-55,20,126,-75,63,-23,14,16,-124,-39,-48,-84,81,14,-27,-56,-41,-13,-43,120,33,98,31,-50,-6,15,-107,-33,41,26,-9,121,18,8,-106,-46,64,127,60,39,-59,-30,-5,-119,-19,-104,-79,-38,86,-121,85,-17,21,44,49,-73,89,73,91,-36,-120,-22,26,-69,-17,-102,-71,103,63,125,105,15,103,-20,-122,-62,-8,61,-116,-78,-116,11,-80,-80,-58,-119,87,-15,99,-111,-87,-84,65,-47,-38,-44,-26,69,-14,-37,-27,-90,-97,29,-4,38,52,-87,109,-72,-50,61,-110,82,-44,8,63,92,-70,-10,-124,69,15,80,83,109,111,25,-47,-110,104,66,32,-16,104,-31,-52,-41,18,102,-70,-49,22,-109,-16,122,62,125,-123,121,-61,-2,92,-90,-81,109,74,5,98,-125,-92,72,101,-120,60,10,-13,80,94,-25,45,-43,58,53,-80,-13,38,-56,-77,-44,-37,46,76,1,-103,-93,74,63,-62,38,-82,73,-124,48,67,-59,-26,116,109,75,70,-30,25,85,76,66,25,-18,-113,106,25,-83,81,-50,-104,-44,-53,-68,124,112,78,99,96,-126,-125,44,33,-75,-29,-60,-6,-26,-84,-61,118,-4,-9,-126,-46,-57,-119,-127,105,21,-120,-121,-33,105,-70,-124,-108,-111,54,-35,-30,57,-101,-79,-48,-65,-108,77,22,44,111,68,-91,-111,41,112,110,56,118,0,-49,62,-54,83,52,-94,38,-14,105,27,78,66,14,106,102,41,24,53,-40,60,59,-124,56,68,-119,102,-70,-119,-101,-25,-95,69,-45,-55,-38,57,-122,106,-96,122,33,-5,61,104,77,122,88,99,126,-74,46,-52,-3,-38,-101,74,-30,96,116,-51,-21,68,74,2,17,71,-124,47,-35,107,-23,64,24,49,41,-50,-23,88,19,-30,10,-96,3,-14,100,-116,55,-91,84,100,-54,125,67,-40,-124,53,10,-126,45,21,-84,13,2,-62,-47,54,72,82,-50,-2,-66,103,-61,-20,-17,59,54,-110,-1,96,-70,-57,123,-111,-94,-125,3,14,37,123,-86,-44,-9,109,-101,-128,113,-104,80,-94,-87,111,120,-7,3,-49,-51,49,-32,40,33,-62,18,-94,-57,-71,-92,-52,3,105,-86,-104,123,1,-93,-73,52,108,38,52,40,2,-44,-62,91,5,-48,114,-61,-40,-128,-93,-88,-91,-115,62,-24,-30,-85,-43,104,102,49,10,-52,25,-52,-94,-20,-103,-25,84,-56,-103,51,-110,26,1,-82,-102,32,126,-108,78,-108,30,86,-17,-23,-112,-32,32,80,-112,-86,-115,8,24,9,-121,-125,91,-73,14,-69,-95,-2,101,-109,1,-49,-110,84,25,24,66,-72,54,108,4,-36,95,126,-63,56,99,-103,-35,-80,5,3,-61,-8,-10,-10,78,-73,72,42,-83,-115,84,97,-66,20,-66,-46,-57,-99,78,-120,120,30,-88,-29,118,15,-110,-52,-92,25,113,-30,92,-94,-29,90,105,89,-110,48,-44,-1,-96,-1,64,115,-3,57,24,-39,118,-2,81,37,15,-47,-14,89,48,-69,-32,-95,-114,-77,33,-103,-127,-82,-9,-100,14,-38,-76,-63,51,59,-31,-8,-75,-37,76,-32,69,101,40,26,80,-23,-110,-23,-84,-67,4,-31,122,65,101,-83,111,-112,-123,124,-56,67,12,-23,-43,-47,55,-87,66,19,21,-12,54,-105,100,35,-89,-80,-76,-85,-61,-9,33,107,42,120,-49,-117,19,-80,-65,-71,86,106,77,-34,-50,108,42,21,65,69,127,-38,-27,-77,120,-28,97,24,-20,89,-66,-63,-17,-110,43,-43,-117,112,-126,28,36,103,0,-68,115,-69,107,-99,53,94,9,-105,-27,70,2,47,80,95,-83,28,119,59,95,16,17,-16,15,-6,4,82,-94,-89,64,-49,-122,88,21,47,50,-21,29,121,-47,-83,-113,-78,-25,-101,9,-36,72,28,-68,23,-67,-98,-24,-101,-98,-28,-89,115,-101,-89,82,102,-124,40,125,23,97,-113,-58,-7,-90,28,35,83,-53,-26,-119,-108,-83,97,-74,6,-40,101,8,11,79,117,-65,-15,-10,-72,-99,-98,101,80,127,95,60,-116,79,2,60,-62,104,15,-29,46,-79,-92,-118,-43,73,107,-43,67,-73,-67,44,74,-111,117,-127,-98,26,113,-41,59,79,45,-60,-30,114,18,54,-124,-52,21,-26,10,-82,-72,-70,-126,-97,108,-19,-52,10,120,-111,102,18,99,49,-128,-17,91,83,-72,-19,-3,45,-104,14,-46,-76,3,112,-41,47,122,-77,-35,121,44,-45,-123,-60,-58,43,-23,41,84,69,-2,50,-69,-98,-11,112,-11,98,-36,67,-33,51,-17,-95,-45,-126,-69,-52,81,101,-38,68,75,-109,-78,107,0,45,67,-37,-100,-55,12,105,11,-24,3,-70,-16,-97,-63,52,97,46,54,77,-22,35,125,93,58,-61,66,-61,-79,-58,-43,-45,-49,-63,-98,12,41,54,-63,-36,48,-33,-110,-36,-76,-48,73,-33,-87,-81,-49,93,-6,4,-78,50,-88,-30,-33,10,30,102,-94,38,97,73,-109,104,6,37,94,-124,56,-106,-18,70,63,10,-31,-90,-113,-116,84,4,50,-18,-27,54,125,-86,-119,33,-127,0,-128,-77,-65,-63,64,26,-79,60,-25,76,5,-5,101,69,59,26,67,121,-26,-79,-91,-49,-87,66,71,-22,7,-73,-51,-114,-18,-72,40,-87,-55,69,0,-22,-23,-96,-115,29,-119,68,-102,124,120,-6,74,5,-111,-85,-99,16,-28,-92,-34,87,-42,-36,123,-52,59,103,-77,43,-80,0,-86,83,-81,96,-15,124,41,-62,-22,77,43,4,71,104,-62,-98,-13,-99,107,80,-121,72,54,-63,-13,10,78,-108,-95,-90,122,88,-92,-119,95,-117,-76,76,-115,52,-10,122,-108,-13,101,12,36,63,26,39,36,-72,-80,107,82,119,-57,-7,-118,-91,-55,-54,11,-30,-44,77,-93,58,-25,102,11,80,-62,111,-33,29,105,-63,-98,51,-77,3,-6,52,39,-50,-80,-5,-50,93,-103,-123,-77,79,-58,-101,-122,116,-20,-16,-45,110,93,-11,57,44,3,107,-118,32,126,-90,24,-60,-25,60,64,80,124,-22,-95,-57,-47,15,-46,-28,26,42,-91,83,74,42,1,78,113,-76,14,33,16,-16,37,89,108,74,20,-93,23,60,107,-22,-117,111,52,-97,-15,86,-127,9,-17,28,78,53,-17,5,123,-78,-120,-76,69,-76,-98,-42,-64,-17,-99,-113,13,120,126,-88,-35,20,10,44,84,-35,74,12,81,99,55,31,115,18,-125,110,2,-82,-110,-94,23,-4,110,84,-122,40,-3,-75,62,-62,34,2,-120,42,-24,-10,124,-46,111,-99,-11,57,126,41,-38,-14,6,27,109,27,72,-29,106,96,82,-69,60,42,92,127,-24,96,53,15,-18,-104,-79,-70,-102,102,-36,-84,32,-119,2,-77,-53,79,7,-24,84,115,103,54,60,-7,19,-49,-7,114,-7,89,1,-64,80,107,-22,-5,-2,-63,-26,-51,-108,9,-111,17,-40,-51,58,108,-55,-68,-117,-51,13,4,-17,-33,-110,-95,99,-117,-23,-71,46,69,4,119,103,31,-117,6,76,-36,106,-124,-30,23,76,80,39,6,18,-3,78,3,-118,-52,23,-100,69,-91,112,40,-16,18,-55,75,-77,126,-87,103,-23,50,7,106,-16,126,41,-127,72,75,105,77,-19,112,67,-102,-69,0,53,-72,-95,53,-4,-56,30,47,38,-60,100,-127,-16,-16,-97,-15,46,90,23,45,-18,29,-111,-38,73,-112,44,115,-93,-32,-104,97,86,69,64,61,-68,-10,-112,60,19,32,87,69,55,-4,123,-105,-28,-82,-1,80,-92,-77,52,-38,76,56,81,-40,-14,115,3,-14,-59,-115,-39,-124,-78,32,69,5,-123,50,70,34,61,-57,-108,-22,127,-13,81,35,-35,34,68,-125,-120,109,89,-21,88,107,-114,99,110,-19,-54,90,87,-32,-81,115,-27,-82,-92,65,-126,64,-94,-90,36,-93,-45,-121,26,-114,-111,118,70,10,-3,106,80,-101,47,125,-12,39,88,-81,10,-25,43,33,-72,114,-109,10,98,-98,-115,-88,96,-43,-80,91,28,105,-122,85,123,-58,26,-26,103,-121,20,-62,101,-88,-113,-36,-88,-66,-58,-46,87,125,-100,93,79,-108,103,-19,-45,-19,29,40,33,49,-48,-15,0,70,122,121,118,86,6,49,111,-26,-67,-28,102,-83,86,50,-86,-124,-104,-28,35,42,126,-128,-87,-70,-109,-94,52,-25,123,-3,-6,18,-49,-120,-62,-89,-37,99,94,109,-85,100,62,-107,-126,-116,110,10,113,-19,-52,-101,84,-44,93,96,-110,-26,65,-45,28,5,-49,-78,-48,62,127,-53,120,-96,67,127,34,91,49,57,-67,107,-85,60,-60,-6,-80,-77,96,127,50,-52,-34,-52,-8,-119,-60,-76,89,-64,-1,34,-25,99,-47,45,-46,-47,3,-85,100,-94,-14,59,12,47,-74,-49,103,-6,-29,6,-25,-2,-23,91,-79,-1,-11,108,0,-44,-48,56,75,-71,-29,-35,-100,-100,54,-62,-77,-46,-56,-3,-98,90,-126,124,1,-26,75,104,101,-113,68,-127,-88,4,39,-106,95,-67,127,-15,-36,23,-71,52,-118,-67,9,10,-12,-51,-77,104,-22,-39,-106,53,34,-67,-35,-38,84,87,-124,41,-98,-74,-103,-125,95,38,-31,3,-89,-107,-106,-24,-90,-58,18,14,-41,-9,-86,-93,-39,83,23,36,-56,75,-119,80,10,109,45,57,-36,-123,113,-68,7,13,35,32,-17,28,118,-119,52,-37,-102,-18,-1,-98,48,-69,6,-97,37,-4,-59,15,40,3,101,91,-31,5,-9,105,-9,-33,-31,-71,46,-99,-71,70,-77,-38,-7,-112,73,42,-2,98,53,48,-1,76,-117,58,-62,117,-127,-66,-120,-33,33,2,-35,67,-100,-117,-82,115,76,15,33,-125,-5,49,91,-111,84,27,24,-89,-87,-72,-35,-49,100,74,65,-71,52,-67,-128,114,41,-63,82,127,0,8,117,5,126,-108,87,8,20,-76,-102,123,71,-73,-37,36,104,-71,-50,-56,41,-26,-62,-105,31,70,18,8,16,-122,-52,-127,11,-100,-109,-35,-86,40,29,-78,-58,-84,117,88,102,18,-45,115,-54,32,-36,51,-66,20,107,38,-119,26,56,52,-77,65,126,78,-113,85,-92,-35,-70,-41,-47,43,-72,-79,-67,-24,-66,-7,-9,62,-77,56,75,67,98,-47,43,-78,-116,-2,49,65,53,20,102,113,-4,-12,-36,8,103,51,-79,-37,-90,49,50,-118,62,107,-120,4,79,-17,61,36,61,96,-117,123,1,51,-15,17,11,-108,39,-87,53,36,-19,-69,126,-72,-91,-90,123,-27,-51,-40,79,-61,127,-62,41,11,14,-67,32,-109,-70,47,38,-1,76,-17,-120,61,-104,73,31,-37,35,-26,106,-83,-53,18,-18,18,-21,59,93,-31,-85,75,-127,19,66,10,4,-62,45,-109,13,44,-74,-25,13,-47,18,30,-59,-96,19,-113,68,46,-5,91,-110,-115,-18,65,-90,25,-75,-21,1,-88,-91,13,93,-61,24,85,28,-17,55,86,27,-14,-60,108,-110,-18,68,113,-64,64,58,52,0,32,70,-52,-97,-100,-9,111,43,-88,13,0,-112,34,-104,108,-125,-9,-32,110,65,-64,92,66,106,113,-116,-35,3,121,-91,13,-75,-44,91,-88,37,-84,-16,-117,-1,-49,13,81,21,33,113,15,-83,27,-77,46,-17,-19,-115,-37,-95,28,83,22,-56,106,66,-57,63,125,53,-23,69,49,-25,-15,-120,106,-86,40,-107,-76,-96,43,101,98,55,4,-116,-89,-26,60,51,-21,106,53,2,86,83,-119,47,42,-49,110,-5,-50,27,36,-75,52,-59,-71,124,28,60,6,63,52,63,-67,16,14,83,65,-58,23,30,49,-27,-66,-26,-39,-88,-46,-81,-123,-61,-18,42,60,-22,-61,-60,66,92,-83,111,100,-72,116,65,-100,103,111,116,50,-5,111,72,101,-88,18,-65,8,-78,87,39,54,113,-70,-44,-128,-70,29,112,63,-52,-48,12,-27,95,93,-31,9,55,-70,-109,-42,-71,122,-46,-115,-58,21,-27,125,9,-82,53,-22,-50,-71,125,50,-6,45,50,-14,-72,95,51,-74,104,-86,57,65,-39,6,-10,-76,-23,103,127,17,-95,10,21,-52,87,24,-128,-36,95,95,21,-96,-14,-44,-8,74,-119,-123,61,-24,-102,107,0,126,83,51,27,-17,43,-95,24,79,-106,115,-64,124,8,-75,-96,118,-84,69,3,122,-97,122,96,-106,14,65,-118,-64,-82,51,-29,-78,-80,121,-66,74,-82,106,82,77,-28,78,-119,121,56,-45,-120,96,-116,-70,-13,41,-109,-91,-55,-49,-31,27,90,-77,-36,97,-78,91,95,-91,-116,-17,-42,111,112,-51,68,53,-21,87,64,106,-82,62,92,-68,-38,-25,-77,-109,-121,5,75,-108,-55,-38,-14,-87,74,-96,-62,12,-97,-91,126,-71,24,-45,97,-19,93,42,-10,-97,-5,79,6,-80,77,-111,-78,18,42,-61,-99,-40,39,-69,64,77,-123,-30,82,127,-39,66,-17,96,-82,-117,56,83,46,46,27,10,-70,77,16,22,114,24,-88,16,118,116,66,-70,114,-89,80,-25,-84,19,111,70,-86,10,-20,-114,80,-95,-15,-77,-88,-1,-121,26,-82,95,-104,-120,-7,123,-20,46,69,59,-76,-41,97,68,100,75,-12,24,-23,79,82,-115,81,-125,-69,-100,-46,-112,-3,44,-108,-121,-55,95,-48,-22,-10,-60,53,48,22,89,16,77,-40,112,-54,-110,79,-99,-51,94,59,-50,31,-55,34,60,64,-5,-103,-10,-58,-10,-115,84,23,112,96,75,87,-79,-106,55,71,-92,85,4,-76,53,-77,-33,-8,63,118,-84,24,98,107,88,-22,-88,-60,99,-41,-36,46,-89,34,-23,78,56,38,-66,-14,123,-80,-6,84,52,-56,67,60,-20,117,115,121,-126,-101,29,-8,22,-108,125,39,-77,55,-31,89,29,123,-46,6,-88,40,26,25,65,15,77,103,-35,-39,62,-58,-118,-25,-50,117,79,-26,-10,64,94,-19,24,44,-79,-67,-114,-114,-31,69,111,14,-52,-71,-21,50,-107,-7,19,-33,110,36,-22,95,63,-95,-71,-38,124,73,-114,120,22,106,-102,-88,47,-5,-18,98,-69,-41,-26,28,-101,-21,-44,-31,-26,-127,85,-41,-105,-31,-50,-120,22,88,111,33,-114,82,-104,71,126,41,46,-53,-12,93,-77,53,-55,-50,90,54,-38,-63,60,-68,-13,40,77,-28,-128,31,-81,-80,34,55,-5,-17,-110,-48,101,96,61,-8,-29,94,30,-128,13,26,43,-6,-60,115,107,-89,-69,54,13,106,107,-62,-57,36,-40,96,114,98,19,-28,14,-48,-50,-60,-64,90,108,-4,-97,75,-54,-71,-107,60,-101,-104,92,-17,-63,25,-60,48,103,113,59,24,51,32,-101,79,42,71,-83,89,65,-26,121,-115,5,-21,-68,-38,28,-91,4,-120,-110,7,122,-70,102,22,89,-58,-42,-57,-51,105,-112,33,21,-114,-110,62,123,76,-6,-83,-14,95,-46,-116,-55,-12,-88,-48,49,84,-64,95,42,114,-8,-126,-67,-112,-20,-94,76,9,-96,-38,-85,54,41,55,127,-46,-121,-38,72,-52,-89,7,117,-95,-97,-113,95,111,89,-105,36,61,120,46,79,-38,-97,96,62,24,90,-111,43,55,14,88,-58,-126,79,-69,48,26,121,25,-89,42,56,-43,109,-81,-50,31,-114,20,62,-88,-53,94,35,69,-1,-93,69,-96,-35,102,12,-86,-44,-79,-49,120,-103,54,-97,126,-96,97,-18,80,-111,-10,2,39,102,-74,-43,-68,-17,11,-89,87,6,-104,-9,53,28,102,-36,-71,-26,-83,-127,-68,-126,32,-96,66,34,87,83,-50,-98,50,-98,-81,-97,75,-48,-60,71,20,-9,108,-74,8,0,124,74,-57,112,1,118,120,-66,-27,-59,15,81,-121,52,-10,42,87,-89,57,31,-1,-74,-47,-89,-92,-123,-50,115,-29,126,-20,-107,51,28,-70,-20,38,-37,67,-114,49,110,-124,-109,-73,-72,7,64,32,101,-51,-98,52,-109,100,-2,-76,-107,-3,122,-89,51,-57,34,-38,-101,-9,47,92,-104,-38,-122,22,15,-18,27,9,47,-58,-20,102,-63,49,85,-71,65,-57,24,-78,-19,27,-113,-112,-48,108,81,-96,99,-9,109,-121,2,-127,122,-47,-67,89,-45,-17,-29,-59,44,-81,55,37,18,40,-11,-69,27,-39,5,-82,-97,0,61,-45,11,-70,31,-104,-3,-98,114,-67,21,-88,117,46,104,115,75,49,18,95,-8,-17,24,55,22,-97,114,31,11,10,-63,-76,39,57,-46,-62,34,68,42,-94,-109,-60,-41,-66,-86,26,-65,-67,124,97,59,118,55,-50,103,-25,-99,-77,55,-104,16,-50,51,-13,-28,91,53,-17,-82,24,73,-54,24,36,-63,-108,-121,-120,-61,118,77,-122,51,-88,104,-31,-115,14,118,29,101,22,76,59,-92,63,122,-66,-48,-7,30,-15,-30,-41,11,2,91,-5,86,75,-110,-87,71,9,18,101,-51,-17,-43,-83,37,-42,-86,-102,-115,106,-108,14,-41,34,65,57,-13,93,-89,25,-69,54,15,12,114,-99,-104,-36,-48,19,-101,-105,-51,51,-112,93,-2,69,122,24,-26,-14,-83,95,-43,77,20,-7,-29,-111,8,115,-102,-67,-97,107,79,46,112,115,-58,-20,-88,98,-30,90,25,75,-47,110,3,-8,94,70,47,22,-103,51,72,58,-12,7,-50,-91,-54,37,27,-38,-50,-112,31,-14,-76,118,30,-109,48,-123,33,70,-95,-2,-7,-111,-75,32,-89,-47,-6,49,112,73,-7,-65,-76,25,67,111,76,-29,-93,8,-95,45,-79,15,-56,23,-96,-58,85,83,84,-70,7,20,-52,106,122,-96,-84,23,33,-101,35,20,73,8,85,112,-86,-30,-14,-93,-30,-8,-39,-89,-27,-36,-107,48,127,-79,-77,49,103,-38,-112,31,-22,68,100,118,-43,57,74,-76,-127,-35,99,101,105,-26,85,-93,44,-1,68,11,85,93,13,-99,-85,39,12,-51,44,-33,-78,12,-63,98,-92,-67,-109,25,-86,64,-58,-5,76,-64,31,-68,-121,-90,126,52,20,-128,-28,120,-117,82,113,-41,27,-128,-39,-86,71,-102,59,30,78,74,94,103,-95,56,41,-128,30,113,46,-11,117,-96,48,-85,-28,30,76,104,-73,101,-89,-25,-79,-22,-103,3,2,83,34,2,-26,-20,52,-82,18,36,90,127,25,13,-21,8,-3,-38,112,-85,-79,-32,26,-72,15,-94,-5,-92,9,-4,-26,98,-26,112,69,-21,-84,-105,-102,-112,46,-60,99,31,-17,3,15,-83,-24,-123,-6,-47,-120,35,-100,125,35,96,-33,22,70,5,89,86,38,64,-55,29,55,126,-125,17,52,113,53,-82,-3,62,-80,89,104,34,77,83,-65,-4,89,2,-114,51,43,-28,-27,-94,-41,68,-37,-85,-36,93,74,-120,-63,109,-70,102,36,-93,-8,44,77,-92,114,50,88,16,99,-67,-9,64,-43,-64,53,19,-9,-70,89,-57,-81,114,-99,5,87,-100,-101,66,75,-120,-70,-31,74,85,-44,-37,108,-32,92,80,-16,123,100,-102,99,-38,102,30,112,-89,102,96,-6,-90,-80,-9,9,2,-40,-114,-128,46,119,52,-47,87,-41,-81,-112,-15,-107,79,15,45,-88,108,-22,19,27,105,-53,82,59,72,36,118,123,-93,-44,99,-8,-98,105,33,76,-46,93,-110,-51,64,-80,-58,-103,87,26,-4,-54,-93,83,70,20,-13,76,-52,21,-13,127,-93,-7,19,102,17,23,41,14,93,76,7,94,54,-81,67,-52,-61,-23,-92,9,-127,-125,99,-128,88,63,-118,110,-24,-76,-53,123,-79,-65,71,59,55,22,-64,-111,48,25,-79,-45,-102,-78,-85,-53,-67,100,0,72,-71,98,56,-6,-46,40,30,19,-42,127,-54,40,58,34,-6,21,-78,12,2,-42,58,-44,-112,-113,-55,62,-14,-25,-127,-40,85,-80,-72,8,29,-27,73,-36,-32,-21,34,-46,84,75,-123,72,-41,-92,41,-12,41,109,106,47,123,20,-73,-38,117,44,69,-119,-102,49,-97,9,-89,-128,-53,60,-65,-43,-39,-118,-33,28,-41,58,-41,111,-25,110,-58,105,90,20,70,39,-21,50,-114,-104,26,-98,96,-16,74,-85,-68,-35,-80,63,58,98,119,21,-124,118,-77,-11,-125,23,-101,-9,8,-61,92,-28,-112,30,-57,93,-49,32,-48,92,87,-96,-29,52,103,-97,-27,57,116,77,-25,-107,-77,114,-96,47,-79,-58,8,-72,-50,99,-113,-80,24,-19,-83,69,-6,92,-5,-115,17,21,-28,-43,55,39,-60,-55,76,-127,40,-43,106,-35,-6,-79,25,19,-59,121,112,-57,-111,4,80,-39,-77,-103,-89,-113,-38,43,61,-125,41,-105,-127,28,-33,124,-50,58,69,2,99,-31,-88,-83,-21,90,-56,-49,83,-119,113,56,38,92,61,-74,-2,101,-73,-53,26,-95,32,119,-23,-114,-7,116,114,-52,49,81,-88,-102,76,-73,50,38,5,-63,-49,-126,69,-124,-47,-13,-53,11,-42,-97,46,83,29,112,41,125,35,46,58,-17,-43,-2,-5,-34,-96,49,29,-13,-80,-82,-112,13,67,-17,84,96,38,81,49,65,117,23,-97,-60,49,-43,-34,-74,52,3,93,-93,-26,-88,-54,5,-113,-73,123,4,-95,17,103,-41,64,23,-90,-35,50,-112,16,26,-104,-119,-41,5,95,60,-31,58,109,-71,-26,-118,28,-71,-126,-93,-50,30,85,71,-31,-92,-48,-65,-48,-51,-52,112,-2,-75,74,-24,41,121,-20,97,122,-49,-73,55,104,-95,38,23,-83,119,-22,-118,45,-37,-105,55,-122,-4,52,34,25,47,37,102,89,125,-12,7,85,-6,-92,107,13,97,117,60,15,17,79,-16,18,20,-80,-3,-23,-70,-125,-81,52,105,88,-111,81,124,-40,28,-36,-44,-57,-96,-49,-5,1,77,-37,-73,-107,-79,18,71,-124,-70,32,53,33,-83,-34,43,59,71,-55,-53,78,33,-125,20,-97,44,15,59,80,-20,65,-72,93,88,23,-3,-44,117,68,-125,64,123,-30,-89,126,59,38,32,-31,-27,125,98,12,-43,-5,40,-59,98,124,-104,125,-48,-74,62,-104,35,73,19,-8,60,43,-6,-62,47,-3,100,37,-125,-100,49,14,20,-15,76,29,-125,95,-74,-85,-56,8,58,70,94,-60,-112,-37,-50,73,78,19,23,-56,82,37,22,92,-40,63,-49,116,113,41,-11,-5,46,-123,45,27,82,106,102,24,85,60,-108,63,-67,53,-126,124,114,-14,-108,64,-6,-27,-19,-101,102,-68,93,-45,-4,69,-109,-27,112,-111,-64,93,-36,-128,-78,-16,-79,-4,-117,-8,-40,87,-79,-62,-51,123,70,-39,-94,-91,15,18,11,-82,100,-104,-59,13,42,98,-51,110,102,-76,40,71,117,-81,-120,-120,79,-17,44,-128,-51,-41,-48,76,123,-20,-44,111,71,-41,-86,123,5,80,124,55,73,-76,-32,21,5,-43,-65,34,-46,-55,-108,-24,111,110,59,-128,59,58,116,-86,-34,85,-61,-111,45,-125,-47,-37,79,48,-56,102,-96,-94,-90,-127,-17,-109,-95,-52,16,-77,40,108,-85,-93,10,-25,-94,31,-59,-2,95,-26,-28,-88,120,30,-69,123,42,90,67,123,86,-24,-9,116,12,81,-92,88,-86,10,-77,104,-75,-119,-43,63,-95,-16,54,-111,-3,-54,-7,-96,112,-68,68,-113,-88,3,-37,-40,55,80,-128,62,-32,-13,74,-48,-21,-64,118,-78,19,-41,-75,-10,97,64,-126,-81,20,-79,-112,86,-20,127,56,125,-84,69,73,65,-53,101,118,-15,-30,-62,52,105,-59,-54,-87,-48,99,-116,-120,-107,-40,87,87,-108,-19,49,71,-98,58,86,-125,-55,-31,-38,91,-76,77,-119,-62,52,123,23,85,120,49,122,-19,47,-83,86,-15,-69,-86,-118,-56,-121,21,-74,-82,119,-39,59,87,-45,-38,19,-67,-13,-91,-84,1,54,-96,-58,-122,100,-118,-97,73,94,20,23,-30,-4,-7,-72,-30,-38,22,-121,-36,-85,50,114,95,8,45,-85,-89,93,30,-105,35,-53,87,-41,93,117,17,-61,-61,-113,10,-52,-99,89,107,69,48,-27,80,-75,-104,119,-76,-30,125,-37,24,55,8,31,-14,75,122,13,33,-13,-37,98,101,-51,27,-49,85,-51,-15,18,92,24,37,-122,-30,110,83,-17,101,12,-54,111,-7,4,-82,90,-91,97,-99,29,-75,73,-46,106,45,68,68,-35,-28,99,-74,74,-70,-111,-63,21,-22,86,-122,-80,-93,50,14,-105,82,45,-41,102,-38,-9,-84,-94,-89,-18,-50,74,120,90,-17,52,-63,-83,-17,124,-118,43,-82,-80,123,-119,-106,75,98,0,-76,61,107,-72,80,-27,-70,-100,77,100,89,-18,-49,93,-52,-68,-46,103,-69,-9,13,-65,39,-89,49,-52,-88,-77,-29,-33,-119,-105,96,-128,5,86,55,-94,-43,29,48,109,73,-76,62,-11,-82,-32,122,-88,-16,29,-40,-69,-59,52,33,77,67,63,-89,-106,112,59,-67,38,-33,-115,-120,81,8,6,-92,69,87,107,40,9,9,-31,-68,-117,-81,-110,113,44,-62,-85,-23,77,-6,84,-126,80,-45,105,75,-62,-8,-63,58,-2,34,-48,38,107,-16,-82,-128,-47,-44,-113,-99,121,-29,-17,57,100,-23,12,-110,42,34,-64,-124,5,-13,105,-128,112,-4,100,123,13,-125,-7,117,86,53,-128,-87,-122,-60,-18,-77,117,-35,-81,-75,100,-124,116,-110,82,77,87,125,-100,-105,123,100,2,-4,29,-127,-49,-77,-54,-117,-110,-101,6,63,-103,122,76,-40,54,-86,53,-103,52,-3,-118,108,57,65,86,-106,-41,51,82,-44,92,-63,4,-99,17,4,68,15,22,-83,-126,65,16,105,76,80,96,34,63,-115,79,-115,-109,-50,-71,-61,-89,98,-123,32,-88,113,81,-29,92,-36,120,110,56,18,108,-31,34,-24,77,84,-8,25,-98,-4,-102,-33,90,76,76,-128,-104,-105,-65,10,101,22,-80,89,77,3,-62,29,-36,-85,-116,120,-44,-107,63,45,-125,-108,16,-29,-103,-38,-19,-126,113,30,1,31,-127,26,-18,-56,-85,47,32,102,-109,-6,-120,-121,-50,-121,-25,-7,-127,-34,55,-114,-69,-34,-6,-44,123,25,-34,82,101,-21,83,-2,33,-23,-108,-107,106,60,56,-30,8,25,-46,-46,-31,-78,38,108,4,124,12,29,21,-87,89,100,-116,-46,37,2,-53,109,40,-48,77,-60,-64,-68,121,-84,-109,-71,12,-118,122,-25,-73,80,28,62,-88,-89,109,106,-74,-64,89,58,-27,96,-74,-62,-110,-73,-65,-73,-87,-128,-122,-72,6,29,22,73,62,-99,54,42,31,-46,-37,-87,23,63,114,10,-63,76,68,-24,30,-86,-20,-43,-25,-12,15,124,-43,38,111,-121,119,39,-49,34,-32,27,69,-5,80,86,-42,-51,-74,-71,-24,73,87,-32,-11,53,-24,99,-25,74,-11,-115,104,117,-78,-7,-113,-99,-103,-10,-20,121,-9,-35,-76,112,111,-68,50,-9,96,-108,10,-38,94,103,-73,-64,116,99,2,-18,-22,22,90,-105,-68,-42,124,-122,90,-52,-43,-6,2,-22,-117,-119,52,-76,47,72,-84,-19,-85,-124,15,127,-115,36,-39,-109,92,13,-76,47,2,107,3,90,-24,1,102,26,-17,-27,-114,-112,-74,-29,-57,-108,-21,32,-104,76,-47,-17,-77,52,38,106,-68,-63,86,-86,67,-28,114,-81,23,-57,-110,-81,64,-1,-97,-29,-25,-24,95,-35,-118,-99,-96,-11,68,-118,-84,68,-1,12,-39,77,80,111,-113,94,-123,97,93,-80,-117,-52,5,-24,-108,70,-27,48,-21,123,5,-98,-28,63,-96,-37,23,67,-33,-96,-50,-124,47,-58,-109,-64,20,-37,44,-101,34,95,-62,-76,-57,39,-51,10,100,94,-37,-72,-4,-21,114,-21,113,45,122,-117,-77,47,-82,40,-68,27,43,-99,105,18,-15,-7,112,27,-110,47,83,-8,44,-50,-86,-37,64,-58,-53,1,14,18,-33,69,29,100,51,35,-44,-99,-17,-90,38,107,-58,-103,106,-49,-90,23,40,-76,-79,7,-106,84,107,-44,-58,-50,-21,-10,-47,34,91,-9,64,20,114,-11,-76,-105,23,113,58,44,-91,-62,-55,38,-101,121,-22,100,81,-55,94,-46,94,-125,78,43,-128,-101,118,-103,-36,81,-8,-66,90,-3,116,-90,48,45,-49,104,2,44,-69,-78,28,-65,-90,-54,103,-71,-62,70,15,-31,36,-81,14,-103,-35,-60,103,-13,127,-54,-32,-93,117,48,45,20,-89,-23,127,59,77,3,-84,-35,-27,44,87,60,-16,-112,-56,37,103,78,-115,11,-3,-44,45,61,121,-106,-104,88,-39,52,-112,-102,104,46,-67,102,-91,-77,-13,-79,24,-59,61,-90,-34,101,118,-52,-84,57,-5,46,-62,47,-66,-18,121,81,102,32,89,-78,122,28,12,-110,-123,-19,-38,8,-78,-94,22,83,111,-36,92,60,-2,44,-59,-43,-2,-66,-29,-71,92,-51,116,-78,-2,39,124,103,7,19,92,7,-66,-100,107,127,-115,80,-3,59,98,-95,-93,11,62,99,-126,-61,-74,109,-58,87,-24,100,122,96,-65,-71,-38,-118,113,21,-71,100,-103,-106,-23,72,0,-55,-105,-90,88,73,99,37,-68,-108,59,-41,82,119,76,-41,-62,94,110,53,67,68,-62,38,18,-37,-24,14,56,-41,-121,-84,13,48,50,-4,-17,110,-77,77,48,116,8,111,-80,-63,-4,112,19,-9,-127,88,-45,72,-85,63,64,-32,74,-61,77,-90,-75,125,-46,-15,-99,36,116,76,0,95,-86,79,14,-55,7,46,76,101,-115,67,-124,38,71,95,-70,18,-18,-35,-42,13,-104,8,98,77,51,-82,-26,-61,-66,2,44,114,-27,-61,-119,-70,26,2,27,99,-99,14,82,30,63,-88,-97,13,97,34,-47,-99,-44,65,-13,48,47,4,78,41,37,11,8,99,117,-29,-59,-94,-7,28,-125,32,-109,14,-61,45,11,101,47,84,-13,-58,-49,90,100,-94,77,19,12,-24,-91,54,112,-48,67,5,-86,-63,47,3,73,4,68,-26,-64,110,-79,-18,-96,105,-35,-36,-71,113,67,36,23,-14,48,68,-33,-5,6,82,-56,-20,29,8,56,39,-33,121,-11,-43,-78,28,-29,-101,116,-98,-76,-81,-72,97,-16,107,123,-89,-47,-84,-67,-77,-107,105,29,49,102,-113,-41,-18,-24,-112,-19,54,49,41,50,-25,84,15,87,61,20,63,-118,42,103,33,48,-48,-121,16,82,90,-13,6,-40,2,-74,-85,-68,-4,-14,-76,17,-101,81,-80,7,-117,-64,-54,21,-50,102,-2,99,21,-74,8,74,-36,-89,-75,2,28,-29,-105,53,126,85,-35,71,-118,2,-55,-84,2,9,-20,124,83,4,76,50,95,-104,45,81,88,-113,10,66,44,-110,122,73,-78,92,-85,5,3,17,30,-32,-127,26,-53,34,-75,81,54,7,96,9,-42,109,6,-15,-13,119,34,-126,-102,67,-70,116,9,-12,-88,19,-9,85,91,-26,103,39,92,116,88,-87,33,-43,120,-68,-87,-53,84,-99,-28,96,-59,3,48,12,-18,87,21,-88,86,-56,-36,63,33,-80,-97,-93,116,-36,-38,100,-65,-62,-87,66,-65,102,104,85,73,60,-96,77,103,-80,-70,-99,103,-6,-67,1,-1,-81,66,-80,93,17,-58,-44,90,63,-35,-59,39,-56,-49,83,71,29,-7,-111,92,-114,-75,-80,-54,56,-107,-7,-48,21,54,-124,-3,80,-49,-13,61,-115,-29,-60,-78,96,-105,-110,123,112,-68,126,-87,53,22,70,16,-40,-90,-74,82,-16,29,-70,-84,-47,14,-117,-3,52,23,64,-84,74,-37,6,-13,-57,108,87,-100,59,82,45,87,2,-39,52,57,-79,84,20,-65,-33,78,-96,-61,-61,63,34,37,-16,-19,12,101,-119,-97,27,-13,21,59,32,9,57,-124,127,6,-105,118,80,-31,89,98,76,83,56,85,27,102,16,-57,68,3,-26,5,-95,-77,23,-110,6,58,-21,-113,-78,26,90,-16,35,-23,46,58,-14,102,-117,80,-108,-47,10,83,-42,119,-49,-38,-58,25,-100,-80,40,-54,-122,-45,80,-85,-77,87,-2,-35,-94,-115,63,86,111,-75,-47,-114,-47,-35,-10,84,71,-111,101,123,43,-99,-22,106,95,-17,-94,111,96,10,-3,-89,104,71,22,-52,7,-99,-90,32,-11,106,-7,-112,78,99,-38,-81,-104,-30,30,-16,-110,30,-31,-125,-113,95,-19,-50,-86,-66,111,-50,26,-74,-66,109,4,70,-4,-14,-30,-78,-83,48,-105,-45,-2,-86,-2,102,118,-62,83,37,58,53,-112,89,46,-25,75,22,100,-66,49,95,-104,125,88,19,-76,-35,-40,-83,20,54,-106,116,101,39,-106,32,-82,61,-80,-52,-45,-86,39,103,-71,108,121,120,-126,-56,-24,71,52,70,117,9,5,110,-39,-56,-97,-79,77,71,-90,-97,3,-8,-64,-102,-99,-6,59,-100,115,112,-5,105,-7,85,-76,-65,14,118,65,10,23,24,68,69,68,-78,-60,116,13,40,-83,-118,-2,-43,79,96,-79,-7,-19,-56,-93,-47,-63,-5,96,19,19,94,31,30,22,43,61,121,61,-49,116,-17,89,-104,-41,32,29,-111,121,-109,-51,7,88,16,-80,-105,115,-25,51,-6,-61,91,-84,-41,69,-80,-12,-70,15,39,75,-38,68,40,45,80,-71,62,-22,111,-51,11,-9,44,29,-114,-27,112,105,-68,51,29,-105,68,-106,-95,-109,-13,-82,51,13,-51,-48,-103,54,-91,33,50,-29,17,-65,-46,123,108,-73,-120,123,-52,100,32,-110,-76,43,27,33,-43,-13,52,-79,-30,-86,109,41,0,103,39,10,-57,-90,49,106,-13,-28,-52,124,-15,10,74,52,83,91,-63,95,-23,-124,26,11,-44,114,-48,13,-57,114,-108,-60,99,39,27,-101,117,82,96,30,5,-34,29,-128,-74,-47,-33,-6,-35,-121,-112,-35,109,-118,-69,117,-80,-18,20,-102,24,-33,47,1,-117,101,4,74,-64,-5,-13,-57,-65,-127,25,-107,125,0,-78,27,61,-100,-1,-84,-29,-60,110,-17,-75,-19,-63,-56,-25,21,107,-83,-100,-33,-89,-48,-3,46,88,-121,-55,109,83,29,28,98,-64,92,-29,-65,-63,-26,47,-59,-73,4,65,-86,30,-111,1,-21,26,-88,77,-119,-1,-35,22,-109,-86,75,-54,113,-29,-95,24,-40,127,97,-77,-24,43,-85,69,80,-56,-32,61,125,-18,-105,19,9,65,-2,-18,9,90,2,27,127,10,-15,-57,-76,-37,11,-51,109,28,-55,-63,90,69,48,-13,17,2,-53,125,22,98,44,-96,-94,-116,79,12,-2,72,-11,44,65,88,64,-112,76,61,72,-103,-29,106,-123,-36,91,72,79,92,-24,78,-121,4,-93,74,-28,83,-109,-98,-43,-57,92,98,-23,92,-99,63,10,83,-39,94,50,79,-111,-32,-124,-19,-34,-26,56,60,-79,40,68,-72,91,115,-101,-73,-55,36,-85,3,-86,-73,-113,34,-83,-59,103,10,3,-98,53,-90,112,-114,-101,-1,46,58,-108,-77,-122,26,29,-87,52,51,25,-51,0,32,-61,13,57,67,-108,-50,97,-36,-67,8,117,-124,-59,28,95,-112,-86,-50,105,-54,-108,-111,10,124,53,-1,-127,-43,65,35,-42,-28,12,63,-92,-97,-71,22,-119,-47,-42,10,15,-50,-23,83,-24,-28,3,-42,114,98,120,13,20,69,123,-101,108,29,-36,-44,87,15,77,56,74,-89,-23,65,-12,19,54,66,-31,-16,79,-8,-43,111,-46,-48,-111,109,124,-17,-87,69,15,61,-28,108,118,43,-55,53,74,-102,-72,-58,-88,-54,83,-80,-38,56,116,-80,-66,117,-3,105,82,74,-125,-75,-120,-58,43,88,-5,6,78,-72,-42,4,85,-49,-55,88,-79,-51,90,-33,-100,123,127,60,-115,20,-19,-97,117,9,90,-32,-123,123,-98,-15,-75,122,92,94,-86,41,40,24,106,-60,-39,73,68,93,-91,-86,-41,-80,-120,-27,125,-87,91,-40,-41,-9,5,34,65,-123,-111,2,35,113,83,-66,114,-111,5,60,126,-93,-105,-35,90,57,-68,11,62,-117,-33,51,-52,-45,59,-43,117,36,69,-95,97,83,64,-62,-81,45,110,88,102,-125,1,-51,43,95,43,-22,107,-97,25,-12,-122,4,100,98,-64,94,-21,-37,45,-38,-104,119,64,-74,29,-123,-46,102,-2,-40,115,-31,-8,18,21,-115,27,-80,15,2,74,8,75,82,90,88,10,37,-99,-105,-82,77,110,-49,-104,-1,35,40,80,-97,24,99,-94,43,43,-63,-40,10,64,-3,20,40,-22,77,113,-71,-79,-82,-44,-53,-106,-95,110,-124,-121,25,23,86,104,-96,97,-27,-14,74,54,120,49,-67,-128,-9,-30,-33,72,107,-12,18,-60,21,-91,77,40,38,-12,111,7,-43,36,-15,33,-70,-108,14,-89,44,85,112,-85,-109,-123,-72,57,100,15,-124,-48,98,-111,60,-17,85,11,90,-105,7,-116,-10,91,-10,64,59,-107,-121,54,-128,-98,83,38,64,-25,36,46,20,-96,-108,-71,-1,-17,101,26,126,67,-89,0,77,32,-72,42,-11,44,-14,119,84,-31,-29,-21,95,-8,-74,123,-128,30,27,94,-51,38,-11,45,74,20,-74,-33,-115,-122,41,7,80,35,18,33,16,-6,95,-111,3,-30,-101,15,-59,-92,-69,-67,-86,28,-43,98,38,27,-111,-126,-34,40,68,83,106,-95,-26,86,-54,-102,-110,11,-122,40,-37,30,112,-88,38,-8,-46,46,81,90,-40,95,-61,-109,-110,-123,-44,127,-83,-73,77,81,-23,105,32,81,-55,77,62,115,32,-70,-62,-123,-33,-44,-33,-36,-96,4,52,86,127,86,38,-16,84,21,106,-12,17,43,53,-98,-80,-125,-69,-25,-70,-72,34,6,91,-119,48,22,0,-33,-115,-18,-19,42,-34,46,-92,-27,106,-113,7,78,44,-123,22,-116,35,14,18,50,-110,-112,113,-91,-51,28,109,-83,-51,86,73,-17,88,-64,-114,-19,30,-33,30,-1,-121,-109,86,-58,51,104,89,119,-76,-28,-90,-95,-100,30,-77,-23,-14,-99,55,69,-55,125,72,58,-112,39,67,54,-6,6,76,50,92,89,97,4,52,3,96,-47,-26,126,80,-80,-100,16,53,-119,-36,123,106,-76,67,53,5,58,-13,31,33,-67,111,-42,-16,7,-111,43,51,-27,48,-105,38,23,-110,-17,-12,-98,89,-66,-1,64,118,93,-75,-32,3,-93,-115,65,21,7,-25,126,59,45,-16,-26,14,50,2,107,-19,-110,-34,-107,75,-11,-109,19,-61,54,-115,-63,123,-39,98,125,-94,121,-16,-24,-11,2,77,102,90,-121,116,-55,109,68,6,52,-110,119,65,-119,-47,6,22,103,-121,-32,104,119,-38,-16,-100,49,-117,90,109,-90,124,-92,61,-115,-107,54,-72,93,27,-79,89,60,-26,-77,123,111,-124,-89,-54,-94,108,-119,55,78,-108,95,123,59,-49,42,36,-4,-28,-7,-99,-42,-100,106,59,-65,-24,-100,115,-6,91,-5,-93,32,-77,35,70,-90,-7,-74,77,-20,105,114,49,-6,40,-32,-91,76,-32,-126,-83,-81,84,-103,102,-69,-99,-127,87,113,80,-69,-108,-13,-29,-43,-11,-126,-113,-90,-22,-11,79,-107,77,119,-104,7,-64,62,26,77,-83,24,-90,115,-37,10,-22,-76,-13,52,-57,-52,-63,114,-38,94,-56,-96,78,74,-95,85,-82,99,-66,59,33,-113,-78,-97,10,50,4,32,102,5,-105,-76,-69,-72,-19,69,20,127,94,-57,-26,-117,-7,-38,24,126,-81,86,91,28,35,-91,59,-126,-39,9,-58,124,101,74,120,94,-40,14,-31,26,-5,-90,54,50,-56,-108,80,19,-37,-39,-45,-22,-107,37,53,38,-126,-117,9,-102,-104,83,-73,-125,90,-106,74,109,29,21,-76,-42,-51,-98,72,52,-45,-56,20,51,-1,122,91,-111,-106,-69,55,-108,-93,12,-18,123,11,-3,51,51,96,-100,91,35,62,70,-39,33,-64,-87,-51,-54,-87,15,-81,-125,-111,14,-109,126,126,-36,65,-34,46,-89,70,-119,-49,-122,-47,126,-87,88,-117,62,-89,29,-65,103,100,-107,119,-88,-117,25,-89,9,-36,56,79,9,-95,66,-5,54,-2,95,-124,-95,-93,-126,-9,-54,81,-106,21,69,122,105,-37,-124,98,-25,108,84,39,-9,-97,59,-25,-67,18,-42,3,-105,117,76,79,35,48,-76,-107,78,-75,3,-81,-61,30,-88,-19,101,-118,-67,76,-99,-99,-82,103,-94,112,-71,-105,-24,-91,-26,-110,90,120,62,-116,-20,83,75,41,-7,34,-77,23,109,107,94,-125,74,-78,26,-13,27,99,49,77,-73,100,-115,-36,0,88,123,-65,87,77,-108,-24,93,-23,-60,-63,-44,0,-96,88,-19,89,108,119,19,102,-103,123,69,85,-68,-99,89,11,-60,47,-106,97,-53,94,-56,116,52,-1,-68,6,-55,-107,-3,-9,-59,78,-21,-69,118,107,-105,-3,37,127,-37,18,-117,-79,-43,-108,76,64,-121,-25,-52,68,124,33,-2,27,52,-71,88,14,25,-115,92,110,-36,-16,-82,-21,57,30,-57,-105,63,-75,-72,30,113,-92,22,56,-77,-20,68,98,-20,-15,79,21,-25,106,115,71,32,20,48,15,112,38,-124,48,122,-70,115,47,62,105,-71,-41,-85,127,-35,-21,122,110,30,-70,-6,9,-103,122,-68,-45,42,68,9,83,93,117,110,8,-42,-82,13,105,-26,21,98,-42,27,110,-123,10,109,31,22,29,22,71,-98,-5,7,-91,-112,-32,-56,60,29,-126,92,-7,-64,-77,72,-20,4,63,-54,-128,74,-53,-92,6,-89,-20,-92,106,32,-94,-50,88,52,46,74,22,-119,-90,-69,107,8,3,13,96,-64,28,-59,58,55,-102,97,110,-106,74,83,-95,-49,-106,-26,-93,9,-19,20,-63,87,71,-28,-52,125,26,49,-73,-11,112,72,-117,-65,88,-33,21,14,121,-29,-74,-128,4,102,125,112,-49,12,118,-28,82,97,16,-82,-7,4,121,46,-71,28,85,50,78,63,-94,74,107,-59,-48,-24,76,-112,93,-47,-67,-32,119,84,108,122,-67,-113,-17,33,-63,74,52,23,-10,-96,27,-54,49,57,-103,-125,62,20,102,7,-20,-58,54,20,109,-18,-78,107,31,-85,5,-32,-90,-61,98,6,64,104,81,125,-100,51,125,104,56,126,24,50,22,23,-100,-128,-82,-86,109,-83,30,15,23,123,-89,14,-48,107,-61,-92,-65,-75,49,-82,-36,-124,-36,-12,10,0,-105,26,119,-55,-47,-37,-38,-17,48,101,120,-118,-92,-89,18,-14,-50,-72,112,-105,-41,-106,-114,-5,87,-100,-125,102,-7,126,-23,-25,71,-111,-11,123,50,57,-84,-66,-101,-76,-106,47,-23,39,-28,102,-65,103,32,-14,-125,82,34,28,-18,10,84,-109,79,32,-112,97,38,56,-36,104,68,-78,-80,93,-95,-70,-6,27,41,33,-120,125,90,-18,-97,30,-51,53,-79,-74,92,-33,-102,41,-72,4,-27,-102,28,-56,114,-117,126,121,8,-126,49,122,-105,-56,-127,-51,63,84,30,-76,-13,49,-112,57,3,127,-111,-45,53,41,-71,34,-85,22,-114,-34,38,97,52,-45,44,4,-111,-35,-98,-24,-53,42,74,22,-89,-19,-119,112,-21,-118,-86,119,71,-52,-88,26,52,35,126,21,-51,-110,4,-120,-107,65,117,-8,-72,47,-66,72,85,3,73,-89,-100,-36,-114,-97,87,72,-27,-111,116,19,71,-53,-68,-121,17,45,-83,-28,116,71,-3,-29,-60,-125,-55,-64,11,4,-123,53,42,-24,-37,104,-22,-2,-77,-122,-45,49,91,101,81,44,-72,-64,-100,-107,-51,-26,108,-4,118,-80,-75,-23,-11,-102,19,-18,-18,125,90,-91,102,8,-54,-35,-35,-84,41,-115,-99,30,21,6,24,102,-108,124,28,39,1,-39,9,26,-8,-9,114,-93,76,44,72,-72,-24,-57,127,-3,-58,16,-1,67,-41,29,36,-92,-31,-87,-124,-34,-23,15,-44,-38,-19,-87,-47,57,118,-2,8,51,121,-82,71,-14,-41,-84,-62,79,118,-20,-12,16,48,5,-127,17,-83,28,54,-95,-89,-97,3,-18,40,-21,45,115,124,15,89,-118,-125,-19,23,-58,-1,2,38,-18,-121,-48,81,39,19,-24,-64,127,-46,19,-16,80,-128,55,121,-43,-73,93,56,-37,123,-62,14,36,-127,42,-117,-43,-99,38,-19,-46,-112,-70,-128,24,-79,11,23,-34,-99,-121,-81,-110,88,54,-80,-51,51,83,10,-76,-53,-58,-35,-128,52,20,27,-109,119,24,51,-19,97,37,112,112,38,-65,84,120,67,-8,67,6,-104,-94,-103,118,-1,30,-94,-127,-50,78,10,58,-97,-95,-42,107,-41,21,-88,63,27,-55,-28,-67,-39,-23,-118,-108,91,-1,-9,16,-37,62,46,-80,-82,1,50,-29,-55,48,-41,78,-112,34,12,-53,123,41,-94,37,108,-16,-42,46,1,-123,-50,71,3,8,86,-39,-24,-82,-86,20,22,8,-72,51,119,114,-110,-55,115,-15,74,83,93,93,51,122,3,-125,28,14,59,41,-56,107,-17,-21,38,-59,71,-23,0,111,79,75,113,69,-48,-17,-110,38,-29,87,32,50,4,-41,-56,12,-27,-77,-87,-113,-4,-117,-99,-20,-61,115,-99,40,-99,2,29,26,119,-86,112,-95,-31,4,-21,-102,-53,94,-82,45,-65,75,116,-85,-17,-109,-111,23,-23,-110,1,-97,100,29,80,-90,93,-18,25,95,112,-22,72,74,3,77,-29,-48,-106,-117,94,9,95,97,-109,-104,-124,-94,-29,113,-1,66,33,-28,12,91,-88,-102,77,-16,-116,-65,95,-79,-107,-76,21,78,78,51,54,-51,-123,2,40,-105,14,-90,64,112,124,49,-124,71,-114,97,-3,3,-83,-105,-50,59,-63,94,35,73,120,-43,116,16,-91,-46,-18,123,-97,-26,84,-119,72,-117,-108,-21,-118,-84,75,34,-59,-108,-104,-26,-11,70,63,53,-81,-65,21,-63,-55,-108,-35,-125,-58,-115,-16,126,-72,7,0,-76,-13,-54,59,81,-118,-12,-67,121,5,27,-23,-6,-79,-125,-14,-19,-45,80,87,-56,-118,-85,-37,-43,72,71,-49,-22,116,-121,-90,-59,49,-91,31,46,-62,34,89,-4,12,23,40,26,-7,-54,120,-89,-37,-39,88,42,-18,12,34,67,123,61,-91,46,54,-38,-104,100,-75,74,-36,0,28,15,113,-44,25,-56,103,28,-16,-92,-100,-7,58,28,44,-75,-121,34,-113,38,-99,66,-2,45,17,-19,11,-45,41,-20,-122,-72,38,110,-58,6,64,-86,44,-73,-70,-45,-93,121,53,36,91,-41,52,17,43,-71,-90,14,110,97,-53,36,-75,-32,122,115,29,102,-88,-46,92,53,-39,20,-102,46,-91,117,-26,36,-108,55,-101,-120,85,82,14,101,-81,-26,115,-24,33,-47,18,-108,33,-18,-50,-46,-24,7,-125,-71,41,99,-66,-2,-14,-25,10,-112,-74,47,-43,10,126,117,53,104,-77,-57,-30,10,34,93,69,-116,65,24,81,90,88,115,89,-90,72,43,51,10,-37,55,-12,-4,40,123,-85,-90,123,8,13,109,105,112,64,-16,25,-83,44,-54,-109,99,-74,54,-82,104,-20,64,-37,-3,-17,-72,40,14,-64,89,36,107,124,-84,-74,60,-47,6,-98,-125,63,112,-41,-70,-62,115,-56,30,14,127,52,109,-38,27,-112,76,-65,114,78,26,-53,77,60,-107,-118,-120,24,-74,-96,48,29,49,-15,-9,-115,1,58,-21,104,-117,-91,-109,-89,-26,-84,82,36,116,121,52,-28,-50,-103,-87,-93,-103,93,-108,49,-39,37,-115,38,-37,-28,-2,-37,-26,19,11,-120,-68,14,-107,-49,-41,107,17,24,24,-100,6,-7,46,-122,102,35,-110,93,-53,98,-84,38,65,-8,-6,-99,13,23,-5,-4,24,7,44,86,66,-111,67,-65,19,9,-92,114,34,-26,-43,-61,-11,48,29,58,-57,5,-105,-33,77,0,-41,22,45,-51,-44,-99,20,-61,-49,-20,47,-29,-30,10,-11,104,99,21,-11,57,44,108,-84,122,-15,-67,-104,39,-71,-83,2,14,127,5,3,-87,98,23,-9,104,-110,-79,68,94,95,89,40,107,24,26,-97,77,-111,-100,112,-111,-97,-36,49,-69,-95,31,-96,-45,89,127,-1,31,85,-5,-53,-6,-9,114,-53,-69,-102,16,113,84,-6,62,-73,-15,-18,-44,68,-105,-36,127,12,-27,-28,-42,-86,93,-121,-19,67,51,-31,51,-119,-74,86,-111,32,73,35,18,-19,98,44,-82,-84,-84,-106,70,-45,-60,72,50,-67,-126,-5,-67,113,-89,-62,-23,28,11,38,-2,-14,52,-54,-110,-61,4,70,-35,118,-80,-46,-11,-100,-54,-100,0,39,-70,-124,49,-120,-69,102,39,44,-115,-49,-50,-102,65,59,16,90,69,53,-27,-113,20,-47,-115,-28,39,-19,-19,-114,75,59,127,-94,65,-54,-27,-115,-46,-85,-4,1,-43,127,-98,-21,-74,75,-67,-124,22,27,-42,-27,53,-45,127,36,59,-44,-23,-126,-59,-90,-83,86,99,-86,10,108,-99,-45,91,19,115,110,106,85,-83,-16,-33,122,-86,-120,-87,67,-4,-57,4,11,107,-58,-2,-128,-12,-111,-5,-53,-68,-91,95,-68,85,19,-40,-32,20,10,58,-65,-9,-36,-56,79,37,-64,-12,-33,88,123,94,-124,-62,67,-2,41,35,114,31,-116,-100,-32,86,-17,-81,67,-85,-3,14,45,5,-78,-87,-110,83,47,-65,-121,-120,-114,-9,-19,-7,-33,61,74,-40,26,-9,-21,106,63,-70,117,78,56,76,-121,-77,50,104,-125,-32,-117,80,14,87,30,-59,69,-101,43,-98,-11,-23,-10,125,52,97,-19,-56,-94,-108,-41,-119,-38,24,-42,25,65,-39,18,-126,-4,109,95,99,7,-102,13,96,110,74,-89,15,-3,6,73,61,35,-78,-83,98,106,72,116,-127,82,-15,54,-17,2,88,31,111,-37,-102,-24,69,-7,-57,-6,-62,-39,-79,103,74,113,65,117,-32,37,123,-5,59,-15,68,-121,-78,-65,94,120,104,60,5,117,61,4,-85,-88,-123,68,-65,-101,46,64,-80,69,-19,-57,97,-27,-47,54,84,104,44,-15,125,114,16,-23,-124,-100,-87,36,81,-34,-77,-73,95,-126,-120,-27,-20,29,66,-80,-64,77,105,-100,44,19,-80,-18,-27,27,-92,79,116,12,-18,-15,-71,45,116,-27,14,-4,-88,1,-110,51,-101,-14,-77,-120,60,-40,-26,108,-123,116,111,124,93,-74,87,121,62,-83,1,2,-64,-69,11,-45,-79,110,-55,67,53,27,-79,-74,98,-37,97,99,26,110,-91,43,9,-43,80,-64,20,60,-36,-79,-113,-103,-23,-31,-52,68,-112,-7,94,-30,73,-25,42,-111,87,-63,108,-100,55,-94,-13,-1,-29,-59,38,-16,-85,-80,-11,0,47,96,-110,-62,-17,12,-54,-90,116,-12,-6,-128,-31,-3,-102,103,-11,39,-67,-64,-109,0,64,58,-118,-18,93,95,-87,88,-31,102,104,-62,-36,-61,-105,-26,46,-53,93,-24,-10,-54,121,-22,29,117,-70,82,-124,-103,52,-122,84,-76,-64,7,-118,-6,52,-82,73,121,-65,108,64,80,-27,-44,81,-107,-88,-39,-68,-59,9,65,-73,84,-100,-82,26,-56,35,-66,-15,75,-44,51,-51,-65,-62,-84,-19,-31,51,78,-112,-73,100,82,93,-92,53,61,43,-66,5,-63,31,-69,-38,26,48,127,-30,24,-71,-67,-60,-49,-101,-26,-43,105,10,-127,-55,-37,116,38,-63,-109,3,-67,-42,78,-59,110,-103,-17,10,17,-89,-47,-47,62,-41,-51,-16,-31,-41,77,-122,15,94,-96,-8,68,37,116,61,-123,101,-122,-11,105,109,45,-94,-111,44,-52,-113,-74,-97,42,-99,114,105,122,87,-59,85,-89,11,120,21,-51,30,-109,-128,-10,120,-49,-75,-19,-79,-26,-32,-28,59,28,-44,-22,-113,64,-71,109,-84,-11,55,-55,-105,114,50,-71,-111,77,36,99,-100,80,-26,-64,118,54,42,-121,-128,56,-10,16,-105,30,93,19,-99,-75,-74,-50,85,36,-122,-84,-72,-20,-63,-23,-73,-53,-86,-118,-9,96,75,-39,96,59,90,-127,-106,42,-122,46,12,-18,29,-94,33,-84,108,94,-2,81,-58,-75,85,61,122,-43,22,101,45,94,-115,-100,2,-63,-128,106,-49,5,38,35,-8,110,-50,35,-114,-114,115,54,15,37,20,87,-76,84,-13,48,14,9,-99,-93,43,-55,-82,54,-58,32,-91,112,77,34,23,-40,62,-100,32,84,-3,-100,93,17,66,33,19,82,117,102,101,-33,112,-90,-9,114,-1,-66,-71,-103,-38,-86,-101,38,-89,41,-113,5,-40,45,68,89,123,-107,3,21,50,-75,58,-73,5,-67,-64,89,-117,-78,94,16,36,61,-124,45,51,-18,-18,-119,69,22,97,-55,112,23,88,119,65,-103,-62,-97,19,-15,-47,7,-109,-84,106,-5,73,-41,81,34,33,20,-46,-108,-109,-102,67,-116,81,67,-40,-9,-49,42,-67,-57,-33,-38,-89,10,121,-36,-113,61,28,-94,-67,-28,52,-84,-38,-96,117,-44,-110,-17,-116,-53,-53,-51,29,54,98,-76,18,104,124,10,-36,15,47,117,83,80,34,-62,102,108,91,-112,-116,87,74,-68,55,25,-34,-10,66,51,-47,-123,-67,-122,57,32,-96,-87,76,67,31,1,13,96,-64,-15,-125,-41,-124,-77,99,47,74,-16,36,67,108,3,105,-44,97,44,-53,-4,-9,-120,99,-55,-30,-122,14,8,40,86,-64,-34,118,-65,-23,106,-95,-26,114,89,97,71,-108,-59,-10,10,-60,61,-87,-19,-4,-28,-32,-126,-124,-123,109,120,-107,-1,35,-1,-36,55,-47,3,-17,121,31,103,118,79,127,-55,125,-80,25,-4,21,-32,-19,70,-95,-104,-2,-92,126,90,97,60,41,-78,-24,20,49,-33,-79,121,56,120,-102,-19,100,1,44,77,-8,113,74,-46,-127,-28,46,-64,-12,-13,-15,-105,84,22,86,37,-56,11,89,110,-83,-95,36,-40,-92,19,-17,76,-54,83,4,-107,127,-82,-25,-85,35,33,-111,-72,76,89,-123,107,-98,-96,95,59,75,-103,28,-35,52,-47,77,-76,87,-14,-27,-92,-45,117,67,-13,5,-56,75,-95,-116,-34,91,-81,-35,83,85,123,-43,-38,89,36,-80,10,-112,-73,104,117,43,-106,47,113,51,-53,-84,93,-84,-86,0,-82,36,-128,82,33,11,-118,-33,-6,-122,-64,98,81,-44,-49,-104,44,35,126,-20,-71,-73,-126,46,44,-17,67,-99,-74,-48,66,-38,-63,-62,-25,92,-61,-28,73,49,45,92,48,85,-91,105,-98,-95,-69,-26,-76,108,80,-30,-56,102,47,-70,89,-78,-31,-112,4,-1,6,-118,115,-85,60,-62,36,72,-17,-56,-92,-60,-104,-54,-53,49,-100,-2,-106,-115,24,-56,-106,85,33,54,-60,-8,44,47,5,114,-79,-77,44,-28,-120,41,90,42,74,-57,-90,-16,79,-67,-88,9,106,-81,-120,-57,83,-97,34,7,-107,-92,89,89,71,113,-78,-22,-59,40,33,-58,-32,-85,-50,58,96,-19,70,-31,-39,90,-21,118,66,-125,-104,-90,-42,25,98,-111,102,44,-4,-88,60,-62,79,-81,-35,-117,14,46,86,-47,6,-5,101,-12,-3,-93,43,42,32,-111,99,96,-120,112,-27,65,-6,89,105,-67,35,-41,57,-126,-98,-22,122,50,48,0,-54,-46,71,45,-125,81,101,-128,23,118,22,-29,7,-26,-95,117,-60,25,-126,74,86,-53,-8,-85,-86,-62,-28,124,-39,65,90,54,64,-77,-128,-1,-112,105,-77,-84,-40,123,53,-46,127,-124,13,-5,63,123,-31,-74,-36,-16,-83,101,-124,-24,13,-5,27,13,48,92,-98,-115,-98,-111,-10,-51,102,98,-81,-82,107,-1,-40,-115,97,109,-52,24,-46,109,50,40,-111,43,71,-70,-9,-1,-48,-23,110,-41,34,-13,108,37,45,-28,-4,-10,-50,121,16,-119,-72,-45,-86,18,9,-66,64,-36,33,5,126,48,93,19,11,-62,-13,-125,95,-116,-6,-61,125,-6,67,111,-4,19,2,82,18,48,-1,-54,-66,20,45,-103,15,94,-91,33,-15,-24,119,82,116,15,67,30,111,-106,90,80,124,-104,71,66,120,59,13,-20,-94,-124,65,108,-95,-80,16,-101,-38,-24,14,25,-69,108,83,90,98,-17,-96,-64,-89,-29,-30,-11,52,105,13,53,2,75,-101,99,105,88,-56,72,26,23,-13,122,-98,67,71,-29,87,7,3,-114,58,-122,-70,-9,126,-30,111,69,-16,56,11,103,94,29,-61,7,-32,23,-6,-6,-31,-63,-47,67,41,74,110,57,97,74,5,61,28,-65,43,54,-22,-115,-126,0,5,-29,-83,-3,-79,-54,86,-50,22,21,-93,116,34,68,77,-76,-55,85,-116,-31,44,-115,-34,84,64,-42,-102,-13,43,85,100,-60,44,-102,-54,120,81,-79,-104,103,59,107,-65,-69,89,-44,121,-24,-7,61,51,75,42,-28,70,-110,110,-102,76,117,-28,-67,-12,102,68,-81,18,121,-33,56,-19,-27,-124,-110,115,-46,108,-83,30,4,105,-9,-17,114,61,11,-97,-79,17,0,88,-86,101,7,14,58,-48,62,-42,121,39,-49,-100,-38,56,94,27,119,-20,7,26,-99,-78,64,120,87,-83,-105,108,-44,-56,76,-2,-117,26,21,-3,8,58,-118,-100,50,-13,65,81,-74,-14,-96,67,9,27,-122,-73,102,51,112,-60,-13,-15,127,-83,-40,-51,-81,-120,16,-7,100,-116,83,114,97,59,121,-53,56,-20,-72,55,-9,-39,-43,107,45,49,-102,-64,101,-54,59,-123,-70,106,-126,-75,62,-44,18,-110,-17,24,-44,18,-107,104,43,122,-19,57,-122,-113,25,-119,-40,-90,123,74,-35,-14,-100,102,-22,1,35,-86,107,109,-124,-51,56,-85,-16,-124,-65,-121,109,30,55,82,-23,-21,1,-78,-102,-75,67,-94,-60,46,0,62,37,6,12,-92,48,-104,-96,-39,-84,39,101,3,68,34,26,-110,91,60,25,2,103,-47,-67,77,46,-2,118,43,-85,-107,83,43,16,-71,-7,-55,-52,-23,-23,-82,57,-110,42,-102,-32,32,-70,-75,-14,116,-11,-128,31,-111,75,1,-123,116,-44,-85,71,33,-72,60,38,70,-72,93,114,78,-102,56,79,48,-15,-83,75,-6,-78,-90,-121,-127,112,-35,8,120,25,-92,-112,82,-37,119,-32,-35,58,11,-128,109,69,48,-30,77,-9,-42,-70,-107,-21,-23,-78,-81,30,64,-51,-8,106,95,-109,-123,-40,-78,122,-127,9,81,-15,-43,27,52,-8,88,37,-45,65,118,-92,-62,119,-109,-106,73,127,-96,-115,8,71,46,47,-107,24,53,-125,70,-40,89,115,15,-119,-64,115,-11,-103,41,54,-108,-20,6,104,-67,-8,95,102,-7,55,15,73,-123,-110,90,19,113,-53,-22,13,51,40,37,-83,-113,-103,34,59,-10,-121,-103,-61,87,-26,114,-25,88,-65,-79,-63,-11,113,-62,31,88,25,92,123,31,14,59,-87,23,35,-49,-83,-64,59,53,-72,-42,52,-21,-59,89,-104,109,-22,24,-60,62,3,-109,-1,-21,15,25,-37,91,7,65,-39,61,-117,-34,26,-2,-51,-48,25,24,-15,24,99,62,61,-55,36,50,-32,6,94,-25,-84,29,65,-95,-94,-85,117,86,-30,-81,69,-102,-53,65,-7,0,-66,-5,66,127,-108,-59,-82,-23,-75,-4,29,62,10,41,-55,58,9,123,99,55,-58,-99,-6,65,-128,-121,-70,-67,-28,11,122,-108,-18,-104,-68,78,103,-108,31,119,1,117,-22,61,121,64,-68,-68,-96,118,14,58,11,21,60,52,41,75,-54,-54,-26,-119,-66,-19,11,-126,62,76,-97,64,117,-64,-5,72,-115,-9,81,23,65,73,-87,-91,57,-48,90,54,-11,-121,-40,42,-53,-82,73,6,102,-104,-117,-1,-12,52,-56,59,12,0,70,-103,32,103,104,123,-75,-104,-123,-109,-44,-35,20,24,76,16,31,-50,-63,55,-116,35,-116,-29,16,109,-34,-68,-115,-39,74,-32,-43,-9,126,-56,32,-74,-46,-19,-82,-103,68,32,94,-29,53,-105,-115,-50,-121,17,105,-7,74,77,98,-23,4,37,-8,-103,45,-123,-68,-99,-80,62,-21,-58,-2,-95,5,-14,35,19,-65,-123,-5,58,35,-90,-53,-37,108,28,39,-21,17,24,34,-53,94,101,20,-38,70,-74,14,30,62,46,-61,94,125,-98,80,88,36,14,10,-121,-122,110,80,-127,-97,72,8,95,50,-48,-39,27,54,8,61,4,113,122,52,-124,-117,94,40,-69,-34,23,89,-56,-123,-97,-16,21,7,57,-87,-90,24,-80,63,-50,-118,-112,-94,-17,24,-32,11,76,-25,32,58,90,-4,-12,28,48,118,116,-112,107,61,-110,127,-38,-69,-62,55,92,-104,0,-46,-54,17,-39,53,54,-90,-69,72,-57,116,-32,33,-36,114,37,-70,121,-84,-67,-49,-95,-105,98,60,60,22,-41,55,-74,-7,-57,-51,-107,48,29,-102,-72,-35,79,71,31,48,65,78,-38,-5,-8,-113,122,76,107,112,-31,102,122,-83,90,-55,-128,101,77,-66,-62,111,126,-75,115,63,-118,52,-6,6,101,-55,76,32,68,-128,90,100,-109,98,-58,79,109,114,121,-77,-59,19,-52,95,-1,84,114,-52,56,-13,91,50,-114,67,-51,-94,-115,113,-58,-33,56,-92,-114,-126,80,-125,-29,-82,55,-120,44,22,-85,126,113,-92,91,-39,113,-81,-90,43,69,-59,63,-34,-5,-91,-21,-3,120,-126,127,43,-73,-13,-111,-99,73,37,66,113,55,-7,47,-46,110,-76,68,105,-76,126,-36,10,21,-80,13,94,10,100,108,-127,-117,21,-95,-79,93,7,-72,98,-15,-62,94,77,-124,25,-63,24,84,-99,28,-99,-117,115,-65,62,-40,85,-82,113,37,-125,13,-51,-96,70,31,26,-36,-5,57,43,44,-97,-27,2,-72,106,-15,-112,126,111,-31,-89,69,-106,-114,-111,1,-54,-66,76,56,-70,51,120,105,-56,-8,-92,-102,-104,40,-52,77,-30,-123,-71,76,48,-20,-93,76,53,-113,-16,18,-21,44,-107,-115,53,40,88,95,123,34,53,-28,21,47,82,-90,109,-114,-104,-108,-30,76,-58,73,7,22,-97,-96,89,-84,-47,-75,-62,110,25,42,-62,-46,-62,55,121,-128,-54,69,54,25,-75,-95,-100,87,88,-96,74,7,122,38,-103,-68,-83,-57,109,-34,51,18,95,89,120,-86,15,72,86,-84,101,66,85,-32,48,-104,-99,-92,27,43,76,41,-74,62,115,-5,-8,-14,76,-114,50,-77,-97,85,50,16,-36,-27,-99,-67,-109,16,-68,106,-52,-22,-112,122,-15,-31,126,23,121,16,18,63,64,64,76,23,54,-57,-75,97,-94,-55,87,72,-40,116,-64,-23,-94,-63,-13,-53,30,9,-72,11,-45,-105,62,59,110,20,-7,-90,11,-80,-27,44,28,46,45,57,35,-60,-56,29,-91,-42,115,5,126,10,-115,77,-65,-17,-67,34,12,-39,54,-119,-20,1,107,56,39,-102,108,-66,22,-75,14,-104,-127,-85,-76,-88,103,-94,-102,-87,-17,23,-95,33,-71,107,92,-96,61,75,-10,78,-33,-125,-72,121,-98,32,-14,-28,33,-96,-4,10,-65,61,87,-27,92,-43,110,7,-52,45,9,-71,100,-52,-70,19,45,106,-110,-74,91,-86,-52,-110,-66,58,114,-126,-27,-77,-63,-50,-65,49,-7,33,116,22,-124,67,-54,76,-115,37,64,-105,50,19,-126,19,32,124,-37,80,-93,81,86,-65,-21,-5,-48,-124,-23,-25,24,-79,-117,65,51,14,-77,16,97,80,-50,29,56,-23,87,96,-52,107,-106,2,55,102,-37,125,49,93,-116,13,61,-11,-23,-119,53,13,15,-86,-96,24,-73,-43,-39,15,112,0,19,76,79,-76,99,-29,111,-18,119,-66,-34,-127,90,38,34,63,3,111,31,-29,24,5,65,-95,-70,-15,86,-43,16,76,-127,-120,6,-39,83,97,-31,-99,126,21,-29,-117,-48,53,-57,38,56,-78,67,109,-92,72,-96,-88,36,-18,43,89,94,100,-37,121,112,-33,-69,49,20,112,-80,26,26,-42,-99,5,124,116,-42,-32,-118,-28,22,40,-76,-105,81,97,59,65,13,52,-104,-98,124,82,96,-99,-46,114,-83,-125,-36,81,8,-27,-74,-28,-61,64,-31,-81,-49,42,48,38,-115,12,-80,-86,62,36,-81,-46,93,68,83,-56,-52,-36,7,-8,-125,-80,38,123,122,-88,-85,-94,-81,5,-106,21,-112,45,-37,-120,-28,48,93,-99,-47,116,81,48,-85,-122,32,50,-67,-109,-14,-22,10,10,56,94,-120,78,-79,-20,74,-98,41,-30,110,50,86,11,65,51,43,-97,-31,74,91,-11,127,-86,-44,-24,119,-16,-66,-127,-30,-95,-64,-11,54,-73,87,45,24,109,98,61,76,109,126,28,114,-1,64,-103,122,24,45,-113,-32,-24,-28,-125,95,102,-7,109,-9,-28,-7,73,-41,-33,-25,111,-45,-101,63,-111,-48,-70,-113,33,-53,-32,-95,75,71,-40,28,-112,-106,-41,76,117,-94,81,19,40,85,96,125,36,-91,19,53,6,65,-9,-82,68,59,9,91,-25,-107,-34,65,-122,20,65,-67,-38,-106,121,125,-83,109,45,-103,-57,49,-42,-42,41,78,122,-31,-69,27,84,23,-116,3,-65,59,37,113,-101,-91,-51,-19,-28,-52,86,119,-29,-29,-104,-84,42,90,119,126,-32,37,-37,59,-113,125,11,-13,65,-21,-49,-80,60,90,4,58,-117,-84,106,-77,-114,7,69,-93,-22,-50,110,-46,125,78,-60,-59,-20,-42,-5,6,93,-124,-52,80,73,75,-105,-14,-58,-59,76,105,59,-46,-79,-81,-72,34,-8,-49,-96,-102,-47,-94,93,-100,69,-126,-115,-102,-103,91,77,-119,107,-86,-115,-68,83,-26,-42,73,-28,22,5,-85,-126,-43,-84,-54,100,-71,-104,-61,97,-128,38,88,-119,36,94,-84,107,87,41,112,-115,60,39,-55,1,-45,-114,-9,-111,-96,-105,-67,-103,-24,-80,88,95,-113,-91,90,-70,91,-113,-70,37,-105,-92,-20,82,81,-122,-83,-10,126,121,117,89,-2,-118,36,-6,118,-85,124,-5,-113,-21,-9,-45,-33,-103,65,122,124,87,58,88,-17,-43,54,94,-106,-30,-47,44,29,-10,-116,-59,41,54,-86,95,13,-116,106,72,55,101,98,-29,-103,-12,-12,-73,6,122,-106,-101,69,54,-93,-43,31,124,79,-72,-102,17,7,71,-44,92,37,127,54,28,-104,-7,-50,-74,-35,-125,-16,-119,28,-23,82,122,63,122,-38,-17,-44,14,-28,117,92,-90,26,88,-74,-41,-104,115,111,112,37,22,127,-9,31,-128,61,29,53,-3,58,78,92,66,-76,39,110,52,-27,-33,-125,-73,27,95,-96,-61,-125,114,47,-107,101,124,21,-16,80,-101,-47,44,63,-31,-99,-57,24,-113,37,18,121,102,-10,46,-24,-76,-71,-104,68,59,-124,112,123,-82,49,78,-17,-47,-83,121,91,2,102,-14,32,-30,-19,-3,67,117,-111,41,-92,26,-26,-50,-42,-74,97,-21,-72,18,-78,104,41,64,-111,122,108,43,-80,67,48,-45,-45,-19,105,-66,115,84,81,125,72,59,60,105,52,-36,-31,30,-64,28,-10,45,-74,11,38,40,70,-3,-46,-77,-70,-16,-118,-69,-114,98,-77,60,123,83,-102,115,7,100,109,-22,-48,-80,42,-127,-87,81,-77,8,57,-72,-41,103,-54,3,-54,105,-37,-41,-9,-16,118,80,-30,-87,22,71,-48,-38,-105,62,-90,-21,-41,-33,121,22,19,116,66,83,112,-39,-28,54,-84,31,-125,112,89,-81,-109,72,-108,-95,-1,-114,120,-73,110,-105,-107,-126,-93,8,-103,20,-55,65,122,-58,68,121,-97,61,-74,57,69,-65,1,-112,94,97,99,-122,100,46,7,-94,116,23,85,-111,83,79,-108,112,-102,106,-105,-87,-66,-128,39,24,-7,-72,-78,115,-51,99,-113,83,-90,-97,-8,89,-88,-114,79,28,56,113,-102,38,-5,-104,-76,-18,38,57,40,-67,-9,89,-8,-121,27,-25,-110,-93,-36,-10,123,-73,-111,-29,3,116,-20,16,-40,-18,87,-123,120,-68,-97,-97,-47,-94,114,113,-121,-111,-53,69,105,-81,77,92,-37,-25,-46,-18,-9,-86,54,46,-80,27,-101,108,-69,53,-109,-44,85,79,-46,-87,34,-30,85,-11,-61,101,-22,-17,-25,99,-65,-30,117,-89,-120,-23,-16,1,-94,12,-80,-29,64,54,106,-111,-75,82,-3,22,-46,11,-103,-63,12,68,120,-17,-117,-52,87,112,-123,-52,-121,105,-53,-55,101,60,-3,71,-122,52,-9,-125,-41,56,-1,85,15,-72,-29,70,-7,-103,-46,-112,127,34,11,4,48,114,56,-109,-32,86,11,89,-1,-80,-18,17,9,-55,-87,114,92,53,-4,42,86,22,57,-50,120,90,110,-90,15,67,-59,49,-46,-97,96,119,100,-80,64,-54,81,126,92,43,-90,-14,-47,-89,21,-17,-37,51,121,-73,-43,110,-54,-30,121,40,-34,85,52,-99,36,-9,-18,-51,91,-71,86,102,-116,95,-55,95,-35,74,118,101,-114,55,-108,-48,-60,-22,20,87,20,49,74,117,-76,-43,41,79,114,-28,83,-68,43,-128,-19,-96,-12,19,111,-44,126,102,-110,56,-77,-27,-14,17,-26,62,-107,71,89,-127,-37,-16,32,-34,126,110,74,107,126,85,8,80,29,104,6,30,-52,79,-74,-11,108,65,29,-107,62,-2,59,-123,71,-128,109,110,110,123,28,-68,-39,-20,-108,112,-32,-36,-12,98,-82,-57,38,-103,55,126,100,-5,89,-41,36,12,-16,99,118,71,-96,88,-92,113,88,-56,97,76,-77,117,60,46,0,23,-41,69,4,-5,-84,33,-3,45,31,38,-119,-20,96,-113,36,28,-38,-96,-23,-115,-50,-106,3,-9,85,-80,7,-19,-111,-120,-3,-107,116,-87,-115,101,92,5,-13,-9,53,1,-35,-125,-23,-107,-122,53,117,-10,-122,-89,19,-33,-32,69,-67,-69,75,-116,-35,107,-48,-74,109,-38,50,-69,43,-85,52,-107,18,83,115,-101,5,44,78,-7,99,105,-72,-39,62,31,27,-46,97,-117,-94,-69,-86,-124,-114,-30,-48,-126,-122,108,-59,-2,-19,49,-22,-29,-21,67,60,37,-75,-55,-22,56,47,15,-111,32,0,35,81,-18,108,41,-120,-20,125,-4,51,119,-115,0,122,78,77,95,-68,-9,109,59,-128,-8,11,-114,7,29,-56,79,-124,-80,-112,9,91,-32,11,-50,29,-115,18,-19,-6,-123,-15,-82,74,-6,15,-55,12,72,-62,12,43,-30,58,-30,2,-56,-100,1,82,-85,63,-17,26,-117,52,-90,-69,-61,-90,121,111,-18,60,7,-26,96,63,-92,5,-11,-52,-81,125,97,122,67,82,33,93,99,25,51,39,-71,110,28,-116,123,48,-68,-103,-9,-31,48,-2,-107,-64,-102,-107,92,-62,-100,83,127,41,58,-122,-7,113,-18,20,-82,-105,23,84,-120,10,-37,-82,11,46,62,-57,16,-58,-18,0,42,-95,-82,39,-105,-78,106,52,-51,36,-40,-3,98,-108,45,121,-59,76,73,19,124,-67,-45,20,76,-21,66,-56,46,-18,-39,90,0,-57,-42,-47,90,79,-120,79,103,34,59,-41,-67,94,125,88,-104,-30,25,-128,120,35,88,68,-48,-47,-99,66,-12,92,-42,46,-25,-10,55,118,125,20,114,67,-9,37,123,48,-84,79,-63,-23,43,119,82,76,-8,-21,-17,27,-108,97,-32,-119,-109,68,80,-9,53,95,-20,-71,41,-50,-57,-16,-4,17,39,-128,19,-113,9,30,-36,66,23,47,82,-76,-87,-35,-48,96,-4,-86,100,15,-58,-10,-1,83,-52,17,-102,37,-89,-33,-2,-23,60,122,-88,-13,-112,-47,-92,-52,28,-101,-99,92,-123,-108,77,101,102,44,-67,-88,-108,-43,118,-96,45,-48,84,-25,-9,59,86,-7,79,23,110,-74,-92,-67,50,-109,29,53,-57,-89,31,8,1,65,126,-119,73,9,-107,92,81,17,53,52,98,-126,111,22,15,-15,-110,-49,60,-82,-82,88,79,110,-113,-124,-127,-51,45,41,-87,-17,-95,-122,88,-48,64,-111,-55,62,-46,-91,116,-55,29,-36,75,95,-56,-100,-125,103,-115,-41,-29,-56,88,-81,-33,29,-127,-6,-90,77,-4,30,-81,-11,-121,30,-17,-10,-24,-124,109,67,126,-109,-57,34,-101,-9,112,25,126,-47,4,79,-38,117,-76,-43,56,-15,-86,85,-80,3,37,-120,39,-40,54,-70,26,-64,-45,-69,-53,19,70,24,-112,-78,-35,-120,69,-113,-97,-29,-53,-106,-74,-61,58,-21,-57,97,-97,-16,94,78,62,-121,-58,46,-38,35,35,-127,-17,30,2,54,30,117,-120,125,9,-20,-30,-44,-53,52,29,95,-66,122,60,-29,-113,68,-92,16,-110,10,102,54,-78,-120,-71,111,-52,107,9,-11,-9,81,-96,-37,-25,-77,39,111,28,0,-55,43,23,-98,-37,-123,-11,-42,-98,-97,102,106,69,-4,98,5,115,-121,-115,-94,-78,-69,-9,51,-84,-86,3,-104,11,34,-38,-113,29,-39,61,10,54,-116,65,-91,83,86,27,-44,-27,-108,-86,34,-40,99,-8,37,101,126,102,126,38,-14,-102,-52,-82,-56,-36,74,95,113,-115,-49,-66,-20,-123,20,-83,-37,96,-44,-55,-98,-1,75,-2,10,74,-55,107,87,41,-123,-90,-61,0,2,94,-63,-103,-85,-13,-107,98,78,-47,6,26,8,-39,36,-119,52,-21,-70,-40,72,117,115,-87,83,-57,-60,127,-78,-78,76,36,54,43,-25,127,19,98,125,-96,20,121,62,-126,13,-30,86,-110,97,124,-32,-104,6,-122,36,0,18,105,-48,-39,20,-105,55,-113,-114,-121,-83,9,-20,-23,-49,86,-48,-107,70,125,-114,-115,83,31,-23,121,-30,-67,48,-86,-90,-91,69,-79,-107,-77,99,21,83,54,-73,64,-60,88,-10,15,57,112,-85,-47,101,-78,7,-29,-128,120,-16,-96,-50,27,116,-128,-11,-35,84,-19,-33,-57,-73,18,49,-67,-15,41,15,36,41,15,9,33,4,39,27,101,-117,77,83,115,-60,-54,-82,46,-56,-18,100,-51,-41,-27,-25,-95,9,74,126,126,-81,-48,10,-60,85,99,80,27,108,-6,-16,77,44,46,114,-26,20,-69,15,28,-121,107,-59,125,-125,92,98,-61,84,-114,-87,-44,-13,116,-120,1,121,-84,-86,26,43,-55,94,-25,-80,-75,34,-97,-12,31,-58,-68,110,2,-109,-27,13,75,84,-21,92,12,-61,-117,36,21,107,22,-61,80,87,-115,29,-3,-125,41,75,45,-108,-29,33,-111,-4,25,-52,8,24,-74,-36,-22,-94,25,-7,97,-124,108,-114,12,3,-10,96,75,34,17,114,-32,84,84,12,-60,-88,-119,-41,41,-48,-11,-25,1,21,10,-71,-3,-16,96,-36,-14,-115,-14,-3,-83,6,-33,70,-18,-108,-81,-31,85,-91,-59,-80,81,36,11,19,74,-22,-80,61,8,57,-110,97,107,91,-40,-82,29,-95,122,-114,-102,-77,-28,111,122,46,-35,-102,123,83,18,-47,-24,-121,-120,114,-93,22,-66,65,113,77,86,82,115,-82,117,28,-78,76,27,79,-128,119,-10,-71,-31,11,-89,-82,-88,63,-99,94,87,124,76,-124,101,-53,-3,-119,9,-50,-29,92,58,-74,-51,57,-114,31,-75,113,-47,-103,4,12,-43,-100,-70,27,40,-81,-36,-26,-12,-102,-118,-88,50,-73,-57,124,-94,122,70,-87,28,-113,-126,100,-1,4,62,7,-91,-91,44,-90,-56,102,-32,30,100,-102,-47,24,34,118,-99,-98,36,113,117,3,-126,-84,97,-73,-124,11,-46,-18,-15,72,-38,24,-47,-4,-65,-73,-86,-112,-37,-125,109,-50,112,72,88,-97,20,-29,-43,-2,-48,121,94,58,103,52,51,-16,-116,94,119,-101,64,48,51,-70,-106,-62,41,82,-66,78,-113,106,71,-105,-44,111,-78,71,115,-50,-111,-46,33,88,-67,-58,-123,4,-82,-34,22,-40,120,-28,-18,-52,10,-15,-109,11,-106,125,-126,-31,94,-89,84,-94,-62,-6,98,62,-50,-78,-34,12,104,50,-39,-11,-60,43,12,-18,36,-62,-58,-36,43,-118,-88,78,-35,-62,-14,-104,-124,-68,21,-18,52,102,18,87,98,-2,-78,29,37,80,25,-106,-99,-86,74,127,6,-31,86,112,35,3,121,-126,-78,114,77,-51,-85,-24,70,7,-109,-25,-58,120,10,-20,26,-100,-18,120,-127,-78,-23,14,8,-116,42,-75,79,44,119,103,102,69,22,26,60,-58,28,-70,-104,25,25,124,3,-15,-44,93,87,-23,-8,-15,-11,10,7,9,120,-68,125,-79,-70,15,115,-75,-90,-5,127,108,108,-66,-122,74,-82,-14,-100,4,58,-106,-96,-65,1,11,102,-41,66,-117,55,-8,6,-69,-72,75,76,16,78,59,-2,-10,-42,-72,-1,-31,-100,113,26,-66,48,-4,103,57,71,-94,-2,14,-28,-36,22,-8,-25,39,-51,25,99,91,70,63,11,-124,69,46,-34,-21,99,-70,-110,-90,32,116,34,-74,82,43,-104,-56,31,-117,-43,67,12,-72,115,-84,-62,-9,21,-30,105,82,94,86,12,40,-47,-39,40,-114,-67,-89,-72,-64,-62,-124,-105,32,95,-124,-41,-14,48,26,8,-116,-57,24,-45,-45,-75,-40,-111,-118,107,116,66,-97,-57,-79,-96,-85,-55,49,-55,-32,-87,-76,-12,42,-85,85,-16,75,-41,-112,49,-29,-28,-124,-10,-60,62,-2,-112,15,-36,-33,81,-95,117,120,51,99,-64,30,11,106,-21,-42,43,-59,51,117,12,45,3,-116,110,88,104,60,67,102,-74,108,80,-58,-108,28,38,-108,16,63,100,-24,-36,-1,70,97,7,32,118,-112,-122,-31,-36,106,10,115,-89,35,58,-15,-5,63,19,-123,-99,-11,-94,108,-18,-13,70,-12,-1,126,-15,-9,-25,113,111,66,-59,81,-88,-114,97,-121,-76,16,8,72,62,3,-107,106,-43,92,-91,63,60,-90,-61,96,-9,93,-24,-17,-22,38,-24,29,-27,-36,-25,117,99,-10,76,66,-77,-71,33,-87,100,48,-13,-122,-49,56,-104,72,72,-84,103,72,115,-10,45,19,-22,52,-97,-77,-107,50,-81,-93,-79,102,-71,46,73,6,-21,-52,5,-96,32,112,15,-44,-4,110,5,-26,-85,89,-87,35,73,-17,59,-95,-5,-123,94,127,-83,9,-122,-64,-58,-72,-111,33,-91,-82,56,63,1,6,-67,-106,-55,26,-12,-105,-32,115,-38,-95,118,117,67,-17,95,99,120,-75,2,28,-113,-105,117,-15,111,22,-46,116,25,-91,40,44,84,37,-4,-66,-125,15,69,-14,49,-12,-11,87,-68,20,91,110,117,125,-65,-34,-36,84,-29,-87,-27,60,-66,-118,-125,49,69,81,54,7,-119,53,-23,-60,-9,22,-116,-125,-58} + +#define IP4_q7_q15_WEIGHT {18,-44,-12,78,104,61,-34,92,-120,40,-75,-19,29,-56,-80,21,60,107,-92,-118,58,94,-104,47,62,11,106,-105,-6,-32,-20,24,43,-116,43,48,53,-50,-86,-38,-108,0,-80,-73,-5,-26,115,111,78,-101,76,-55,94,-61,39,118,94,-20,13,-81,100,-111,70,94,-125,71,63,-121,-70,-14,-69,-74,54,60,-121,107,-121,51,-106,-38,-61,110,26,103,-43,-116,94,111,60,-28,-125,88,83,62,120,-39,-79,-85,112,34,121,-121,-93,97,-45,-90,-97,12,-97,109,90,-45,-59,-105,-100,-21,0,-122,-26,-37,28,-10,35,-115,-87,-62,6,108,-15,118,26,-84,-26,-74,1,73,-41,97,-65,86,94,34,67,59,-99,-67,106,-80,-26,-21,-71,-20,115,-43,109,-107,-21,37,64,-2,-20,115,-75,108,53,-102,35,45,83,-49,-106,-59,-46,121,-102,-41,51,22,-55,19,-58,-116,-103,80,25,122,-126,-76,-7,-2,-34,110,15,82,-46,-16,15,-52,-19,-39,-73,93,62,67,117,62,-27,-12,-89,-100,-15,-57,59,-127,20,52,-37,-41,-79,-43,111,99,-31,13,-12,99,43,-1,-31,124,43,-15,-30,-69,120,-79,-36,-89,-19,89,46,54,116,-46,49,85,94,67,113,24,11,-59,-17,-119,119,110,-57,-1,-81,77,32,-38,118,-13,113,-94,-53,111,110,-14,-19,-53,4,-20,117,-35,121,-97,24,119,18,108,-31,54,30,-121,-74,16,101,3,65,107,-12,14,-38,-53,125,-59,60,17,52,-65,21,-118,76,-112,91,106,-38,26,98,-4,-53,-108,-63,95,-58,19,63,111,-74,37,73,63,-115,-44,-84,22,-47,60,-51,9,29,-57,22,81,-87,-65,-27,-63,-93,110,63,-26,-126,7,-12,-118,-127,-70,-113,45,107,-69,103,-48,56,55,25,-55,79,111,113,120,-2,108,43,-122,-41,40,93,44,88,-78,107,-34,124,63,122,-67,29,24,14,-69,-72,108,67,26,116,90,88,-48,93,-37,-103,127,-24,-76,115,-80,-97,96,-61,-54,-22,-123,-14,-49,62,-1,-17,21,-65,10,116,113,10,88,30,-24,-119,89,-95,58,124,-112,-119,-115,88,119,57,68,-17,-27,31,-9,-64,-26,18,109,-60,59,4,-89,-127,-35,8,-90,88,22,-76,109,-123,88,-51,-90,18,45,25,47,-80,-66,75,-24,-109,-42,-47,68,-8,78,-98,-122,19,-72,33,94,2,-84,-109,82,102,55,71,-121,19,76,76,93,66,-23,-42,-2,40,106,3,123,-111,83,8,105,117,-52,121,2,-4,-18,-4,-19,-125,80,38,83,25,123,-64,47,36,29,105,-71,-72,-41,-127,-82,31,-43,3,9,73,91,124,-3,-99,101,-27,77,-51,60,-96,15,74,35,54,-119,116,-4,53,46,-29,2,8,93,75,38,-18,49,40,-30,30,22,97,-8,97,-35,-111,-62,21,97,-96,82,-12,28,-118,-12,87,29,-16,110,46,8,95,40,58,41,29,-58,105,-108,-29,36,-117,106,-118,-124,11,60,84,-87,-83,21,53,125,-31,-5,114,93,-75,-41,-127,49,-98,31,96,-112,64,60,-126,69,2,-73,94,-100,-23,81,-115,94,-116,-25,-44,91,46,-89,12,75,-47,107,-77,-10,-82,79,-70,75,-106,-1,62,-69,104,-7,-41,53,73,-32,74,-113,26,111,-115,66,-55,20,-91,-47,7,51,-96,121,126,-75,63,-23,81,14,-124,-39,-41,-13,14,16,-27,-56,-48,-84,-43,120,33,98,41,26,-6,15,18,8,31,-50,-9,121,-107,-33,-106,-46,64,127,-19,-104,-59,-30,86,-121,60,39,-79,-38,-5,-119,85,-17,21,44,-120,-22,89,73,-17,-102,49,-73,26,-69,91,-36,-71,103,63,125,-8,61,103,-20,-116,11,105,15,-116,-78,-122,-62,-80,-80,-58,-119,65,-47,99,-111,-26,69,87,-15,-38,-44,-87,-84,-14,-37,-27,-90,109,-72,-4,38,-110,82,-97,29,-50,61,52,-87,-44,8,63,92,83,109,-124,69,-47,-110,-70,-10,111,25,15,80,104,66,32,-16,-70,-49,-52,-41,-16,122,104,-31,22,-109,18,102,62,125,-123,121,74,5,92,-90,-92,72,-61,-2,98,-125,-81,109,101,-120,60,10,58,53,94,-25,38,-56,-13,80,-80,-13,45,-43,-77,-44,-37,46,-62,38,-103,-93,-124,48,76,1,-82,73,74,63,67,-59,-26,116,76,66,70,-30,-113,106,109,75,25,-18,25,85,25,-83,81,-50,78,99,-53,-68,-125,44,-104,-44,96,-126,124,112,33,-75,-29,-60,-9,-126,-84,-61,-119,-127,-6,-26,-46,-57,118,-4,105,21,-120,-121,54,-35,-70,-124,-101,-79,-33,105,-30,57,-108,-111,-48,-65,-108,77,41,112,111,68,118,0,22,44,110,56,-91,-111,-49,62,-54,83,78,66,38,-14,102,41,52,-94,14,106,105,27,24,53,-40,60,-70,-119,56,68,-95,69,59,-124,-101,-25,-119,102,-45,-55,-38,57,61,104,-96,122,88,99,-122,106,77,122,33,-5,126,-74,46,-52,116,-51,-101,74,74,2,-3,-38,-21,68,-30,96,17,71,-124,47,-23,64,-35,107,24,49,41,-50,-23,88,19,-30,55,-91,3,-14,-54,125,10,-96,84,100,100,-116,67,-40,-124,53,2,-62,45,21,72,82,10,-126,-47,54,-84,13,-50,-2,-66,103,-1,96,-17,59,123,-111,-61,-20,-70,-57,54,-110,-94,-125,3,14,-101,-128,-86,-44,80,-94,37,123,113,-104,-9,109,-87,111,120,-7,33,-62,-51,49,-57,-71,3,-49,18,-94,-32,40,-92,-52,3,105,52,108,123,1,40,2,-86,-104,38,52,-93,-73,-44,-62,91,5,-88,-91,-61,-40,-24,-30,-48,114,-115,62,-128,-93,-85,-43,104,102,-20,-103,-52,25,-56,-103,49,10,-25,84,-52,-94,51,-110,26,1,-108,30,32,126,-23,-112,-82,-102,86,-17,-108,78,-32,32,80,-112,-125,91,8,24,-69,-95,-86,-115,-73,14,9,-121,-2,101,-109,1,-72,54,84,25,-36,95,-49,-110,108,4,24,66,126,-63,56,99,-8,-10,-80,5,-73,72,-103,-35,-10,78,3,-61,42,-83,-115,84,-99,78,20,-66,30,-88,97,-66,-120,120,-46,-57,-29,118,15,-110,-94,-29,25,113,89,-110,-52,-92,90,105,-30,92,48,-44,-1,-96,-39,118,115,-3,37,15,-1,64,-2,81,57,24,-47,-14,89,48,-103,-127,-95,-114,-100,14,-69,-32,-82,-9,-77,33,-38,-76,-63,51,-32,69,-8,-75,26,80,59,-31,101,40,-37,76,-23,-110,-23,-84,-83,111,-31,122,124,-56,-67,4,-112,-123,65,101,67,12,-23,-43,-12,54,-87,66,35,-89,-47,55,-105,100,19,21,-80,-76,-85,-61,-117,19,107,42,-71,86,-9,33,-80,-65,120,-49,106,77,-34,-50,-38,-27,21,65,-28,97,108,42,-77,120,69,127,24,-20,89,-66,112,-126,-110,43,103,0,-63,-17,28,36,-43,-117,-68,115,-69,107,70,2,94,9,95,-83,-99,53,47,80,-105,-27,28,119,59,95,82,-94,-16,15,-49,-122,16,17,-89,64,-6,4,88,21,47,50,-78,-25,121,-47,-36,72,-21,29,-101,9,-83,-113,28,-68,23,-67,115,-101,-101,-98,102,-124,-98,-24,-89,82,-28,-89,40,125,23,97,83,-53,-7,-90,-108,-83,-113,-58,-26,-119,28,35,97,-74,6,-40,-15,-10,11,79,-98,101,101,8,-72,-99,117,-65,80,127,95,60,15,-29,2,60,-92,-118,-116,79,46,-79,-62,104,-43,73,107,-43,117,-127,-67,44,113,-41,67,-73,-98,26,74,-111,59,79,45,-60,21,-26,18,54,-72,-70,-30,114,10,-82,-124,-52,-126,-97,108,-19,120,-111,-52,10,102,18,99,49,-128,-17,91,83,-46,-76,-3,45,-41,47,-72,-19,3,112,-104,14,122,-77,-35,121,-23,41,-123,-60,-2,50,44,-45,84,69,-58,43,-69,-98,-11,112,-17,-95,-36,67,-69,-52,-11,98,-45,-126,-33,51,81,101,-38,68,67,-37,-78,107,12,105,75,-109,-100,-55,0,45,11,-24,3,-70,54,77,-63,52,125,93,-16,-97,-22,35,97,46,58,-61,66,-61,-98,12,-43,-45,-63,-36,-79,-58,41,54,-49,-63,48,-33,-110,-36,-49,93,73,-33,-78,50,-76,-48,-6,4,-87,-81,-88,-30,-33,10,-109,104,-94,38,94,-124,30,102,6,37,97,73,56,-106,-18,70,84,4,-31,-90,-27,54,63,10,50,-18,-113,-116,125,-86,-119,33,64,26,-128,-77,-25,76,-127,0,-79,60,-65,-63,5,-5,101,69,-91,-49,67,121,71,-22,59,26,-87,66,-26,-79,7,-73,-51,-114,0,-22,40,-87,-115,29,-18,-72,-23,-96,-55,69,-119,68,-102,124,-99,16,74,5,-34,87,120,-6,-28,-92,-111,-85,-42,-36,123,-52,-86,83,-77,43,-15,124,59,103,-81,96,-80,0,41,-62,-22,77,-13,-99,71,104,-121,72,43,4,107,80,-62,-98,54,-63,-13,10,-92,-119,-95,-90,-76,76,78,-108,95,-117,122,88,-115,52,-10,122,26,39,101,12,-80,107,-108,-13,36,-72,36,63,82,119,-57,-7,-44,77,-55,-54,-25,102,-118,-91,-93,58,11,-30,11,80,-62,111,-77,3,105,-63,39,-50,-33,29,-6,52,-98,51,-80,-5,-50,93,-122,116,-77,79,-45,110,-103,-123,-20,-16,-58,-101,93,-11,57,44,24,-60,-118,32,64,80,3,107,-25,60,126,-90,124,-22,-95,-57,-91,83,-46,-28,1,78,-47,15,74,42,26,42,113,-76,14,33,20,-93,37,89,107,-22,16,-16,23,60,108,74,-117,111,52,-97,78,53,-127,9,123,-78,-15,86,-17,5,-17,28,-120,-76,69,-76,13,120,-64,-17,-35,20,-98,-42,126,-88,-99,-113,10,44,84,-35,115,18,81,99,2,-82,74,12,-125,110,55,31,-110,-94,23,-4,62,-62,-122,40,-120,42,110,84,34,2,-3,-75,-24,-10,124,-46,-38,-14,-11,57,109,27,111,-99,6,27,126,41,72,-29,106,96,-24,96,60,42,-18,-104,82,-69,53,15,92,127,-79,-70,-102,102,-53,79,32,-119,84,115,-36,-84,7,-24,2,-77,103,54,60,-7,1,-64,-7,114,-22,-5,19,-49,80,107,-7,89,-2,-63,-26,-51,-111,17,-108,9,-40,-51,58,108,-55,-68,-117,-51,99,-117,-17,-33,46,69,13,4,-23,-71,-110,-95,4,119,103,31,-30,23,76,-36,39,6,-117,6,76,80,106,-124,18,-3,78,3,112,40,23,-100,-55,75,-118,-52,-16,18,69,-91,-77,126,-87,103,41,-127,7,106,105,77,-23,50,72,75,-16,126,-19,112,67,-102,-4,-56,53,-72,38,-60,-69,0,30,47,-95,53,100,-127,-16,-16,-18,29,46,90,73,-112,-97,-15,-111,-38,23,45,44,115,-93,-32,-68,-10,86,69,19,32,-104,97,-112,60,64,61,87,69,55,-4,-92,-77,-28,-82,76,56,123,-105,52,-38,-1,80,81,-40,-14,115,-78,32,-59,-115,-123,50,3,-14,69,5,-39,-124,70,34,61,-57,-35,34,127,-13,-120,109,-108,-22,68,-125,81,35,89,-21,88,107,87,-32,110,-19,-27,-82,-114,99,-81,115,-54,90,-92,65,-126,64,26,-114,36,-93,70,10,-94,-90,-111,118,-45,-121,-3,106,80,-101,10,-25,-12,39,-72,114,47,125,43,33,88,-81,-109,10,98,-98,28,105,96,-43,123,-58,-115,-88,-122,85,-80,91,26,-26,103,-121,-88,-66,101,-88,87,125,20,-62,-58,-46,-113,-36,-100,93,79,-108,33,49,-45,-19,0,70,103,-19,-48,-15,29,40,122,121,118,86,102,-83,111,-26,-86,-124,6,49,86,50,-67,-28,-104,-28,35,42,52,-25,-87,-70,-6,18,126,-128,123,-3,-109,-94,-49,-120,-62,-89,62,-107,94,109,110,10,-37,99,-126,-116,-85,100,113,-19,-52,-101,65,-45,93,96,-49,-78,84,-44,28,5,-110,-26,-48,62,127,-53,49,57,67,127,-85,60,120,-96,-67,107,34,91,-60,-6,-80,-77,-8,-119,50,-52,89,-64,96,127,-60,-76,-34,-52,-1,34,-25,99,100,-94,-46,-47,12,47,-47,45,-14,59,3,-85,-74,-49,103,-6,-79,-1,-25,-2,0,-44,-29,6,-11,108,-23,91,-48,56,75,-71,-77,-46,-100,-100,-98,90,-29,-35,-56,-3,54,-62,-126,124,1,-26,-88,4,101,-113,95,-67,75,104,39,-106,68,-127,127,-15,-36,23,-12,-51,-118,-67,-22,-39,-71,52,-77,104,9,10,-106,53,34,-67,-98,-74,84,87,95,38,-35,-38,-103,-125,-124,41,-31,3,-89,-107,-41,-9,-90,-58,-39,83,-106,-24,-86,-93,18,14,23,36,-56,75,-36,-123,10,109,7,13,-119,80,113,-68,45,57,35,32,-17,28,-1,-98,52,-37,6,-97,118,-119,48,-69,-102,-18,37,-4,-59,15,101,91,40,3,-31,5,-9,105,-9,-33,-31,-71,-7,-112,-71,70,-2,98,46,-99,73,42,-77,-38,53,48,-1,76,-120,-33,-62,117,-35,67,-117,58,33,2,-127,-66,-100,-117,-82,115,91,-111,33,-125,24,-89,76,15,84,27,-5,49,-87,-72,-35,-49,-128,114,65,-71,82,127,100,74,41,-63,52,-67,0,8,117,5,-102,123,87,8,-37,36,126,-108,71,-73,20,-76,104,-71,-50,-56,18,8,-62,-105,-52,-127,41,-26,16,-122,31,70,11,-100,-109,-35,117,88,29,-78,-45,115,-86,40,102,18,-58,-84,-54,32,-36,51,56,52,107,38,126,78,-66,20,-77,65,-119,26,-113,85,-92,-35,-67,-24,-47,43,-9,62,-70,-41,-66,-7,-72,-79,-77,56,75,67,49,65,43,-78,102,113,98,-47,53,20,-116,-2,-4,-12,-36,8,50,-118,-79,-37,-120,4,103,51,62,107,-90,49,79,-17,61,36,-15,17,-117,123,39,-87,61,96,11,-108,1,51,53,36,-19,-69,-51,-40,-91,-90,127,-62,126,-72,79,-61,123,-27,41,11,14,-67,76,-17,-70,47,-104,73,32,-109,-120,61,38,-1,31,-37,35,-26,-21,59,-53,18,-85,75,106,-83,93,-31,-18,18,-127,19,66,10,-74,-25,45,-109,18,30,4,-62,13,-47,13,44,-59,-96,19,-113,-18,65,-5,91,-75,-21,68,46,-90,25,-110,-115,1,-88,-91,13,55,86,24,85,-60,108,93,-61,27,-14,28,-17,-110,-18,68,113,70,-52,58,52,-9,111,-64,64,-97,-100,0,32,43,-88,13,0,-32,110,-104,108,92,66,-112,34,65,-64,-125,-9,106,113,-116,-35,91,-88,-91,13,-16,-117,3,121,37,-84,-75,-44,-1,-49,13,81,-77,46,113,15,-115,-37,21,33,-17,-19,-83,27,-95,28,83,22,53,-23,66,-57,-25,-15,-56,106,69,49,63,125,-120,106,-86,40,55,4,-96,43,-26,60,-107,-76,-116,-89,101,98,51,-21,106,53,-49,110,83,-119,27,36,2,86,-5,-50,47,42,-75,52,-59,-71,63,-67,60,6,83,65,124,28,16,14,63,52,-58,23,30,49,-81,-123,-26,-39,42,60,-27,-66,-61,-18,-88,-46,-22,-61,-60,66,65,-100,111,100,116,50,92,-83,103,111,-72,116,-5,111,72,101,39,54,-65,8,-44,-128,-88,18,113,-70,-78,87,-70,29,112,63,-31,9,12,-27,-109,-42,-52,-48,55,-70,95,93,-71,122,-46,-115,53,-22,-27,125,125,50,-58,21,-50,-71,9,-82,-6,45,50,-14,51,-74,-72,95,104,-86,57,65,-39,6,-10,-76,21,-52,127,17,-128,-36,-23,103,87,24,-95,10,95,95,21,-96,61,-24,-8,74,0,126,-14,-44,-102,107,-119,-123,83,51,27,-17,-64,124,24,79,-96,118,43,-95,8,-75,-106,115,-84,69,3,122,-118,-64,96,-106,-29,-78,-97,122,-82,51,14,65,-80,121,-66,74,-119,121,82,77,-120,96,-82,106,56,-45,-28,78,-116,-70,-13,41,90,-77,-55,-49,-78,91,-109,-91,-36,97,-31,27,95,-91,-116,-17,-21,87,112,-51,-82,62,-42,111,64,106,68,53,92,-68,-38,-25,-55,-38,-121,5,74,-96,-77,-109,-14,-87,75,-108,-62,12,-97,-91,93,42,24,-45,-5,79,126,-71,-10,-97,97,-19,6,-80,77,-111,39,-69,42,-61,-123,-30,-78,18,64,77,-99,-40,82,127,-39,66,46,46,-82,-117,-70,77,-17,96,27,10,56,83,16,22,114,24,114,-89,118,116,-84,19,-88,16,80,-25,66,-70,111,70,-86,10,-88,-1,80,-95,-82,95,-20,-114,-121,26,-15,-77,-104,-120,-7,123,97,68,69,59,-12,24,-20,46,100,75,-76,-41,-23,79,82,-115,-3,44,-69,-100,-55,95,81,-125,-108,-121,-46,-112,-48,-22,-10,-60,-40,112,22,89,79,-99,53,48,-54,-110,16,77,-51,94,59,-50,-103,-10,34,60,-115,84,31,-55,-58,-10,64,-5,23,112,96,75,85,4,-106,55,-77,-33,87,-79,-76,53,71,-92,-8,63,118,-84,-60,99,107,88,46,-89,24,98,-41,-36,-22,-88,34,-23,78,56,84,52,-14,123,60,-20,38,-66,-56,67,-80,-6,117,115,121,-126,39,-77,-8,22,89,29,-101,29,55,-31,-108,125,123,-46,6,-88,103,-35,25,65,-58,-118,40,26,-39,62,15,77,-25,-50,117,79,44,-79,64,94,-114,-31,-26,-10,-67,-114,-19,24,69,111,14,-52,-33,110,50,-107,95,63,-71,-21,36,-22,-7,19,-95,-71,-38,124,-88,47,120,22,98,-69,73,-114,-5,-18,106,-102,-41,-26,28,-101,-41,-105,-31,-26,-120,22,-21,-44,-31,-50,-127,85,88,111,33,-114,-53,-12,71,126,53,-55,82,-104,93,-77,41,46,-50,90,54,-38,-28,-128,-68,-13,-80,34,-63,60,31,-81,40,77,55,-5,-17,-110,94,30,96,61,26,43,-48,101,-128,13,-8,-29,-6,-60,115,107,-62,-57,54,13,96,114,-89,-69,36,-40,106,107,98,19,-28,14,-4,-97,-60,-64,-71,-107,-48,-50,75,-54,90,108,60,-101,-104,92,25,-60,-17,-63,48,103,113,59,24,51,32,-101,-26,121,71,-83,-21,-68,79,42,-115,5,89,65,-38,28,-91,4,22,89,7,122,-57,-51,-120,-110,-58,-42,-70,102,105,-112,33,21,-83,-14,62,123,-116,-55,-114,-110,95,-46,76,-6,-12,-88,-48,49,-126,-67,95,42,-94,76,84,-64,-112,-20,114,-8,9,-96,-38,-85,-38,72,55,127,7,117,54,41,-52,-89,-46,-121,-95,-97,-113,95,46,79,-105,36,96,62,111,89,-38,-97,61,120,24,90,-111,43,-69,48,88,-58,25,-89,55,14,26,121,-126,79,42,56,-43,109,-88,-53,31,-114,69,-1,-81,-50,94,35,20,62,-93,69,-96,-35,120,-103,-86,-44,126,-96,102,12,54,-97,-79,-49,97,-18,80,-111,-68,-17,39,102,87,6,-10,2,11,-89,-74,-43,-104,-9,53,28,-68,-126,-71,-26,66,34,102,-36,32,-96,-83,-127,87,83,-50,-98,-60,71,-81,-97,108,-74,50,-98,20,-9,75,-48,8,0,124,74,-27,-59,1,118,-121,52,-57,112,15,81,120,-66,-10,42,87,-89,-92,-123,-1,-74,-29,126,57,31,-50,115,-47,-89,-20,-107,51,28,49,110,38,-37,-73,-72,-70,-20,-124,-109,67,-114,7,64,32,101,-76,-107,52,-109,-89,51,-51,-98,-3,122,100,-2,-57,34,-38,-101,22,15,92,-104,9,47,-9,47,-18,27,-38,-122,-58,-20,102,-63,-78,-19,-71,65,-112,-48,49,85,27,-113,-57,24,108,81,-96,99,-47,-67,-121,2,-17,-29,-9,109,89,-45,-127,122,-59,44,-81,55,-39,5,40,-11,0,61,37,18,-82,-97,-69,27,-45,11,-70,31,-88,117,-98,114,115,75,-104,-3,46,104,-67,21,49,18,95,-8,31,11,55,22,-76,39,-17,24,10,-63,-97,114,57,-46,-62,34,-66,-86,-94,-109,-67,124,68,42,26,-65,-60,-41,97,59,118,55,-104,16,-25,-99,-13,-28,-50,103,-50,51,-77,55,91,53,-17,-82,-108,-121,-54,24,118,77,24,73,-120,-61,36,-63,-122,51,-88,104,22,76,14,118,63,122,-31,-115,59,-92,29,101,-66,-48,-7,30,-5,86,-41,11,-87,71,-15,-30,75,-110,2,91,9,18,101,-51,-102,-115,-83,37,14,-41,-17,-43,106,-108,-42,-86,34,65,57,-13,12,114,25,-69,-36,-48,93,-89,-99,-104,54,15,19,-101,-105,-51,24,-26,93,-2,95,-43,51,-112,-14,-83,69,122,77,20,-7,-29,107,79,115,-102,115,-58,-111,8,46,112,-67,-97,-20,-88,98,-30,75,-47,90,25,110,3,-8,94,70,47,22,-103,-91,-54,58,-12,-38,-50,51,72,37,27,7,-50,-112,31,-14,-76,70,-95,-109,48,-111,-75,118,30,-2,-7,-123,33,32,-89,-47,-6,25,67,73,-7,-29,-93,49,112,111,76,-65,-76,8,-95,45,-79,83,84,23,-96,20,-52,15,-56,-70,7,-58,85,106,122,-96,-84,8,85,-101,35,-30,-14,23,33,112,-86,20,73,-93,-30,-8,-39,-79,-77,-36,-107,-38,-112,-89,-27,49,103,48,127,31,-22,68,100,-35,99,57,74,-26,85,118,-43,101,105,-76,-127,-93,44,-1,68,39,12,93,13,-33,-78,11,85,-51,44,-99,-85,12,-63,98,-92,-5,76,25,-86,-68,-121,-67,-109,-64,31,64,-58,-90,126,52,20,-41,27,120,-117,-86,71,-128,-28,-128,-39,82,113,-102,59,30,78,-128,30,103,-95,-11,117,74,94,113,46,56,41,-96,48,-85,-28,-25,-79,104,-73,3,2,30,76,-22,-103,101,-89,83,34,2,-26,127,25,-82,18,8,-3,-20,52,13,-21,36,90,-38,112,-85,-79,-92,9,-72,15,98,-26,-32,26,-4,-26,-94,-5,112,69,-21,-84,31,-17,-112,46,-83,-24,-105,-102,3,15,-60,99,-123,-6,-47,-120,22,70,125,35,86,38,35,-100,5,89,96,-33,64,-55,29,55,-82,-3,17,52,89,104,126,-125,62,-80,113,53,34,77,83,-65,-28,-27,2,-114,68,-37,-4,89,-94,-41,51,43,-85,-36,93,74,-93,-8,109,-70,-92,114,-120,-63,44,77,102,36,50,88,16,99,19,-9,64,-43,-57,-81,-67,-9,-70,89,-64,53,114,-99,5,87,-31,74,66,75,-37,108,-100,-101,85,-44,-120,-70,-32,92,80,-16,30,112,-102,99,96,-6,123,100,-89,102,-38,102,-90,-80,-9,9,52,-47,-114,-128,-81,-112,2,-40,87,-41,46,119,-15,-107,79,15,105,-53,108,-22,72,36,45,-88,82,59,19,27,118,123,-93,-44,-46,93,-98,105,64,-80,99,-8,-110,-51,33,76,-58,-103,87,26,-13,76,-93,83,-13,127,-4,-54,-52,21,70,20,-93,-7,19,102,7,94,41,14,67,-52,17,23,54,-81,93,76,-61,-23,-92,9,-118,110,99,-128,-53,123,-127,-125,-24,-76,88,63,-79,-65,71,59,-79,-45,-64,-111,-85,-53,55,22,-102,-78,48,25,-67,100,0,72,30,19,56,-6,-54,40,-71,98,-42,127,-46,40,58,34,-6,21,-112,-113,2,-42,-14,-25,-78,12,-55,62,58,-44,-127,-40,85,-80,29,-27,-72,8,73,-36,-32,-21,34,-46,84,75,41,109,-41,-92,123,20,-123,72,106,47,41,-12,-73,-38,117,44,-89,-128,-102,49,-65,-43,69,-119,-53,60,-97,9,-39,-118,-33,28,-58,105,-41,111,70,39,-41,58,90,20,-25,110,-21,50,-114,-104,-68,-35,96,-16,58,98,26,-98,-80,63,74,-85,119,21,-124,118,8,-61,-125,23,-112,30,-77,-11,92,-28,-101,-9,-57,93,-49,32,103,-97,87,-96,116,77,-48,92,-27,57,-29,52,-25,-107,-77,114,-50,99,-79,-58,24,-19,-96,47,-113,-80,8,-72,-83,69,-6,92,55,39,17,21,76,-127,-5,-115,-60,-55,-28,-43,40,-43,106,-35,112,-57,25,19,80,-39,-6,-79,-111,4,-59,121,-77,-103,-89,-113,-127,28,61,-125,-50,58,-38,43,-33,124,41,-105,69,2,99,-31,83,-119,-21,90,38,92,-88,-83,113,56,-56,-49,61,-74,-2,101,-23,-114,26,-95,114,-52,-73,-53,-7,116,32,119,49,81,-88,-102,-49,-126,50,38,-47,-13,76,-73,69,-124,5,-63,-53,11,-42,-97,35,46,29,112,-43,-2,46,83,58,-17,41,125,-5,-34,-96,49,67,-17,-80,-82,38,81,29,-13,84,96,-112,13,49,65,117,23,52,3,49,-43,-26,-88,-97,-60,93,-93,-34,-74,-54,5,-113,-73,64,23,-95,17,50,-112,123,4,-90,-35,103,-41,16,26,-104,-119,109,-71,95,60,28,-71,-41,5,-26,-118,-31,58,-126,-93,-50,30,-48,-51,-31,-92,-2,-75,85,71,-52,112,-48,-65,74,-24,41,121,104,-95,122,-49,-83,119,-20,97,38,23,-73,55,-22,-118,45,-37,25,47,-122,-4,89,125,-105,55,37,102,52,34,-12,7,85,-6,15,17,13,97,18,20,-92,107,79,-16,117,60,-80,-3,-23,-70,81,124,52,105,-36,-44,-125,-81,-40,28,88,-111,-57,-96,-49,-5,18,71,-37,-73,32,53,1,77,-124,-70,-107,-79,33,-83,-34,43,-125,20,-55,-53,15,59,59,71,-97,44,78,33,80,-20,65,-72,68,-125,23,-3,-30,-89,93,88,64,123,-44,117,126,59,38,32,-5,40,125,98,124,-104,-31,-27,-59,98,12,-43,125,-48,-74,62,43,-6,73,19,-3,100,-104,35,-62,47,-8,60,37,-125,-100,49,95,-74,-15,76,8,58,14,20,-85,-56,29,-125,70,94,-60,-112,-56,82,73,78,92,-40,-37,-50,37,22,19,23,63,-49,116,113,27,82,-5,46,24,85,41,-11,106,102,-123,45,60,-108,63,-67,124,114,53,-126,-14,-108,64,-6,-27,-19,-101,102,-27,112,-45,-4,93,-36,-68,93,-111,-64,69,-109,-128,-78,-16,-79,-62,-51,-8,-40,-39,-94,-4,-117,123,70,87,-79,-91,15,18,11,98,-51,-104,-59,-76,40,-82,100,110,102,13,42,71,117,-81,-120,-41,-48,-17,44,-20,-44,-120,79,76,123,-128,-51,111,71,-41,-86,-76,-32,80,124,-43,-65,123,5,21,5,55,73,34,-46,-55,-108,58,116,110,59,85,-61,-24,111,-86,-34,-128,59,-111,45,-125,-47,-94,-90,48,-56,-109,-95,-37,79,-127,-17,102,-96,-52,16,-77,40,31,-59,-93,10,-26,-28,108,-85,-2,95,-25,-94,-88,120,30,-69,-24,-9,90,67,81,-92,123,42,116,12,123,86,88,-86,10,-77,-16,54,-119,-43,-54,-7,104,-75,-111,-3,63,-95,-96,112,-68,68,80,-128,3,-37,-13,74,-113,-88,62,-32,-40,55,-48,-21,-64,118,64,-126,-41,-75,-79,-112,-78,19,-81,20,-10,97,86,-20,127,56,101,118,69,73,-62,52,125,-84,-15,-30,65,-53,105,-59,-54,-87,87,87,-116,-120,49,71,-48,99,-108,-19,-107,-40,-98,58,86,-125,-119,-62,-38,91,23,85,-55,-31,52,123,-76,77,120,49,122,-19,-118,-56,86,-15,-74,-82,47,-83,-121,21,-69,-86,119,-39,59,87,-84,1,19,-67,-58,-122,-45,-38,54,-96,-13,-91,100,-118,-97,73,-72,-30,23,-30,-121,-36,94,20,-38,22,-4,-7,-85,50,114,95,-105,35,-85,-89,-41,93,8,45,-53,87,93,30,117,17,-61,-61,69,48,-52,-99,-75,-104,-113,10,-27,80,89,107,119,-76,-30,125,75,122,55,8,-13,-37,-37,24,13,33,31,-14,98,101,-51,27,24,37,-51,-15,110,83,-49,85,-122,-30,18,92,-17,101,12,-54,97,-99,4,-82,73,-46,111,-7,29,-75,90,-91,106,45,68,68,-111,-63,99,-74,86,-122,-35,-28,21,-22,74,-70,-80,-93,50,14,-9,-84,45,-41,-18,-50,-105,82,-94,-89,102,-38,74,120,90,-17,43,-82,-83,-17,-119,-106,52,-63,-80,123,124,-118,75,98,0,-76,-100,77,-72,80,-18,-49,61,107,100,89,-27,-70,93,-52,-68,-46,-89,49,-9,13,-77,-29,103,-69,-52,-88,-65,39,-33,-119,-105,96,29,48,86,55,-76,62,-128,5,109,73,-94,-43,-11,-82,-32,122,52,33,29,-40,63,-89,-88,-16,77,67,-69,-59,-106,112,59,-67,6,-92,-115,-120,107,40,38,-33,69,87,81,8,9,9,-31,-68,-110,113,-117,-81,44,-62,-85,-23,77,-6,84,-126,-63,58,105,75,-48,38,80,-45,-2,34,-62,-8,107,-16,-82,-128,-17,57,-113,-99,12,-110,-47,-44,100,-23,121,-29,42,34,-64,-124,100,123,105,-128,-7,117,5,-13,13,-125,112,-4,86,53,-128,-87,-81,-75,-18,-77,116,-110,-122,-60,100,-124,117,-35,82,77,87,125,29,-127,123,100,-54,-117,-100,-105,-49,-77,2,-4,-110,-101,6,63,53,-103,76,-40,-118,108,-103,122,52,-3,54,-86,57,65,86,-106,4,-99,82,-44,68,15,-41,51,17,4,92,-63,22,-83,-126,65,63,-115,76,80,-109,-50,16,105,79,-115,96,34,-71,-61,-89,98,92,-36,-88,113,56,18,-123,32,120,110,81,-29,108,-31,34,-24,-102,-33,-8,25,76,-128,77,84,90,76,-98,-4,-104,-105,-65,10,-62,29,-80,89,-116,120,101,22,-36,-85,77,3,-44,-107,63,45,-19,-126,16,-29,1,31,-125,-108,113,30,-103,-38,-127,26,-18,-56,-120,-121,32,102,-25,-7,-85,47,-50,-121,-109,-6,-127,-34,55,-114,-34,82,-6,-44,83,-2,-69,-34,101,-21,123,25,33,-23,-108,-107,-46,-46,56,-30,38,108,106,60,-31,-78,8,25,4,124,12,29,37,2,89,100,40,-48,21,-87,-53,109,-116,-46,77,-60,-64,-68,122,-25,-109,-71,28,62,121,-84,-73,80,12,-118,-88,-89,109,106,-74,-62,89,58,-65,-73,-74,-64,-110,-73,-27,96,-87,-128,-122,-72,54,42,22,73,-37,-87,6,29,31,-46,62,-99,23,63,114,10,-20,-43,68,-24,15,124,-63,76,-25,-12,30,-86,-43,38,111,-121,69,-5,-49,34,-42,-51,119,39,80,86,-32,27,-74,-71,-24,73,-25,74,-11,53,104,117,87,-32,-11,-115,-24,99,-78,-7,-113,-99,-76,112,-20,121,50,-9,-103,-10,111,-68,-9,-35,96,-108,10,-38,2,-18,-73,-64,90,-105,94,103,-22,22,116,99,-68,-42,124,-122,-117,-119,-43,-6,47,72,90,-52,52,-76,2,-22,-84,-19,-85,-124,92,13,-115,36,2,107,15,127,-76,47,-39,-109,3,90,-24,1,-74,-29,-17,-27,-21,32,102,26,-57,-108,-114,-112,-104,76,-47,-17,86,-86,38,106,114,-81,-77,52,67,-28,-68,-63,23,-57,-110,-81,95,-35,-97,-29,-96,-11,64,-1,-118,-99,-25,-24,68,-118,-84,68,-113,94,-39,77,93,-80,-1,12,-123,97,80,111,-117,-52,5,-24,5,-98,-27,48,-96,-37,-108,70,-28,63,-21,123,23,67,-33,-96,47,-58,-50,-124,-109,-64,20,-37,44,-101,34,95,100,94,-57,39,-4,-21,-62,-76,-37,-72,-51,10,114,-21,113,45,-68,27,-77,47,105,18,122,-117,43,-99,-82,40,-15,-7,112,27,-86,-37,83,-8,-53,1,-110,47,64,-58,44,-50,14,18,-33,69,-17,-90,51,35,-58,-103,29,100,38,107,-44,-99,106,-49,-90,23,107,-44,-79,7,-21,-10,40,-76,-58,-50,-106,84,-47,34,91,-9,23,113,114,-11,-91,-62,64,20,58,44,-76,-105,-55,38,-101,121,94,-125,81,-55,-128,-101,-22,100,78,43,94,-46,118,-103,-36,81,48,45,90,-3,2,44,-8,-66,-49,104,116,-90,-69,-78,28,-65,15,-31,103,-71,14,-103,-90,-54,36,-81,-62,70,-35,-60,103,-13,45,20,-32,-93,127,59,127,-54,-89,-23,117,48,77,3,-84,-35,-56,37,87,60,-115,11,-27,44,103,78,-16,-112,-3,-44,45,61,-112,-102,-104,88,-67,102,121,-106,104,46,-39,52,-91,-77,-13,-79,118,-52,61,-90,-5,46,24,-59,-84,57,-34,101,-62,47,-66,-18,122,28,102,32,-123,-19,121,81,12,-110,89,-78,-38,8,-78,-94,-2,44,111,-36,-2,-66,22,83,-59,-43,92,60,-29,-71,92,-51,7,19,-2,39,-66,-100,116,-78,92,7,124,103,107,127,-115,80,62,99,98,-95,-74,109,-3,59,-126,-61,-93,11,-58,87,-24,100,113,21,-65,-71,-103,-106,122,96,-71,100,-38,-118,-23,72,0,-55,-68,-108,88,73,82,119,-105,-90,59,-41,99,37,76,-41,-62,94,18,-37,67,68,56,-41,110,53,-24,14,-62,38,-121,-84,13,48,48,116,-17,110,-80,-63,50,-4,8,111,-77,77,-4,112,19,-9,64,-32,-45,72,77,-90,-127,88,74,-61,-85,63,-75,125,-46,-15,-86,79,116,76,7,46,-99,36,14,-55,0,95,76,101,-115,67,-18,-35,71,95,-104,8,-124,38,-42,13,-70,18,98,77,51,-82,-27,-61,-66,2,26,2,-26,-61,-119,-70,44,114,27,99,-99,14,97,34,63,-88,-44,65,82,30,-47,-99,-97,13,-13,48,47,4,117,-29,37,11,-7,28,78,41,-59,-94,8,99,-125,32,-109,14,-13,-58,11,101,100,-94,-61,45,-49,90,47,84,77,19,12,-24,-86,-63,112,-48,73,4,-91,54,47,3,67,5,68,-26,-64,110,-71,113,-96,105,23,-14,-79,-18,67,36,-35,-36,48,68,-33,-5,56,39,-56,-20,-11,-43,6,82,-33,121,29,8,-78,28,-29,-101,-76,-81,116,-98,-72,97,-16,107,123,-89,-47,-84,102,-113,-107,105,-24,-112,-67,-77,-41,-18,29,49,-19,54,49,41,20,63,84,15,103,33,50,-25,-118,42,87,61,48,-48,-121,16,-74,-85,-13,6,-14,-76,82,90,-68,-4,-40,2,17,-101,81,-80,102,-2,-64,-54,-74,8,7,-117,99,21,21,-50,74,-36,-89,-75,85,-35,-29,-105,2,-55,2,28,71,-118,53,126,-84,2,9,-20,-104,45,4,76,-113,10,124,83,81,88,50,95,66,44,-110,122,17,30,92,-85,26,-53,73,-78,-32,-127,5,3,34,-75,81,54,-15,-13,9,-42,-126,-102,7,96,119,34,109,6,67,-70,116,9,-26,103,19,-9,116,88,-12,-88,39,92,85,91,-87,33,-43,120,96,-59,-53,84,12,-18,-68,-87,3,48,-99,-28,87,21,-88,86,-93,116,63,33,100,-65,-56,-36,-36,-38,-80,-97,-62,-87,66,-65,77,103,85,73,-99,103,102,104,-80,-70,60,-96,-6,-67,1,-1,-44,90,-80,93,-59,39,-81,66,63,-35,17,-58,-56,-49,83,71,-80,-54,-111,92,-7,-48,29,-7,56,-107,-114,-75,21,54,-124,-3,-60,-78,-13,61,-110,123,80,-49,96,-105,-115,-29,112,-68,126,-87,-74,82,70,16,-70,-84,53,22,-16,29,-40,-90,-47,14,-117,-3,6,-13,64,-84,87,-100,52,23,-57,108,74,-37,59,82,45,87,20,-65,52,57,-96,-61,2,-39,-33,78,-79,84,-61,63,34,37,27,-13,12,101,32,9,-16,-19,21,59,-119,-97,57,-124,127,6,76,83,80,-31,27,102,-105,118,56,85,89,98,16,-57,68,3,6,58,-95,-77,-78,26,-26,5,-21,-113,23,-110,90,-16,35,-23,-108,-47,-14,102,-42,119,46,58,10,83,-117,80,-49,-38,-58,25,80,-85,40,-54,-2,-35,-100,-80,-77,87,-122,-45,-94,-115,63,86,-10,84,-47,-114,101,123,111,-75,71,-111,-47,-35,43,-99,-22,106,-3,-89,-94,111,22,-52,95,-17,104,71,96,10,7,-99,-90,32,-38,-81,-7,-112,30,-16,-11,106,-104,-30,78,99,-110,30,-31,-125,111,-50,-19,-50,-66,109,-113,95,26,-74,-86,-66,4,70,-4,-14,-2,-86,-83,48,118,-62,-30,-78,-2,102,-105,-45,83,37,58,53,100,-66,46,-25,-104,125,-112,89,49,95,75,22,88,19,-76,-35,101,39,20,54,-82,61,-40,-83,-106,32,-106,116,-80,-52,-45,-86,-126,-56,-71,108,52,70,39,103,-24,71,121,120,117,9,5,110,-97,-79,-39,-56,77,71,-90,-97,3,-8,-64,-102,-5,105,59,-100,-76,-65,-99,-6,-7,85,115,112,14,118,65,10,-60,116,68,69,-83,-118,23,24,13,40,68,-78,-2,-43,79,96,-63,-5,-19,-56,19,94,-79,-7,96,19,-93,-47,31,30,22,43,89,-104,61,-49,29,-111,61,121,-41,32,116,-17,121,-109,-51,7,51,-6,-80,-105,-84,-41,88,16,-61,91,115,-25,69,-80,-12,-70,45,80,75,-38,-22,111,15,39,-71,62,68,40,-51,11,-9,44,51,29,-27,112,-106,-95,29,-114,-105,68,105,-68,-109,-13,-82,51,33,50,-48,-103,-65,-46,13,-51,-29,17,54,-91,123,108,-73,-120,43,27,100,32,-13,52,123,-52,33,-43,-110,-76,-79,-30,-86,109,-90,49,103,39,-28,-52,41,0,106,-13,10,-57,124,-15,10,74,-124,26,91,-63,114,-48,52,83,11,-44,95,-23,13,-57,114,-108,82,96,39,27,-34,29,-60,99,30,5,-101,117,-128,-74,-47,-33,-118,-69,-121,-112,-18,20,-6,-35,117,-80,-35,109,-102,24,-33,47,-5,-13,101,4,-127,25,1,-117,-57,-65,74,-64,-107,125,0,-78,-60,110,-100,-1,-19,-63,27,61,-17,-75,-84,-29,-56,-25,21,107,46,88,-33,-89,109,83,-83,-100,-121,-55,-48,-3,29,28,98,-64,-59,-73,-65,-63,-86,30,92,-29,4,65,-26,47,-111,1,-21,26,-109,-86,-119,-1,113,-29,-88,77,75,-54,-35,22,-95,24,-40,127,80,-56,-24,43,125,-18,97,-77,-32,61,-85,69,-105,19,9,65,127,10,9,90,-76,-37,-2,-18,-15,-57,2,27,11,-51,109,28,17,2,90,69,22,98,-55,-63,-53,125,48,-13,44,-96,-94,-116,65,88,-2,72,76,61,79,12,64,-112,-11,44,72,-103,-29,106,-24,78,91,72,-93,74,-123,-36,-121,4,79,92,-28,83,-109,-98,-99,63,92,98,-39,94,-43,-57,10,83,-23,92,50,79,-111,-32,-79,40,-34,-26,91,115,-124,-19,68,-72,56,60,-101,-73,-55,36,-83,-59,-86,-73,3,-98,-85,3,103,10,-113,34,53,-90,112,-114,-122,26,46,58,52,51,-101,-1,29,-87,-108,-77,25,-51,0,32,97,-36,57,67,117,-124,-61,13,-67,8,-108,-50,-59,28,95,-112,10,124,105,-54,-127,-43,-86,-50,53,-1,-108,-111,65,35,-42,-28,-119,-47,-92,-97,15,-50,12,63,-42,10,-71,22,-23,83,-24,-28,20,69,114,98,108,29,3,-42,123,-101,120,13,-36,-44,87,15,74,-89,77,56,-23,65,-12,19,54,66,-31,-16,-111,109,-43,111,-87,69,79,-8,124,-17,-46,-48,15,61,-28,108,-72,-58,-55,53,83,-80,118,43,-88,-54,74,-102,-38,56,116,-80,-125,-75,-3,105,43,88,-66,117,-120,-58,82,74,-5,6,78,-72,-79,-51,85,-49,-100,123,-42,4,90,-33,-55,88,127,60,-115,20,-123,123,117,9,-75,122,-19,-97,-98,-15,90,-32,92,94,-86,41,68,93,106,-60,-41,-80,40,24,-91,-86,-39,73,-120,-27,125,-87,65,-123,-41,-9,35,113,91,-40,-111,2,5,34,83,-66,114,-111,90,57,126,-93,62,-117,5,60,-68,11,-105,-35,-33,51,-52,-45,97,83,117,36,-81,45,59,-43,64,-62,69,-95,110,88,102,-125,107,-97,43,95,-122,4,1,-51,25,-12,43,-22,100,98,-64,94,64,-74,45,-38,-46,102,-21,-37,29,-123,-104,119,-2,-40,115,-31,15,2,21,-115,75,82,-8,18,74,8,27,-80,90,88,10,37,-104,-1,-82,77,80,-97,-99,-105,35,40,110,-49,24,99,-94,43,20,40,-40,10,113,-71,43,-63,-22,77,64,-3,-79,-82,-44,-53,23,86,110,-124,97,-27,-106,-95,104,-96,-121,25,-14,74,54,120,72,107,-128,-9,-60,21,49,-67,-12,18,-30,-33,-91,77,40,38,33,-70,7,-43,-89,44,-12,111,-108,14,36,-15,85,112,-85,-109,-48,98,57,100,-17,85,-123,-72,-111,60,15,-124,11,90,-105,7,-107,-121,91,-10,-98,83,-116,-10,54,-128,64,59,38,64,-25,36,-17,101,-96,-108,67,-89,46,20,26,126,-71,-1,0,77,32,-72,-31,-29,44,-14,-8,-74,42,-11,-21,95,119,84,123,-128,30,27,20,-74,38,-11,-122,41,94,-51,-33,-115,45,74,7,80,35,18,-30,-101,-6,95,-92,-69,33,16,15,-59,-111,3,-67,-86,28,-43,40,68,27,-111,-95,-26,98,38,83,106,-126,-34,86,-54,-102,-110,-88,38,40,-37,46,81,11,-122,-8,-46,30,112,90,-40,95,-61,-73,77,-123,-44,105,32,-109,-110,81,-23,127,-83,81,-55,77,62,-44,-33,-70,-62,4,52,115,32,-36,-96,-123,-33,86,127,86,38,43,53,21,106,-125,-69,-16,84,-98,-80,-12,17,-25,-70,-72,34,-33,-115,-119,48,42,-34,6,91,-18,-19,22,0,46,-92,-27,106,-116,35,78,44,50,-110,-113,7,14,18,-123,22,-112,113,-91,-51,-17,88,-83,-51,-19,30,28,109,-64,-114,86,73,-33,30,-1,-121,-58,51,-109,86,104,89,119,-76,-28,-90,-95,-100,69,-55,-23,-14,58,-112,30,-77,125,72,-99,55,39,67,54,-6,4,52,50,92,-47,-26,6,76,3,96,89,97,126,80,-80,-100,-76,67,-119,-36,58,-13,16,53,53,5,123,106,31,33,-67,111,-27,48,7,-111,23,-110,-42,-16,-105,38,43,51,-17,-12,-98,89,-32,3,64,118,65,21,-66,-1,-93,-115,93,-75,7,-25,126,59,107,-19,-26,14,-107,75,45,-16,-110,-34,50,2,-11,-109,19,-61,125,-94,-63,123,-24,-11,54,-115,121,-16,-39,98,2,77,102,90,52,-110,-55,109,-119,-47,-121,116,119,65,68,6,6,22,103,-121,49,-117,119,-38,-90,124,-32,104,90,109,-16,-100,-92,61,-115,-107,60,-26,93,27,111,-124,54,-72,-77,123,-79,89,-89,-54,-94,108,59,-49,78,-108,-4,-28,-119,55,42,36,95,123,-7,-99,-42,-100,-6,91,-65,-24,32,-77,106,59,-5,-93,-100,115,35,70,-90,-7,-6,40,-20,105,76,-32,-74,77,-32,-91,114,49,-126,-83,-81,84,113,80,-69,-99,-13,-29,-103,102,-69,-108,-127,87,-43,-11,-126,-113,119,-104,-11,79,62,26,-90,-22,7,-64,-107,77,77,-83,24,-90,52,-57,10,-22,114,-38,115,-37,-52,-63,-76,-13,94,-56,-96,78,59,33,85,-82,-97,10,74,-95,-113,-78,99,-66,50,4,32,102,69,20,-76,-69,-57,-26,5,-105,127,94,-72,-19,-117,-7,-38,24,-91,59,86,91,9,-58,126,-81,-126,-39,28,35,124,101,74,120,-90,54,14,-31,-108,80,94,-40,50,-56,26,-5,19,-37,-39,-45,-117,9,37,53,83,-73,-22,-107,-102,-104,38,-126,-125,90,-106,74,-98,72,21,-76,-56,20,109,29,52,-45,-42,-51,51,-1,122,91,12,-18,-69,55,-3,51,-111,-106,123,11,-108,-93,51,96,-100,91,-87,-51,70,-39,15,-81,35,62,-54,-87,33,-64,-125,-111,14,-109,-89,70,-36,65,-122,-47,126,126,-119,-49,-34,46,126,-87,88,-117,-107,119,29,-65,25,-89,62,-89,-88,-117,103,100,9,-36,56,79,95,-124,66,-5,-126,-9,9,-95,-95,-93,54,-2,-54,81,-106,21,-25,108,105,-37,-9,-97,69,122,84,39,-124,98,59,-25,-67,18,35,48,-105,117,78,-75,-42,3,-76,-107,76,79,3,-81,-61,30,-99,-99,101,-118,-94,112,-88,-19,-82,103,-67,76,-71,-105,-24,-91,-20,83,90,120,-7,34,-26,-110,75,41,62,-116,-77,23,109,107,74,-78,94,-125,26,-13,27,99,49,77,-73,100,87,77,0,88,93,-23,-115,-36,-108,-24,123,-65,-60,-63,-44,0,19,102,-19,89,69,85,-96,88,-103,123,108,119,-68,-99,89,11,-56,116,-106,97,-68,6,-60,47,52,-1,-53,94,-55,-107,-3,-9,-105,-3,-21,-69,-37,18,-59,78,37,127,118,107,-117,-79,-43,-108,124,33,-121,-25,52,-71,76,64,-2,27,-52,68,88,14,25,-115,57,30,-36,-16,63,-75,92,110,-57,-105,-82,-21,-72,30,113,-92,-20,-15,-77,-20,-25,106,22,56,79,21,68,98,115,71,32,20,122,-70,112,38,62,105,48,15,115,47,-124,48,-71,-41,-85,127,-6,9,122,110,-68,-45,-35,-21,-103,122,30,-70,42,68,9,83,13,105,110,8,98,-42,93,117,-26,21,-42,-82,27,110,-123,10,-98,-5,22,29,-112,-32,109,31,7,-91,22,71,-56,60,29,-126,4,63,-64,-77,74,-53,92,-7,-54,-128,72,-20,-92,6,-89,-20,52,46,32,-94,-119,-90,-92,106,74,22,-50,88,-69,107,8,3,55,-102,-64,28,-106,74,13,96,97,110,-59,58,83,-95,-49,-106,87,71,9,-19,125,26,-26,-93,-28,-52,20,-63,49,-73,-11,112,14,121,-65,88,-128,4,72,-117,-29,-74,-33,21,102,125,112,-49,-82,-7,-28,82,46,-71,12,118,4,121,97,16,28,85,50,78,-24,76,74,107,-47,-67,63,-94,-112,93,-59,-48,-32,119,84,108,74,52,-113,-17,-96,27,122,-67,23,-10,33,-63,-54,49,57,-103,-58,54,20,102,-18,-78,-125,62,20,109,7,-20,107,31,-85,5,104,81,-61,98,51,125,-32,-90,125,-100,6,64,104,56,126,24,-86,109,23,-100,15,23,50,22,-83,30,-128,-82,123,-89,14,-48,-82,-36,-92,-65,-12,10,107,-61,-124,-36,-75,49,0,-105,26,119,101,120,-37,-38,-89,18,-55,-47,-118,-92,-17,48,-14,-50,-72,112,-100,-125,-106,-114,126,-23,-105,-41,102,-7,-5,87,-25,71,-111,-11,-76,-106,57,-84,39,-28,123,50,47,-23,-66,-101,102,-65,103,32,10,84,82,34,32,-112,-14,-125,-109,79,28,-18,97,38,56,-36,-70,-6,-78,-80,33,-120,104,68,27,41,93,-95,125,90,-18,-97,-33,-102,53,-79,4,-27,30,-51,41,-72,-74,92,-102,28,-56,114,122,-105,121,8,-51,63,-117,126,-56,-127,-126,49,84,30,-76,-13,-45,53,57,3,34,-85,49,-112,41,-71,127,-111,22,-114,-34,38,-45,44,97,52,4,-111,-35,-98,-24,-53,42,74,-118,-86,-19,-119,-52,-88,22,-89,119,71,112,-21,26,52,35,126,65,117,-110,4,47,-66,21,-51,-8,-72,-120,-107,72,85,3,73,72,-27,-36,-114,19,71,-89,-100,-111,116,-97,87,-53,-68,-121,17,-29,-60,-28,116,-64,11,45,-83,-125,-55,71,-3,4,-123,53,42,-122,-45,104,-22,101,81,-24,-37,49,91,-2,-77,44,-72,-64,-100,-80,-75,-26,108,-102,19,-107,-51,-23,-11,-4,118,-18,-18,125,90,-84,41,8,-54,30,21,-91,102,-115,-99,-35,-35,6,24,102,-108,26,-8,39,1,-93,76,124,28,-9,114,-39,9,44,72,-72,-24,67,-41,-3,-58,-92,-31,-57,127,29,36,16,-1,-87,-124,-34,-23,57,118,-38,-19,51,121,15,-44,-2,8,-87,-47,-82,71,-14,-41,16,48,79,118,17,-83,-84,-62,5,-127,-20,-12,28,54,-95,-89,115,124,-18,40,-118,-125,-97,3,15,89,-21,45,-19,23,-58,-1,39,19,-18,-121,127,-46,2,38,-24,-64,-48,81,19,-16,80,-128,-37,123,-43,-73,36,-127,55,121,-62,14,93,56,42,-117,-43,-99,24,-79,-46,-112,-34,-99,38,-19,11,23,-70,-128,-121,-81,-110,88,-76,-53,-51,51,-128,52,54,-80,-58,-35,83,10,20,27,-109,119,112,38,-19,97,120,67,24,51,-65,84,37,112,-8,67,6,-104,-127,-50,118,-1,58,-97,-94,-103,78,10,30,-94,-95,-42,107,-41,-67,-39,63,27,-108,91,21,-88,-23,-118,-55,-28,-1,-9,16,-37,-29,-55,-80,-82,78,-112,62,46,48,-41,1,50,34,12,-53,123,46,1,37,108,71,3,41,-94,-123,-50,-16,-42,8,86,-39,-24,51,119,20,22,-55,115,-82,-86,114,-110,8,-72,-15,74,83,93,14,59,122,3,107,-17,93,51,41,-56,-125,28,-21,38,-59,71,69,-48,111,79,38,-29,-23,0,-17,-110,75,113,87,32,50,4,-113,-4,12,-27,-20,-61,-41,-56,-117,-99,-77,-87,115,-99,40,-99,-95,-31,26,119,-102,-53,2,29,4,-21,-86,112,94,-82,45,-65,23,-23,-85,-17,-97,100,75,116,-110,1,-109,-111,29,80,-90,93,74,3,95,112,-48,-106,-18,25,77,-29,-22,72,-117,94,9,95,113,-1,-104,-124,-28,12,97,-109,66,33,-94,-29,91,-88,-102,77,-76,21,-65,95,51,54,-16,-116,78,78,-79,-107,-51,-123,2,40,49,-124,-90,64,97,-3,-105,14,71,-114,112,124,3,-83,-105,-50,94,35,59,-63,73,120,-43,116,16,-91,-46,-18,-117,-108,-26,84,-84,75,123,-97,-21,-118,-119,72,34,-59,-108,-104,-65,21,70,63,-108,-35,-26,-11,-63,-55,53,-81,-125,-58,-115,-16,-54,59,7,0,-12,-67,126,-72,81,-118,-76,-13,121,5,27,-23,80,87,-125,-14,-85,-37,-6,-79,-56,-118,-19,-45,-43,72,71,-49,-91,31,-121,-90,34,89,-22,116,46,-62,-59,49,-4,12,23,40,-39,88,-54,120,12,34,26,-7,42,-18,-89,-37,67,123,61,-91,74,-36,-38,-104,15,113,46,54,0,28,100,-75,-44,25,-56,103,28,44,-92,-100,34,-113,28,-16,-75,-121,-7,58,38,-99,66,-2,-20,-122,-19,11,110,-58,45,17,-72,38,-45,41,6,64,-86,44,36,91,-45,-93,17,43,-73,-70,-41,52,121,53,-71,-90,14,110,115,29,36,-75,-46,92,97,-53,102,-88,-32,122,53,-39,20,-102,55,-101,117,-26,82,14,46,-91,-120,85,36,-108,101,-81,-26,115,-18,-50,-47,18,7,-125,-24,33,-46,-24,-108,33,-71,41,99,-66,47,-43,-25,10,117,53,-2,-14,10,126,-112,-74,104,-77,-57,-30,24,81,93,69,115,89,10,34,90,88,-116,65,-90,72,43,51,123,-85,55,-12,8,13,10,-37,-90,123,-4,40,109,105,112,64,99,-74,-83,44,104,-20,-16,25,54,-82,-54,-109,64,-37,-3,-17,107,124,14,-64,60,-47,-72,40,-84,-74,89,36,6,-98,-125,63,30,14,-70,-62,109,-38,112,-41,127,52,115,-56,27,-112,76,-65,-107,-118,26,-53,-74,-96,114,78,-120,24,77,60,48,29,49,-15,-117,-91,1,58,-26,-84,-9,-115,-109,-89,-21,104,82,36,116,121,-103,93,-50,-103,-39,37,52,-28,-108,49,-87,-93,-115,38,-37,-28,-68,14,-26,19,-41,107,-2,-37,-107,-49,11,-120,17,24,24,-100,-110,93,46,-122,-84,38,6,-7,-53,98,102,35,65,-8,-6,-99,44,86,-5,-4,67,-65,13,23,66,-111,24,7,19,9,-92,114,29,58,-43,-61,-105,-33,34,-26,-57,5,-11,48,77,0,-41,22,-49,-20,-44,-99,-30,10,45,-51,47,-29,20,-61,-11,104,99,21,-15,-67,44,108,-71,-83,-11,57,-104,39,-84,122,2,14,127,5,-110,-79,98,23,95,89,3,-87,68,94,-9,104,40,107,24,26,-97,-36,-111,-100,-95,31,-97,77,49,-69,112,-111,-96,-45,89,127,-9,114,85,-5,-102,16,-1,31,-53,-69,-53,-6,113,84,-6,62,-18,-44,-73,-15,68,-105,-36,127,12,-27,-28,-42,-31,51,-121,-19,86,-111,-86,93,-119,-74,67,51,32,73,35,18,-106,70,44,-82,72,50,-19,98,-45,-60,-84,-84,-67,-126,-5,-67,38,-2,-62,-23,-54,-110,113,-89,-14,52,28,11,-61,4,70,-35,-100,0,-46,-11,-124,49,118,-80,39,-70,-100,-54,-120,-69,102,39,59,16,-49,-50,53,-27,44,-115,90,69,-102,65,-113,20,-47,-115,59,127,-19,-19,-54,-27,-28,39,-94,65,-114,75,-115,-46,-85,-4,75,-67,127,-98,27,-42,1,-43,-124,22,-21,-74,-27,53,-45,127,-90,-83,-44,-23,-86,10,36,59,86,99,-126,-59,108,-99,-45,91,-16,-33,110,106,-120,-87,19,115,122,-86,85,-83,67,-4,-57,4,-111,-5,-58,-2,-91,95,11,107,-53,-68,-128,-12,-68,85,19,-40,-36,-56,10,58,-64,-12,-32,20,79,37,-65,-9,-33,88,123,94,114,31,67,-2,-32,86,-124,-62,-116,-100,41,35,-17,-81,67,-85,-110,83,45,5,-121,-120,-3,14,47,-65,-78,-87,-114,-9,-19,-7,-21,106,74,-40,117,78,-33,61,63,-70,26,-9,56,76,-121,-77,14,87,-125,-32,69,-101,50,104,30,-59,-117,80,43,-98,-11,-23,-94,-108,52,97,-38,24,-10,125,-41,-119,-19,-56,-42,25,65,-39,7,-102,-4,109,110,74,18,-126,13,96,95,99,-89,15,-3,6,106,72,35,-78,82,-15,73,61,116,-127,-83,98,54,-17,2,88,-7,-57,-37,-102,-39,-79,31,111,-6,-62,-24,69,103,74,113,65,-15,68,37,123,-65,94,117,-32,-121,-78,-5,59,120,104,60,5,68,-65,4,-85,64,-80,117,61,-101,46,-88,-123,69,-19,-57,97,-15,125,54,84,-23,-124,-27,-47,114,16,104,44,-100,-87,36,81,-27,-20,-73,95,-80,-64,-34,-77,29,66,-126,-120,77,105,-100,44,79,116,-18,-27,-15,-71,19,-80,12,-18,27,-92,45,116,-27,14,-14,-77,1,-110,-40,-26,-4,-88,-120,60,51,-101,108,-123,116,111,-83,1,-74,87,-69,11,124,93,2,-64,121,62,-45,-79,110,-55,-37,97,27,-79,110,-91,67,53,99,26,-74,98,43,9,-43,80,-103,-23,60,-36,68,-112,-64,20,-31,-52,-79,-113,-7,94,-30,73,-100,55,-111,87,-1,-29,-25,42,-94,-13,-63,108,-59,38,-16,-85,-62,-17,0,47,-90,116,-80,-11,12,-54,96,-110,-12,-6,-128,-31,-64,-109,103,-11,58,-118,-3,-102,0,64,39,-67,-18,93,95,-87,102,104,88,-31,-62,-36,-61,-105,-26,46,-53,93,117,-70,-54,121,-103,52,-24,-10,82,-124,-22,29,-122,84,-76,-64,121,-65,-6,52,80,-27,7,-118,108,64,-82,73,-44,81,-107,-88,84,-100,-59,9,-56,35,-39,-68,-82,26,65,-73,-66,-15,75,-44,-31,51,-65,-62,-73,100,51,-51,78,-112,-84,-19,82,93,-92,53,-69,-38,-66,5,127,-30,61,43,26,48,-63,31,24,-71,-67,-60,-127,-55,-26,-43,38,-63,-49,-101,-37,116,105,10,-109,3,-67,-42,17,-89,110,-103,62,-41,78,-59,-47,-47,-17,10,-51,-16,-31,-41,68,37,15,94,-123,101,77,-122,116,61,-96,-8,-122,-11,105,109,-74,-97,-111,44,114,105,45,-94,42,-99,-52,-113,122,87,-59,85,-109,-128,120,21,-49,-75,-89,11,-10,120,-51,30,-19,-79,-26,-32,64,-71,28,-44,-11,55,-28,59,109,-84,-22,-113,-55,-105,114,50,80,-26,77,36,54,42,-71,-111,-64,118,99,-100,-121,-128,56,-10,-75,-74,30,93,36,-122,16,-105,-50,85,19,-99,-84,-72,-20,-63,96,75,-53,-86,59,90,-23,-73,-39,96,-118,-9,-127,-106,42,-122,-84,108,-18,29,81,-58,46,12,94,-2,-94,33,-75,85,61,122,-100,2,101,45,106,-49,-43,22,-63,-128,94,-115,5,38,35,-8,54,15,35,-114,87,-76,110,-50,37,20,-114,115,84,-13,48,14,54,-58,-93,43,112,77,9,-99,32,-91,-55,-82,34,23,-40,62,17,66,84,-3,82,117,-100,32,33,19,-100,93,102,101,-33,112,-103,-38,114,-1,38,-89,-90,-9,-86,-101,-66,-71,41,-113,5,-40,21,50,89,123,-73,5,45,68,-75,58,-107,3,-67,-64,89,-117,45,51,16,36,-119,69,-78,94,-18,-18,61,-124,22,97,-55,112,-97,19,119,65,7,-109,23,88,-15,-47,-103,-62,-84,106,-5,73,-108,-109,34,33,-116,81,-41,81,-102,67,20,-46,67,-40,-9,-49,10,121,-57,-33,61,28,42,-67,-36,-113,-38,-89,-94,-67,-28,52,-17,-116,-96,117,-51,29,-84,-38,-53,-53,-44,-110,54,98,-76,18,117,83,10,-36,-62,102,104,124,80,34,15,47,108,91,-112,-116,-10,66,-68,55,-123,-67,87,74,51,-47,25,-34,-122,57,32,-96,96,-64,67,31,-41,-124,-87,76,-15,-125,1,13,-77,99,47,74,-44,97,67,108,-4,-9,-16,36,44,-53,3,105,-120,99,-55,-30,-34,118,8,40,106,-95,-122,14,-65,-23,86,-64,-26,114,89,97,-59,-10,71,-108,10,-60,61,-87,-19,-4,-28,-32,-1,35,-123,109,55,-47,-126,-124,-1,-36,120,-107,3,-17,121,31,-80,25,79,127,-32,-19,103,118,-4,21,-55,125,70,-95,-104,-2,-78,-24,90,97,-33,-79,-92,126,20,49,60,41,121,56,120,-102,113,74,1,44,-28,46,-19,100,-46,-127,77,-8,-64,-12,-13,-15,11,89,22,86,-95,36,-105,84,110,-83,37,-56,-40,-92,19,-17,-82,-25,83,4,33,-111,76,-54,-85,35,-107,127,-72,76,89,-123,-103,28,-96,95,-47,77,107,-98,-35,52,59,75,-76,87,-14,-27,-56,75,117,67,-34,91,-92,-45,-95,-116,-13,5,-81,-35,83,85,10,-112,-38,89,117,43,123,-43,-73,104,36,-80,-106,47,113,51,-82,36,93,-84,33,11,-53,-84,-128,82,-86,0,-118,-33,-6,-122,44,35,81,-44,-71,-73,-64,98,126,-20,-49,-104,-126,46,44,-17,-63,-62,-74,-48,-61,-28,67,-99,-25,92,66,-38,73,49,45,92,-69,-26,-91,105,80,-30,48,85,-76,108,-98,-95,-56,102,47,-70,6,-118,-31,-112,60,-62,89,-78,115,-85,4,-1,36,72,-17,-56,-100,-2,-104,-54,24,-56,-92,-60,-106,-115,-53,49,-106,85,33,54,-79,-77,44,47,-120,41,-60,-8,44,-28,5,114,90,42,74,-57,106,-81,79,-67,83,-97,-90,-16,-120,-57,-88,9,34,7,-107,-92,-59,40,71,113,-32,-85,89,89,33,-58,-78,-22,-50,58,96,-19,66,-125,-39,90,-42,25,70,-31,-104,-90,-21,118,98,-111,102,44,-35,-117,60,-62,86,-47,-4,-88,14,46,79,-81,6,-5,101,-12,99,96,43,42,-27,65,-3,-93,-120,112,32,-111,-6,89,105,-67,122,50,57,-126,-54,-46,35,-41,48,0,-98,-22,71,45,-125,81,7,-26,23,118,-60,25,101,-128,-95,117,22,-29,-126,74,86,-53,-39,65,-86,-62,64,-77,-8,-85,90,54,-28,124,-128,-1,-112,105,127,-124,-40,123,63,123,-77,-84,13,-5,53,-46,-31,-74,-36,-16,27,13,-124,-24,-98,-115,-83,101,48,92,13,-5,-98,-111,-10,-51,-40,-115,-81,-82,-52,24,102,98,97,109,107,-1,-46,109,50,40,-48,-23,71,-70,34,-13,-111,43,110,-41,-9,-1,108,37,45,-28,-72,-45,-50,121,9,-66,-4,-10,-86,18,16,-119,64,-36,33,5,-13,-125,93,19,-6,-61,126,48,95,-116,11,-62,125,-6,67,111,-1,-54,2,82,45,-103,-4,19,-66,20,18,48,15,94,-91,33,119,82,-15,-24,116,15,67,30,111,-106,90,80,13,-20,71,66,65,108,124,-104,-94,-124,120,59,-95,-80,16,-101,83,90,14,25,-96,-64,-38,-24,98,-17,-69,108,-89,-29,-30,-11,-101,99,13,53,-56,72,52,105,105,88,2,75,26,23,-13,122,3,-114,71,-29,-70,-9,-98,67,58,-122,87,7,126,-30,111,69,-61,7,11,103,-6,-6,-16,56,-32,23,94,29,-31,-63,-47,67,5,61,110,57,43,54,41,74,28,-65,97,74,-22,-115,-126,0,86,-50,-83,-3,-93,116,5,-29,22,21,-79,-54,34,68,77,-76,-34,84,-116,-31,-102,-13,-55,85,64,-42,44,-115,43,85,100,-60,-104,103,-54,120,-65,-69,44,-102,59,107,81,-79,89,-44,121,-24,70,-110,51,75,76,117,-7,61,110,-102,42,-28,-28,-67,-12,102,-19,-27,18,121,115,-46,68,-81,-124,-110,-33,56,108,-83,30,4,-97,-79,-17,114,88,-86,105,-9,17,0,61,11,101,7,14,58,-100,-38,-42,121,27,119,-48,62,56,94,39,-49,-20,7,26,-99,108,-44,120,87,-2,-117,-78,64,-56,76,-83,-105,26,21,-3,8,81,-74,-100,50,67,9,58,-118,-14,-96,-13,65,27,-122,-73,102,-83,-40,-60,-13,-120,16,51,112,-51,-81,-15,127,-7,100,-116,83,-20,-72,59,121,-39,-43,114,97,55,-9,-53,56,107,45,49,-102,106,-126,-54,59,-44,18,-64,101,-75,62,-123,-70,-110,-17,24,-44,57,-122,104,43,-119,-40,18,-107,-113,25,122,-19,-90,123,74,-35,-86,107,102,-22,-51,56,-14,-100,109,-124,1,35,-85,-16,-124,-65,-21,1,30,55,-75,67,-121,109,-78,-102,82,-23,-94,-60,46,0,-104,-96,6,12,39,101,62,37,-39,-84,-92,48,3,68,34,26,-47,-67,60,25,-2,118,-110,91,77,46,2,103,43,-85,-107,83,-23,-23,-71,-7,-110,42,43,16,-82,57,-55,-52,-102,-32,32,-70,-111,75,116,-11,116,-44,-75,-14,1,-123,-128,31,-85,71,33,-72,78,-102,70,-72,48,-15,60,38,56,79,93,114,-83,75,-6,-78,120,25,-127,112,82,-37,-90,-121,-92,-112,-35,8,119,-32,-35,58,77,-9,109,69,-107,-21,11,-128,-42,-70,48,-30,-23,-78,-81,30,-123,-40,-8,106,-127,9,64,-51,-78,122,95,-109,81,-15,-43,27,118,-92,88,37,-109,-106,52,-8,-62,119,-45,65,73,127,-96,-115,53,-125,46,47,89,115,8,71,70,-40,-107,24,15,-119,-64,115,41,54,-11,-103,-108,-20,6,104,-67,-8,95,102,90,19,15,73,-22,13,-7,55,113,-53,-123,-110,51,40,37,-83,-103,-61,34,59,114,-25,-113,-103,87,-26,-10,-121,88,-65,-79,-63,92,123,-62,31,59,-87,-11,113,31,14,88,25,23,35,-49,-83,-21,-59,53,-72,109,-22,-64,59,89,-104,-42,52,24,-60,62,3,91,7,-21,15,61,-117,-109,-1,65,-39,25,-37,-34,26,-2,-51,62,61,24,-15,50,-32,-48,25,-55,36,24,99,6,94,-25,-84,86,-30,-95,-94,-102,-53,29,65,-81,69,-85,117,65,-7,0,-66,-23,-75,127,-108,62,10,-5,66,-4,29,-59,-82,41,-55,58,9,65,-128,55,-58,-67,-28,123,99,-121,-70,-99,-6,11,122,-108,-18,119,1,78,103,61,121,-104,-68,117,-22,-108,31,64,-68,-68,-96,52,41,58,11,-54,-26,118,14,75,-54,21,60,-119,-66,-19,11,-64,-5,76,-97,-9,81,-126,62,72,-115,64,117,23,65,73,-87,-121,-40,-48,90,-82,73,-91,57,42,-53,54,-11,6,102,-104,-117,0,70,52,-56,103,104,-1,-12,-103,32,59,12,123,-75,-104,-123,16,31,-35,20,55,-116,-109,-44,-50,-63,24,76,35,-116,-29,16,-32,-43,-68,-115,-56,32,109,-34,-9,126,-39,74,-74,-46,-19,-82,-105,-115,32,94,17,105,-103,68,-50,-121,-29,53,-7,74,77,98,-123,-68,37,-8,62,-21,-23,4,-99,-80,-103,45,-58,-2,-95,5,58,35,19,-65,-37,108,-14,35,-90,-53,-123,-5,28,39,-21,17,-38,70,-53,94,30,62,24,34,-74,14,101,20,46,-61,94,125,-121,-122,88,36,-127,-97,-98,80,110,80,14,10,72,8,95,50,4,113,27,54,-124,-117,-48,-39,122,52,8,61,94,40,-69,-34,21,7,-56,-123,-90,24,23,89,57,-87,-97,-16,-80,63,-50,-118,76,-25,-17,24,90,-4,-112,-94,32,58,-32,11,-12,28,48,118,-38,-69,107,61,92,-104,116,-112,-62,55,-110,127,0,-46,-54,17,-57,116,54,-90,-36,114,-39,53,-32,33,-69,72,37,-70,121,-84,60,22,-95,-105,-74,-7,-67,-49,-41,55,98,60,-57,-51,-107,48,31,48,-72,-35,-38,-5,29,-102,65,78,79,71,-8,-113,122,76,90,-55,-31,102,77,-66,107,112,-128,101,122,-83,-62,111,126,-75,101,-55,-118,52,68,-128,115,63,76,32,-6,6,90,100,-109,98,-59,19,109,114,-1,84,-58,79,-52,95,121,-77,114,-52,56,-13,-114,67,91,50,-51,-94,-115,113,-58,-33,56,-92,55,-120,80,-125,-85,126,-114,-126,44,22,-29,-82,113,-92,91,-39,63,-34,-90,43,-21,-3,113,-81,-5,-91,69,-59,120,-126,127,43,66,113,-111,-99,47,-46,-73,-13,55,-7,73,37,110,-76,68,105,13,94,-36,10,108,-127,-76,126,10,100,21,-80,-117,21,-95,-79,94,77,-72,98,-63,24,93,7,-124,25,-15,-62,84,-99,28,-99,-82,113,-65,62,13,-51,-117,115,37,-125,-40,85,-96,70,31,26,-27,2,57,43,-15,-112,-36,-5,-72,106,44,-97,126,111,-31,-89,-66,76,-114,-111,51,120,69,-106,56,-70,1,-54,105,-56,-8,-92,-123,-71,40,-52,-20,-93,-102,-104,76,48,77,-30,76,53,-113,-16,40,88,44,-107,34,53,18,-21,95,123,-115,53,-28,21,47,82,76,-58,-114,-104,22,-97,-90,109,73,7,-108,-30,-96,89,-84,-47,-46,-62,110,25,-128,-54,-75,-62,55,121,42,-62,69,54,25,-75,7,122,87,88,-68,-83,-95,-100,38,-103,-96,74,-57,109,-34,51,72,86,89,120,66,85,18,95,-84,101,-86,15,-32,48,-104,-99,62,115,43,76,-14,76,-92,27,-5,-8,41,-74,-114,50,-77,-97,-67,-109,16,-36,106,-52,85,50,16,-68,-27,-99,-22,-112,122,-15,63,64,23,121,23,54,-31,126,64,76,16,18,-57,-75,97,-94,-23,-94,72,-40,-53,30,-55,87,-63,-13,116,-64,9,-72,11,-45,-90,11,59,110,44,28,-105,62,-80,-27,20,-7,46,45,57,35,5,126,29,-91,77,-65,-60,-56,10,-115,-42,115,-17,-67,34,12,56,39,-119,-20,-66,22,-39,54,-102,108,1,107,-75,14,-104,-127,-87,-17,-88,103,33,-71,-85,-76,23,-95,-94,-102,107,92,-96,61,121,-98,78,-33,-28,33,75,-10,32,-14,-125,-72,-96,-4,10,-65,7,-52,-27,92,-71,100,61,87,45,9,-43,110,-52,-70,19,45,-110,-66,-74,91,-126,-27,106,-110,58,114,-86,-52,-77,-63,-50,-65,67,-54,33,116,37,64,49,-7,76,-115,22,-124,-105,50,19,-126,81,86,124,-37,-5,-48,19,32,-65,-21,80,-93,-124,-23,-25,24,16,97,65,51,29,56,-79,-117,80,-50,14,-77,-23,87,96,-52,125,49,2,55,13,61,107,-106,93,-116,102,-37,-11,-23,-119,53,-43,-39,-86,-96,0,19,13,15,15,112,24,-73,76,79,-76,99,-127,90,-18,119,63,3,-29,111,38,34,-66,-34,111,31,-29,24,-95,-70,5,65,-15,86,-43,16,76,-127,-120,6,21,-29,97,-31,53,-57,-39,83,-117,-48,-99,126,38,56,-78,67,-18,43,72,-96,100,-37,109,-92,89,94,-88,36,121,112,-33,-69,-42,-99,112,-80,116,-42,49,20,5,124,26,26,-32,-118,-28,22,65,13,-105,81,-98,124,40,-76,52,-104,97,59,82,96,-99,-46,-27,-74,-125,-36,64,-31,114,-83,-28,-61,81,8,-81,-49,42,48,36,-81,12,-80,68,83,38,-115,-46,93,-86,62,-56,-52,-36,7,-88,-85,-80,38,5,-106,-8,-125,-94,-81,123,122,21,-112,45,-37,116,81,48,93,-122,32,-120,-28,48,-85,-99,-47,50,-67,-109,-14,78,-79,10,56,-98,41,-22,10,-20,74,94,-120,-30,110,50,86,74,91,51,43,-86,-44,11,65,-11,127,-97,-31,-24,119,-16,-66,-73,87,-95,-64,109,98,-127,-30,45,24,-11,54,61,76,109,126,24,45,-1,64,-24,-28,28,114,-113,-32,-103,122,-125,95,102,-7,-33,-25,-28,-7,-101,63,109,-9,111,-45,73,-41,-111,-48,-70,-113,-40,28,-32,-95,-41,76,33,-53,-112,-106,75,71,117,-94,81,19,19,53,96,125,-9,-82,40,85,6,65,36,-91,68,59,9,91,65,-67,-34,65,121,125,-25,-107,-38,-106,-122,20,-83,109,45,-103,122,-31,-42,-42,84,23,-57,49,-69,27,41,78,-116,3,-65,59,-28,-52,-101,-91,-29,-29,37,113,86,119,-51,-19,-104,-84,42,90,-113,125,-32,37,65,-21,119,126,11,-13,-37,59,-49,-80,60,90,-114,7,-117,-84,-22,-50,4,58,69,-93,106,-77,110,-46,125,78,93,-124,-20,-42,73,75,-60,-59,-52,80,-5,6,-105,-14,-58,-59,-72,34,59,-46,-96,-102,76,105,-8,-49,-79,-81,-47,-94,93,-100,77,-119,-115,-102,-115,-68,69,-126,107,-86,-103,91,83,-26,-42,73,-84,-54,5,-85,-104,-61,-28,22,100,-71,-126,-43,97,-128,38,88,41,112,94,-84,39,-55,-119,36,-115,60,107,87,1,-45,-114,-9,-80,88,-105,-67,-91,90,-111,-96,95,-113,-103,-24,-70,91,-113,-70,-122,-83,-92,-20,121,117,37,-105,-10,126,82,81,89,-2,-118,36,-21,-9,-85,124,-103,65,-6,118,-45,-33,-5,-113,122,124,87,58,-30,-47,-43,54,-10,-116,88,-17,44,29,94,-106,-59,41,54,-86,101,98,-116,106,-12,-12,95,13,-29,-103,72,55,-73,6,122,-106,124,79,54,-93,17,7,-101,69,-72,-102,-43,31,71,-44,92,37,28,-104,127,54,-7,-50,-74,-35,-125,-16,-119,28,-17,-44,122,63,117,92,-23,82,14,-28,122,-38,-90,26,88,-74,22,127,115,111,-128,61,-41,-104,-9,31,112,37,29,53,-3,58,52,-27,66,-76,-73,27,78,92,-33,-125,39,110,95,-96,-61,-125,-16,80,-107,101,44,63,114,47,-101,-47,124,21,-31,-99,-57,24,46,-24,18,121,-104,68,-113,37,-76,-71,102,-10,59,-124,112,123,121,91,78,-17,-14,32,-82,49,2,102,-47,-83,-30,-19,-3,67,-50,-42,41,-92,-21,-72,117,-111,-74,97,26,-26,18,-78,104,41,67,48,122,108,-19,105,64,-111,-45,-45,43,-80,-66,115,84,81,-36,-31,59,60,28,-10,125,72,30,-64,105,52,45,-74,11,38,-16,-118,-3,-46,98,-77,40,70,-69,-114,-77,-70,60,123,83,-102,-80,42,100,109,81,-77,115,7,-127,-87,-22,-48,8,57,-72,-41,-41,-9,3,-54,80,-30,103,-54,-16,118,105,-37,-87,22,71,-48,-33,121,62,-90,116,66,-38,-105,22,19,-21,-41,83,112,-39,-28,-81,-109,31,-125,-95,-1,54,-84,72,-108,112,89,-114,120,-73,110,20,-55,-126,-93,-58,68,-105,-107,65,122,8,-103,121,-97,61,-74,97,99,-65,1,46,7,57,69,-122,100,-112,94,-94,116,23,85,106,-105,79,-108,-128,39,-111,83,-87,-66,112,-102,24,-7,-72,-78,-97,-8,99,-113,-114,79,115,-51,89,-88,83,-90,28,56,113,-102,57,40,-104,-76,89,-8,38,-5,-67,-9,-18,38,-121,27,-25,-110,-29,3,-10,123,16,-40,-93,-36,116,-20,-73,-111,-18,87,-123,120,113,-121,-97,-47,69,105,-68,-97,-111,-53,-94,114,-81,77,92,-37,46,-80,-18,-9,108,-69,-25,-46,27,-101,-86,54,53,-109,-44,85,-11,-61,-87,34,-17,-25,79,-46,101,-22,-30,85,99,-65,-30,117,12,-80,-23,-16,54,106,-89,-120,-29,64,1,-94,-111,-75,82,-3,68,120,11,-103,-52,87,22,-46,-17,-117,-63,12,112,-123,-52,-121,71,-122,-55,101,-125,-41,105,-53,52,-9,60,-3,56,-1,85,15,-112,127,70,-7,4,48,-72,-29,34,11,-103,-46,114,56,-109,-32,17,9,89,-1,114,92,86,11,-55,-87,-80,-18,53,-4,42,86,-90,15,-50,120,49,-46,22,57,67,-59,90,110,-97,96,119,100,43,-90,-54,81,-89,21,-80,64,-14,-47,126,92,-17,-37,51,121,40,-34,110,-54,-99,36,-73,-43,85,52,-30,121,-9,-18,-51,91,102,-116,-71,86,95,-55,95,-35,74,118,101,-114,87,20,-48,-60,117,-76,55,-108,49,74,-22,20,-43,41,79,114,-96,-12,-68,43,-44,126,-28,83,19,111,-128,-19,102,-110,56,-77,71,89,17,-26,-16,32,-27,-14,-127,-37,62,-107,-34,126,110,74,104,6,85,8,79,-74,107,126,30,-52,80,29,-11,108,65,29,-128,109,-2,59,123,28,-107,62,110,110,-123,71,-68,-39,-20,-108,-57,38,-36,-12,126,100,112,-32,-103,55,98,-82,-5,89,-41,36,88,-92,99,118,-56,97,12,-16,113,88,71,-96,76,-77,117,60,-5,-84,23,-41,45,31,46,0,33,-3,69,4,38,-119,-20,96,-115,-50,28,-38,-9,85,-113,36,-106,3,-96,-23,-80,7,-19,-111,101,92,-107,116,-9,53,-120,-3,5,-13,-87,-115,1,-35,-125,-23,-89,19,53,117,69,-67,-107,-122,-33,-32,-10,-122,-69,75,-116,-35,-69,43,-74,109,-107,18,107,-48,-85,52,-38,50,83,115,-101,5,-39,62,-7,99,-46,97,44,78,31,27,105,-72,-117,-94,-69,-86,108,-59,-30,-48,49,-22,-124,-114,-2,-19,-126,-122,-29,-21,67,60,15,-111,-55,-22,35,81,37,-75,32,0,56,47,-18,108,41,-120,0,122,-4,51,95,-68,-20,125,78,77,119,-115,-9,109,59,-128,79,-124,-114,7,9,91,-8,11,-80,-112,29,-56,-32,11,-50,29,-82,74,-19,-6,-55,12,-115,18,-6,15,-123,-15,72,-62,12,43,1,82,-30,2,-17,26,-30,58,-85,63,-56,-100,-117,52,-90,-69,7,-26,121,111,-92,5,-61,-90,96,63,-18,60,-11,-52,-81,125,99,25,67,82,-71,110,97,122,51,39,33,93,28,-116,123,48,-107,-64,-9,-31,92,-62,-68,-103,-102,-107,48,-2,-100,83,127,41,-82,-105,-7,113,-120,10,58,-122,23,84,-18,20,-37,-82,11,46,42,-95,16,-58,-105,-78,62,-57,-82,39,-18,0,106,52,-51,36,-59,76,98,-108,124,-67,-40,-3,73,19,45,121,-45,20,76,-21,0,-57,46,-18,90,79,66,-56,-42,-47,-39,90,-120,79,103,34,-104,-30,-67,94,120,35,59,-41,25,-128,125,88,88,68,-48,-47,-25,-10,-12,92,125,20,-99,66,55,118,-42,46,114,67,-9,37,43,119,-84,79,-8,-21,123,48,82,76,-63,-23,-17,27,-108,97,53,95,-109,68,41,-50,-32,-119,-20,-71,80,-9,-57,-16,-4,17,-36,66,19,-113,82,-76,39,-128,23,47,9,30,-87,-35,-48,96,100,15,-4,-86,-58,-10,-1,83,-52,17,-102,37,-88,-13,-2,-23,-92,-52,-89,-33,-112,-47,60,122,28,-101,-99,92,-67,-88,77,101,118,-96,-123,-108,-108,-43,102,44,45,-48,84,-25,110,-74,86,-7,50,-109,-9,59,-92,-67,79,23,29,53,-57,-89,73,9,1,65,81,17,31,8,-107,92,126,-119,53,52,98,-126,60,-82,15,-15,79,110,111,22,-82,88,-110,-49,-113,-124,-127,-51,88,-48,-87,-17,-55,62,45,41,64,-111,-95,-122,-46,-91,116,-55,-125,103,75,95,-29,-56,29,-36,-115,-41,-56,-100,88,-81,-33,29,-81,-11,-90,77,-17,-10,-127,-6,-121,30,-4,30,-24,-124,109,67,112,25,-57,34,4,79,126,-109,126,-47,-101,-9,-38,117,-76,-43,37,-120,-86,85,54,-70,56,-15,39,-40,-80,3,26,-64,-45,-69,-35,-120,70,24,-97,-29,-53,19,69,-113,-112,-78,-53,-106,-74,-61,94,78,-57,97,-58,46,58,-21,62,-121,-97,-16,-38,35,35,-127,-120,125,2,54,-30,-44,-17,30,9,-20,30,117,-53,52,29,95,-92,16,60,-29,102,54,-66,122,-110,10,-113,68,-78,-120,-71,111,-96,-37,9,-11,39,111,-52,107,-25,-77,-9,81,28,0,-55,43,-98,-97,-37,-123,69,-4,23,-98,102,106,-11,-42,98,5,115,-121,-84,-86,-78,-69,11,34,-115,-94,3,-104,-9,51,-38,-113,29,-39,83,86,54,-116,-27,-108,61,10,27,-44,65,-91,-86,34,-40,99,38,-14,101,126,-82,-56,-8,37,-102,-52,102,126,-36,74,95,113,-83,-37,-66,-20,-55,-98,-115,-49,96,-44,-123,20,-1,75,-2,10,-90,-61,107,87,94,-63,74,-55,0,2,41,-123,-103,-85,-13,-107,-39,36,-47,6,-21,-70,98,78,-119,52,26,8,-40,72,117,115,-78,76,-57,-60,43,-25,-87,83,36,54,127,-78,127,19,98,125,-30,86,121,62,124,-32,-96,20,-110,97,-126,13,-104,6,-122,36,-105,55,105,-48,-121,-83,0,18,-113,-114,-39,20,9,-20,-23,-49,-115,83,-107,70,121,-30,86,-48,31,-23,125,-114,-67,48,-86,-90,21,83,-79,-107,64,-60,-91,69,54,-73,-77,99,88,-10,15,57,-29,-128,-47,101,-96,-50,112,-85,120,-16,-78,7,27,116,-128,-11,18,49,-19,-33,41,15,-35,84,-67,-15,-57,-73,36,41,15,9,77,83,39,27,-54,-82,33,4,115,-60,101,-117,46,-56,-18,100,74,126,-27,-25,-48,10,-51,-41,126,-81,-95,9,-60,85,99,80,-6,-16,27,108,77,44,46,114,-26,20,-69,15,92,98,107,-59,-114,-87,28,-121,-61,84,125,-125,-44,-13,116,-120,-55,94,-84,-86,-75,34,1,121,-25,-80,26,43,-97,-12,31,-58,75,84,2,-109,12,-61,-68,110,-21,92,-27,13,-117,36,21,107,-3,-125,80,87,45,-108,22,-61,41,75,-115,29,-29,33,-111,-4,-22,-94,8,24,97,-124,25,-52,25,-7,-74,-36,108,-114,12,3,-32,84,75,34,-60,-88,-10,96,84,12,17,114,-119,-41,41,-48,-3,-16,1,21,-14,-115,-11,-25,96,-36,10,-71,-14,-3,-83,6,85,-91,-18,-108,81,36,-33,70,-59,-80,-81,-31,11,19,74,-22,107,91,8,57,29,-95,-80,61,-40,-82,-110,97,122,-114,-102,-77,123,83,122,46,-24,-121,-28,111,18,-47,-35,-102,-120,114,-93,22,115,-82,113,77,-78,76,-66,65,117,28,86,82,27,79,-128,119,-88,63,-31,11,87,124,-10,-71,-99,94,-89,-82,76,-124,101,-53,58,-74,9,-50,-114,31,-3,-119,-51,57,-29,92,-75,113,-47,-103,40,-81,-43,-100,-12,-102,4,12,-36,-26,-70,27,-118,-88,50,-73,28,-113,-94,122,-1,4,-57,124,-126,100,70,-87,62,7,-91,-91,100,-102,-56,102,34,118,44,-90,-47,24,-32,30,-99,-98,36,113,-124,11,-126,-84,-15,72,117,3,-46,-18,97,-73,-38,24,-47,-4,109,-50,-86,-112,88,-97,-65,-73,112,72,-37,-125,20,-29,-43,-2,51,-16,94,58,119,-101,-48,121,-116,94,103,52,64,48,51,-70,-113,106,41,82,-44,111,-106,-62,71,-105,-66,78,-78,71,115,-50,-123,4,33,88,22,-40,-111,-46,-82,-34,-67,-58,120,-28,-18,-52,-126,-31,-109,11,84,-94,10,-15,94,-89,-106,125,-62,-6,98,62,-39,-11,-34,12,12,-18,-50,-78,-60,43,104,50,36,-62,-58,-36,-14,-104,-88,78,21,-18,43,-118,-124,-68,-35,-62,52,102,18,87,25,-106,-78,29,74,127,98,-2,-99,-86,37,80,6,-31,86,112,77,-51,121,-126,70,7,35,3,-85,-24,-78,114,-109,-25,-58,120,-127,-78,26,-100,8,-116,10,-20,-23,14,-18,120,42,-75,79,44,60,-58,102,69,-104,25,119,103,28,-70,22,26,25,124,3,-15,-11,10,87,-23,120,-68,-44,93,7,9,-8,-15,125,-79,-70,15,108,-66,-90,-5,-82,-14,115,-75,-122,74,127,108,-100,4,58,-106,66,-117,1,11,6,-69,-96,-65,55,-8,102,-41,-72,75,76,16,-2,-10,78,59,-42,-72,-1,-31,-100,113,26,-66,48,-4,103,57,71,-94,-2,14,-28,-36,22,-8,-25,39,-51,25,99,91,70,63,11,-124,69,46,-34,-21,99,-70,-110,-90,32,116,34,-74,82,43,-104,-56,31,-117,-43,67,12,-72,115,-84,-62,-9,21,-30,105,82,94,86,12,40,-47,-39,40,-114,-67,-89,-72,-64,-62,-124,-105,32,95,-124,-41,-14,48,26,8,-116,-57,24,-45,-45,-75,-40,-111,-118,107,116,66,-97,-57,-79,-96,-85,-55,49,-55,-32,-87,-76,-12,42,-85,85,-16,75,-41,-112,49,-29,-28,-124,-10,-60,62,-2,-112,15,-36,-33,81,-95,117,120,51,99,-64,30,11,106,-21,-42,43,-59,51,117,12,45,3,-116,110,88,104,60,67,102,-74,108,80,-58,-108,28,38,-108,16,63,100,-24,-36,-1,70,97,7,32,118,-112,-122,-31,-36,106,10,115,-89,35,58,-15,-5,63,19,-123,-99,-11,-94,108,-18,-13,70,-12,-1,126,-15,-9,-25,113,111,66,-59,81,-88,-114,97,-121,-76,16,8,72,62,3,-107,106,-43,92,-91,63,60,-90,-61,96,-9,93,-24,-17,-22,38,-24,29,-27,-36,-25,117,99,-10,76,66,-77,-71,33,-87,100,48,-13,-122,-49,56,-104,72,72,-84,103,72,115,-10,45,19,-22,52,-97,-77,-107,50,-81,-93,-79,102,-71,46,73,6,-21,-52,5,-96,32,112,15,-44,-4,110,5,-26,-85,89,-87,35,73,-17,59,-95,-5,-123,94,127,-83,9,-122,-64,-58,-72,-111,33,-91,-82,56,63,1,6,-67,-106,-55,26,-12,-105,-32,115,-38,-95,118,117,67,-17,95,99,120,-75,2,28,-113,-105,117,-15,111,22,-46,116,25,-91,40,44,84,37,-4,-66,-125,15,69,-14,49,-12,-11,87,-68,20,91,110,117,125,-65,-34,-36,84,-29,-87,-27,60,-66,-118,-125,49,69,81,54,7,-119,53,-23,-60,-9,22,-116,-125,-58} + +#define IP4_WEIGHT_Q15 {18,-12,-44,78,104,-34,61,92,-120,-75,40,-19,29,-80,-56,21,60,-92,107,-118,58,-104,94,47,62,106,11,-105,-6,-20,-32,24,43,43,-116,48,53,-86,-50,-38,-108,-80,0,-73,-5,115,-26,111,78,76,-101,-55,94,39,-61,118,94,13,-20,-81,100,70,-111,94,-125,63,71,-121,-70,-69,-14,-74,54,-121,60,107,-121,-106,51,-38,-61,26,110,103,-43,94,-116,111,60,-125,-28,88,83,120,62,-39,-79,112,-85,34,121,-93,-121,97,-45,-97,-90,12,-97,90,109,-45,-59,-100,-105,-21,0,-26,-122,-37,28,35,-10,-115,-87,6,-62,108,-15,26,118,-84,-26,1,-74,73,-41,-65,97,86,94,67,34,59,-99,106,-67,-80,-26,-71,-21,-20,115,109,-43,-107,-21,64,37,-2,-20,-75,115,108,53,35,-102,45,83,-106,-49,-59,-46,-102,121,-41,51,-55,22,19,-58,-103,-116,80,25,-126,122,-76,-7,-34,-2,110,15,-46,82,-16,15,-19,-52,-39,-73,62,93,67,117,-27,62,-12,-89,-15,-100,-57,59,20,-127,52,-37,-79,-41,-43,111,-31,99,13,-12,43,99,-1,-31,43,124,-15,-30,120,-69,-79,-36,-19,-89,89,46,116,54,-46,49,94,85,67,113,11,24,-59,-17,119,-119,110,-57,-81,-1,77,32,118,-38,-13,113,-53,-94,111,110,-19,-14,-53,4,117,-20,-35,121,24,-97,119,18,-31,108,54,30,-74,-121,16,101,65,3,107,-12,-38,14,-53,125,60,-59,17,52,21,-65,-118,76,91,-112,106,-38,98,26,-4,-53,-63,-108,95,-58,63,19,111,-74,73,37,63,-115,-84,-44,22,-47,-51,60,9,29,22,-57,81,-87,-27,-65,-63,-93,63,110,-26,-126,-12,7,-118,-127,-113,-70,45,107,103,-69,-48,56,25,55,-55,79,113,111,120,-2,43,108,-122,-41,93,40,44,88,107,-78,-34,124,122,63,-67,29,14,24,-69,-72,67,108,26,116,88,90,-48,93,-103,-37,127,-24,115,-76,-80,-97,-61,96,-54,-22,-14,-123,-49,62,-17,-1,21,-65,116,10,113,10,30,88,-24,-119,-95,89,58,124,-119,-112,-115,88,57,119,68,-17,31,-27,-9,-64,18,-26,109,-60,4,59,-89,-127,8,-35,-90,88,-76,22,109,-123,-51,88,-90,18,25,45,47,-80,75,-66,-24,-109,-47,-42,68,-8,-98,78,-122,19,33,-72,94,2,-109,-84,82,102,71,55,-121,19,76,76,93,66,-42,-23,-2,40,3,106,123,-111,8,83,105,117,121,-52,2,-4,-18,-4,-19,-125,38,80,83,25,-64,123,47,36,105,29,-71,-72,-127,-41,-82,31,3,-43,9,73,124,91,-3,-99,-27,101,77,-51,-96,60,15,74,54,35,-119,116,53,-4,46,-29,8,2,93,75,-18,38,49,40,30,-30,22,97,97,-8,-35,-111,21,-62,97,-96,-12,82,28,-118,87,-12,29,-16,46,110,8,95,58,40,41,29,105,-58,-108,-29,-117,36,106,-118,11,-124,60,84,-83,-87,21,53,-31,125,-5,114,-75,93,-41,-127,-98,49,31,96,64,-112,60,-126,2,69,-73,94,-23,-100,81,-115,-116,94,-25,-44,46,91,-89,12,-47,75,107,-77,-82,-10,79,-70,-106,75,-1,62,104,-69,-7,-41,73,53,-32,74,26,-113,111,-115,-55,66,20,-91,7,-47,51,-96,126,121,-75,63,81,-23,14,-124,-41,-39,-13,14,-27,16,-56,-48,-43,-84,120,33,41,98,26,-6,18,15,8,31,-9,-50,121,-107,-106,-33,-46,64,-19,127,-104,-59,86,-30,-121,60,-79,39,-38,-5,85,-119,-17,21,-120,44,-22,89,-17,73,-102,49,26,-73,-69,91,-71,-36,103,63,-8,125,61,103,-116,-20,11,105,-116,15,-78,-122,-80,-62,-80,-58,65,-119,-47,99,-26,-111,69,87,-38,-15,-44,-87,-14,-84,-37,-27,109,-90,-72,-4,-110,38,82,-97,-50,29,61,52,-44,-87,8,63,83,92,109,-124,-47,69,-110,-70,111,-10,25,15,104,80,66,32,-70,-16,-49,-52,-16,-41,122,104,22,-31,-109,18,62,102,125,-123,74,121,5,92,-92,-90,72,-61,98,-2,-125,-81,101,109,-120,60,58,10,53,94,38,-25,-56,-13,-80,80,-13,45,-77,-43,-44,-37,-62,46,38,-103,-124,-93,48,76,-82,1,73,74,67,63,-59,-26,76,116,66,70,-113,-30,106,109,25,75,-18,25,25,85,-83,81,78,-50,99,-53,-125,-68,44,-104,96,-44,-126,124,33,112,-75,-29,-9,-60,-126,-84,-119,-61,-127,-6,-46,-26,-57,118,105,-4,21,-120,54,-121,-35,-70,-101,-124,-79,-33,-30,105,57,-108,-48,-111,-65,-108,41,77,112,111,118,68,0,22,110,44,56,-91,-49,-111,62,-54,78,83,66,38,102,-14,41,52,14,-94,106,105,24,27,53,-40,-70,60,-119,56,-95,68,69,59,-101,-124,-25,-119,-45,102,-55,-38,61,57,104,-96,88,122,99,-122,77,106,122,33,126,-5,-74,46,116,-52,-51,-101,74,74,2,-3,-21,-38,68,-30,17,96,71,-124,-23,47,64,-35,24,107,49,41,-50,-23,88,19,55,-30,-91,3,-54,-14,125,10,84,-96,100,100,67,-116,-40,-124,2,53,-62,45,72,21,82,10,-47,-126,54,-84,-50,13,-2,-66,-1,103,96,-17,123,59,-111,-61,-70,-20,-57,54,-94,-110,-125,3,-101,14,-128,-86,80,-44,-94,37,113,123,-104,-9,-87,109,111,120,33,-7,-62,-51,-57,49,-71,3,18,-49,-94,-32,-92,40,-52,3,52,105,108,123,40,1,2,-86,38,-104,52,-93,-44,-73,-62,91,-88,5,-91,-61,-24,-40,-30,-48,-115,114,62,-128,-85,-93,-43,104,-20,102,-103,-52,-56,25,-103,49,-25,10,84,-52,51,-94,-110,26,-108,1,30,32,-23,126,-112,-82,86,-102,-17,-108,-32,78,32,80,-125,-112,91,8,-69,24,-95,-86,-73,-115,14,9,-2,-121,101,-109,-72,1,54,84,-36,25,95,-49,108,-110,4,24,126,66,-63,56,-8,99,-10,-80,-73,5,72,-103,-10,-35,78,3,42,-61,-83,-115,-99,84,78,20,30,-66,-88,97,-120,-66,120,-46,-29,-57,118,15,-94,-110,-29,25,89,113,-110,-52,90,-92,105,-30,48,92,-44,-1,-39,-96,118,115,37,-3,15,-1,-2,64,81,57,-47,24,-14,89,-103,48,-127,-95,-100,-114,14,-69,-82,-32,-9,-77,-38,33,-76,-63,-32,51,69,-8,26,-75,80,59,101,-31,40,-37,-23,76,-110,-23,-83,-84,111,-31,124,122,-56,-67,-112,4,-123,65,67,101,12,-23,-12,-43,54,-87,35,66,-89,-47,-105,55,100,19,-80,21,-76,-85,-117,-61,19,107,-71,42,86,-9,-80,33,-65,120,106,-49,77,-34,-38,-50,-27,21,-28,65,97,108,-77,42,120,69,24,127,-20,89,112,-66,-126,-110,103,43,0,-63,28,-17,36,-43,-68,-117,115,-69,70,107,2,94,95,9,-83,-99,47,53,80,-105,28,-27,119,59,82,95,-94,-16,-49,15,-122,16,-89,17,64,-6,88,4,21,47,-78,50,-25,121,-36,-47,72,-21,-101,29,9,-83,28,-113,-68,23,115,-67,-101,-101,102,-98,-124,-98,-89,-24,82,-28,40,-89,125,23,83,97,-53,-7,-108,-90,-83,-113,-26,-58,-119,28,97,35,-74,6,-15,-40,-10,11,-98,79,101,101,-72,8,-99,117,80,-65,127,95,15,60,-29,2,-92,60,-118,-116,46,79,-79,-62,-43,104,73,107,117,-43,-127,-67,113,44,-41,67,-98,-73,26,74,59,-111,79,45,21,-60,-26,18,-72,54,-70,-30,10,114,-82,-124,-126,-52,-97,108,120,-19,-111,-52,102,10,18,99,49,-128,-17,91,-46,83,-76,-3,-41,45,47,-72,3,-19,112,-104,122,14,-77,-35,-23,121,41,-123,-2,-60,50,44,84,-45,69,-58,-69,43,-98,-11,-17,112,-95,-36,-69,67,-52,-11,-45,98,-126,-33,81,51,101,-38,67,68,-37,-78,12,107,105,75,-100,-109,-55,0,11,45,-24,3,54,-70,77,-63,125,52,93,-16,-22,-97,35,97,58,46,-61,66,-98,-61,12,-43,-63,-45,-36,-79,41,-58,54,-49,48,-63,-33,-110,-49,-36,93,73,-78,-33,50,-76,-6,-48,4,-87,-88,-81,-30,-33,-109,10,104,-94,94,38,-124,30,6,102,37,97,56,73,-106,-18,84,70,4,-31,-27,-90,54,63,50,10,-18,-113,125,-116,-86,-119,64,33,26,-128,-25,-77,76,-127,-79,0,60,-65,5,-63,-5,101,-91,69,-49,67,71,121,-22,59,-87,26,66,-26,7,-79,-73,-51,0,-114,-22,40,-115,-87,29,-18,-23,-72,-96,-55,-119,69,68,-102,-99,124,16,74,-34,5,87,120,-28,-6,-92,-111,-42,-85,-36,123,-86,-52,83,-77,-15,43,124,59,-81,103,96,-80,41,0,-62,-22,-13,77,-99,71,-121,104,72,43,107,4,80,-62,54,-98,-63,-13,-92,10,-119,-95,-76,-90,76,78,95,-108,-117,122,-115,88,52,-10,26,122,39,101,-80,12,107,-108,36,-13,-72,36,82,63,119,-57,-44,-7,77,-55,-25,-54,102,-118,-93,-91,58,11,11,-30,80,-62,-77,111,3,105,39,-63,-50,-33,-6,29,52,-98,-80,51,-5,-50,-122,93,116,-77,-45,79,110,-103,-20,-123,-16,-58,93,-101,-11,57,24,44,-60,-118,64,32,80,3,-25,107,60,126,124,-90,-22,-95,-91,-57,83,-46,1,-28,78,-47,74,15,42,26,113,42,-76,14,20,33,-93,37,107,89,-22,16,23,-16,60,108,-117,74,111,52,78,-97,53,-127,123,9,-78,-15,-17,86,5,-17,-120,28,-76,69,13,-76,120,-64,-35,-17,20,-98,126,-42,-88,-99,10,-113,44,84,115,-35,18,81,2,99,-82,74,-125,12,110,55,-110,31,-94,23,62,-4,-62,-122,-120,40,42,110,34,84,2,-3,-24,-75,-10,124,-38,-46,-14,-11,109,57,27,111,6,-99,27,126,72,41,-29,106,-24,96,96,60,-18,42,-104,82,53,-69,15,92,-79,127,-70,-102,-53,102,79,32,84,-119,115,-36,7,-84,-24,2,103,-77,54,60,1,-7,-64,-7,-22,114,-5,19,80,-49,107,-7,-2,89,-63,-26,-111,-51,17,-108,-40,9,-51,58,108,-55,-68,-117,99,-51,-117,-17,46,-33,69,13,-23,4,-71,-110,4,-95,119,103,-30,31,23,76,39,-36,6,-117,76,6,80,106,18,-124,-3,78,112,3,40,23,-55,-100,75,-118,-16,-52,18,69,-77,-91,126,-87,41,103,-127,7,105,106,77,-23,72,50,75,-16,-19,126,112,67,-4,-102,-56,53,38,-72,-60,-69,30,0,47,-95,100,53,-127,-16,-18,-16,29,46,73,90,-112,-97,-111,-15,-38,23,44,45,115,-93,-68,-32,-10,86,19,69,32,-104,-112,97,60,64,87,61,69,55,-92,-4,-77,-28,76,-82,56,123,52,-105,-38,-1,81,80,-40,-14,-78,115,32,-59,-123,-115,50,3,69,-14,5,-39,70,-124,34,61,-35,-57,34,127,-120,-13,109,-108,68,-22,-125,81,89,35,-21,88,87,107,-32,110,-27,-19,-82,-114,-81,99,115,-54,-92,90,65,-126,26,64,-114,36,70,-93,10,-94,-111,-90,118,-45,-3,-121,106,80,10,-101,-25,-12,-72,39,114,47,43,125,33,88,-109,-81,10,98,28,-98,105,96,123,-43,-58,-115,-122,-88,85,-80,26,91,-26,103,-88,-121,-66,101,87,-88,125,20,-58,-62,-46,-113,-100,-36,93,79,33,-108,49,-45,0,-19,70,103,-48,-19,-15,29,122,40,121,118,102,86,-83,111,-86,-26,-124,6,86,49,50,-67,-104,-28,-28,35,52,42,-25,-87,-6,-70,18,126,123,-128,-3,-109,-49,-94,-120,-62,62,-89,-107,94,110,109,10,-37,-126,99,-116,-85,113,100,-19,-52,65,-101,-45,93,-49,96,-78,84,28,-44,5,-110,-48,-26,62,127,49,-53,57,67,-85,127,60,120,-67,-96,107,34,-60,91,-6,-80,-8,-77,-119,50,89,-52,-64,96,-60,127,-76,-34,-1,-52,34,-25,100,99,-94,-46,12,-47,47,-47,-14,45,59,3,-74,-85,-49,103,-79,-6,-1,-25,0,-2,-44,-29,-11,6,108,-23,-48,91,56,75,-77,-71,-46,-100,-98,-100,90,-29,-56,-35,-3,54,-126,-62,124,1,-88,-26,4,101,95,-113,-67,75,39,104,-106,68,127,-127,-15,-36,-12,23,-51,-118,-22,-67,-39,-71,-77,52,104,9,-106,10,53,34,-98,-67,-74,84,95,87,38,-35,-103,-38,-125,-124,-31,41,3,-89,-41,-107,-9,-90,-39,-58,83,-106,-86,-24,-93,18,23,14,36,-56,-36,75,-123,10,7,109,13,-119,113,80,-68,45,35,57,32,-17,-1,28,-98,52,6,-37,-97,118,48,-119,-69,-102,37,-18,-4,-59,101,15,91,40,-31,3,5,-9,105,-9,-33,-31,-7,-71,-112,-71,-2,70,98,46,73,-99,42,-77,53,-38,48,-1,-120,76,-33,-62,-35,117,67,-117,33,58,2,-127,-100,-66,-117,-82,91,115,-111,33,24,-125,-89,76,84,15,27,-5,-87,49,-72,-35,-128,-49,114,65,82,-71,127,100,41,74,-63,52,0,-67,8,117,-102,5,123,87,-37,8,36,126,71,-108,-73,20,104,-76,-71,-50,18,-56,8,-62,-52,-105,-127,41,16,-26,-122,31,11,70,-100,-109,117,-35,88,29,-45,-78,115,-86,102,40,18,-58,-54,-84,32,-36,56,51,52,107,126,38,78,-66,-77,20,65,-119,-113,26,85,-92,-67,-35,-24,-47,-9,43,62,-70,-66,-41,-7,-72,-77,-79,56,75,49,67,65,43,102,-78,113,98,53,-47,20,-116,-4,-2,-12,-36,50,8,-118,-79,-120,-37,4,103,62,51,107,-90,79,49,-17,61,-15,36,17,-117,39,123,-87,61,11,96,-108,1,53,51,36,-19,-51,-69,-40,-91,127,-90,-62,126,79,-72,-61,123,41,-27,11,14,76,-67,-17,-70,-104,47,73,32,-120,-109,61,38,31,-1,-37,35,-21,-26,59,-53,-85,18,75,106,93,-83,-31,-18,-127,18,19,66,-74,10,-25,45,18,-109,30,4,13,-62,-47,13,-59,44,-96,19,-18,-113,65,-5,-75,91,-21,68,-90,46,25,-110,1,-115,-88,-91,55,13,86,24,-60,85,108,93,27,-61,-14,28,-110,-17,-18,68,70,113,-52,58,-9,52,111,-64,-97,64,-100,0,43,32,-88,13,-32,0,110,-104,92,108,66,-112,65,34,-64,-125,106,-9,113,-116,91,-35,-88,-91,-16,13,-117,3,37,121,-84,-75,-1,-44,-49,13,-77,81,46,113,-115,15,-37,21,-17,33,-19,-83,-95,27,28,83,53,22,-23,66,-25,-57,-15,-56,69,106,49,63,-120,125,106,-86,55,40,4,-96,-26,43,60,-107,-116,-76,-89,101,51,98,-21,106,-49,53,110,83,27,-119,36,2,-5,86,-50,47,-75,42,52,-59,63,-71,-67,60,83,6,65,124,16,28,14,63,-58,52,23,30,-81,49,-123,-26,42,-39,60,-27,-61,-66,-18,-88,-22,-46,-61,-60,65,66,-100,111,116,100,50,92,103,-83,111,-72,-5,116,111,72,39,101,54,-65,-44,8,-128,-88,113,18,-70,-78,-70,87,29,112,-31,63,9,12,-109,-27,-42,-52,55,-48,-70,95,-71,93,122,-46,53,-115,-22,-27,125,125,50,-58,-50,21,-71,9,-6,-82,45,50,51,-14,-74,-72,104,95,-86,57,65,-39,6,-10,21,-76,-52,127,-128,17,-36,-23,87,103,24,-95,95,10,95,21,61,-96,-24,-8,0,74,126,-14,-102,-44,107,-119,83,-123,51,27,-64,-17,124,24,-96,79,118,43,8,-95,-75,-106,-84,115,69,3,-118,122,-64,96,-29,-106,-78,-97,-82,122,51,14,-80,65,121,-66,-119,74,121,82,-120,77,96,-82,56,106,-45,-28,-116,78,-70,-13,90,41,-77,-55,-78,-49,91,-109,-36,-91,97,-31,95,27,-91,-116,-21,-17,87,112,-82,-51,62,-42,64,111,106,68,92,53,-68,-38,-55,-25,-38,-121,74,5,-96,-77,-14,-109,-87,75,-62,-108,12,-97,93,-91,42,24,-5,-45,79,126,-10,-71,-97,97,6,-19,-80,77,39,-111,-69,42,-123,-61,-30,-78,64,18,77,-99,82,-40,127,-39,46,66,46,-82,-70,-117,77,-17,27,96,10,56,16,83,22,114,114,24,-89,118,-84,116,19,-88,80,16,-25,66,111,-70,70,-86,-88,10,-1,80,-82,-95,95,-20,-121,-114,26,-15,-104,-77,-120,-7,97,123,68,69,-12,59,24,-20,100,46,75,-76,-23,-41,79,82,-3,-115,44,-69,-55,-100,95,81,-108,-125,-121,-46,-48,-112,-22,-10,-40,-60,112,22,79,89,-99,53,-54,48,-110,16,-51,77,94,59,-103,-50,-10,34,-115,60,84,31,-58,-55,-10,64,23,-5,112,96,85,75,4,-106,-77,55,-33,87,-76,-79,53,71,-8,-92,63,118,-60,-84,99,107,46,88,-89,24,-41,98,-36,-22,34,-88,-23,78,84,56,52,-14,60,123,-20,38,-56,-66,67,-80,117,-6,115,121,39,-126,-77,-8,89,22,29,-101,55,29,-31,-108,123,125,-46,6,103,-88,-35,25,-58,65,-118,40,-39,26,62,15,-25,77,-50,117,44,79,-79,64,-114,94,-31,-26,-67,-10,-114,-19,69,24,111,14,-33,-52,110,50,95,-107,63,-71,36,-21,-22,-7,-95,19,-71,-38,-88,124,47,120,98,22,-69,73,-5,-114,-18,106,-41,-102,-26,28,-41,-101,-105,-31,-120,-26,22,-21,-31,-44,-50,-127,88,85,111,33,-53,-114,-12,71,53,126,-55,82,93,-104,-77,41,-50,46,90,54,-28,-38,-128,-68,-80,-13,34,-63,31,60,-81,40,55,77,-5,-17,94,-110,30,96,26,61,43,-48,-128,101,13,-8,-6,-29,-60,115,-62,107,-57,54,96,13,114,-89,36,-69,-40,106,98,107,19,-28,-4,14,-97,-60,-71,-64,-107,-48,75,-50,-54,90,60,108,-101,-104,25,92,-60,-17,48,-63,103,113,59,24,51,32,-26,-101,121,71,-21,-83,-68,79,-115,42,5,89,-38,65,28,-91,22,4,89,7,-57,122,-51,-120,-58,-110,-42,-70,105,102,-112,33,-83,21,-14,62,-116,123,-55,-114,95,-110,-46,76,-12,-6,-88,-48,-126,49,-67,95,-94,42,76,84,-112,-64,-20,114,9,-8,-96,-38,-38,-85,72,55,7,127,117,54,-52,41,-89,-46,-95,-121,-97,-113,46,95,79,-105,96,36,62,111,-38,89,-97,61,24,120,90,-111,-69,43,48,88,25,-58,-89,55,26,14,121,-126,42,79,56,-43,-88,109,-53,31,69,-114,-1,-81,94,-50,35,20,-93,62,69,-96,120,-35,-103,-86,126,-44,-96,102,54,12,-97,-79,97,-49,-18,80,-68,-111,-17,39,87,102,6,-10,11,2,-89,-74,-104,-43,-9,53,-68,28,-126,-71,66,-26,34,102,32,-36,-96,-83,87,-127,83,-50,-60,-98,71,-81,108,-97,-74,50,20,-98,-9,75,8,-48,0,124,-27,74,-59,1,-121,118,52,-57,15,112,81,120,-10,-66,42,87,-92,-89,-123,-1,-29,-74,126,57,-50,31,115,-47,-20,-89,-107,51,49,28,110,38,-73,-37,-72,-70,-124,-20,-109,67,7,-114,64,32,-76,101,-107,52,-89,-109,51,-51,-3,-98,122,100,-57,-2,34,-38,22,-101,15,92,9,-104,47,-9,-18,47,27,-38,-58,-122,-20,102,-78,-63,-19,-71,-112,65,-48,49,27,85,-113,-57,108,24,81,-96,-47,99,-67,-121,-17,2,-29,-9,89,109,-45,-127,-59,122,44,-81,-39,55,5,40,0,-11,61,37,-82,18,-97,-69,-45,27,11,-70,-88,31,117,-98,115,114,75,-104,46,-3,104,-67,49,21,18,95,31,-8,11,55,-76,22,39,-17,10,24,-63,-97,57,114,-46,-62,-66,34,-86,-94,-67,-109,124,68,26,42,-65,-60,97,-41,59,118,-104,55,16,-25,-13,-99,-28,-50,-50,103,51,-77,91,55,53,-17,-108,-82,-121,-54,118,24,77,24,-120,73,-61,36,-122,-63,51,-88,22,104,76,14,63,118,122,-31,59,-115,-92,29,-66,101,-48,-7,-5,30,86,-41,-87,11,71,-15,75,-30,-110,2,9,91,18,101,-102,-51,-115,-83,14,37,-41,-17,106,-43,-108,-42,34,-86,65,57,12,-13,114,25,-36,-69,-48,93,-99,-89,-104,54,19,15,-101,-105,24,-51,-26,93,95,-2,-43,51,-14,-112,-83,69,77,122,20,-7,107,-29,79,115,115,-102,-58,-111,46,8,112,-67,-20,-97,-88,98,75,-30,-47,90,110,25,3,-8,94,70,47,22,-91,-103,-54,58,-38,-12,-50,51,37,72,27,7,-112,-50,31,-14,70,-76,-95,-109,-111,48,-75,118,-2,30,-7,-123,32,33,-89,-47,25,-6,67,73,-29,-7,-93,49,111,112,76,-65,8,-76,-95,45,83,-79,84,23,20,-96,-52,15,-70,-56,7,-58,106,85,122,-96,8,-84,85,-101,-30,35,-14,23,112,33,-86,20,-93,73,-30,-8,-79,-39,-77,-36,-38,-107,-112,-89,49,-27,103,48,31,127,-22,68,-35,100,99,57,-26,74,85,118,101,-43,105,-76,-93,-127,44,-1,39,68,12,93,-33,13,-78,11,-51,85,44,-99,12,-85,-63,98,-5,-92,76,25,-68,-86,-121,-67,-64,-109,31,64,-90,-58,126,52,-41,20,27,120,-86,-117,71,-128,-128,-28,-39,82,-102,113,59,30,-128,78,30,103,-11,-95,117,74,113,94,46,56,-96,41,48,-85,-25,-28,-79,104,3,-73,2,30,-22,76,-103,101,83,-89,34,2,127,-26,25,-82,8,18,-3,-20,13,52,-21,36,-38,90,112,-85,-92,-79,9,-72,98,15,-26,-32,-4,26,-26,-94,112,-5,69,-21,31,-84,-17,-112,-83,46,-24,-105,3,-102,15,-60,-123,99,-6,-47,22,-120,70,125,86,35,38,35,5,-100,89,96,64,-33,-55,29,-82,55,-3,17,89,52,104,126,62,-125,-80,113,34,53,77,83,-28,-65,-27,2,68,-114,-37,-4,-94,89,-41,51,-85,43,-36,93,-93,74,-8,109,-92,-70,114,-120,44,-63,77,102,50,36,88,16,19,99,-9,64,-57,-43,-81,-67,-70,-9,89,-64,114,53,-99,5,-31,87,74,66,-37,75,108,-100,85,-101,-44,-120,-32,-70,92,80,30,-16,112,-102,96,99,-6,123,-89,100,102,-38,-90,102,-80,-9,52,9,-47,-114,-81,-128,-112,2,87,-40,-41,46,-15,119,-107,79,105,15,-53,108,72,-22,36,45,82,-88,59,19,118,27,123,-93,-46,-44,93,-98,64,105,-80,99,-110,-8,-51,33,-58,76,-103,87,-13,26,76,-93,-13,83,127,-4,-52,-54,21,70,-93,20,-7,19,7,102,94,41,67,14,-52,17,54,23,-81,93,-61,76,-23,-92,-118,9,110,99,-53,-128,123,-127,-24,-125,-76,88,-79,63,-65,71,-79,59,-45,-64,-85,-111,-53,55,-102,22,-78,48,-67,25,100,0,30,72,19,56,-54,-6,40,-71,-42,98,127,-46,58,40,34,-6,-112,21,-113,2,-14,-42,-25,-78,-55,12,62,58,-127,-44,-40,85,29,-80,-27,-72,73,8,-36,-32,-21,34,-46,84,41,75,109,-41,123,-92,20,-123,106,72,47,41,-73,-12,-38,117,-89,44,-128,-102,-65,49,-43,69,-53,-119,60,-97,-39,9,-118,-33,-58,28,105,-41,70,111,39,-41,90,58,20,-25,-21,110,50,-114,-68,-104,-35,96,58,-16,98,26,-80,-98,63,74,119,-85,21,-124,8,118,-61,-125,-112,23,30,-77,92,-11,-28,-101,-57,-9,93,-49,103,32,-97,87,116,-96,77,-48,-27,92,57,-29,-25,52,-107,-77,-50,114,99,-79,24,-58,-19,-96,-113,47,-80,8,-83,-72,69,-6,55,92,39,17,76,21,-127,-5,-60,-115,-55,-28,40,-43,-43,106,112,-35,-57,25,80,19,-39,-6,-111,-79,4,-59,-77,121,-103,-89,-127,-113,28,61,-50,-125,58,-38,-33,43,124,41,69,-105,2,99,83,-31,-119,-21,38,90,92,-88,113,-83,56,-56,61,-49,-74,-2,-23,101,-114,26,114,-95,-52,-73,-7,-53,116,32,49,119,81,-88,-49,-102,-126,50,-47,38,-13,76,69,-73,-124,5,-53,-63,11,-42,35,-97,46,29,-43,112,-2,46,58,83,-17,41,-5,125,-34,-96,67,49,-17,-80,38,-82,81,29,84,-13,96,-112,49,13,65,117,52,23,3,49,-26,-43,-88,-97,93,-60,-93,-34,-54,-74,5,-113,64,-73,23,-95,50,17,-112,123,-90,4,-35,103,16,-41,26,-104,109,-119,-71,95,28,60,-71,-41,-26,5,-118,-31,-126,58,-93,-50,-48,30,-51,-31,-2,-92,-75,85,-52,71,112,-48,74,-65,-24,41,104,121,-95,122,-83,-49,119,-20,38,97,23,-73,-22,55,-118,45,25,-37,47,-122,89,-4,125,-105,37,55,102,52,-12,34,7,85,15,-6,17,13,18,97,20,-92,79,107,-16,117,-80,60,-3,-23,81,-70,124,52,-36,105,-44,-125,-40,-81,28,88,-57,-111,-96,-49,18,-5,71,-37,32,-73,53,1,-124,77,-70,-107,33,-79,-83,-34,-125,43,20,-55,15,-53,59,59,-97,71,44,78,80,33,-20,65,68,-72,-125,23,-30,-3,-89,93,64,88,123,-44,126,117,59,38,-5,32,40,125,124,98,-104,-31,-59,-27,98,12,125,-43,-48,-74,43,62,-6,73,-3,19,100,-104,-62,35,47,-8,37,60,-125,-100,95,49,-74,-15,8,76,58,14,-85,20,-56,29,70,-125,94,-60,-56,-112,82,73,92,78,-40,-37,37,-50,22,19,63,23,-49,116,27,113,82,-5,24,46,85,41,106,-11,102,-123,60,45,-108,63,124,-67,114,53,-14,-126,-108,64,-6,-27,-19,-101,-27,102,112,-45,93,-4,-36,-68,-111,93,-64,69,-128,-109,-78,-16,-62,-79,-51,-8,-39,-40,-94,-4,123,-117,70,87,-91,-79,15,18,98,11,-51,-104,-76,-59,40,-82,110,100,102,13,71,42,117,-81,-41,-120,-48,-17,-20,44,-44,-120,76,79,123,-128,111,-51,71,-41,-76,-86,-32,80,-43,124,-65,123,21,5,5,55,34,73,-46,-55,58,-108,116,110,85,59,-61,-24,-86,111,-34,-128,-111,59,45,-125,-94,-47,-90,48,-109,-56,-95,-37,-127,79,-17,102,-52,-96,16,-77,31,40,-59,-93,-26,10,-28,108,-2,-85,95,-25,-88,-94,120,30,-24,-69,-9,90,81,67,-92,123,116,42,12,123,88,86,-86,10,-16,-77,54,-119,-54,-43,-7,104,-111,-75,-3,63,-96,-95,112,-68,80,68,-128,3,-13,-37,74,-113,62,-88,-32,-40,-48,55,-21,-64,64,118,-126,-41,-79,-75,-112,-78,-81,19,20,-10,86,97,-20,127,101,56,118,69,-62,73,52,125,-15,-84,-30,65,105,-53,-59,-54,87,-87,87,-116,49,-120,71,-48,-108,99,-19,-107,-98,-40,58,86,-119,-125,-62,-38,23,91,85,-55,52,-31,123,-76,120,77,49,122,-118,-19,-56,86,-74,-15,-82,47,-121,-83,21,-69,119,-86,-39,59,-84,87,1,19,-58,-67,-122,-45,54,-38,-96,-13,100,-91,-118,-97,-72,73,-30,23,-121,-30,-36,94,-38,20,22,-4,-85,-7,50,114,-105,95,35,-85,-41,-89,93,8,-53,45,87,93,117,30,17,-61,69,-61,48,-52,-75,-99,-104,-113,-27,10,80,89,119,107,-76,-30,75,125,122,55,-13,8,-37,-37,13,24,33,31,98,-14,101,-51,24,27,37,-51,110,-15,83,-49,-122,85,-30,18,-17,92,101,12,97,-54,-99,4,73,-82,-46,111,29,-7,-75,90,106,-91,45,68,-111,68,-63,99,86,-74,-122,-35,21,-28,-22,74,-80,-70,-93,50,-9,14,-84,45,-18,-41,-50,-105,-94,82,-89,102,74,-38,120,90,43,-17,-82,-83,-119,-17,-106,52,-80,-63,123,124,75,-118,98,0,-100,-76,77,-72,-18,80,-49,61,100,107,89,-27,93,-70,-52,-68,-89,-46,49,-9,-77,13,-29,103,-52,-69,-88,-65,-33,39,-119,-105,29,96,48,86,-76,55,62,-128,109,5,73,-94,-11,-43,-82,-32,52,122,33,29,63,-40,-89,-88,77,-16,67,-69,-106,-59,112,59,6,-67,-92,-115,107,-120,40,38,69,-33,87,81,9,8,9,-31,-110,-68,113,-117,44,-81,-62,-85,-23,77,-6,84,-63,-126,58,105,-48,75,38,80,-2,-45,34,-62,107,-8,-16,-82,-17,-128,57,-113,12,-99,-110,-47,100,-44,-23,121,42,-29,34,-64,100,-124,123,105,-7,-128,117,5,13,-13,-125,112,86,-4,53,-128,-81,-87,-75,-18,116,-77,-110,-122,100,-60,-124,117,82,-35,77,87,29,125,-127,123,-54,100,-117,-100,-49,-105,-77,2,-110,-4,-101,6,53,63,-103,76,-118,-40,108,-103,52,122,-3,54,57,-86,65,86,4,-106,-99,82,68,-44,15,-41,17,51,4,92,22,-63,-83,-126,63,65,-115,76,-109,80,-50,16,79,105,-115,96,-71,34,-61,-89,92,98,-36,-88,56,113,18,-123,120,32,110,81,108,-29,-31,34,-102,-24,-33,-8,76,25,-128,77,90,84,76,-98,-104,-4,-105,-65,-62,10,29,-80,-116,89,120,101,-36,22,-85,77,-44,3,-107,63,-19,45,-126,16,1,-29,31,-125,113,-108,30,-103,-127,-38,26,-18,-120,-56,-121,32,-25,102,-7,-85,-50,47,-121,-109,-127,-6,-34,55,-34,-114,82,-6,83,-44,-2,-69,101,-34,-21,123,33,25,-23,-108,-46,-107,-46,56,38,-30,108,106,-31,60,-78,8,4,25,124,12,37,29,2,89,40,100,-48,21,-53,-87,109,-116,77,-46,-60,-64,122,-68,-25,-109,28,-71,62,121,-73,-84,80,12,-88,-118,-89,109,-74,106,-62,89,-65,58,-73,-74,-110,-64,-73,-27,-87,96,-128,-122,54,-72,42,22,-37,73,-87,6,31,29,-46,62,23,-99,63,114,-20,10,-43,68,15,-24,124,-63,-25,76,-12,30,-43,-86,38,111,69,-121,-5,-49,-42,34,-51,119,80,39,86,-32,-74,27,-71,-24,-25,73,74,-11,104,53,117,87,-11,-32,-115,-24,-78,99,-7,-113,-76,-99,112,-20,50,121,-9,-103,111,-10,-68,-9,96,-35,-108,10,2,-38,-18,-73,90,-64,-105,94,-22,103,22,116,-68,99,-42,124,-117,-122,-119,-43,47,-6,72,90,52,-52,-76,2,-84,-22,-19,-85,92,-124,13,-115,2,36,107,15,-76,127,47,-39,3,-109,90,-24,-74,1,-29,-17,-21,-27,32,102,-57,26,-108,-114,-104,-112,76,-47,86,-17,-86,38,114,106,-81,-77,67,52,-28,-68,23,-63,-57,-110,95,-81,-35,-97,-96,-29,-11,64,-118,-1,-99,-25,68,-24,-118,-84,-113,68,94,-39,93,77,-80,-1,-123,12,97,80,-117,111,-52,5,5,-24,-98,-27,-96,48,-37,-108,-28,70,63,-21,23,123,67,-33,47,-96,-58,-50,-109,-124,-64,20,-37,44,-101,34,100,95,94,-57,-4,39,-21,-62,-37,-76,-72,-51,114,10,-21,113,-68,45,27,-77,105,47,18,122,43,-117,-99,-82,-15,40,-7,112,-86,27,-37,83,-53,-8,1,-110,64,47,-58,44,14,-50,18,-33,-17,69,-90,51,-58,35,-103,29,38,100,107,-44,106,-99,-49,-90,107,23,-44,-79,-21,7,-10,40,-58,-76,-50,-106,-47,84,34,91,23,-9,113,114,-91,-11,-62,64,58,20,44,-76,-55,-105,38,-101,94,121,-125,81,-128,-55,-101,-22,78,100,43,94,118,-46,-103,-36,48,81,45,90,2,-3,44,-8,-49,-66,104,116,-69,-90,-78,28,15,-65,-31,103,14,-71,-103,-90,36,-54,-81,-62,-35,70,-60,103,45,-13,20,-32,127,-93,59,127,-89,-54,-23,117,77,48,3,-84,-56,-35,37,87,-115,60,11,-27,103,44,78,-16,-3,-112,-44,45,-112,61,-102,-104,-67,88,102,121,104,-106,46,-39,-91,52,-77,-13,118,-79,-52,61,-5,-90,46,24,-84,-59,57,-34,-62,101,47,-66,122,-18,28,102,-123,32,-19,121,12,81,-110,89,-38,-78,8,-78,-2,-94,44,111,-2,-36,-66,22,-59,83,-43,92,-29,60,-71,92,7,-51,19,-2,-66,39,-100,116,92,-78,7,124,107,103,127,-115,62,80,99,98,-74,-95,109,-3,-126,59,-61,-93,-58,11,87,-24,113,100,21,-65,-103,-71,-106,122,-71,96,100,-38,-23,-118,72,0,-68,-55,-108,88,82,73,119,-105,59,-90,-41,99,76,37,-41,-62,18,94,-37,67,56,68,-41,110,-24,53,14,-62,-121,38,-84,13,48,48,116,-17,-80,110,-63,50,8,-4,111,-77,-4,77,112,19,64,-9,-32,-45,77,72,-90,-127,74,88,-61,-85,-75,63,125,-46,-86,-15,79,116,7,76,46,-99,14,36,-55,0,76,95,101,-115,-18,67,-35,71,-104,95,8,-124,-42,38,13,-70,98,18,77,51,-27,-82,-61,-66,26,2,2,-26,-119,-61,-70,44,27,114,99,-99,97,14,34,63,-44,-88,65,82,-47,30,-99,-97,-13,13,48,47,117,4,-29,37,-7,11,28,78,-59,41,-94,8,-125,99,32,-109,-13,14,-58,11,100,101,-94,-61,-49,45,90,47,77,84,19,12,-86,-24,-63,112,73,-48,4,-91,47,54,3,67,68,5,-26,-64,-71,110,113,-96,23,105,-14,-79,67,-18,36,-35,48,-36,68,-33,56,-5,39,-56,-11,-20,-43,6,-33,82,121,29,-78,8,28,-29,-76,-101,-81,116,-72,-98,97,-16,107,123,-89,-47,102,-84,-113,-107,-24,105,-112,-67,-41,-77,-18,29,-19,49,54,49,20,41,63,84,103,15,33,50,-118,-25,42,87,48,61,-48,-121,-74,16,-85,-13,-14,6,-76,82,-68,90,-4,-40,17,2,-101,81,102,-80,-2,-64,-74,-54,8,7,99,-117,21,21,74,-50,-36,-89,85,-75,-35,-29,2,-105,-55,2,71,28,-118,53,-84,126,2,9,-104,-20,45,4,-113,76,10,124,81,83,88,50,66,95,44,-110,17,122,30,92,26,-85,-53,73,-32,-78,-127,5,34,3,-75,81,-15,54,-13,9,-126,-42,-102,7,119,96,34,109,67,6,-70,116,-26,9,103,19,116,-9,88,-12,39,-88,92,85,-87,91,33,-43,96,120,-59,-53,12,84,-18,-68,3,-87,48,-99,87,-28,21,-88,-93,86,116,63,100,33,-65,-56,-36,-36,-38,-80,-62,-97,-87,66,77,-65,103,85,-99,73,103,102,-80,104,-70,60,-6,-96,-67,1,-44,-1,90,-80,-59,93,39,-81,63,66,-35,17,-56,-58,-49,83,-80,71,-54,-111,-7,92,-48,29,56,-7,-107,-114,21,-75,54,-124,-60,-3,-78,-13,-110,61,123,80,96,-49,-105,-115,112,-29,-68,126,-74,-87,82,70,-70,16,-84,53,-16,22,29,-40,-47,-90,14,-117,6,-3,-13,64,87,-84,-100,52,-57,23,108,74,59,-37,82,45,20,87,-65,52,-96,57,-61,2,-33,-39,78,-79,-61,84,63,34,27,37,-13,12,32,101,9,-16,21,-19,59,-119,57,-97,-124,127,76,6,83,80,27,-31,102,-105,56,118,85,89,16,98,-57,68,6,3,58,-95,-78,-77,26,-26,-21,5,-113,23,90,-110,-16,35,-108,-23,-47,-14,-42,102,119,46,10,58,83,-117,-49,80,-38,-58,80,25,-85,40,-2,-54,-35,-100,-77,-80,87,-122,-94,-45,-115,63,-10,86,84,-47,101,-114,123,111,71,-75,-111,-47,43,-35,-99,-22,-3,106,-89,-94,22,111,-52,95,104,-17,71,96,7,10,-99,-90,-38,32,-81,-7,30,-112,-16,-11,-104,106,-30,78,-110,99,30,-31,111,-125,-50,-19,-66,-50,109,-113,26,95,-74,-86,4,-66,70,-4,-2,-14,-86,-83,118,48,-62,-30,-2,-78,102,-105,83,-45,37,58,100,53,-66,46,-104,-25,125,-112,49,89,95,75,88,22,19,-76,101,-35,39,20,-82,54,61,-40,-106,-83,32,-106,-80,116,-52,-45,-126,-86,-56,-71,52,108,70,39,-24,103,71,121,117,120,9,5,-97,110,-79,-39,77,-56,71,-90,-97,3,-8,-64,-5,-102,105,59,-76,-100,-65,-99,-7,-6,85,115,14,112,118,65,-60,10,116,68,-83,69,-118,23,13,24,40,68,-2,-78,-43,79,-63,96,-5,-19,19,-56,94,-79,96,-7,19,-93,31,-47,30,22,89,43,-104,61,29,-49,-111,61,-41,121,32,116,121,-17,-109,-51,51,7,-6,-80,-84,-105,-41,88,-61,16,91,115,69,-25,-80,-12,45,-70,80,75,-22,-38,111,15,-71,39,62,68,-51,40,11,-9,51,44,29,-27,-106,112,-95,29,-105,-114,68,105,-109,-68,-13,-82,33,51,50,-48,-65,-103,-46,13,-29,-51,17,54,123,-91,108,-73,43,-120,27,100,-13,32,52,123,33,-52,-43,-110,-79,-76,-30,-86,-90,109,49,103,-28,39,-52,41,106,0,-13,10,124,-57,-15,10,-124,74,26,91,114,-63,-48,52,11,83,-44,95,13,-23,-57,114,82,-108,96,39,-34,27,29,-60,30,99,5,-101,-128,117,-74,-47,-118,-33,-69,-121,-18,-112,20,-6,117,-35,-80,-35,-102,109,24,-33,-5,47,-13,101,-127,4,25,1,-57,-117,-65,74,-107,-64,125,0,-60,-78,110,-100,-19,-1,-63,27,-17,61,-75,-84,-56,-29,-25,21,46,107,88,-33,109,-89,83,-83,-121,-100,-55,-48,29,-3,28,98,-59,-64,-73,-65,-86,-63,30,92,4,-29,65,-26,-111,47,1,-21,-109,26,-86,-119,113,-1,-29,-88,75,77,-54,-35,-95,22,24,-40,80,127,-56,-24,125,43,-18,97,-32,-77,61,-85,-105,69,19,9,127,65,10,9,-76,90,-37,-2,-15,-18,-57,2,11,27,-51,109,17,28,2,90,22,69,98,-55,-53,-63,125,48,44,-13,-96,-94,65,-116,88,-2,76,72,61,79,64,12,-112,-11,72,44,-103,-29,-24,106,78,91,-93,72,74,-123,-121,-36,4,79,-28,92,83,-109,-99,-98,63,92,-39,98,94,-43,10,-57,83,-23,50,92,79,-111,-79,-32,40,-34,91,-26,115,-124,68,-19,-72,56,-101,60,-73,-55,-83,36,-59,-86,3,-73,-98,-85,103,3,10,-113,53,34,-90,112,-122,-114,26,46,52,58,51,-101,29,-1,-87,-108,25,-77,-51,0,97,32,-36,57,117,67,-124,-61,-67,13,8,-108,-59,-50,28,95,10,-112,124,105,-127,-54,-43,-86,53,-50,-1,-108,65,-111,35,-42,-119,-28,-47,-92,15,-97,-50,12,-42,63,10,-71,-23,22,83,-24,20,-28,69,114,108,98,29,3,123,-42,-101,120,-36,13,-44,87,74,15,-89,77,-23,56,65,-12,19,54,66,-31,-111,-16,109,-43,-87,111,69,79,124,-8,-17,-46,15,-48,61,-28,-72,108,-58,-55,83,53,-80,118,-88,43,-54,74,-38,-102,56,116,-125,-80,-75,-3,43,105,88,-66,-120,117,-58,82,-5,74,6,78,-79,-72,-51,85,-100,-49,123,-42,90,4,-33,-55,127,88,60,-115,-123,20,123,117,-75,9,122,-19,-98,-97,-15,90,92,-32,94,-86,68,41,93,106,-41,-60,-80,40,-91,24,-86,-39,-120,73,-27,125,65,-87,-123,-41,35,-9,113,91,-111,-40,2,5,83,34,-66,114,90,-111,57,126,62,-93,-117,5,-68,60,11,-105,-33,-35,51,-52,97,-45,83,117,-81,36,45,59,64,-43,-62,69,110,-95,88,102,107,-125,-97,43,-122,95,4,1,25,-51,-12,43,100,-22,98,-64,64,94,-74,45,-46,-38,102,-21,29,-37,-123,-104,-2,119,-40,115,15,-31,2,21,75,-115,82,-8,74,18,8,27,90,-80,88,10,-104,37,-1,-82,80,77,-97,-99,35,-105,40,110,24,-49,99,-94,20,43,40,-40,113,10,-71,43,-22,-63,77,64,-79,-3,-82,-44,23,-53,86,110,97,-124,-27,-106,104,-95,-96,-121,-14,25,74,54,72,120,107,-128,-60,-9,21,49,-12,-67,18,-30,-91,-33,77,40,33,38,-70,7,-89,-43,44,-12,-108,111,14,36,85,-15,112,-85,-48,-109,98,57,-17,100,85,-123,-111,-72,60,15,11,-124,90,-105,-107,7,-121,91,-98,-10,83,-116,54,-10,-128,64,38,59,64,-25,-17,36,101,-96,67,-108,-89,46,26,20,126,-71,0,-1,77,32,-31,-72,-29,44,-8,-14,-74,42,-21,-11,95,119,123,84,-128,30,20,27,-74,38,-122,-11,41,94,-33,-51,-115,45,7,74,80,35,-30,18,-101,-6,-92,95,-69,33,15,16,-59,-111,-67,3,-86,28,40,-43,68,27,-95,-111,-26,98,83,38,106,-126,86,-34,-54,-102,-88,-110,38,40,46,-37,81,11,-8,-122,-46,30,90,112,-40,95,-73,-61,77,-123,105,-44,32,-109,81,-110,-23,127,81,-83,-55,77,-44,62,-33,-70,4,-62,52,115,-36,32,-96,-123,86,-33,127,86,43,38,53,21,-125,106,-69,-16,-98,84,-80,-12,-25,17,-70,-72,-33,34,-115,-119,42,48,-34,6,-18,91,-19,22,46,0,-92,-27,-116,106,35,78,50,44,-110,-113,14,7,18,-123,-112,22,113,-91,-17,-51,88,-83,-19,-51,30,28,-64,109,-114,86,-33,73,30,-1,-58,-121,51,-109,104,86,89,119,-76,-28,-90,-95,69,-100,-55,-23,58,-14,-112,30,125,-77,72,-99,39,55,67,54,4,-6,52,50,-47,92,-26,6,3,76,96,89,126,97,80,-80,-76,-100,67,-119,58,-36,-13,16,53,53,5,123,31,106,33,-67,-27,111,48,7,23,-111,-110,-42,-105,-16,38,43,-17,51,-12,-98,-32,89,3,64,65,118,21,-66,-93,-1,-115,93,7,-75,-25,126,107,59,-19,-26,-107,14,75,45,-110,-16,-34,50,-11,2,-109,19,125,-61,-94,-63,-24,123,-11,54,121,-115,-16,-39,2,98,77,102,52,90,-110,-55,-119,109,-47,-121,119,116,65,68,6,6,22,103,49,-121,-117,119,-90,-38,124,-32,90,104,109,-16,-92,-100,61,-115,60,-107,-26,93,111,27,-124,54,-77,-72,123,-79,-89,89,-54,-94,59,108,-49,78,-4,-108,-28,-119,42,55,36,95,-7,123,-99,-42,-6,-100,91,-65,32,-24,-77,106,-5,59,-93,-100,35,115,70,-90,-6,-7,40,-20,76,105,-32,-74,-32,77,-91,114,-126,49,-83,-81,113,84,80,-69,-13,-99,-29,-103,-69,102,-108,-127,-43,87,-11,-126,119,-113,-104,-11,62,79,26,-90,7,-22,-64,-107,77,77,-83,24,52,-90,-57,10,114,-22,-38,115,-52,-37,-63,-76,94,-13,-56,-96,59,78,33,85,-97,-82,10,74,-113,-95,-78,99,50,-66,4,32,69,102,20,-76,-57,-69,-26,5,127,-105,94,-72,-117,-19,-7,-38,-91,24,59,86,9,91,-58,126,-126,-81,-39,28,124,35,101,74,-90,120,54,14,-108,-31,80,94,50,-40,-56,26,19,-5,-37,-39,-117,-45,9,37,83,53,-73,-22,-102,-107,-104,38,-125,-126,90,-106,-98,74,72,21,-56,-76,20,109,52,29,-45,-42,51,-51,-1,122,12,91,-18,-69,-3,55,51,-111,123,-106,11,-108,51,-93,96,-100,-87,91,-51,70,15,-39,-81,35,-54,62,-87,33,-125,-64,-111,14,-89,-109,70,-36,-122,65,-47,126,-119,126,-49,-34,126,46,-87,88,-107,-117,119,29,25,-65,-89,62,-88,-89,-117,103,9,100,-36,56,95,79,-124,66,-126,-5,-9,9,-95,-95,-93,54,-54,-2,81,-106,-25,21,108,105,-9,-37,-97,69,84,122,39,-124,59,98,-25,-67,35,18,48,-105,78,117,-75,-42,-76,3,-107,76,3,79,-81,-61,-99,30,-99,101,-94,-118,112,-88,-82,-19,103,-67,-71,76,-105,-24,-20,-91,83,90,-7,120,34,-26,75,-110,41,62,-77,-116,23,109,74,107,-78,94,26,-125,-13,27,99,49,77,-73,87,100,77,0,93,88,-23,-115,-108,-36,-24,123,-60,-65,-63,-44,19,0,102,-19,69,89,85,-96,-103,88,123,108,-68,119,-99,89,-56,11,116,-106,-68,97,6,-60,52,47,-1,-53,-55,94,-107,-3,-105,-9,-3,-21,-37,-69,18,-59,37,78,127,118,-117,107,-79,-43,124,-108,33,-121,52,-25,-71,76,-2,64,27,-52,88,68,14,25,57,-115,30,-36,63,-16,-75,92,-57,110,-105,-82,-72,-21,30,113,-20,-92,-15,-77,-25,-20,106,22,79,56,21,68,115,98,71,32,122,20,-70,112,62,38,105,48,115,15,47,-124,-71,48,-41,-85,-6,127,9,122,-68,110,-45,-35,-103,-21,122,30,42,-70,68,9,13,83,105,110,98,8,-42,93,-26,117,21,-42,27,-82,110,-123,-98,10,-5,22,-112,29,-32,109,7,31,-91,22,-56,71,60,29,4,-126,63,-64,74,-77,-53,92,-54,-7,-128,72,-92,-20,6,-89,52,-20,46,32,-119,-94,-90,-92,74,106,22,-50,-69,88,107,8,55,3,-102,-64,-106,28,74,13,97,96,110,-59,83,58,-95,-49,87,-106,71,9,125,-19,26,-26,-28,-93,-52,20,49,-63,-73,-11,14,112,121,-65,-128,88,4,72,-29,-117,-74,-33,102,21,125,112,-82,-49,-7,-28,46,82,-71,12,4,118,121,97,28,16,85,50,-24,78,76,74,-47,107,-67,63,-112,-94,93,-59,-32,-48,119,84,74,108,52,-113,-96,-17,27,122,23,-67,-10,33,-54,-63,49,57,-58,-103,54,20,-18,102,-78,-125,20,62,109,7,107,-20,31,-85,104,5,81,-61,51,98,125,-32,125,-90,-100,6,104,64,56,126,-86,24,109,23,15,-100,23,50,-83,22,30,-128,123,-82,-89,14,-82,-48,-36,-92,-12,-65,10,107,-124,-61,-36,-75,0,49,-105,26,101,119,120,-37,-89,-38,18,-55,-118,-47,-92,-17,-14,48,-50,-72,-100,112,-125,-106,126,-114,-23,-105,102,-41,-7,-5,-25,87,71,-111,-76,-11,-106,57,39,-84,-28,123,47,50,-23,-66,102,-101,-65,103,10,32,84,82,32,34,-112,-14,-109,-125,79,28,97,-18,38,56,-70,-36,-6,-78,33,-80,-120,104,27,68,41,93,125,-95,90,-18,-33,-97,-102,53,4,-79,-27,30,41,-51,-72,-74,-102,92,28,-56,122,114,-105,121,-51,8,63,-117,-56,126,-127,-126,84,49,30,-76,-45,-13,53,57,34,3,-85,49,41,-112,-71,127,22,-111,-114,-34,-45,38,44,97,4,52,-111,-35,-98,-24,-53,42,-118,74,-86,-19,-52,-119,-88,22,119,-89,71,112,26,-21,52,35,65,126,117,-110,47,4,-66,21,-8,-51,-72,-120,72,-107,85,3,72,73,-27,-36,19,-114,71,-89,-111,-100,116,-97,-53,87,-68,-121,-29,17,-60,-28,-64,116,11,45,-125,-83,-55,71,4,-3,-123,53,-122,42,-45,104,101,-22,81,-24,49,-37,91,-2,44,-77,-72,-64,-80,-100,-75,-26,-102,108,19,-107,-23,-51,-11,-4,-18,118,-18,125,-84,90,41,8,30,-54,21,-91,-115,102,-99,-35,6,-35,24,102,26,-108,-8,39,-93,1,76,124,-9,28,114,-39,44,9,72,-72,67,-24,-41,-3,-92,-58,-31,-57,29,127,36,16,-87,-1,-124,-34,57,-23,118,-38,51,-19,121,15,-2,-44,8,-87,-82,-47,71,-14,16,-41,48,79,17,118,-83,-84,5,-62,-127,-20,28,-12,54,-95,115,-89,124,-18,-118,40,-125,-97,15,3,89,-21,-19,45,23,-58,39,-1,19,-18,127,-121,-46,2,-24,38,-64,-48,19,81,-16,80,-37,-128,123,-43,36,-73,-127,55,-62,121,14,93,42,56,-117,-43,24,-99,-79,-46,-34,-112,-99,38,11,-19,23,-70,-121,-128,-81,-110,-76,88,-53,-51,-128,51,52,54,-58,-80,-35,83,20,10,27,-109,112,119,38,-19,120,97,67,24,-65,51,84,37,-8,112,67,6,-127,-104,-50,118,58,-1,-97,-94,78,-103,10,30,-95,-94,-42,107,-67,-41,-39,63,-108,27,91,21,-23,-88,-118,-55,-1,-28,-9,16,-29,-37,-55,-80,78,-82,-112,62,48,46,-41,1,34,50,12,-53,46,123,1,37,71,108,3,41,-123,-94,-50,-16,8,-42,86,-39,51,-24,119,20,-55,22,115,-82,114,-86,-110,8,-15,-72,74,83,14,93,59,122,107,3,-17,93,41,51,-56,-125,-21,28,38,-59,69,71,-48,111,38,79,-29,-23,-17,0,-110,75,87,113,32,50,-113,4,-4,12,-20,-27,-61,-41,-117,-56,-99,-77,115,-87,-99,40,-95,-99,-31,26,-102,119,-53,2,4,29,-21,-86,94,112,-82,45,23,-65,-23,-85,-97,-17,100,75,-110,116,1,-109,29,-111,80,-90,74,93,3,95,-48,112,-106,-18,77,25,-29,-22,-117,72,94,9,113,95,-1,-104,-28,-124,12,97,66,-109,33,-94,91,-29,-88,-102,-76,77,21,-65,51,95,54,-16,78,-116,78,-79,-51,-107,-123,2,49,40,-124,-90,97,64,-3,-105,71,14,-114,112,3,124,-83,-105,94,-50,35,59,73,-63,120,-43,116,16,-91,-46,-117,-18,-108,-26,-84,84,75,123,-21,-97,-118,-119,34,72,-59,-108,-65,-104,21,70,-108,63,-35,-26,-63,-11,-55,53,-125,-81,-58,-115,-54,-16,59,7,-12,0,-67,126,81,-72,-118,-76,121,-13,5,27,80,-23,87,-125,-85,-14,-37,-6,-56,-79,-118,-19,-43,-45,72,71,-91,-49,31,-121,34,-90,89,-22,46,116,-62,-59,-4,49,12,23,-39,40,88,-54,12,120,34,26,42,-7,-18,-89,67,-37,123,61,74,-91,-36,-38,15,-104,113,46,0,54,28,100,-44,-75,25,-56,28,103,44,-92,34,-100,-113,28,-75,-16,-121,-7,38,58,-99,66,-20,-2,-122,-19,110,11,-58,45,-72,17,38,-45,6,41,64,-86,36,44,91,-45,17,-93,43,-73,-41,-70,52,121,-71,53,-90,14,115,110,29,36,-46,-75,92,97,102,-53,-88,-32,53,122,-39,20,55,-102,-101,117,82,-26,14,46,-120,-91,85,36,101,-108,-81,-26,-18,115,-50,-47,7,18,-125,-24,-46,33,-24,-108,-71,33,41,99,47,-66,-43,-25,117,10,53,-2,10,-14,126,-112,104,-74,-77,-57,24,-30,81,93,115,69,89,10,90,34,88,-116,-90,65,72,43,123,51,-85,55,8,-12,13,10,-90,-37,123,-4,109,40,105,112,99,64,-74,-83,104,44,-20,-16,54,25,-82,-54,64,-109,-37,-3,107,-17,124,14,60,-64,-47,-72,-84,40,-74,89,6,36,-98,-125,30,63,14,-70,109,-62,-38,112,127,-41,52,115,27,-56,-112,76,-107,-65,-118,26,-74,-53,-96,114,-120,78,24,77,48,60,29,49,-117,-15,-91,1,-26,58,-84,-9,-109,-115,-89,-21,82,104,36,116,-103,121,93,-50,-39,-103,37,52,-108,-28,49,-87,-115,-93,38,-37,-68,-28,14,-26,-41,19,107,-2,-107,-37,-49,11,17,-120,24,24,-110,-100,93,46,-84,-122,38,6,-53,-7,98,102,65,35,-8,-6,44,-99,86,-5,67,-4,-65,13,66,23,-111,24,19,7,9,-92,29,114,58,-43,-105,-61,-33,34,-57,-26,5,-11,77,48,0,-41,-49,22,-20,-44,-30,-99,10,45,47,-51,-29,20,-11,-61,104,99,-15,21,-67,44,-71,108,-83,-11,-104,57,39,-84,2,122,14,127,-110,5,-79,98,95,23,89,3,68,-87,94,-9,40,104,107,24,-97,26,-36,-111,-95,-100,31,-97,49,77,-69,112,-96,-111,-45,89,-9,127,114,85,-102,-5,16,-1,-53,31,-69,-53,113,-6,84,-6,-18,62,-44,-73,68,-15,-105,-36,127,12,-27,-28,-31,-42,51,-121,86,-19,-111,-86,-119,93,-74,67,32,51,73,35,-106,18,70,44,72,-82,50,-19,-45,98,-60,-84,-67,-84,-126,-5,38,-67,-2,-62,-54,-23,-110,113,-14,-89,52,28,-61,11,4,70,-100,-35,0,-46,-124,-11,49,118,39,-80,-70,-100,-120,-54,-69,102,59,39,16,-49,53,-50,-27,44,90,-115,69,-102,-113,65,20,-47,59,-115,127,-19,-54,-19,-27,-28,-94,39,65,-114,-115,75,-46,-85,75,-4,-67,127,27,-98,-42,1,-124,-43,22,-21,-27,-74,53,-45,-90,127,-83,-44,-86,-23,10,36,86,59,99,-126,108,-59,-99,-45,-16,91,-33,110,-120,106,-87,19,122,115,-86,85,67,-83,-4,-57,-111,4,-5,-58,-91,-2,95,11,-53,107,-68,-128,-68,-12,85,19,-36,-40,-56,10,-64,58,-12,-32,79,20,37,-65,-33,-9,88,123,114,94,31,67,-32,-2,86,-124,-116,-62,-100,41,-17,35,-81,67,-110,-85,83,45,-121,5,-120,-3,47,14,-65,-78,-114,-87,-9,-19,-21,-7,106,74,117,-40,78,-33,63,61,-70,26,56,-9,76,-121,14,-77,87,-125,69,-32,-101,50,30,104,-59,-117,43,80,-98,-11,-94,-23,-108,52,-38,97,24,-10,-41,125,-119,-19,-42,-56,25,65,7,-39,-102,-4,110,109,74,18,13,-126,96,95,-89,99,15,-3,106,6,72,35,82,-78,-15,73,116,61,-127,-83,54,98,-17,2,-7,88,-57,-37,-39,-102,-79,31,-6,111,-62,-24,103,69,74,113,-15,65,68,37,-65,123,94,117,-121,-32,-78,-5,120,59,104,60,68,5,-65,4,64,-85,-80,117,-101,61,46,-88,69,-123,-19,-57,-15,97,125,54,-23,84,-124,-27,114,-47,16,104,-100,44,-87,36,-27,81,-20,-73,-80,95,-64,-34,29,-77,66,-126,77,-120,105,-100,79,44,116,-18,-15,-27,-71,19,12,-80,-18,27,45,-92,116,-27,-14,14,-77,1,-40,-110,-26,-4,-120,-88,60,51,108,-101,-123,116,-83,111,1,-74,-69,87,11,124,2,93,-64,121,-45,62,-79,110,-37,-55,97,27,110,-79,-91,67,99,53,26,-74,43,98,9,-43,-103,80,-23,60,68,-36,-112,-64,-31,20,-52,-79,-7,-113,94,-30,-100,73,55,-111,-1,87,-29,-25,-94,42,-13,-63,-59,108,38,-16,-62,-85,-17,0,-90,47,116,-80,12,-11,-54,96,-12,-110,-6,-128,-64,-31,-109,103,58,-11,-118,-3,0,-102,64,39,-18,-67,93,95,102,-87,104,88,-62,-31,-36,-61,-105,-26,46,-53,117,93,-70,-54,-103,121,52,-24,82,-10,-124,-22,-122,29,84,-76,121,-64,-65,-6,80,52,-27,7,108,-118,64,-82,-44,73,81,-107,84,-88,-100,-59,-56,9,35,-39,-82,-68,26,65,-66,-73,-15,75,-31,-44,51,-65,-73,-62,100,51,78,-51,-112,-84,82,-19,93,-92,-69,53,-38,-66,127,5,-30,61,26,43,48,-63,24,31,-71,-67,-127,-60,-55,-26,38,-43,-63,-49,-37,-101,116,105,-109,10,3,-67,17,-42,-89,110,62,-103,-41,78,-47,-59,-47,-17,-51,10,-16,-31,68,-41,37,15,-123,94,101,77,116,-122,61,-96,-122,-8,-11,105,-74,109,-97,-111,114,44,105,45,42,-94,-99,-52,122,-113,87,-59,-109,85,-128,120,-49,21,-75,-89,-10,11,120,-51,-19,30,-79,-26,64,-32,-71,28,-11,-44,55,-28,109,59,-84,-22,-55,-113,-105,114,80,50,-26,77,54,36,42,-71,-64,-111,118,99,-121,-100,-128,56,-75,-10,-74,30,36,93,-122,16,-50,-105,85,19,-84,-99,-72,-20,96,-63,75,-53,59,-86,90,-23,-39,-73,96,-118,-127,-9,-106,42,-84,-122,108,-18,81,29,-58,46,94,12,-2,-94,-75,33,85,61,-100,122,2,101,106,45,-49,-43,-63,22,-128,94,5,-115,38,35,54,-8,15,35,87,-114,-76,110,37,-50,20,-114,84,115,-13,48,54,14,-58,-93,112,43,77,9,32,-99,-91,-55,34,-82,23,-40,17,62,66,84,82,-3,117,-100,33,32,19,-100,102,93,101,-33,-103,112,-38,114,38,-1,-89,-90,-86,-9,-101,-66,41,-71,-113,5,21,-40,50,89,-73,123,5,45,-75,68,58,-107,-67,3,-64,89,45,-117,51,16,-119,36,69,-78,-18,94,-18,61,22,-124,97,-55,-97,112,19,119,7,65,-109,23,-15,88,-47,-103,-84,-62,106,-5,-108,73,-109,34,-116,33,81,-41,-102,81,67,20,67,-46,-40,-9,10,-49,121,-57,61,-33,28,42,-36,-67,-113,-38,-94,-89,-67,-28,-17,52,-116,-96,-51,117,29,-84,-53,-38,-53,-44,54,-110,98,-76,117,18,83,10,-62,-36,102,104,80,124,34,15,108,47,91,-112,-10,-116,66,-68,-123,55,-67,87,51,74,-47,25,-122,-34,57,32,96,-96,-64,67,-41,31,-124,-87,-15,76,-125,1,-77,13,99,47,-44,74,97,67,-4,108,-9,-16,44,36,-53,3,-120,105,99,-55,-34,-30,118,8,106,40,-95,-122,-65,14,-23,86,-26,-64,114,89,-59,97,-10,71,10,-108,-60,61,-87,-19,-4,-28,-1,-32,35,-123,55,109,-47,-126,-1,-124,-36,120,3,-107,-17,121,-80,31,25,79,-32,127,-19,103,-4,118,21,-55,70,125,-95,-104,-78,-2,-24,90,-33,97,-79,-92,20,126,49,60,121,41,56,120,113,-102,74,1,-28,44,46,-19,-46,100,-127,77,-64,-8,-12,-13,11,-15,89,22,-95,86,36,-105,110,84,-83,37,-40,-56,-92,19,-82,-17,-25,83,33,4,-111,76,-85,-54,35,-107,-72,127,76,89,-103,-123,28,-96,-47,95,77,107,-35,-98,52,59,-76,75,87,-14,-56,-27,75,117,-34,67,91,-92,-95,-45,-116,-13,-81,5,-35,83,10,85,-112,-38,117,89,43,123,-73,-43,104,36,-106,-80,47,113,-82,51,36,93,33,-84,11,-53,-128,-84,82,-86,-118,0,-33,-6,44,-122,35,81,-71,-44,-73,-64,126,98,-20,-49,-126,-104,46,44,-63,-17,-62,-74,-61,-48,-28,67,-25,-99,92,66,73,-38,49,45,-69,92,-26,-91,80,105,-30,48,-76,85,108,-98,-56,-95,102,47,6,-70,-118,-31,60,-112,-62,89,115,-78,-85,4,36,-1,72,-17,-100,-56,-2,-104,24,-54,-56,-92,-106,-60,-115,-53,-106,49,85,33,-79,54,-77,44,-120,47,41,-60,44,-8,-28,5,90,114,42,74,106,-57,-81,79,83,-67,-97,-90,-120,-16,-57,-88,34,9,7,-107,-59,-92,40,71,-32,113,-85,89,33,89,-58,-78,-50,-22,58,96,66,-19,-125,-39,-42,90,25,70,-104,-31,-90,-21,98,118,-111,102,-35,44,-117,60,86,-62,-47,-4,14,-88,46,79,6,-81,-5,101,99,-12,96,43,-27,42,65,-3,-120,-93,112,32,-6,-111,89,105,122,-67,50,57,-54,-126,-46,35,48,-41,0,-98,71,-22,45,-125,7,81,-26,23,-60,118,25,101,-95,-128,117,22,-126,-29,74,86,-39,-53,65,-86,64,-62,-77,-8,90,-85,54,-28,-128,124,-1,-112,127,105,-124,-40,63,123,123,-77,13,-84,-5,53,-31,-46,-74,-36,27,-16,13,-124,-98,-24,-115,-83,48,101,92,13,-98,-5,-111,-10,-40,-51,-115,-81,-52,-82,24,102,97,98,109,107,-46,-1,109,50,-48,40,-23,71,34,-70,-13,-111,110,43,-41,-9,108,-1,37,45,-72,-28,-45,-50,9,121,-66,-4,-86,-10,18,16,64,-119,-36,33,-13,5,-125,93,-6,19,-61,126,95,48,-116,11,125,-62,-6,67,-1,111,-54,2,45,82,-103,-4,-66,19,20,18,15,48,94,-91,119,33,82,-15,116,-24,15,67,30,111,-106,90,13,80,-20,71,65,66,108,124,-94,-104,-124,120,-95,59,-80,16,83,-101,90,14,-96,25,-64,-38,98,-24,-17,-69,-89,108,-29,-30,-101,-11,99,13,-56,53,72,52,105,105,88,2,26,75,23,-13,3,122,-114,71,-70,-29,-9,-98,58,67,-122,87,126,7,-30,111,-61,69,7,11,-6,103,-6,-16,-32,56,23,94,-31,29,-63,-47,5,67,61,110,43,57,54,41,28,74,-65,97,-22,74,-115,-126,86,0,-50,-83,-93,-3,116,5,22,-29,21,-79,34,-54,68,77,-34,-76,84,-116,-102,-31,-13,-55,64,85,-42,44,43,-115,85,100,-104,-60,103,-54,-65,120,-69,44,59,-102,107,81,89,-79,-44,121,70,-24,-110,51,76,75,117,-7,110,61,-102,42,-28,-28,-67,-12,-19,102,-27,18,115,121,-46,68,-124,-81,-110,-33,108,56,-83,30,-97,4,-79,-17,88,114,-86,105,17,-9,0,61,101,11,7,14,-100,58,-38,-42,27,121,119,-48,56,62,94,39,-20,-49,7,26,108,-99,-44,120,-2,87,-117,-78,-56,64,76,-83,26,-105,21,-3,81,8,-74,-100,67,50,9,58,-14,-118,-96,-13,27,65,-122,-73,-83,102,-40,-60,-120,-13,16,51,-51,112,-81,-15,-7,127,100,-116,-20,83,-72,59,-39,121,-43,114,55,97,-9,-53,107,56,45,49,106,-102,-126,-54,-44,59,18,-64,-75,101,62,-123,-110,-70,-17,24,57,-44,-122,104,-119,43,-40,18,-113,-107,25,122,-90,-19,123,74,-86,-35,107,102,-51,-22,56,-14,109,-100,-124,1,-85,35,-16,-124,-21,-65,1,30,-75,55,67,-121,-78,109,-102,82,-94,-23,-60,46,-104,0,-96,6,39,12,101,62,-39,37,-84,-92,3,48,68,34,-47,26,-67,60,-2,25,118,-110,77,91,46,2,43,103,-85,-107,-23,83,-23,-71,-110,-7,42,43,-82,16,57,-55,-102,-52,-32,32,-111,-70,75,116,116,-11,-44,-75,1,-14,-123,-128,-85,31,71,33,78,-72,-102,70,48,-72,-15,60,56,38,79,93,-83,114,75,-6,120,-78,25,-127,82,112,-37,-90,-92,-121,-112,-35,119,8,-32,-35,77,58,-9,109,-107,69,-21,11,-42,-128,-70,48,-23,-30,-78,-81,-123,30,-40,-8,-127,106,9,64,-78,-51,122,95,81,-109,-15,-43,118,27,-92,88,-109,37,-106,52,-62,-8,119,-45,73,65,127,-96,53,-115,-125,46,89,47,115,8,70,71,-40,-107,15,24,-119,-64,41,115,54,-11,-108,-103,-20,6,104,-67,-8,95,90,102,19,15,-22,73,13,-7,113,55,-53,-123,51,-110,40,37,-103,-83,-61,34,114,59,-25,-113,87,-103,-26,-10,88,-121,-65,-79,92,-63,123,-62,59,31,-87,-11,31,113,14,88,23,25,35,-49,-21,-83,-59,53,109,-72,-22,-64,89,59,-104,-42,24,52,-60,62,91,3,7,-21,61,15,-117,-109,65,-1,-39,25,-34,-37,26,-2,62,-51,61,24,50,-15,-32,-48,-55,25,36,24,6,99,94,-25,86,-84,-30,-95,-102,-94,-53,29,-81,65,69,-85,65,117,-7,0,-23,-66,-75,127,62,-108,10,-5,-4,66,29,-59,41,-82,-55,58,65,9,-128,55,-67,-58,-28,123,-121,99,-70,-99,11,-6,122,-108,119,-18,1,78,61,103,121,-104,117,-68,-22,-108,64,31,-68,-68,52,-96,41,58,-54,11,-26,118,75,14,-54,21,-119,60,-66,-19,-64,11,-5,76,-9,-97,81,-126,72,62,-115,64,23,117,65,73,-121,-87,-40,-48,-82,90,73,-91,42,57,-53,54,6,-11,102,-104,0,-117,70,52,103,-56,104,-1,-103,-12,32,59,123,12,-75,-104,16,-123,31,-35,55,20,-116,-109,-50,-44,-63,24,35,76,-116,-29,-32,16,-43,-68,-56,-115,32,109,-9,-34,126,-39,-74,74,-46,-19,-105,-82,-115,32,17,94,105,-103,-50,68,-121,-29,-7,53,74,77,-123,98,-68,37,62,-8,-21,-23,-99,4,-80,-103,-58,45,-2,-95,58,5,35,19,-37,-65,108,-14,-90,35,-53,-123,28,-5,39,-21,-38,17,70,-53,30,94,62,24,-74,34,14,101,46,20,-61,94,-121,125,-122,88,-127,36,-97,-98,110,80,80,14,72,10,8,95,4,50,113,27,-124,54,-117,-48,122,-39,52,8,94,61,40,-69,21,-34,7,-56,-90,-123,24,23,57,89,-87,-97,-80,-16,63,-50,76,-118,-25,-17,90,24,-4,-112,32,-94,58,-32,-12,11,28,48,-38,118,-69,107,92,61,-104,116,-62,-112,55,-110,0,127,-46,-54,-57,17,116,54,-36,-90,114,-39,-32,53,33,-69,37,72,-70,121,60,-84,22,-95,-74,-105,-7,-67,-41,-49,55,98,-57,60,-51,-107,31,48,48,-72,-38,-35,-5,29,65,-102,78,79,-8,71,-113,122,90,76,-55,-31,77,102,-66,107,-128,112,101,122,-62,-83,111,126,101,-75,-55,-118,68,52,-128,115,76,63,32,-6,90,6,100,-109,-59,98,19,109,-1,114,84,-58,-52,79,95,121,114,-77,-52,56,-114,-13,67,91,-51,50,-94,-115,113,-58,-33,56,55,-92,-120,80,-85,-125,126,-114,44,-126,22,-29,113,-82,-92,91,63,-39,-34,-90,-21,43,-3,113,-5,-81,-91,69,120,-59,-126,127,66,43,113,-111,47,-99,-46,-73,55,-13,-7,73,110,37,-76,68,13,105,94,-36,108,10,-127,-76,10,126,100,21,-117,-80,21,-95,94,-79,77,-72,-63,98,24,93,-124,7,25,-15,84,-62,-99,28,-82,-99,113,-65,13,62,-51,-117,37,115,-125,-40,-96,85,70,31,-27,26,2,57,-15,43,-112,-36,-72,-5,106,44,126,-97,111,-31,-66,-89,76,-114,51,-111,120,69,56,-106,-70,1,105,-54,-56,-8,-123,-92,-71,40,-20,-52,-93,-102,76,-104,48,77,76,-30,53,-113,40,-16,88,44,34,-107,53,18,95,-21,123,-115,-28,53,21,47,76,82,-58,-114,22,-104,-97,-90,73,109,7,-108,-96,-30,89,-84,-46,-47,-62,110,-128,25,-54,-75,55,-62,121,42,69,-62,54,25,7,-75,122,87,-68,88,-83,-95,38,-100,-103,-96,-57,74,109,-34,72,51,86,89,66,120,85,18,-84,95,101,-86,-32,15,48,-104,62,-99,115,43,-14,76,76,-92,-5,27,-8,41,-114,-74,50,-77,-67,-97,-109,16,106,-36,-52,85,16,50,-68,-27,-22,-99,-112,122,63,-15,64,23,23,121,54,-31,64,126,76,16,-57,18,-75,97,-23,-94,-94,72,-53,-40,30,-55,-63,87,-13,116,9,-64,-72,11,-90,-45,11,59,44,110,28,-105,-80,62,-27,20,46,-7,45,57,5,35,126,29,77,-91,-65,-60,10,-56,-115,-42,-17,115,-67,34,56,12,39,-119,-66,-20,22,-39,-102,54,108,1,-75,107,14,-104,-87,-127,-17,-88,33,103,-71,-85,23,-76,-95,-94,107,-102,92,-96,121,61,-98,78,-28,-33,33,75,32,-10,-14,-125,-96,-72,-4,10,7,-65,-52,-27,-71,92,100,61,45,87,9,-43,-52,110,-70,19,-110,45,-66,-74,-126,91,-27,106,58,-110,114,-86,-77,-52,-63,-50,67,-65,-54,33,37,116,64,49,76,-7,-115,22,-105,-124,50,19,81,-126,86,124,-5,-37,-48,19,-65,32,-21,80,-124,-93,-23,-25,16,24,97,65,29,51,56,-79,80,-117,-50,14,-23,-77,87,96,125,-52,49,2,13,55,61,107,93,-106,-116,102,-11,-37,-23,-119,-43,53,-39,-86,0,-96,19,13,15,15,112,24,76,-73,79,-76,-127,99,90,-18,63,119,3,-29,38,111,34,-66,111,-34,31,-29,-95,24,-70,5,-15,65,86,-43,16,76,-127,-120,21,6,-29,97,53,-31,-57,-39,-117,83,-48,-99,38,126,56,-78,-18,67,43,72,100,-96,-37,109,89,-92,94,-88,121,36,112,-33,-42,-69,-99,112,116,-80,-42,49,5,20,124,26,-32,26,-118,-28,65,22,13,-105,-98,81,124,40,52,-76,-104,97,82,59,96,-99,-27,-46,-74,-125,64,-36,-31,114,-28,-83,-61,81,-81,8,-49,42,36,48,-81,12,68,-80,83,38,-46,-115,93,-86,-56,62,-52,-36,-88,7,-85,-80,5,38,-106,-8,-94,-125,-81,123,21,122,-112,45,116,-37,81,48,-122,93,32,-120,48,-28,-85,-99,50,-47,-67,-109,78,-14,-79,10,-98,56,41,-22,-20,10,74,94,-30,-120,110,50,74,86,91,51,-86,43,-44,11,-11,65,127,-97,-24,-31,119,-16,-73,-66,87,-95,109,-64,98,-127,45,-30,24,-11,61,54,76,109,24,126,45,-1,-24,64,-28,28,-113,114,-32,-103,-125,122,95,102,-33,-7,-25,-28,-101,-7,63,109,111,-9,-45,73,-111,-41,-48,-70,-40,-113,28,-32,-41,-95,76,33,-112,-53,-106,75,117,71,-94,81,19,19,53,96,-9,125,-82,40,6,85,65,36,68,-91,59,9,65,91,-67,-34,121,65,125,-25,-38,-107,-106,-122,-83,20,109,45,122,-103,-31,-42,84,-42,23,-57,-69,49,27,41,-116,78,3,-65,-28,59,-52,-101,-29,-91,-29,37,86,113,119,-51,-104,-19,-84,42,-113,90,125,-32,65,37,-21,119,11,126,-13,-37,-49,59,-80,60,-114,90,7,-117,-22,-84,-50,4,69,58,-93,106,110,-77,-46,125,93,78,-124,-20,73,-42,75,-60,-52,-59,80,-5,-105,6,-14,-58,-72,-59,34,59,-96,-46,-102,76,-8,105,-49,-79,-47,-81,-94,93,77,-100,-119,-115,-115,-102,-68,69,107,-126,-86,-103,83,91,-26,-42,-84,73,-54,5,-104,-85,-61,-28,100,22,-71,-126,97,-43,-128,38,41,88,112,94,39,-84,-55,-119,-115,36,60,107,1,87,-45,-114,-80,-9,88,-105,-91,-67,90,-111,95,-96,-113,-103,-70,-24,91,-113,-122,-70,-83,-92,121,-20,117,37,-10,-105,126,82,89,81,-2,-118,-21,36,-9,-85,-103,124,65,-6,-45,118,-33,-5,122,-113,124,87,-30,58,-47,-43,-10,54,-116,88,44,-17,29,94,-59,-106,41,54,101,-86,98,-116,-12,106,-12,95,-29,13,-103,72,-73,55,6,122,124,-106,79,54,17,-93,7,-101,-72,69,-102,-43,71,31,-44,92,28,37,-104,127,-7,54,-50,-74,-35,-125,-16,-119,-17,28,-44,122,117,63,92,-23,14,82,-28,122,-90,-38,26,88,22,-74,127,115,-128,111,61,-41,-9,-104,31,112,29,37,53,-3,52,58,-27,66,-73,-76,27,78,-33,92,-125,39,95,110,-96,-61,-16,-125,80,-107,44,101,63,114,-101,47,-47,124,-31,21,-99,-57,46,24,-24,18,-104,121,68,-113,-76,37,-71,102,59,-10,-124,112,121,123,91,78,-14,-17,32,-82,2,49,102,-47,-30,-83,-19,-3,-50,67,-42,41,-21,-92,-72,117,-74,-111,97,26,18,-26,-78,104,67,41,48,122,-19,108,105,64,-45,-111,-45,43,-66,-80,115,84,-36,81,-31,59,28,60,-10,125,30,72,-64,105,45,52,-74,11,-16,38,-118,-3,98,-46,-77,40,-69,70,-114,-77,60,-70,123,83,-80,-102,42,100,81,109,-77,115,-127,7,-87,-22,8,-48,57,-72,-41,-41,-9,3,80,-54,-30,103,-16,-54,118,105,-87,-37,22,71,-33,-48,121,62,116,-90,66,-38,22,-105,19,-21,83,-41,112,-39,-81,-28,-109,31,-95,-125,-1,54,72,-84,-108,112,-114,89,120,-73,20,110,-55,-126,-58,-93,68,-105,65,-107,122,8,121,-103,-97,61,97,-74,99,-65,46,1,7,57,-122,69,100,-112,-94,94,116,23,106,85,-105,79,-128,-108,39,-111,-87,83,-66,112,24,-102,-7,-72,-97,-78,-8,99,-114,-113,79,115,89,-51,-88,83,28,-90,56,113,57,-102,40,-104,89,-76,-8,38,-67,-5,-9,-18,-121,38,27,-25,-29,-110,3,-10,16,123,-40,-93,116,-36,-20,-73,-18,-111,87,-123,113,120,-121,-97,69,-47,105,-68,-111,-97,-53,-94,-81,114,77,92,46,-37,-80,-18,108,-9,-69,-25,27,-46,-101,-86,53,54,-109,-44,-11,85,-61,-87,-17,34,-25,79,101,-46,-22,-30,99,85,-65,-30,12,117,-80,-23,54,-16,106,-89,-29,-120,64,1,-111,-94,-75,82,68,-3,120,11,-52,-103,87,22,-17,-46,-117,-63,112,12,-123,-52,71,-121,-122,-55,-125,101,-41,105,52,-53,-9,60,56,-3,-1,85,-112,15,127,70,4,-7,48,-72,34,-29,11,-103,114,-46,56,-109,17,-32,9,89,114,-1,92,86,-55,11,-87,-80,53,-18,-4,42,-90,86,15,-50,49,120,-46,22,67,57,-59,90,-97,110,96,119,43,100,-90,-54,-89,81,21,-80,-14,64,-47,126,-17,92,-37,51,40,121,-34,110,-99,-54,36,-73,85,-43,52,-30,-9,121,-18,-51,102,91,-116,-71,95,86,-55,95,-35,74,118,101,87,-114,20,-48,117,-60,-76,55,49,-108,74,-22,-43,20,41,79,-96,114,-12,-68,-44,43,126,-28,19,83,111,-128,102,-19,-110,56,71,-77,89,17,-16,-26,32,-27,-127,-14,-37,62,-34,-107,126,110,104,74,6,85,79,8,-74,107,30,126,-52,80,-11,29,108,65,-128,29,109,-2,123,59,28,-107,110,62,110,-123,-68,71,-39,-20,-57,-108,38,-36,126,-12,100,112,-103,-32,55,98,-5,-82,89,-41,88,36,-92,99,-56,118,97,12,113,-16,88,71,76,-96,-77,117,-5,60,-84,23,45,-41,31,46,33,0,-3,69,38,4,-119,-20,-115,96,-50,28,-9,-38,85,-113,-106,36,3,-96,-80,-23,7,-19,101,-111,92,-107,-9,116,53,-120,5,-3,-13,-87,1,-115,-35,-125,-89,-23,19,53,69,117,-67,-107,-33,-122,-32,-10,-69,-122,75,-116,-69,-35,43,-74,-107,109,18,107,-85,-48,52,-38,83,50,115,-101,-39,5,62,-7,-46,99,97,44,31,78,27,105,-117,-72,-94,-69,108,-86,-59,-30,49,-48,-22,-124,-2,-114,-19,-126,-29,-122,-21,67,15,60,-111,-55,35,-22,81,37,32,-75,0,56,-18,47,108,41,0,-120,122,-4,95,51,-68,-20,78,125,77,119,-9,-115,109,59,79,-128,-124,-114,9,7,91,-8,-80,11,-112,29,-32,-56,11,-50,-82,29,74,-19,-55,-6,12,-115,-6,18,15,-123,72,-15,-62,12,1,43,82,-30,-17,2,26,-30,-85,58,63,-56,-117,-100,52,-90,7,-69,-26,121,-92,111,5,-61,96,-90,63,-18,-11,60,-52,-81,99,125,25,67,-71,82,110,97,51,122,39,33,28,93,-116,123,-107,48,-64,-9,92,-31,-62,-68,-102,-103,-107,48,-100,-2,83,127,-82,41,-105,-7,-120,113,10,58,23,-122,84,-18,-37,20,-82,11,42,46,-95,16,-105,-58,-78,62,-82,-57,39,-18,106,0,52,-51,-59,36,76,98,124,-108,-67,-40,73,-3,19,45,-45,121,20,76,0,-21,-57,46,90,-18,79,66,-42,-56,-47,-39,-120,90,79,103,-104,34,-30,-67,120,94,35,59,25,-41,-128,125,88,88,68,-48,-25,-47,-10,-12,125,92,20,-99,55,66,118,-42,114,46,67,-9,43,37,119,-84,-8,79,-21,123,82,48,76,-63,-17,-23,27,-108,53,97,95,-109,41,68,-50,-32,-20,-119,-71,80,-57,-9,-16,-4,-36,17,66,19,82,-113,-76,39,23,-128,47,9,-87,30,-35,-48,100,96,15,-4,-58,-86,-10,-1,83,-52,17,-102,-88,37,-13,-2,-92,-23,-52,-89,-112,-33,-47,60,28,122,-101,-99,-67,92,-88,77,118,101,-96,-123,-108,-108,-43,102,45,44,-48,84,110,-25,-74,86,50,-7,-109,-9,-92,59,-67,79,29,23,53,-57,73,-89,9,1,81,65,17,31,-107,8,92,126,53,-119,52,98,60,-126,-82,15,79,-15,110,111,-82,22,88,-110,-113,-49,-124,-127,88,-51,-48,-87,-55,-17,62,45,64,41,-111,-95,-46,-122,-91,116,-125,-55,103,75,-29,95,-56,29,-115,-36,-41,-56,88,-100,-81,-33,-81,29,-11,-90,-17,77,-10,-127,-121,-6,30,-4,-24,30,-124,109,112,67,25,-57,4,34,79,126,126,-109,-47,-101,-38,-9,117,-76,37,-43,-120,-86,54,85,-70,56,39,-15,-40,-80,26,3,-64,-45,-35,-69,-120,70,-97,24,-29,-53,69,19,-113,-112,-53,-78,-106,-74,94,-61,78,-57,-58,97,46,58,62,-21,-121,-97,-38,-16,35,35,-120,-127,125,2,-30,54,-44,-17,9,30,-20,30,-53,117,52,29,-92,95,16,60,102,-29,54,-66,-110,122,10,-113,-78,68,-120,-71,-96,111,-37,9,39,-11,111,-52,-25,107,-77,-9,28,81,0,-55,-98,43,-97,-37,69,-123,-4,23,102,-98,106,-11,98,-42,5,115,-84,-121,-86,-78,11,-69,34,-115,3,-94,-104,-9,-38,51,-113,29,83,-39,86,54,-27,-116,-108,61,27,10,-44,65,-86,-91,34,-40,38,99,-14,101,-82,126,-56,-8,-102,37,-52,102,-36,126,74,95,-83,113,-37,-66,-55,-20,-98,-115,96,-49,-44,-123,-1,20,75,-2,-90,10,-61,107,94,87,-63,74,0,-55,2,41,-103,-123,-85,-13,-39,-107,36,-47,-21,6,-70,98,-119,78,52,26,-40,8,72,117,-78,115,76,-57,43,-60,-25,-87,36,83,54,127,127,-78,19,98,-30,125,86,121,124,62,-32,-96,-110,20,97,-126,-104,13,6,-122,-105,36,55,105,-121,-48,-83,0,-113,18,-114,-39,9,20,-20,-23,-115,-49,83,-107,121,70,-30,86,31,-48,-23,125,-67,-114,48,-86,21,-90,83,-79,64,-107,-60,-91,54,69,-73,-77,88,99,-10,15,-29,57,-128,-47,-96,101,-50,112,120,-85,-16,-78,27,7,116,-128,18,-11,49,-19,41,-33,15,-35,-67,84,-15,-57,36,-73,41,15,77,9,83,39,-54,27,-82,33,115,4,-60,101,46,-117,-56,-18,74,100,126,-27,-48,-25,10,-51,126,-41,-81,-95,-60,9,85,99,-6,80,-16,27,77,108,44,46,114,-26,20,-69,92,15,98,107,-114,-59,-87,28,-61,-121,84,125,-44,-125,-13,116,-55,-120,94,-84,-75,-86,34,1,-25,121,-80,26,-97,43,-12,31,75,-58,84,2,12,-109,-61,-68,-21,110,92,-27,-117,13,36,21,-3,107,-125,80,45,87,-108,22,41,-61,75,-115,-29,29,33,-111,-22,-4,-94,8,97,24,-124,25,25,-52,-7,-74,108,-36,-114,12,-32,3,84,75,-60,34,-88,-10,84,96,12,17,-119,114,-41,41,-3,-48,-16,1,-14,21,-115,-11,96,-25,-36,10,-14,-71,-3,-83,85,6,-91,-18,81,-108,36,-33,-59,70,-80,-81,11,-31,19,74,107,-22,91,8,29,57,-95,-80,-40,61,-82,-110,122,97,-114,-102,123,-77,83,122,-24,46,-121,-28,18,111,-47,-35,-120,-102,114,-93,115,22,-82,113,-78,77,76,-66,117,65,28,86,27,82,79,-128,-88,119,63,-31,87,11,124,-10,-99,-71,94,-89,76,-82,-124,101,58,-53,-74,9,-114,-50,31,-3,-51,-119,57,-29,-75,92,113,-47,40,-103,-81,-43,-12,-100,-102,4,-36,12,-26,-70,-118,27,-88,50,28,-73,-113,-94,-1,122,4,-57,-126,124,100,70,62,-87,7,-91,100,-91,-102,-56,34,102,118,44,-47,-90,24,-32,-99,30,-98,36,-124,113,11,-126,-15,-84,72,117,-46,3,-18,97,-38,-73,24,-47,109,-4,-50,-86,88,-112,-97,-65,112,-73,72,-37,20,-125,-29,-43,51,-2,-16,94,119,58,-101,-48,-116,121,94,103,64,52,48,51,-113,-70,106,41,-44,82,111,-106,71,-62,-105,-66,-78,78,71,115,-123,-50,4,33,22,88,-40,-111,-82,-46,-34,-67,120,-58,-28,-18,-126,-52,-31,-109,84,11,-94,10,94,-15,-89,-106,-62,125,-6,98,-39,62,-11,-34,12,12,-18,-50,-60,-78,43,104,36,50,-62,-58,-14,-36,-104,-88,21,78,-18,43,-124,-118,-68,-35,52,-62,102,18,25,87,-106,-78,74,29,127,98,-99,-2,-86,37,6,80,-31,86,77,112,-51,121,70,-126,7,35,-85,3,-24,-78,-109,114,-25,-58,-127,120,-78,26,8,-100,-116,10,-23,-20,14,-18,42,120,-75,79,60,44,-58,102,-104,69,25,119,28,103,-70,22,25,26,124,3,-11,-15,10,87,120,-23,-68,-44,7,93,9,-8,125,-15,-79,-70,108,15,-66,-90,-82,-5,-14,115,-122,-75,74,127,-100,108,4,58,66,-106,-117,1,6,11,-69,-96,55,-65,-8,102,-72,-41,75,76,-2,16,-10,78,-42,59,-72,-1,-31,-100,113,26,-66,48,-4,103,57,71,-94,-2,14,-28,-36,22,-8,-25,39,-51,25,99,91,70,63,11,-124,69,46,-34,-21,99,-70,-110,-90,32,116,34,-74,82,43,-104,-56,31,-117,-43,67,12,-72,115,-84,-62,-9,21,-30,105,82,94,86,12,40,-47,-39,40,-114,-67,-89,-72,-64,-62,-124,-105,32,95,-124,-41,-14,48,26,8,-116,-57,24,-45,-45,-75,-40,-111,-118,107,116,66,-97,-57,-79,-96,-85,-55,49,-55,-32,-87,-76,-12,42,-85,85,-16,75,-41,-112,49,-29,-28,-124,-10,-60,62,-2,-112,15,-36,-33,81,-95,117,120,51,99,-64,30,11,106,-21,-42,43,-59,51,117,12,45,3,-116,110,88,104,60,67,102,-74,108,80,-58,-108,28,38,-108,16,63,100,-24,-36,-1,70,97,7,32,118,-112,-122,-31,-36,106,10,115,-89,35,58,-15,-5,63,19,-123,-99,-11,-94,108,-18,-13,70,-12,-1,126,-15,-9,-25,113,111,66,-59,81,-88,-114,97,-121,-76,16,8,72,62,3,-107,106,-43,92,-91,63,60,-90,-61,96,-9,93,-24,-17,-22,38,-24,29,-27,-36,-25,117,99,-10,76,66,-77,-71,33,-87,100,48,-13,-122,-49,56,-104,72,72,-84,103,72,115,-10,45,19,-22,52,-97,-77,-107,50,-81,-93,-79,102,-71,46,73,6,-21,-52,5,-96,32,112,15,-44,-4,110,5,-26,-85,89,-87,35,73,-17,59,-95,-5,-123,94,127,-83,9,-122,-64,-58,-72,-111,33,-91,-82,56,63,1,6,-67,-106,-55,26,-12,-105,-32,115,-38,-95,118,117,67,-17,95,99,120,-75,2,28,-113,-105,117,-15,111,22,-46,116,25,-91,40,44,84,37,-4,-66,-125,15,69,-14,49,-12,-11,87,-68,20,91,110,117,125,-65,-34,-36,84,-29,-87,-27,60,-66,-118,-125,49,69,81,54,7,-119,53,-23,-60,-9,22,-116,-125,-58} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/ref_functions.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/ref_functions.h new file mode 100644 index 0000000..5a25ffa --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/Ref_Implementations/ref_functions.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _REF_FUNCTIONS_H_ +#define _REF_FUNCTIONS_H_ + +#include "arm_math.h" +#include "arm_nnfunctions.h" +//#include "arm_nnsupportfunctions.h" +#include "fully_connected_testing_weights.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * + * Convolution reference implemenation + * + */ + + void arm_convolve_HWC_q7_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q7_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ); + + void arm_convolve_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const q7_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q7_t * Im_out, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y, // output image dimension y + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ); + + void arm_convolve_HWC_q15_ref(const q15_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q15_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q15_t * bias, // bias + const uint16_t bias_shift, const uint16_t out_shift, q15_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ); + void arm_convolve_HWC_q15_nonsquare_ref(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB); + + void arm_depthwise_separable_conv_HWC_q7_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimention + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel, // filter kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const q7_t * bias, // bias + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + q7_t * Im_out, // output image + const uint16_t dim_im_out, // output image dimension + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ); + void arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(const q7_t * Im_in, // input image + const uint16_t dim_im_in_x, // input image dimention x + const uint16_t dim_im_in_y, // input image dimention y + const uint16_t ch_im_in, // number of input image channels + const q7_t * wt, // kernel weights + const uint16_t ch_im_out, // number of filters, i.e., output image channels + const uint16_t dim_kernel_x, // filter kernel size x + const uint16_t dim_kernel_y, // filter kernel size y + const uint16_t padding_x, // padding sizes x + const uint16_t padding_y, // padding sizes y + const uint16_t stride_x, // stride x + const uint16_t stride_y, // stride y + const q7_t * bias, // bias + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + q7_t * Im_out, // output image + const uint16_t dim_im_out_x, // output image dimension x + const uint16_t dim_im_out_y, // output image dimension y + q15_t * bufferA, //buffer space for input + q7_t * bufferB //buffer space for output + ); + +/* + * + * Fully-connected reference implemenation + * + */ + + void arm_fully_connected_q7_ref(const q7_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q7_t * pOut, // output operand + q15_t * vec_buffer); + + void arm_fully_connected_q15_ref(const q15_t * pV, // pointer to vector + const q15_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q15_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer); + + void arm_fully_connected_mat_q7_vec_q15_ref(const q15_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer); + + void arm_fully_connected_q7_opt_ref(const q7_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q7_t * pOut, // output operand + q15_t * vec_buffer); + + void arm_fully_connected_q15_opt_ref(const q15_t * pV, // pointer to vector + const q15_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q15_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer); + + void arm_fully_connected_mat_q7_vec_q15_opt_ref(const q15_t * pV, // pointer to vector + const q7_t * pM, // pointer to matrix + const uint16_t dim_vec, // length of the vector + const uint16_t num_of_rows, // numCol of A + const uint16_t bias_shift, // amount of left-shift for bias + const uint16_t out_shift, // amount of right-shift for output + const q7_t * bias, q15_t * pOut, // output operand + q15_t * vec_buffer); + +/* + * + * Pooling reference implemenation + * + */ + + void arm_avepool_q7_HWC_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimension + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel, // window kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const uint16_t dim_im_out, // output image dimension + q7_t * bufferA, // a buffer for local storage + q7_t * Im_out); + + void arm_maxpool_q7_HWC_ref(const q7_t * Im_in, // input image + const uint16_t dim_im_in, // input image dimension + const uint16_t ch_im_in, // number of input image channels + const uint16_t dim_kernel, // window kernel size + const uint16_t padding, // padding sizes + const uint16_t stride, // stride + const uint16_t dim_im_out, // output image dimension + q7_t * bufferA, // a buffer for local storage + q7_t * Im_out); + +/* + * + * Other reference implemenation + * + */ + + void arm_relu_q7_ref(q7_t * data, uint16_t size); + + void arm_relu_q15_ref(q15_t * data, uint16_t size); + + void arm_nn_mult_q7_ref(q7_t * pSrcA, q7_t * pSrcB, q7_t * pDst, const uint16_t out_shift, uint32_t blockSize); + + void arm_nn_mult_q15_ref(q15_t * pSrcA, q15_t * pSrcB, q15_t * pDst, const uint16_t out_shift, uint32_t blockSize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.cpp b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.cpp new file mode 100644 index 0000000..41088fe --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.cpp @@ -0,0 +1,801 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2018 Arm Limited. All rights reserved. +* +* +* Project: CMSIS NN Library +* Title: arm_nnexamples_nn_test.cpp +* +* Description: Example code for NN kernel testing. +* +* Target Processor: Cortex-M cores +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* - Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* - Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* - Neither the name of ARM LIMITED nor the names of its contributors +* may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#include "arm_nnexamples_nn_test.h" + +//#define TEST_SIGMOID +//#define TEST_TANH +#define TEST_POOL +#define TEST_RELU +#define TEST_IP +#define TEST_CONV +#define TEST_NONSQUARE +#define TEST_NNMULT + +int test_index = 0; +q7_t test_flags[50]; +bool test_pass; + +int main() +{ + printf("start tests\n"); + + srand(1); + + // common pointers for testing data + q7_t *test1; + q15_t *test2; + q7_t *test3; + q15_t *test4; + + for (test_index = 0; test_index<50; test_index++) { + test_flags[test_index] = -1; + } + test_index = 0; + +#ifdef TEST_NNMULT +#define NNMULT_DIM 128 + test1 = new q7_t[NNMULT_DIM*2]; + test2 = new q15_t[NNMULT_DIM*2]; + test3 = new q7_t[NNMULT_DIM*2]; + test4 = new q15_t[NNMULT_DIM*2]; + + q7_t * mult_out_q7 = test3; + q7_t * mult_ref_q7 = test3 + NNMULT_DIM; + q15_t * mult_out_q15 = test4; + q15_t * mult_ref_q15 = test4 + NNMULT_DIM; + + for (int i=0;i= 2 || pool_out_opt[i] - pool_out_ref[i] >= 2) + { + printf("Output mismatch at %d, expected %d, actual %d\n", i, pool_out_ref[i], pool_out_opt[i]); + if_ave_pool_match = false; + } + } + if (if_ave_pool_match == true) + { + printf("Outputs match.\n"); + } + + delete[]test1; + delete[]test2; + delete[]test3; + +#endif + +#ifdef TEST_RELU + +#define RELU_DIM 127 + + test1 = new q7_t[RELU_DIM]; + test2 = new q15_t[RELU_DIM]; + test3 = new q7_t[RELU_DIM]; + test4 = new q15_t[RELU_DIM]; + + for (int i = 0; i < RELU_DIM; i++) + { + test1[i] = (rand() % 256 - 128); + test2[i] = (rand() % 65536 - 32768); + test3[i] = test1[i]; + test4[i] = test2[i]; + } + + q7_t *relu_ref_data_q7 = test1; + q7_t *relu_opt_data_q7 = test3; + q15_t *relu_ref_data_q15 = test2; + q15_t *relu_opt_data_q15 = test4; + + printf("Start ref relu q7 implementation\n"); + + arm_relu_q7_ref(relu_ref_data_q7, RELU_DIM); + + printf("Start opt relu q7 implementation\n"); + + arm_relu_q7(relu_opt_data_q7, RELU_DIM); + + verify_results_q7(relu_ref_data_q7, relu_opt_data_q7, RELU_DIM); + + printf("Start ref relu q15 implementation\n"); + + arm_relu_q15_ref(relu_ref_data_q15, RELU_DIM); + + printf("Start opt relu q15 implementation\n"); + + arm_relu_q15(relu_opt_data_q15, RELU_DIM); + + verify_results_q15(relu_ref_data_q15, relu_opt_data_q15, RELU_DIM); + + delete[]test1; + delete[]test2; + delete[]test3; + delete[]test4; + +#endif + +#ifdef TEST_IP + +#define IP_ROW_DIM 127 +#define IP_COL_DIM 127 + + q7_t ip_weights[IP_ROW_DIM * IP_COL_DIM] = IP2_WEIGHT; + q7_t ip_q7_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_WEIGHT; + q7_t ip_q7_q15_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_q7_q15_WEIGHT; + q15_t ip_q15_weights[IP_ROW_DIM * IP_COL_DIM] = IP2_WEIGHT; + q15_t ip_q15_opt_weights[IP_ROW_DIM * IP_COL_DIM] = IP4_WEIGHT_Q15; + + test1 = new q7_t[IP_COL_DIM + IP_ROW_DIM]; + test2 = new q15_t[IP_COL_DIM]; + test3 = new q7_t[IP_ROW_DIM * 3]; + test4 = new q15_t[IP_COL_DIM + IP_ROW_DIM * 2]; + + for (int i = 0; i < IP_ROW_DIM + IP_COL_DIM; i++) + { + test1[i] = rand() % 256 - 100; + } + for (int i = 0; i < IP_ROW_DIM * 3; i++) + { + test3[i] = 0; + } + + q7_t *ip_bias_q7 = test1 + IP_COL_DIM; + + q7_t *ip_out_q7_ref = test3; + q7_t *ip_out_q7_opt = test3 + IP_ROW_DIM; + q7_t *ip_out_q7_opt_fast = test3 + 2 * IP_ROW_DIM; + q15_t *ip_out_q15_ref = test4 + IP_COL_DIM; + q15_t *ip_out_q15_opt = test4 + IP_COL_DIM + IP_ROW_DIM; + + initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt, IP_ROW_DIM); + initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM); + initialize_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM); + + printf("Start ref q7 implementation\n"); + + arm_fully_connected_q7_ref(test1, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_ref, test2); + + printf("Start q7 implementation\n"); + + arm_fully_connected_q7(test1, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_opt, test2); + + verify_results_q7(ip_out_q7_ref, ip_out_q7_opt, IP_ROW_DIM); + + printf("Start q7 ref opt implementation\n"); + + arm_fully_connected_q7_opt_ref(test1, ip_q7_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, + ip_out_q7_opt_fast, test2); + + verify_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM); + + printf("Start q7 opt implementation\n"); + + arm_fully_connected_q7_opt(test1, ip_q7_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q7_opt_fast, + test2); + + verify_results_q7(ip_out_q7_ref, ip_out_q7_opt_fast, IP_ROW_DIM); + + for (int i = 0; i < IP_ROW_DIM + IP_COL_DIM; i++) + { + test4[i] = (rand() % 65536 - 32768); + } + + initialize_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start ref q15 implementation\n"); + + arm_fully_connected_q15_ref(test4, ip_q15_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_ref, NULL); + + printf("Start q15 implementation\n"); + + arm_fully_connected_q15(test4, ip_q15_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt, NULL); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start ref opt q15 implementation\n"); + + arm_fully_connected_q15_opt_ref(test4, ip_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt, + NULL); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start opt q15 implementation\n"); + + arm_fully_connected_q15_opt(test4, ip_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, test2, ip_out_q15_opt, NULL); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + initialize_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start ref q7_q15 implementation\n"); + + arm_fully_connected_mat_q7_vec_q15_ref(test4, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q15_ref, + test2); + + printf("Start q7_q15 implementation\n"); + + arm_fully_connected_mat_q7_vec_q15(test4, ip_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, ip_out_q15_opt, + test2); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start ref opt q7_q15 implementation\n"); + + arm_fully_connected_mat_q7_vec_q15_opt_ref(test4, ip_q7_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, + ip_out_q15_opt, test2); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + printf("Start opt q7_q15 implementation\n"); + + arm_fully_connected_mat_q7_vec_q15_opt(test4, ip_q7_q15_opt_weights, IP_COL_DIM, IP_ROW_DIM, 1, 7, ip_bias_q7, + ip_out_q15_opt, test2); + + verify_results_q15(ip_out_q15_ref, ip_out_q15_opt, IP_ROW_DIM); + + delete[]test1; + delete[]test2; + delete[]test3; + delete[]test4; + +#endif + +#ifdef TEST_NONSQUARE + +/* Use RCONV to differential with square CONV */ + +#define RCONV_IM_DIM_X 10 +#define RCONV_IM_DIM_Y 8 +#define RCONV_IM_CH 4 +#define RCONV_KER_DIM_X 5 +#define RCONV_KER_DIM_Y 3 +#define RCONV_STRIDE_X 1 +#define RCONV_STRIDE_Y 1 +#define RCONV_PADDING_X 2 +#define RCONV_PADDING_Y 1 +#define RCONV_OUT_CH 4 +#define RCONV_OUT_DIM_X 10 +#define RCONV_OUT_DIM_Y 8 + + test1 = new q7_t[RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH]; + test2 = new q15_t[2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH]; + test3 = + new q7_t[RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH]; + + for (int i = 0; i < RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH; i++) + { + test1[i] = rand() % 256 - 100; + } + + for (int i = 0; + i < RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH; i++) + { + test3[i] = rand() % 256 - 100; + } + + q7_t *rconv_weight_q7 = test1; + q7_t *rconv_bias_q7 = test1 + RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH; + + q15_t *rconv_buf = test2; + + q7_t *rconv_im_in_q7 = test3; + q7_t *rconv_im_out_ref_q7 = test3 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH; + q7_t *rconv_im_out_opt_q7 = + test3 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH; + + initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + printf("start conv q7 nonsquare ref implementation\n"); + arm_convolve_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + printf("start conv q7 nonsquare opt implementation\n"); + arm_convolve_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + printf("start conv q7 nonsquare ref implementation\n"); + arm_convolve_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + printf("start conv q7 nonsquare basic implementation\n"); + arm_convolve_HWC_q7_basic_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + initialize_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + printf("start 1x1 conv q7 nonsquare fast implementation\n"); + arm_convolve_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, 1, 1, 0, 0, RCONV_STRIDE_X, + RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, RCONV_OUT_DIM_X, + RCONV_OUT_DIM_Y, rconv_buf, NULL); + + printf("start 1x1 conv q7 nonsquare dedicated function implementation\n"); + arm_convolve_1x1_HWC_q7_fast_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q7, + RCONV_OUT_CH, 1, 1, 0, 0, RCONV_STRIDE_X, + RCONV_STRIDE_Y, rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, RCONV_OUT_DIM_X, + RCONV_OUT_DIM_Y, rconv_buf, NULL); + + verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + printf("start depthwise separable conv q7 nonsquare ref implementation\n"); + arm_depthwise_separable_conv_HWC_q7_ref_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, + rconv_weight_q7, RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, + RCONV_PADDING_X, RCONV_PADDING_Y, RCONV_STRIDE_X, RCONV_STRIDE_Y, + rconv_bias_q7, 1, 7, rconv_im_out_ref_q7, RCONV_OUT_DIM_X, + RCONV_OUT_DIM_Y, rconv_buf, NULL); + + printf("start depthwise separable conv q7 nonsquare opt implementation\n"); + arm_depthwise_separable_conv_HWC_q7_nonsquare(rconv_im_in_q7, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, + rconv_weight_q7, RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, + RCONV_PADDING_X, RCONV_PADDING_Y, RCONV_STRIDE_X, RCONV_STRIDE_Y, + rconv_bias_q7, 1, 7, rconv_im_out_opt_q7, RCONV_OUT_DIM_X, + RCONV_OUT_DIM_Y, rconv_buf, NULL); + + verify_results_q7(rconv_im_out_ref_q7, rconv_im_out_opt_q7, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + delete[]test1; + delete[]test2; + delete[]test3; + + test2 = new q15_t[RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH]; // weights + bias + test4 = new q15_t[2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH //buffer + + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH]; // i/o + + for (int i = 0; i < RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH + RCONV_OUT_CH; i++) + { + test2[i] = rand() % 256 - 100; + } + + for (int i = 0; + i < 2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH + + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH + 2 * RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH; + i++) + { + test4[i] = rand() % 256 - 100; + } + + q15_t *rconv_weight_q15 = test2; + q15_t *rconv_bias_q15 = test2 + RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH * RCONV_OUT_CH; + + rconv_buf = test4; + + q15_t *rconv_im_in_q15 = test4 + 2 * RCONV_KER_DIM_Y * RCONV_KER_DIM_X * RCONV_IM_CH; + q15_t *rconv_im_out_ref_q15 = rconv_im_in_q15 + RCONV_IM_DIM_Y * RCONV_IM_DIM_X * RCONV_IM_CH; + q15_t *rconv_im_out_opt_q15 = rconv_im_out_ref_q15 + RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH; + + initialize_results_q15(rconv_im_out_ref_q15, rconv_im_out_opt_q15, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + printf("start conv q15 nonsquare ref implementation\n"); + arm_convolve_HWC_q15_nonsquare_ref(rconv_im_in_q15, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q15, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q15, 1, 7, rconv_im_out_ref_q15, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + printf("start conv q5 nonsquare opt implementation\n"); + arm_convolve_HWC_q15_fast_nonsquare(rconv_im_in_q15, RCONV_IM_DIM_X, RCONV_IM_DIM_Y, RCONV_IM_CH, rconv_weight_q15, + RCONV_OUT_CH, RCONV_KER_DIM_X, RCONV_KER_DIM_Y, RCONV_PADDING_X, RCONV_PADDING_Y, + RCONV_STRIDE_X, RCONV_STRIDE_Y, rconv_bias_q15, 1, 7, rconv_im_out_opt_q15, + RCONV_OUT_DIM_X, RCONV_OUT_DIM_Y, rconv_buf, NULL); + + verify_results_q15(rconv_im_out_ref_q15, rconv_im_out_opt_q15, RCONV_OUT_DIM_Y * RCONV_OUT_DIM_X * RCONV_OUT_CH); + + delete [] test2; + delete [] test4; +#endif + +#ifdef TEST_CONV + +#define CONV_IM_DIM 16 +#define CONV_IM_CH 16 +#define CONV_KER_DIM 5 +#define CONV_OUT_CH 16 +#define CONV_OUT_DIM 16 + + test1 = new q7_t[CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH]; + test2 = + new q15_t[CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + + 2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH]; + test3 = new q7_t[CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH]; + test4 = new q15_t[CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH]; + + for (int i = 0; i < CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH; i++) + { + test1[i] = rand() % 256 - 100; + } + + for (int i = 0; + i < + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + + 2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + CONV_OUT_CH; i++) + { + test2[i] = (rand() % 65536 - 32768); + } + + for (int i = 0; i < CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; i++) + { + test3[i] = rand() % 256 - 100; + } + + for (int i = 0; i < CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + 2 * CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; i++) + { + test4[i] = (rand() % 65536 - 32768); + } + + q7_t *conv_weight_q7 = test1; + q7_t *conv_bias_q7 = test1 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH; + + q15_t *conv_weight_q15 = test2; + q15_t *conv_buf = test2 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH; + q15_t *conv_bias_q15 = + test2 + CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH + + 2 * CONV_KER_DIM * CONV_KER_DIM * CONV_IM_CH * CONV_OUT_CH; + + q7_t *conv_im_in_q7 = test3; + q7_t *conv_im_out_ref_q7 = test3 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH; + q7_t *conv_im_out_opt_q7 = + test3 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; + + q15_t *conv_im_in_q15 = test4; + q15_t *conv_im_out_ref_q15 = test4 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH; + q15_t *conv_im_out_opt_q15 = + test4 + CONV_IM_DIM * CONV_IM_DIM * CONV_IM_CH + CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH; + + initialize_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q7 ref implementation\n"); + + arm_convolve_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7, + CONV_OUT_DIM, conv_buf, NULL); + + printf("start q7 basic implementation\n"); + + arm_convolve_HWC_q7_basic(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q7 fast implementation\n"); + + arm_convolve_HWC_q7_fast(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + // testing with RGB + printf("start q7 ref implementation for RGB\n"); + + arm_convolve_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7, + CONV_OUT_DIM, conv_buf, NULL); + + printf("start q7 basic implementation for RGB\n"); + + arm_convolve_HWC_q7_basic(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q7 RGB implementation for RGB\n"); + + arm_convolve_HWC_q7_RGB(conv_im_in_q7, CONV_IM_DIM, 3, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + // testing q15 + initialize_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q15 ref implementation\n"); + + arm_convolve_HWC_q15_ref(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_ref_q15, + CONV_OUT_DIM, conv_buf, NULL); + + printf("start q15 basic implementation\n"); + + arm_convolve_HWC_q15_basic(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_opt_q15, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q15 fast implementation\n"); + + arm_convolve_HWC_q15_fast(conv_im_in_q15, CONV_IM_DIM, CONV_IM_CH, conv_weight_q15, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q15, 0, 15, conv_im_out_opt_q15, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q15(conv_im_out_ref_q15, conv_im_out_opt_q15, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + // depthwise separable conv + initialize_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + printf("start q7 depthwise_separable_conv ref implementation\n"); + + arm_depthwise_separable_conv_HWC_q7_ref(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_ref_q7, + CONV_OUT_DIM, conv_buf, NULL); + + printf("start q7 depthwise_separable_conv implementation\n"); + + arm_depthwise_separable_conv_HWC_q7(conv_im_in_q7, CONV_IM_DIM, CONV_IM_CH, conv_weight_q7, + CONV_OUT_CH, CONV_KER_DIM, 2, 1, conv_bias_q7, 1, 7, conv_im_out_opt_q7, + CONV_OUT_DIM, conv_buf, NULL); + + verify_results_q7(conv_im_out_ref_q7, conv_im_out_opt_q7, CONV_OUT_DIM * CONV_OUT_DIM * CONV_OUT_CH); + + delete[]test1; + delete[]test2; + delete[]test3; + delete[]test4; + +#endif + + test_pass = true; + test_index = 0; + while (test_flags[test_index] != -1) { + if (test_flags[test_index]) { + test_pass = false; + } + test_index ++; + } + if (test_pass) { + printf("All tests passed\n"); + } else { + printf("Test failed passed\n"); + } + + return 0; +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.h b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.h new file mode 100644 index 0000000..2e33988 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/NN_Lib_Tests/nn_test/arm_nnexamples_nn_test.h @@ -0,0 +1,78 @@ +#ifndef _MAIN_H_ +#define _MAIN_H_ + +#include +#include +#include + +#include "arm_math.h" + +#include "arm_nnfunctions.h" +#include "ref_functions.h" + +extern int test_index; +extern q7_t test_flags[50]; + +void initialize_results_q7(q7_t * ref, q7_t * opt, int length) +{ + arm_fill_q7(0, ref, length); + arm_fill_q7(37, opt, length); +} + +void initialize_results_q15(q15_t * ref, q15_t * opt, int length) +{ + arm_fill_q15(0, ref, length); + arm_fill_q15(0x5F5, opt, length); +} + +void verify_results_q7(q7_t * ref, q7_t * opt, int length) +{ + + bool if_match = true; + + for (int i = 0; i < length; i++) + { + if (ref[i] != opt[i]) + { + printf("Output mismatch at %d, expected %d, actual %d\r\n", i, ref[i], opt[i]); + + if_match = false; + } + } + + if (if_match == true) + { + printf("Outputs match.\r\n\r\n"); + test_flags[test_index++] = 0; + } else { + test_flags[test_index++] = 1; + } + +} + +void verify_results_q15(q15_t * ref, q15_t * opt, int length) +{ + + bool if_match = true; + + for (int i = 0; i < length; i++) + { + if (ref[i] != opt[i]) + { + printf("Output mismatch at %d, expected %d, actual %d\r\n", i, ref[i], opt[i]); + + if_match = false; + } + } + + if (if_match == true) + { + printf("Outputs match.\r\n\r\n"); + test_flags[test_index++] = 0; + } else { + test_flags[test_index++] = 1; + } + +} + +#endif diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c new file mode 100644 index 0000000..fd447e5 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q15.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_activations_q15.c + * Description: Q15 neural network activation function using direct table look-up + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q15 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + * + * @details + * + * This is the direct table look-up approach. + * + * Assume here the integer part of the fixed-point is <= 3. + * More than 3 just not making much sense, makes no difference with + * saturation followed by any of these activation functions. + */ + +void arm_nn_activations_direct_q15(q15_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type) +{ + uint16_t i = size; + q15_t *pIn = data; + q15_t *pOut = data; + uint16_t shift_size = 8 + 3 - int_width; + uint32_t bit_mask = 0x7FF >> int_width; + uint32_t full_frac = bit_mask + 1; + const q15_t *lookup_table; + + switch (type) + { + case ARM_SIGMOID: + lookup_table = sigmoidTable_q15; + break; + case ARM_TANH: + default: + lookup_table = tanhTable_q15; + break; + } + + while (i) + { + q15_t out; + q15_t in = *pIn++; + q15_t frac = (uint32_t) in & bit_mask; + q15_t value = lookup_table[__USAT(in >> shift_size, 8)]; + q15_t value2 = lookup_table[__USAT(1 + (in >> shift_size), 8)]; + + /* doing the interpolation here for better accuracy */ + out = ((q31_t) (full_frac - frac) * value + (q31_t) value2 * frac) >> shift_size; + + *pOut++ = out; + i--; + } + +} + +/** + * @} end of Acti group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c new file mode 100644 index 0000000..2953bd5 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_nn_activations_q7.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_activations_q7.c + * Description: Q7 neural network activation function using direct table look-up + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_common_tables.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q7 neural network activation function using direct table look-up + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @param[in] int_width bit-width of the integer part, assume to be smaller than 3 + * @param[in] type type of activation functions + * @return none. + * + * @details + * + * This is the direct table look-up approach. + * + * Assume here the integer part of the fixed-point is <= 3. + * More than 3 just not making much sense, makes no difference with + * saturation followed by any of these activation functions. + */ + +void arm_nn_activations_direct_q7(q7_t * data, uint16_t size, uint16_t int_width, arm_nn_activation_type type) +{ + uint16_t i = size; + q7_t *pIn = data; + q7_t *pOut = data; + q7_t in; + q7_t out; + uint16_t shift_size = 3 - int_width; + const q7_t *lookup_table; + switch (type) + { + case ARM_SIGMOID: + lookup_table = sigmoidTable_q7; + break; + case ARM_TANH: + default: + lookup_table = tanhTable_q7; + break; + } + while (i) + { + in = *pIn++; + out = lookup_table[(uint8_t) (in >> shift_size)]; + *pOut++ = out; + i--; + } +} + +/** + * @} end of Acti group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c new file mode 100644 index 0000000..6a1b907 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q15.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_relu_q15.c + * Description: Q15 version of ReLU + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q15 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + * + * @details + * + * Optimized relu with QSUB instructions. + * + */ + +void arm_relu_q15(q15_t * data, uint16_t size) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + uint16_t i = size >> 1; + q15_t *pIn = data; + q15_t *pOut = data; + q31_t in; + q31_t buf; + q31_t mask; + + while (i) + { + in = *__SIMD32(pIn)++; + + /* extract the first bit */ + buf = __ROR(in & 0x80008000, 15); + + /* if MSB=1, mask will be 0xFF, 0x0 otherwise */ + mask = __QSUB16(0x00000000, buf); + + *__SIMD32(pOut)++ = in & (~mask); + i--; + } + + if (size & 0x1) + { + if (*pIn < 0) + { + *pIn = 0; + } + pIn++; + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } + +#endif /* ARM_MATH_DSP */ + +} + +/** + * @} end of Acti group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c new file mode 100644 index 0000000..caa027b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ActivationFunctions/arm_relu_q7.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_relu_q7.c + * Description: Q7 version of ReLU + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Acti + * @{ + */ + + /** + * @brief Q7 RELU function + * @param[in,out] data pointer to input + * @param[in] size number of elements + * @return none. + * + * @details + * + * Optimized relu with QSUB instructions. + * + */ + +void arm_relu_q7(q7_t * data, uint16_t size) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + uint16_t i = size >> 2; + q7_t *pIn = data; + q7_t *pOut = data; + q31_t in; + q31_t buf; + q31_t mask; + + while (i) + { + in = *__SIMD32(pIn)++; + + /* extract the first bit */ + buf = __ROR(in & 0x80808080, 7); + + /* if MSB=1, mask will be 0xFF, 0x0 otherwise */ + mask = __QSUB8(0x00000000, buf); + + *__SIMD32(pOut)++ = in & (~mask); + i--; + } + + i = size & 0x3; + while (i) + { + if (*pIn < 0) + { + *pIn = 0; + } + pIn++; + i--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + uint16_t i; + + for (i = 0; i < size; i++) + { + if (data[i] < 0) + data[i] = 0; + } + +#endif /* ARM_MATH_DSP */ + +} + +/** + * @} end of Acti group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c new file mode 100644 index 0000000..4c69e7c --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_1x1_HWC_q7_fast_nonsquare.c @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_1x1_HWC_q7_fast_nonsquare.c + * Description: Fast Q7 version of 1x1 convolution (non-square shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Fast Q7 version of 1x1 convolution (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is optimized for convolution with 1x1 kernel size (i.e., dim_kernel_x=1 + * and dim_kernel_y=1). It can be used for the second half of MobileNets [1] after depthwise + * separable convolution. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + * + * [1] MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications + * https://arxiv.org/abs/1704.04861 + */ + +arm_status arm_convolve_1x1_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x; + int16_t i_ch_out; + + /* ----------------------- + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1 + || padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_out_y * dim_im_in_x + i_out_x) * ch_im_in, pBuffer, + ch_im_in); + pBuffer += ch_im_in; + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + q31_t sum = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (const q7_t *)read_and_pad_reordered((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0 || dim_kernel_x != 1 || dim_kernel_y != 1 + || padding_x != 0 || padding_y != 0 || stride_x != 1 || stride_y != 1) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_y + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c new file mode 100644 index 0000000..ee08d74 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_basic.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_basic.c + * Description: Q15 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * bufferA size: ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * This basic version is designed to work for any input tensor and weight + * dimension. + */ + +arm_status +arm_convolve_HWC_q15_basic(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + uint16_t im2col_out_pixel_index = 0; + q15_t *pBuffer = bufferA; + q15_t *pOut = Im_out; + q15_t *im_buffer = bufferA; + const q15_t *pA; + int i; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + pA = wt; + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = im_buffer; + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + while (colCnt) + { + q31_t inA1 = *__SIMD32(pA)++; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inA2 = *__SIMD32(pA)++; + q31_t inB2 = *__SIMD32(pB)++; + + sum = __SMLAD(inA1, inB1, sum); + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q15_t) __SSAT((sum >> out_shift), 16); + pOut++; + } + + /* counter reset */ + pBuffer = im_buffer; + im2col_out_pixel_index++; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c new file mode 100644 index 0000000..a02aaa0 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_fast.c + * Description: Fast Q15 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q15 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + +arm_status +arm_convolve_HWC_q15_fast(const q15_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + q15_t *pBuffer = bufferA; + q15_t *im_buffer = bufferA; + q15_t *pOut = Im_out; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (i_out_x & 0x1) + { + int i; + /* initialize the matrix pointers for A */ + const q15_t *pA = wt; + + /* set up the second output pointers */ + q15_t *pOut2 = pOut + ch_im_out; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + q15_t *pB = im_buffer; + const q15_t *pB2 = pB + ch_im_in * dim_kernel * dim_kernel; + + /* aling the second pointer for A */ + const q15_t *pA2 = pA + ch_im_in * dim_kernel * dim_kernel; + + /* init the sum with bias */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 1; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA1 = *__SIMD32(pA)++; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inA2 = *__SIMD32(pA2)++; + q31_t inB2 = *__SIMD32(pB2)++; + + sum = __SMLAD(inA1, inB1, sum); + sum2 = __SMLAD(inA1, inB2, sum2); + sum3 = __SMLAD(inA2, inB1, sum3); + sum4 = __SMLAD(inA2, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x1; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q15_t) __SSAT(sum >> out_shift, 16); + *pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16); + + /* skip the row computed with A2 */ + pA += ch_im_in * dim_kernel * dim_kernel; + } /* for over ch_im_out */ + + pOut += ch_im_out; + /* counter reset */ + pBuffer = im_buffer; + } + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c new file mode 100644 index 0000000..14d9130 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q15_fast_nonsquare.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q15_fast.c + * Description: Fast Q15 version of convolution + * + * $Date: 24. May 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q15 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 2 + * + * ch_im_out is multipe of 2 + * + */ + +arm_status +arm_convolve_HWC_q15_fast_nonsquare(const q15_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q15_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q15_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q15_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + q15_t *pBuffer = bufferA; + q15_t *im_buffer = bufferA; + q15_t *pOut = Im_out; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* arm_copy_q15((q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q15_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, sizeof(q15_t)*ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (i_out_x & 0x1) + { + int i; + /* initialize the matrix pointers for A */ + const q15_t *pA = wt; + + /* set up the second output pointers */ + q15_t *pOut2 = pOut + ch_im_out; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + q15_t *pB = im_buffer; + const q15_t *pB2 = pB + ch_im_in * dim_kernel_y * dim_kernel_x; + + /* aling the second pointer for A */ + const q15_t *pA2 = pA + ch_im_in * dim_kernel_y * dim_kernel_x; + + /* init the sum with bias */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)bias[i + 1] << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 1; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA1 = *__SIMD32(pA)++; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inA2 = *__SIMD32(pA2)++; + q31_t inB2 = *__SIMD32(pB2)++; + + sum = __SMLAD(inA1, inB1, sum); + sum2 = __SMLAD(inA1, inB2, sum2); + sum3 = __SMLAD(inA2, inB1, sum3); + sum4 = __SMLAD(inA2, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x1; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q15_t) __SSAT(sum >> out_shift, 16); + *pOut++ = (q15_t) __SSAT(sum3 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum2 >> out_shift, 16); + *pOut2++ = (q15_t) __SSAT(sum4 >> out_shift, 16); + + /* skip the row computed with A2 */ + pA += ch_im_in * dim_kernel_y * dim_kernel_x; + } /* for over ch_im_out */ + + pOut += ch_im_out; + /* counter reset */ + pBuffer = im_buffer; + } + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + if (ch_im_in % 2 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel_x * dim_kernel_y + (m * dim_kernel_x + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q15_t) __SSAT((conv_out >> out_shift), 16); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c new file mode 100644 index 0000000..e53c6f9 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_RGB.c @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_RGB.c + * Description: Q7 version of convolution for RGB image + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Q7 convolution function for RGB image + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in equals 3 + * + * This kernel is written exclusively for convolution with ch_im_in + * equals 3. This applies on the first layer of CNNs which has input + * image with RGB format. + */ + +arm_status +arm_convolve_HWC_q7_RGB(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, const uint16_t dim_im_out, q15_t * bufferA, q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + // check if number of input channels is 3 + if (ch_im_in != 3) + { + return ARM_MATH_SIZE_MISMATCH; + } + // This part implements the im2col function + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Equivalent to arm_fill_q15(0, pBuffer, ch_im_in) with assumption: ch_im_in = 3 */ + *__SIMD32(pBuffer) = 0x0; + *(pBuffer + 2) = 0; + pBuffer += 3; + } else + { + /* + * Equivalent to: + * arm_q7_to_q15_no_shift( (q7_t*)Im_in+(i_ker_y*dim_im_in+i_ker_x)*3, pBuffer, 3); + */ + + const q7_t *pPixel = Im_in + (i_ker_y * dim_im_in + i_ker_x) * 3; + q31_t buf = *__SIMD32(pPixel); + + union arm_nnword top; + union arm_nnword bottom; + + top.word = __SXTB16(buf); + bottom.word = __SXTB16(__ROR(buf, 8)); + +#ifndef ARM_MATH_BIG_ENDIAN + /* + * little-endian, | omit | 3rd | 2nd | 1st | + * MSB LSB + * top | 3rd | 1st |; bottom | omit | 2nd | + * + * version 1, need to swap 2nd and 3rd weight + * *__SIMD32(pBuffer) = top.word; + * *(pBuffer+2) = bottom.half_words[0]; + * + * version 2, no weight shuffling required + */ + *pBuffer++ = top.half_words[0]; + *__SIMD32(pBuffer) = __PKHBT(bottom.word, top.word, 0); +#else + /* + * big-endian, | 1st | 2nd | 3rd | omit | + * MSB LSB + * top | 2nd | omit |; bottom | 1st | 3rd | + * + * version 1, need to swap 2nd and 3rd weight + * *__SIMD32(pBuffer) = bottom.word; + * *(pBuffer+2) = top.half_words[1]; + * + * version 2, no weight shuffling required + */ + *pBuffer++ = bottom.half_words[0]; + *__SIMD32(pBuffer) = __PKHTB(top.word, bottom.word, 0); +#endif + pBuffer += 2; + } + } + } + + if (pBuffer == bufferA + 2 * 3 * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + 3 * dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = 3 * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = 3 * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + // check if number of input channels is 3 + if (ch_im_in != 3) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + /* if-for implementation */ + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return (ARM_MATH_SUCCESS); +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c new file mode 100644 index 0000000..7c9ec65 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_basic.c + * Description: Q7 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * This basic version is designed to work for any input tensor and weight + * dimension. + */ + +arm_status +arm_convolve_HWC_q7_basic(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* Copying the pixel data to column */ + arm_q7_to_q15_no_shift((q7_t *) + Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* Computation is filed for every 2 columns */ + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + ch_im_in * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + /* Load the accumulator with bias first */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + + /* Point to the beging of the im2col buffer */ + q15_t *pB = bufferA; + + /* Each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + // if-for implementation + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c new file mode 100644 index 0000000..24356d9 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_basic_nonsquare.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_basic.c + * Description: Q7 version of convolution + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Basic Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns ARM_MATH_SUCCESS + */ + +arm_status arm_convolve_HWC_q7_basic_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + /* This part implements the im2col function */ + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* Filling 0 for out-of-bound paddings */ + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + /* Copying the pixel data to column */ + arm_q7_to_q15_no_shift((q7_t *) + Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* Computation is filed for every 2 columns */ + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_y * dim_kernel_x) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15(wt, bufferA, + ch_im_out, + ch_im_in * + dim_kernel_y * dim_kernel_x, bias_shift, out_shift, bias, pOut); + + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* left-over because odd number of output pixels */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + /* Load the accumulator with bias first */ + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + + /* Point to the beging of the im2col buffer */ + q15_t *pB = bufferA; + + /* Each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_y * dim_kernel_x >> 2; + + while (colCnt) + { + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (q7_t *) read_and_pad((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel_y * dim_kernel_x & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + } + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + // if-for implementation + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + + (m * dim_kernel_x + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c new file mode 100644 index 0000000..e2d469f --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast.c @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_fast.c + * Description: Fast Q7 version of convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + + /** + * @brief Fast Q7 convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in is multiple of 4 ( because of the SIMD32 read and swap ) + * + * ch_im_out is multipe of 2 ( bacause 2x2 mat_mult kernel ) + * + * The im2col converts the Q7 tensor input into Q15 column, which is stored in + * bufferA. There is reordering happenning during this im2col process with + * arm_q7_to_q15_reordered_no_shift. For every four elements, the second and + * third elements are swapped. + * + * The computation kernel arm_nn_mat_mult_kernel_q7_q15_reordered does the + * GEMM computation with the reordered columns. + * + * To speed-up the determination of the padding condition, we split the + * computation into 3x3 parts, i.e., {top, mid, bottom} X {left, mid, right}. + * This reduces the total number of boundary condition checks and improves + * the data copying performance. + */ + +arm_status +arm_convolve_HWC_q7_fast(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* + * Here we split the entire matrix into three regions depending on the padding situation + * Top: i_out_y from 0 to padding - 1 + * Middle: i_out_y from padding to dim_im_out-padding-1 + * Bottom: i_out_y from dim_im_out-padding to dim_im_out-1 + */ + + /* top part */ + for (i_out_y = 0; i_out_y < padding; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* middle part, here we also divide the x into left, mid and right */ + for (; i_out_y < dim_im_out - padding; i_out_y++) + { + + /* left part */ + for (i_out_x = 0; i_out_x < padding; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* mid part */ + for (; i_out_x < dim_im_out - padding; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + + + (i_ker_y * + dim_im_in + + i_out_x * + stride - padding) * ch_im_in, pBuffer, ch_im_in * dim_kernel); + pBuffer += ch_im_in * dim_kernel; + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* right part */ + for (; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + for (; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift + ((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel * dim_kernel) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, + bufferA, + ch_im_out, + ch_im_in + * + dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = bufferA; + /* each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel * dim_kernel >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (q7_t *) read_and_pad_reordered((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = ch_im_in * dim_kernel * dim_kernel & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + uint16_t i, j, k, l, m, n; + int conv_out; + signed char in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out; j++) + { + for (k = 0; k < dim_im_out; k++) + { + conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel; m++) + { + for (n = 0; n < dim_kernel; n++) + { + // if-for implementation + in_row = stride * j + m - padding; + in_col = stride * k + n - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += + Im_in[(in_row * dim_im_in + in_col) * ch_im_in + + l] * wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c new file mode 100644 index 0000000..6dc6f0b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_convolve_HWC_q7_fast_nonsquare.c @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_convolve_HWC_q7_fast_nonsquare.c + * Description: Fast Q7 version of convolution (non-sqaure shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Fast Q7 convolution function (non-sqaure shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding size x + * @param[in] padding_y padding size y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 4 + * ch_im_out is multiple of 2 + */ + +arm_status arm_convolve_HWC_q7_fast_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; + + /* ----------------------- + * Here we use bufferA as q15_t internally as computation are done with q15_t level + * im2col are done to output in q15_t format from q7_t input + */ + + q15_t *pBuffer = bufferA; + q7_t *pOut = Im_out; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + /* + * Here we split the entire matrix into three regions depending on the padding situation + * Top: i_out_y from 0 to padding - 1 + * Middle: i_out_y from padding to dim_im_out-padding-1 + * Bottom: i_out_y from dim_im_out-padding to dim_im_out-1 + */ + + /* top part */ + for (i_out_y = 0; i_out_y < padding_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* middle part, here we also divide the x into left, mid and right */ + for (; i_out_y < dim_im_out_y - padding_y; i_out_y++) + { + + /* left part */ + for (i_out_x = 0; i_out_x < padding_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* mid part */ + for (; i_out_x < dim_im_out_x - padding_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + + (i_ker_y * dim_im_in_x + i_out_x * stride_x - padding_x) * ch_im_in, + pBuffer, ch_im_in * dim_kernel_x); + pBuffer += ch_im_in * dim_kernel_x; + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + + /* right part */ + for (; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + for (; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* This part implements the im2col function */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q15(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, sizeof(q15_t)*ch_im_in); + } else + { + arm_q7_to_q15_reordered_no_shift((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, + pBuffer, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + if (pBuffer == bufferA + 2 * ch_im_in * dim_kernel_x * dim_kernel_y) + { + pOut = + arm_nn_mat_mult_kernel_q7_q15_reordered(wt, bufferA, ch_im_out, ch_im_in * dim_kernel_x * dim_kernel_y, + bias_shift, out_shift, bias, pOut); + /* counter reset */ + pBuffer = bufferA; + } + } + } + + /* check if there is left-over for compute */ + if (pBuffer != bufferA) + { + const q7_t *pA = wt; + int i; + for (i = 0; i < ch_im_out; i++) + { + q31_t sum = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + q15_t *pB = bufferA; + /* basically each time it process 4 entries */ + uint16_t colCnt = ch_im_in * dim_kernel_x * dim_kernel_y >> 2; + + while (colCnt) + { + + q31_t inA1, inA2; + q31_t inB1, inB2; + + pA = (const q7_t *)read_and_pad_reordered((void *)pA, &inA1, &inA2); + + inB1 = *__SIMD32(pB)++; + sum = __SMLAD(inA1, inB1, sum); + inB2 = *__SIMD32(pB)++; + sum = __SMLAD(inA2, inB2, sum); + + colCnt--; + } + colCnt = (ch_im_in * dim_kernel_y * dim_kernel_x) & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + sum += inA1 * inB1; + colCnt--; + } + *pOut = (q7_t) __SSAT((sum >> out_shift), 8); + pOut++; + + } + + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i, j, k, l, m, n; + int conv_out; + int in_row, in_col; + + if (ch_im_in % 4 != 0 || ch_im_out % 2 != 0) + { + /* check if the input dimension meets the constraints */ + return ARM_MATH_SIZE_MISMATCH; + } + + for (i = 0; i < ch_im_out; i++) + { + for (j = 0; j < dim_im_out_y; j++) + { + for (k = 0; k < dim_im_out_x; k++) + { + conv_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (m = 0; m < dim_kernel_y; m++) + { + for (n = 0; n < dim_kernel_x; n++) + { + /* if-for implementation */ + in_row = stride_y * j + m - padding_y; + in_col = stride_x * k + n - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + for (l = 0; l < ch_im_in; l++) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + l] * + wt[i * ch_im_in * dim_kernel_y * dim_kernel_x + (m * dim_kernel_x + n) * ch_im_in + l]; + } + } + } + } + Im_out[i + (j * dim_im_out_x + k) * ch_im_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c new file mode 100644 index 0000000..705fa6a --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7.c @@ -0,0 +1,418 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_separable_conv_HWC_q7.c + * Description: Q7 depthwise separable convolution function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Q7 depthwise separable convolution function + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*ch_im_in*dim_kernel*dim_kernel + * + * bufferB size: 0 + * + * Input dimension constraints: + * + * ch_im_in equals ch_im_out + * + * Implementation: + * There are 3 nested loop here: + * Inner loop: calculate each output value with MAC instruction over an accumulator + * Mid loop: loop over different output channel + * Outer loop: loop over different output (x, y) + */ + +arm_status arm_depthwise_separable_conv_HWC_q7(const q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_out_y, i_out_x; + int16_t i_ker_y, i_ker_x; + q7_t *colBuffer = (q7_t *) bufferA; + q7_t *pBuffer = colBuffer; + const q7_t *pBias = bias; + q7_t *pOut = Im_out; + uint16_t rowCnt; + uint16_t row_shift; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + /* we first do im2col here */ + for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) + { + for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) + { + /* arm_fill_q7(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, ch_im_in); + } else + { + /* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in + i_ker_x) * ch_im_in, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* we will do the computation here for each channel */ + rowCnt = ch_im_out >> 2; + row_shift = 0; + pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = (dim_kernel * dim_kernel) >> 1; + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + row_shift += 4; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = *__SIMD32(pB); + pB += ch_im_in; + opB = *__SIMD32(pB); + pB += ch_im_in; + inB2 = __PKHTB(opB, inB1, 16); + inB1 = __PKHBT(inB1, opB, 16); + inA1 = *__SIMD32(pA); + pA += ch_im_in; + opB = *__SIMD32(pA); + pA += ch_im_in; + inA2 = __PKHTB(opB, inA1, 16); + inA1 = __PKHBT(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum3 = __SMLAD(opA, opB, sum3); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum4 = __SMLAD(opA, opB, sum4); + colCnt--; + } +#else + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = *__SIMD32(pB); + pB += ch_im_in; + opB = *__SIMD32(pB); + pB += ch_im_in; + inB2 = __PKHBT(opB, inB1, 16); + inB1 = __PKHTB(inB1, opB, 16); + inA1 = *__SIMD32(pA); + pA += ch_im_in; + opB = *__SIMD32(pA); + pA += ch_im_in; + inA2 = __PKHBT(opB, inA1, 16); + inA1 = __PKHTB(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum4 = __SMLAD(opA, opB, sum4); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum3 = __SMLAD(opA, opB, sum3); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + +#ifndef ARM_MATH_BIG_ENDIAN + /* + * r0 r1 r2 r3 r4 r5 + * inA1, inA2, inB1, inB2, opA, opB + */ + + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhtb r3, r5, r2, ASR #16\n" + "pkhbt r2, r2, r5, LSL #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhtb r1, r5, r0, ASR #16\n" + "pkhbt r0, r0, r5, LSL #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum], r4, r5, %[sum]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] + "+r"(sum),[sum2] "+r"(sum2), + [sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB), + [pA] "+r"(pA):[colCnt] + "r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#else + /* + * r0 r1 r2 r3 r4 r5 + * inA1, inA2, inB1, inB2, opA, opB + */ + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhbt r3, r5, r2, LSL #16\n" + "pkhtb r2, r2, r5, ASR #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhbt r1, r5, r0, LSL #16\n" + "pkhtb r0, r0, r5, ASR #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum], r4, r5, %[sum]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] + "+r"(sum),[sum2] "+r"(sum2), + [sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB), + [pA] "+r"(pA):[colCnt] + "r"(colCnt),[ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = (dim_kernel * dim_kernel) & 0x1; + while (colCnt) + { + union arm_nnword inA, inB; + inA.word = *__SIMD32(pA); + pA += ch_im_in; + inB.word = *__SIMD32(pB); + pB += ch_im_in; + sum += inA.bytes[0] * inB.bytes[0]; + sum2 += inA.bytes[1] * inB.bytes[1]; + sum3 += inA.bytes[2] * inB.bytes[2]; + sum4 += inA.bytes[3] * inB.bytes[3]; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = ch_im_out & 0x3; + while (rowCnt) + { + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = (dim_kernel * dim_kernel); + + row_shift += 1; + + while (colCnt) + { + q7_t A1 = *pA; + q7_t B1 = *pB; + pA += ch_im_in; + pB += ch_im_in; + sum += A1 * B1; + + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + rowCnt--; + } + + /* clear counter and pointers */ + pBuffer = colBuffer; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i_out_y, i_out_x, i_ch_out, i_ker_x, i_ker_y; + int conv_out; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output + conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + for (i_ker_y = 0; i_ker_y < dim_kernel; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel; i_ker_x++) + { + int in_row = stride * i_out_y + i_ker_y - padding; + int in_col = stride * i_out_x + i_ker_x - padding; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) + { + conv_out += + Im_in[(in_row * + dim_im_in + + in_col) * + ch_im_in + + i_ch_out] * wt[(i_ker_y * dim_kernel + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out + + i_out_x) * ch_im_out + i_ch_out] = (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return ARM_MATH_SUCCESS; + +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c new file mode 100644 index 0000000..5989304 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_depthwise_separable_conv_HWC_q7_nonsquare.c @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_depthwise_separable_conv_HWC_q7_nonsquare.c + * Description: Q7 depthwise separable convolution function (non-square shape) + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup NNConv + * @{ + */ + +/** + * @brief Q7 depthwise separable convolution function (non-square shape) + * @param[in] Im_in pointer to input tensor + * @param[in] dim_im_in_x input tensor dimention x + * @param[in] dim_im_in_y input tensor dimention y + * @param[in] ch_im_in number of input tensor channels + * @param[in] wt pointer to kernel weights + * @param[in] ch_im_out number of filters, i.e., output tensor channels + * @param[in] dim_kernel_x filter kernel size x + * @param[in] dim_kernel_y filter kernel size y + * @param[in] padding_x padding sizes x + * @param[in] padding_y padding sizes y + * @param[in] stride_x convolution stride x + * @param[in] stride_y convolution stride y + * @param[in] bias pointer to bias + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in,out] Im_out pointer to output tensor + * @param[in] dim_im_out_x output tensor dimension x + * @param[in] dim_im_out_y output tensor dimension y + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] bufferB pointer to buffer space for output + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + * + * This function is the version with full list of optimization tricks, but with + * some contraints: + * ch_im_in is multiple of 2 + * ch_im_out is multiple of 2 + */ + +arm_status arm_depthwise_separable_conv_HWC_q7_nonsquare(const q7_t * Im_in, + const uint16_t dim_im_in_x, + const uint16_t dim_im_in_y, + const uint16_t ch_im_in, + const q7_t * wt, + const uint16_t ch_im_out, + const uint16_t dim_kernel_x, + const uint16_t dim_kernel_y, + const uint16_t padding_x, + const uint16_t padding_y, + const uint16_t stride_x, + const uint16_t stride_y, + const q7_t * bias, + const uint16_t bias_shift, + const uint16_t out_shift, + q7_t * Im_out, + const uint16_t dim_im_out_x, + const uint16_t dim_im_out_y, + q15_t * bufferA, + q7_t * bufferB) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + +/* + * Implementation: + * There are 3 nested loop here: + * Inner loop: calculate each output value with MAC instruction over an accumulator + * Mid loop: loop over different output channel + * Outer loop: loop over different output (x, y) + * + */ + + int16_t i_out_y, i_out_x; + int16_t i_ker_y, i_ker_x; + q7_t *colBuffer = (q7_t *) bufferA; + q7_t *pBuffer = colBuffer; + const q7_t *pBias = bias; + q7_t *pOut = Im_out; + uint16_t rowCnt; + uint16_t row_shift; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + /* we first do im2col here */ + for (i_ker_y = i_out_y * stride_y - padding_y; i_ker_y < i_out_y * stride_y - padding_y + dim_kernel_y; + i_ker_y++) + { + for (i_ker_x = i_out_x * stride_x - padding_x; i_ker_x < i_out_x * stride_x - padding_x + dim_kernel_x; + i_ker_x++) + { + if (i_ker_y < 0 || i_ker_y >= dim_im_in_y || i_ker_x < 0 || i_ker_x >= dim_im_in_x) + { + /* arm_fill_q7(0, pBuffer, ch_im_in); */ + memset(pBuffer, 0, ch_im_in); + } else + { + /* arm_copy_q7((q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, pBuffer, ch_im_in); */ + memcpy(pBuffer, (q7_t *) Im_in + (i_ker_y * dim_im_in_x + i_ker_x) * ch_im_in, ch_im_in); + } + pBuffer += ch_im_in; + } + } + + /* we will do the computation here for each channel */ + rowCnt = ch_im_out >> 2; + row_shift = 0; + pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = (dim_kernel_x * dim_kernel_y) >> 1; + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + row_shift += 4; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = *__SIMD32(pB); + pB += ch_im_in; + opB = *__SIMD32(pB); + pB += ch_im_in; + inB2 = __PKHTB(opB, inB1, 16); + inB1 = __PKHBT(inB1, opB, 16); + inA1 = *__SIMD32(pA); + pA += ch_im_in; + opB = *__SIMD32(pA); + pA += ch_im_in; + inA2 = __PKHTB(opB, inA1, 16); + inA1 = __PKHBT(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum3 = __SMLAD(opA, opB, sum3); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum4 = __SMLAD(opA, opB, sum4); + colCnt--; + } +#else + + while (colCnt) + { + q31_t inA1, inA2, inB1, inB2, opA, opB; + + inB1 = *__SIMD32(pB); + pB += ch_im_in; + opB = *__SIMD32(pB); + pB += ch_im_in; + inB2 = __PKHBT(opB, inB1, 16); + inB1 = __PKHTB(inB1, opB, 16); + inA1 = *__SIMD32(pA); + pA += ch_im_in; + opB = *__SIMD32(pA); + pA += ch_im_in; + inA2 = __PKHBT(opB, inA1, 16); + inA1 = __PKHTB(inA1, opB, 16); + opA = __SXTB16(inA1); + opB = __SXTB16(inB1); + sum2 = __SMLAD(opA, opB, sum2); + opA = __SXTB16(__ROR(inA1, 8)); + opB = __SXTB16(__ROR(inB1, 8)); + sum = __SMLAD(opA, opB, sum); + opA = __SXTB16(inA2); + opB = __SXTB16(inB2); + sum4 = __SMLAD(opA, opB, sum4); + opA = __SXTB16(__ROR(inA2, 8)); + opB = __SXTB16(__ROR(inB2, 8)); + sum3 = __SMLAD(opA, opB, sum3); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + +#ifndef ARM_MATH_BIG_ENDIAN + // r0 r1 r2 r3 r4 r5 + // inA1, inA2, inB1, inB2, opA, opB + asm volatile ("COL_LOOP:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhtb r3, r5, r2, ASR #16\n" + "pkhbt r2, r2, r5, LSL #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhtb r1, r5, r0, ASR #16\n" + "pkhbt r0, r0, r5, LSL #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum], r4, r5, %[sum]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt), + [ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#else + // r0 r1 r2 r3 r4 r5 + // inA1, inA2, inB1, inB2, opA, opB + asm volatile ("COL_LOOP:\n" + "ldr.w r2, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "ldr.w r5, [%[pB], #0]\n" + "add.w %[pB], %[pB], %[ch_im_in]\n" + "pkhbt r3, r5, r2, LSL #16\n" + "pkhtb r2, r2, r5, ASR #16\n" + "ldr.w r0, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "ldr.w r5, [%[pA], #0]\n" + "add.w %[pA], %[pA], %[ch_im_in]\n" + "pkhbt r1, r5, r0, LSL #16\n" + "pkhtb r0, r0, r5, ASR #16\n" + "sxtb16 r4, r0\n" + "sxtb16 r5, r2\n" + "smlad %[sum2], r4, r5, %[sum2]\n" + "mov.w r4, r0, ror #8\n" + "mov.w r5, r2, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum], r4, r5, %[sum]\n" + "sxtb16 r4, r1\n" + "sxtb16 r5, r3\n" + "smlad %[sum4], r4, r5, %[sum4]\n" + "mov.w r4, r1, ror #8\n" + "mov.w r5, r3, ror #8\n" + "sxtb16 r4, r4\n" + "sxtb16 r5, r5\n" + "smlad %[sum3], r4, r5, %[sum3]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP\n":[sum] "+r"(sum),[sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt), + [ch_im_in] "r"(ch_im_in):"r0", "r1", "r2", "r3", "r4", "r5"); +#endif /*ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = (dim_kernel_x * dim_kernel_y) & 0x1; + while (colCnt) + { + union arm_nnword inA, inB; + inA.word = *__SIMD32(pA); + pA += ch_im_in; + inB.word = *__SIMD32(pB); + pB += ch_im_in; + sum += inA.bytes[0] * inB.bytes[0]; + sum2 += inA.bytes[1] * inB.bytes[1]; + sum3 += inA.bytes[2] * inB.bytes[2]; + sum4 += inA.bytes[3] * inB.bytes[3]; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = ch_im_out & 0x3; + while (rowCnt) + { + q7_t *pB = colBuffer + row_shift; + const q7_t *pA = wt + row_shift; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = (dim_kernel_x * dim_kernel_y); + + row_shift += 1; + + while (colCnt) + { + q7_t A1 = *pA; + q7_t B1 = *pB; + pA += ch_im_in; + pB += ch_im_in; + sum += A1 * B1; + + colCnt--; + } + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + rowCnt--; + } + + // clear counter and pointers + pBuffer = colBuffer; + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + int i_out_y, i_out_x, i_ch_out; + int i_ker_y, i_ker_x; + + /* do some checking here, basically ch_im_in == ch_im_out */ + if (ch_im_in != ch_im_out) + { + return ARM_MATH_SIZE_MISMATCH; + } + + for (i_out_y = 0; i_out_y < dim_im_out_y; i_out_y++) + { + for (i_out_x = 0; i_out_x < dim_im_out_x; i_out_x++) + { + for (i_ch_out = 0; i_ch_out < ch_im_out; i_ch_out++) + { + // for each output + int conv_out = ((q31_t)(bias[i_ch_out]) << bias_shift) + NN_ROUND(out_shift); + for (i_ker_y = 0; i_ker_y < dim_kernel_y; i_ker_y++) + { + for (i_ker_x = 0; i_ker_x < dim_kernel_x; i_ker_x++) + { + int in_row = stride_y * i_out_y + i_ker_y - padding_y; + int in_col = stride_x * i_out_x + i_ker_x - padding_x; + if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in_y && in_col < dim_im_in_x) + { + conv_out += Im_in[(in_row * dim_im_in_x + in_col) * ch_im_in + i_ch_out] * + wt[(i_ker_y * dim_kernel_x + i_ker_x) * ch_im_out + i_ch_out]; + } + } + } + Im_out[(i_out_y * dim_im_out_x + i_out_x) * ch_im_out + i_ch_out] = + (q7_t) __SSAT((conv_out >> out_shift), 8); + } + } + } + +#endif /* ARM_MATH_DSP */ + + + /* Return to application */ + return ARM_MATH_SUCCESS; + +} + +/** + * @} end of NNConv group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c new file mode 100644 index 0000000..24ab412 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_q7_q15.c + * Description: Matrix-multiplication function for convolution + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + + /** + * @brief Matrix-multiplication function for convolution + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + * + * @details + * + * This function does the matrix multiplication with weight matrix + * and 2 columns from im2col. + */ + +q7_t *arm_nn_mat_mult_kernel_q7_q15(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut) +{ +#if defined (ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *pOut2 = pOut + ch_im_out; + const q7_t *pBias = bias; + + uint16_t rowCnt = ch_im_out >> 1; + /* this loop over rows in A */ + while (rowCnt) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* align the second pointer for A */ + const q7_t *pA2 = pA + numCol_A; + + /* init the sum with bias */ + q31_t sum = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA11, inA12, inA21, inA22; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inB2 = *__SIMD32(pB2)++; + + pA = (q7_t *) read_and_pad((void *)pA, &inA11, &inA12); + pA2 = (q7_t *) read_and_pad((void *)pA2, &inA21, &inA22); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + sum3 = __SMLAD(inA21, inB1, sum3); + sum4 = __SMLAD(inA21, inB2, sum4); + + inB1 = *__SIMD32(pB)++; + inB2 = *__SIMD32(pB2)++; + + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + sum3 = __SMLAD(inA22, inB1, sum3); + sum4 = __SMLAD(inA22, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q7_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + /* skip the row computed with A2 */ + pA += numCol_A; + rowCnt--; + } /* for over ch_im_out */ + + /* compute left-over row if any */ + if (ch_im_out & 0x1) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* load the bias */ + q31_t sum = ((q31_t)(*pBias) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + while (colCnt) + { + q31_t inA11, inA12; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inB2 = *__SIMD32(pB2)++; + + pA = (q7_t *) read_and_pad((void *)pA, &inA11, &inA12); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + + inB1 = *__SIMD32(pB)++; + inB2 = *__SIMD32(pB2)++; + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + + colCnt--; + } + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + colCnt--; + } + + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + } + + pOut += ch_im_out; + + /* return the new output pointer with offset */ + return pOut; +#else + /* To be completed */ + return NULL; +#endif /* ARM_MATH_DSP */ + +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c new file mode 100644 index 0000000..36af21a --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/ConvolutionFunctions/arm_nn_mat_mult_kernel_q7_q15_reordered.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mat_mult_kernel_q7_q15_reordered.c + * Description: Matrix-multiplication function for convolution with reordered columns + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * -------------------------------------------------------------------- */ + +#include "arm_nnfunctions.h" +#include "arm_math.h" + + /** + * @brief Matrix-multiplication function for convolution with reordered columns + * @param[in] pA pointer to operand A + * @param[in] pInBuffer pointer to operand B, always conssists of 2 vectors + * @param[in] ch_im_out numRow of A + * @param[in] numCol_A numCol of A + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias the bias + * @param[in,out] pOut pointer to output + * @return The function returns the incremented output pointer + * + * @details + * + * This function assumes that data in pInBuffer are reordered + */ + +q7_t *arm_nn_mat_mult_kernel_q7_q15_reordered(const q7_t * pA, + const q15_t * pInBuffer, + const uint16_t ch_im_out, + const uint16_t numCol_A, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut) +{ + +#if defined (ARM_MATH_DSP) + /* set up the second output pointers */ + q7_t *pOut2 = pOut + ch_im_out; + int i; + + /* this loop over rows in A */ + for (i = 0; i < ch_im_out; i += 2) + { + /* setup pointers for B */ + const q15_t *pB = pInBuffer; + const q15_t *pB2 = pB + numCol_A; + + /* align the second pointer for A */ + const q7_t *pA2 = pA + numCol_A; + + /* init the sum with bias */ + q31_t sum = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(bias[i + 1]) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(bias[i + 1]) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = numCol_A >> 2; + /* accumulate over the vector */ + while (colCnt) + { + q31_t inA11, inA12, inA21, inA22; + q31_t inB1 = *__SIMD32(pB)++; + q31_t inB2 = *__SIMD32(pB2)++; + + pA = (q7_t *) read_and_pad_reordered((void *)pA, &inA11, &inA12); + pA2 = (q7_t *) read_and_pad_reordered((void *)pA2, &inA21, &inA22); + + sum = __SMLAD(inA11, inB1, sum); + sum2 = __SMLAD(inA11, inB2, sum2); + sum3 = __SMLAD(inA21, inB1, sum3); + sum4 = __SMLAD(inA21, inB2, sum4); + + inB1 = *__SIMD32(pB)++; + inB2 = *__SIMD32(pB2)++; + + sum = __SMLAD(inA12, inB1, sum); + sum2 = __SMLAD(inA12, inB2, sum2); + sum3 = __SMLAD(inA22, inB1, sum3); + sum4 = __SMLAD(inA22, inB2, sum4); + + colCnt--; + } /* while over colCnt */ + colCnt = numCol_A & 0x3; + while (colCnt) + { + q7_t inA1 = *pA++; + q15_t inB1 = *pB++; + q7_t inA2 = *pA2++; + q15_t inB2 = *pB2++; + + sum += inA1 * inB1; + sum2 += inA1 * inB2; + sum3 += inA2 * inB1; + sum4 += inA2 * inB2; + colCnt--; + } /* while over colCnt */ + *pOut++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pOut++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pOut2++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + /* skip the row computed with A2 */ + pA += numCol_A; + } /* for over ch_im_out */ + + pOut += ch_im_out; + + /* return the new output pointer with offset */ + return pOut; +#else + /* To be completed */ + return NULL; +#endif /* ARM_MATH_DSP */ +} diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c new file mode 100644 index 0000000..bb9a091 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_mat_q7_vec_q15.c + * Description: Mixed Q15-Q7 fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Mixed Q15-Q7 fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Q7_Q15 version of the fully connected layer + * + * Weights are in q7_t and Activations are in q15_t + * + */ + +arm_status +arm_fully_connected_mat_q7_vec_q15(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + const q7_t *pB2; + q15_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 1; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV, inM11, inM12, inM21, inM22; + pB = (q7_t *) read_and_pad((void *)pB, &inM11, &inM12); + pB2 = (q7_t *) read_and_pad((void *)pB2, &inM21, &inM22); + + inV = *__SIMD32(pA)++; + + sum = __SMLAD(inV, inM11, sum); + sum2 = __SMLAD(inV, inM21, sum2); + + inV = *__SIMD32(pA)++; + + sum = __SMLAD(inV, inM12, sum); + sum2 = __SMLAD(inV, inM22, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + + /*adjust the pointers and counters */ + pB += dim_vec; + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x1; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = (q7_t *) read_and_pad((void *)pB, &inM11, &inM12); + + inV1 = *__SIMD32(pA)++; + sum = __SMLAD(inV1, inM11, sum); + + inV2 = *__SIMD32(pA)++; + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + int i, j; + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c new file mode 100644 index 0000000..b0c308b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_mat_q7_vec_q15_opt.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_mat_q7_vec_q15_opt.c + * Description: Mixed Q15-Q7 opt fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Mixed Q15-Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Q7_Q15 version of the fully connected layer + * + * Weights are in q7_t and Activations are in q15_t + * + * Limitation: x4 version requires weight reordering to work + * + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original q7_t matrix looks like this: + * + * | a11 | a12 | a13 | a14 | a15 | a16 | a17 | + * + * | a21 | a22 | a23 | a24 | a25 | a26 | a27 | + * + * | a31 | a32 | a33 | a34 | a35 | a36 | a37 | + * + * | a41 | a42 | a43 | a44 | a45 | a46 | a47 | + * + * | a51 | a52 | a53 | a54 | a55 | a56 | a57 | + * + * | a61 | a62 | a63 | a64 | a65 | a66 | a67 | + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a21 | a12 | a22 | a31 | a41 | a32 | a42 | + * + * | a13 | a23 | a14 | a24 | a33 | a43 | a34 | a44 | + * + * | a15 | a25 | a16 | a26 | a35 | a45 | a36 | a46 | + * + * The column left over will be in-order. + * which is: + * | a17 | a27 | a37 | a47 | + * + * For the left-over rows, we do 1x1 computation, so the data remains + * as its original order. + * + * So the stored weight matrix looks like this: + * + * | a11 | a21 | a12 | a22 | a31 | a41 | + * + * | a32 | a42 | a13 | a23 | a14 | a24 | + * + * | a33 | a43 | a34 | a44 | a15 | a25 | + * + * | a16 | a26 | a35 | a45 | a36 | a46 | + * + * | a17 | a27 | a37 | a47 | a51 | a52 | + * + * | a53 | a54 | a55 | a56 | a57 | a61 | + * + * | a62 | a63 | a64 | a65 | a66 | a67 | + * + */ + +arm_status +arm_fully_connected_mat_q7_vec_q15_opt(const q15_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, const q7_t * bias, q15_t * pOut, q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + q15_t *pO = pOut; + const q7_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 2; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + colCnt--; + } + +#else + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + colCnt--; + } + +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + +#ifndef ARM_MATH_BIG_ENDIAN + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r1, [%[pB]], #8\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#else + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r1, [%[pB]], #8\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB++; + q7_t inM3 = *pB++; + q7_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum3 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum4 >> out_shift), 16)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = (q7_t *) read_and_pad((void *)pB, &inM11, &inM12); + + inV1 = *__SIMD32(pA)++; + sum = __SMLAD(inV1, inM11, sum); + + inV2 = *__SIMD32(pA)++; + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + colCnt--; + } + + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c new file mode 100644 index 0000000..a4c6bba --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15.c @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q15.c + * Description: Q15 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + */ + +arm_status +arm_fully_connected_q15(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q15_t *pB = pM; + const q15_t *pB2 = pB + dim_vec; + q15_t *pO = pOut; + const q15_t *pA; + const q15_t *pBias = bias; + uint16_t rowCnt = num_of_rows >> 1; + + /* this loop loops over different output */ + while (rowCnt) { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV1, inM1, inM2; + inV1 = *__SIMD32(pA)++; + inM1 = *__SIMD32(pB)++; + sum = __SMLAD(inV1, inM1, sum); + inM2 = *__SIMD32(pB2)++; + sum2 = __SMLAD(inV1, inM2, sum2); + + inV1 = *__SIMD32(pA)++; + inM1 = *__SIMD32(pB)++; + sum = __SMLAD(inV1, inM1, sum); + inM2 = *__SIMD32(pB2)++; + sum2 = __SMLAD(inV1, inM2, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2>> out_shift), 16)); + + /* adjust the pointers and counters */ + pB = pB + dim_vec; + rowCnt --; + } + + rowCnt = num_of_rows & 0x1; + + while (rowCnt) { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) { + q31_t inV1, inM1; + inV1 = *__SIMD32(pA)++; + inM1 = *__SIMD32(pB)++; + sum = __SMLAD(inV1, inM1, sum); + + inV1 = *__SIMD32(pA)++; + inM1 = *__SIMD32(pB)++; + sum = __SMLAD(inV1, inM1, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while(colCnt) { + q15_t inV = *pA++; + q15_t inM = *pB++; + + sum += inV * inM; + + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt --; + } + +#else + int i, j; + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q15_t) __SSAT((ip_out >> out_shift), 16); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to application */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c new file mode 100644 index 0000000..8f3bbea --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q15_opt.c @@ -0,0 +1,332 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q15_opt.c + * Description: Q15 opt fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q15 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * + * @details + * + * Buffer size: + * + * vec_buffer size: 0 + * + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original matrix looks like this: + * + * | a11 | a12 | a13 | + * + * | a21 | a22 | a23 | + * + * | a31 | a32 | a33 | + * + * | a41 | a42 | a43 | + * + * | a51 | a52 | a53 | + * + * | a61 | a62 | a63 | + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a12 | a21 | a22 | a31 | a32 | a41 | a42 | + * + * | a13 | a23 | a33 | a43 | + * + * Remaining rows are kept the same original order. + * + * So the stored weight matrix looks like this: + * + * + * | a11 | a12 | a21 | a22 | a31 | a32 | a41 | a42 | + * + * | a13 | a23 | a33 | a43 | a51 | a52 | a53 | a61 | + * + * | a62 | a63 | + */ + +arm_status +arm_fully_connected_q15_opt(const q15_t * pV, + const q15_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q15_t * bias, + q15_t * pOut, + q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q15_t *pB = pM; + q15_t *pO = pOut; + const q15_t *pBias = bias; + const q15_t *pA = pV; + + uint16_t rowCnt = num_of_rows >> 2; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + +#ifdef USE_INTRINSIC + + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + sum = __SMLAD(inV, inM11, sum); + inM12 = *__SIMD32(pB)++; + sum2 = __SMLAD(inV, inM12, sum2); + inM13 = *__SIMD32(pB)++; + sum3 = __SMLAD(inV, inM13, sum3); + inM14 = *__SIMD32(pB)++; + sum4 = __SMLAD(inV, inM14, sum4); + colCnt--; + } + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #4\n" + "ldr.w r0, [%[pB]], #16\n" + "smlad %[sum], r4, r0, %[sum]\n" + "ldr.w r1, [%[pB] , #-12]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r2, [%[pB] , #-8]\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "ldr.w r3, [%[pB] , #-4]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x1; + while (colCnt) + { + + q15_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB++; + q15_t inM3 = *pB++; + q15_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum2 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum3 >> out_shift), 16)); + *pO++ = (q15_t) (__SSAT((sum4 >> out_shift), 16)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q31_t inV1, inV2, inM1, inM2; + + inM1 = *__SIMD32(pB)++; + inV1 = *__SIMD32(pA)++; + sum = __SMLAD(inV1, inM1, sum); + + inM2 = *__SIMD32(pB)++; + inV2 = *__SIMD32(pA)++; + sum = __SMLAD(inV2, inM2, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q15_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q15_t) (__SSAT((sum >> out_shift), 16)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q15_t *pB = pM; + const q15_t *pA; + q15_t *pO = pOut; + const q15_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 1; + + pA = pV; + while (colCnt) + { + q15_t inA1 = *pA++; + q15_t inA2 = *pA++; + + q15_t inB1 = *pB++; + q15_t inB2 = *pB++; + sum += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum2 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum3 += inA1 * inB1 + inA2 * inB2; + + inB1 = *pB++; + inB2 = *pB++; + sum4 += inA1 * inB1 + inA2 * inB2; + + colCnt--; + } + colCnt = dim_vec & 0x1; + while (colCnt) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + colCnt--; + } + *pO++ = (q15_t) __SSAT((sum >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum2 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum3 >> out_shift), 16); + *pO++ = (q15_t) __SSAT((sum4 >> out_shift), 16); + + rowCnt--; + } + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q15_t inA = *pA++; + q15_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q15_t) __SSAT((ip_out >> out_shift), 16); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c new file mode 100644 index 0000000..75e924f --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q7.c + * Description: Q7 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q7 basic fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: dim_vec + * + * This basic function is designed to work with regular weight + * matrix without interleaving. + * + */ + +arm_status +arm_fully_connected_q7(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, const q7_t * bias, q7_t * pOut, q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + const q7_t *pB2; + q7_t *pO = pOut; + const q7_t *pBias = bias; + q15_t *pA; + uint16_t rowCnt = num_of_rows >> 1; + + /* expand the vector into the buffer */ + arm_q7_to_q15_reordered_no_shift(pV, vec_buffer, dim_vec); + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + pB2 = pB + dim_vec; + + while (colCnt) + { + q31_t inV, inM11, inM12, inM21, inM22; + pB = (q7_t *) read_and_pad_reordered((void *)pB, &inM11, &inM12); + pB2 = (q7_t *) read_and_pad_reordered((void *)pB2, &inM21, &inM22); + + inV = *__SIMD32(pA)++; + + sum = __SMLAD(inV, inM11, sum); + sum2 = __SMLAD(inV, inM21, sum2); + + inV = *__SIMD32(pA)++; + + sum = __SMLAD(inV, inM12, sum); + sum2 = __SMLAD(inV, inM22, sum2); + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inV = *pA++; + q15_t inM = *pB++; + q15_t inM2 = *pB2++; + + sum += inV * inM; + sum2 += inV * inM2; + colCnt--; + } /* while over colCnt */ + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum2 >> out_shift), 8)); + + /* adjust the pointers and counters */ + pB += dim_vec; + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x1; + + while (rowCnt) + { + uint16_t colCnt = dim_vec >> 2; + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + pA = vec_buffer; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = (q7_t *) read_and_pad_reordered((void *)pB, &inM11, &inM12); + + inV1 = *__SIMD32(pA)++; + sum = __SMLAD(inV1, inM11, sum); + + inV2 = *__SIMD32(pA)++; + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inV = *pA++; + q15_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + + rowCnt--; + } + +#else + int i, j; + + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + for (i = 0; i < num_of_rows; i++) + { + int ip_out = ((q31_t)(bias[i]) << bias_shift) + NN_ROUND(out_shift); + for (j = 0; j < dim_vec; j++) + { + ip_out += pV[j] * pM[i * dim_vec + j]; + } + pOut[i] = (q7_t) __SSAT((ip_out >> out_shift), 8); + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c new file mode 100644 index 0000000..d197adc --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/FullyConnectedFunctions/arm_fully_connected_q7_opt.c @@ -0,0 +1,484 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_fully_connected_q7_opt.c + * Description: Q7 basic fully-connected layer function + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup FC + * @{ + */ + + /** + * @brief Q7 opt fully-connected layer function + * @param[in] pV pointer to input vector + * @param[in] pM pointer to matrix weights + * @param[in] dim_vec length of the vector + * @param[in] num_of_rows number of rows in weight matrix + * @param[in] bias_shift amount of left-shift for bias + * @param[in] out_shift amount of right-shift for output + * @param[in] bias pointer to bias + * @param[in,out] pOut pointer to output vector + * @param[in,out] vec_buffer pointer to buffer space for input + * @return The function returns ARM_MATH_SUCCESS + * + * @details + * + * Buffer size: + * + * vec_buffer size: dim_vec + * + * This opt function is designed to work with interleaved weight + * matrix. The vector input is assumed in q7_t format, we call + * arm_q7_to_q15_no_shift_shuffle function to expand into + * q15_t format with certain weight re-ordering, refer to the function + * comments for more details. + * Here we use only one pointer to read 4 rows in the weight + * matrix. So if the original q7_t matrix looks like this: + * + * | a11 | a12 | a13 | a14 | a15 | a16 | a17 | + * + * | a21 | a22 | a23 | a24 | a25 | a26 | a27 | + * + * | a31 | a32 | a33 | a34 | a35 | a36 | a37 | + * + * | a41 | a42 | a43 | a44 | a45 | a46 | a47 | + * + * | a51 | a52 | a53 | a54 | a55 | a56 | a57 | + * + * | a61 | a62 | a63 | a64 | a65 | a66 | a67 | + * + * + * We operates on multiple-of-4 rows, so the first four rows becomes + * + * | a11 | a21 | a13 | a23 | a31 | a41 | a33 | a43 | + * + * | a12 | a22 | a14 | a24 | a32 | a42 | a34 | a44 | + * + * | a15 | a25 | a35 | a45 | a16 | a26 | a36 | a46 | + * + * So within the kernel, we first read the re-ordered vector in as: + * + * | b1 | b3 | and | b2 | b4 | + * + * the four q31_t weights will look like + * + * | a11 | a13 |, | a21 | a23 |, | a31 | a33 |, | a41 | a43 | + * + * | a12 | a14 |, | a22 | a24 |, | a32 | a34 |, | a42 | a44 | + * + * The column left over will be in-order. + * which is: + * + * | a17 | a27 | a37 | a47 | + * + * For the left-over rows, we do 1x1 computation, so the data remains + * as its original order. + * + * So the stored weight matrix looks like this: + * + * | a11 | a21 | a13 | a23 | a31 | a41 | + * + * | a33 | a43 | a12 | a22 | a14 | a24 | + * + * | a32 | a42 | a34 | a44 | a15 | a25 | + * + * | a35 | a45 | a16 | a26 | a36 | a46 | + * + * | a17 | a27 | a37 | a47 | a51 | a52 | + * + * | a53 | a54 | a55 | a56 | a57 | a61 | + * + * | a62 | a63 | a64 | a65 | a66 | a67 | + * + * + */ + +arm_status +arm_fully_connected_q7_opt(const q7_t * pV, + const q7_t * pM, + const uint16_t dim_vec, + const uint16_t num_of_rows, + const uint16_t bias_shift, + const uint16_t out_shift, + const q7_t * bias, + q7_t * pOut, + q15_t * vec_buffer) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + const q7_t *pB = pM; + q7_t *pO = pOut; + const q7_t *pBias = bias; + q15_t *pA; + uint16_t rowCnt = num_of_rows >> 2; + + arm_q7_to_q15_reordered_no_shift(pV, vec_buffer, dim_vec); + + while (rowCnt) + { + + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + +#ifdef USE_INTRINSIC + +#ifndef ARM_MATH_BIG_ENDIAN + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM11, inV, sum); + sum2 = __SMLAD(inM12, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM13, inV, sum3); + sum4 = __SMLAD(inM14, inV, sum4); + colCnt--; + } +#else + while (colCnt) + { + q31_t inM11, inM12, inM13, inM14; + q31_t inV; + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + + inV = *__SIMD32(pA)++; + inM11 = *__SIMD32(pB)++; + inM12 = __SXTB16(__ROR(inM11, 8)); + inM11 = __SXTB16(inM11); + sum = __SMLAD(inM12, inV, sum); + sum2 = __SMLAD(inM11, inV, sum2); + inM13 = *__SIMD32(pB)++; + inM14 = __SXTB16(__ROR(inM13, 8)); + inM13 = __SXTB16(inM13); + sum3 = __SMLAD(inM14, inV, sum3); + sum4 = __SMLAD(inM13, inV, sum4); + colCnt--; + } +#endif /* ARM_MATH_BIG_ENDIAN */ + +#else + + /* + * register needed: + * loop counter: colCnt + * accumulators: sum, sum2, sum3, sum4 + * pointers: pB, pA + * weight data: inM11, inM12, inM13, inM14 + * activation data: inV + */ + +#ifndef ARM_MATH_BIG_ENDIAN + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #8\n" + "ldr.w r1, [%[pB]], #16\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-12]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "ldr.w r4, [%[pA], #-4]\n" + "ldr.w r1, [%[pB], #-8]\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r1, %[sum]\n" + "smlad %[sum2], r4, r0, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r3, %[sum3]\n" + "smlad %[sum4], r4, r2, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#else + asm volatile ("COL_LOOP_%=:\n" + "ldr.w r4, [%[pA]], #8\n" + "ldr.w r1, [%[pB]], #16\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-12]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "ldr.w r4, [%[pA], #-4]\n" + "ldr.w r1, [%[pB], #-8]\n" + "mov.w r0, r1, ror #8\n" + "sxtb16 r0, r0\n" + "sxtb16 r1, r1\n" + "smlad %[sum], r4, r0, %[sum]\n" + "smlad %[sum2], r4, r1, %[sum2]\n" + "ldr.w r3, [%[pB], #-4]\n" + "mov.w r2, r3, ror #8\n" + "sxtb16 r2, r2\n" + "sxtb16 r3, r3\n" + "smlad %[sum3], r4, r2, %[sum3]\n" + "smlad %[sum4], r4, r3, %[sum4]\n" + "subs %[colCnt], #1\n" + "bne COL_LOOP_%=\n":[sum] "+r"(sum), + [sum2] "+r"(sum2),[sum3] "+r"(sum3), + [sum4] "+r"(sum4),[pB] "+r"(pB),[pA] "+r"(pA):[colCnt] "r"(colCnt):"r0", "r1", "r2", "r3", "r4"); +#endif /* ARM_MATH_BIG_ENDIAN */ + +#endif /* USE_INTRINSIC */ + + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + q7_t inM2 = *pB++; + q7_t inM3 = *pB++; + q7_t inM4 = *pB++; + + sum += inV * inM; + sum2 += inV * inM2; + sum3 += inV * inM3; + sum4 += inV * inM4; + colCnt--; + } /* while over colCnt */ + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum2 >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum3 >> out_shift), 8)); + *pO++ = (q7_t) (__SSAT((sum4 >> out_shift), 8)); + + /* adjust the pointers and counters */ + rowCnt--; + } + + /* left-over part of the rows */ + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + uint16_t colCnt = dim_vec >> 2; + + pA = vec_buffer; + + while (colCnt) + { + q31_t inV1, inV2, inM11, inM12; + + pB = (q7_t *) read_and_pad_reordered((void *)pB, &inM11, &inM12); + + inV1 = *__SIMD32(pA)++; + sum = __SMLAD(inV1, inM11, sum); + + inV2 = *__SIMD32(pA)++; + sum = __SMLAD(inV2, inM12, sum); + + colCnt--; + } + + /* left-over of the vector */ + colCnt = dim_vec & 0x3; + while (colCnt) + { + q15_t inV = *pA++; + q7_t inM = *pB++; + sum += inV * inM; + colCnt--; + } + + *pO++ = (q7_t) (__SSAT((sum >> out_shift), 8)); + + rowCnt--; + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + uint16_t rowCnt = num_of_rows >> 2; + const q7_t *pB = pM; + const q7_t *pA; + q7_t *pO = pOut; + const q7_t *pBias = bias; + + while (rowCnt) + { + q31_t sum = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum2 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum3 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + q31_t sum4 = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + uint16_t colCnt = dim_vec >> 2; + + pA = pV; + + while (colCnt) + { + q7_t inA1 = *pA++; + q7_t inA3 = *pA++; + q7_t inA2 = *pA++; + q7_t inA4 = *pA++; + + q7_t inB1 = *pB++; + q7_t inB3 = *pB++; + q7_t inB2 = *pB++; + q7_t inB4 = *pB++; + + sum += inA1 * inB1 + inA2 * inB2; + sum2 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA1 * inB1 + inA2 * inB2; + sum4 += inA1 * inB3 + inA2 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum += inA3 * inB1 + inA4 * inB2; + sum2 += inA3 * inB3 + inA4 * inB4; + + inB1 = *pB++; + inB3 = *pB++; + inB2 = *pB++; + inB4 = *pB++; + + sum3 += inA3 * inB1 + inA4 * inB2; + sum4 += inA3 * inB3 + inA4 * inB4; + + colCnt--; + } + colCnt = dim_vec & 0x3; + while (colCnt) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + sum += inA * inB; + inB = *pB++; + sum2 += inA * inB; + inB = *pB++; + sum3 += inA * inB; + inB = *pB++; + sum4 += inA * inB; + + colCnt--; + } + *pO++ = (q7_t) __SSAT((sum >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum2 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum3 >> out_shift), 8); + *pO++ = (q7_t) __SSAT((sum4 >> out_shift), 8); + + rowCnt--; + } + + rowCnt = num_of_rows & 0x3; + + while (rowCnt) + { + int ip_out = ((q31_t)(*pBias++) << bias_shift) + NN_ROUND(out_shift); + + int j; + + pA = pV; + for (j = 0; j < dim_vec; j++) + { + q7_t inA = *pA++; + q7_t inB = *pB++; + ip_out += inA * inB; + } + *pO++ = (q7_t) __SSAT((ip_out >> out_shift), 8); + + rowCnt--; + } + +#endif /* ARM_MATH_DSP */ + + /* Return to ARM_MATH_SUCCESS */ + return (ARM_MATH_SUCCESS); + +} + +/** + * @} end of FC group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c new file mode 100644 index 0000000..de7668b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q15.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mult_q15.c + * Description: Q15 vector multiplication with variable output shifts + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q15 range [0x8000 0x7FFF] will be saturated. + */ + +void arm_nn_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) +{ + uint32_t blkCnt; /* loop counters */ + +#if defined (ARM_MATH_DSP) + +/* Run the below code for Cortex-M4 and Cortex-M3 */ + q31_t inA1, inA2, inB1, inB2; /* temporary input variables */ + q15_t out1, out2, out3, out4; /* temporary output variables */ + q31_t mul1, mul2, mul3, mul4; /* temporary variables */ + + /* loop Unrolling */ + blkCnt = blockSize >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0U) + { + /* read two samples at a time from sourceA */ + inA1 = *__SIMD32(pSrcA)++; + /* read two samples at a time from sourceB */ + inB1 = *__SIMD32(pSrcB)++; + /* read two samples at a time from sourceA */ + inA2 = *__SIMD32(pSrcA)++; + /* read two samples at a time from sourceB */ + inB2 = *__SIMD32(pSrcB)++; + + /* multiply mul = sourceA * sourceB */ + mul1 = (q31_t) ((q15_t) (inA1 >> 16) * (q15_t) (inB1 >> 16)); + mul2 = (q31_t) ((q15_t) inA1 * (q15_t) inB1); + mul3 = (q31_t) ((q15_t) (inA2 >> 16) * (q15_t) (inB2 >> 16)); + mul4 = (q31_t) ((q15_t) inA2 * (q15_t) inB2); + + /* saturate result to 16 bit */ + out1 = (q15_t) __SSAT((mul1 + NN_ROUND(out_shift)) >> out_shift, 16); + out2 = (q15_t) __SSAT((mul2 + NN_ROUND(out_shift)) >> out_shift, 16); + out3 = (q15_t) __SSAT((mul3 + NN_ROUND(out_shift)) >> out_shift, 16); + out4 = (q15_t) __SSAT((mul4 + NN_ROUND(out_shift)) >> out_shift, 16); + + /* store the result */ +#ifndef ARM_MATH_BIG_ENDIAN + + *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16); + *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16); + +#else + + *__SIMD32(pDst)++ = __PKHBT(out2, out1, 16); + *__SIMD32(pDst)++ = __PKHBT(out4, out3, 16); + +#endif /* #ifndef ARM_MATH_BIG_ENDIAN */ + + /* Decrement the blockSize loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4U; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_DSP) */ + + + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the result in the destination buffer */ + *pDst++ = (q15_t) __SSAT((((q31_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 16); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } +} + +/** + * @} end of NNBasicMath group + */ + diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c new file mode 100644 index 0000000..1b4e02c --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nn_mult_q7.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nn_mult_q7.c + * Description: Q7 vector multiplication with variable output shifts + * + * $Date: 13. July 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_nnfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup NNBasicMath + * @{ + */ + +/** + * @brief Q7 vector multiplication with variable output shifts + * @param[in] *pSrcA pointer to the first input vector + * @param[in] *pSrcB pointer to the second input vector + * @param[out] *pDst pointer to the output vector + * @param[in] out_shift amount of right-shift for output + * @param[in] blockSize number of samples in each vector + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function uses saturating arithmetic. + * Results outside of the allowable Q7 range [0x80 0x7F] will be saturated. + */ + +void arm_nn_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + const uint16_t out_shift, + uint32_t blockSize) +{ + uint32_t blkCnt; /* loop counters */ + +#if defined (ARM_MATH_DSP) + +/* Run the below code for Cortex-M4 and Cortex-M3 */ + q7_t out1, out2, out3, out4; /* Temporary variables to store the product */ + + /* loop Unrolling */ + blkCnt = blockSize >> 2U; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the results in temporary variables */ + out1 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out2 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out3 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + out4 = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + + /* Store the results of 4 inputs in the destination buffer in single cycle by packing */ + *__SIMD32(pDst)++ = __PACKq7(out1, out2, out3, out4); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4U; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Initialize blkCnt with number of samples */ + blkCnt = blockSize; + +#endif /* #if defined (ARM_MATH_DSP) */ + + + while (blkCnt > 0U) + { + /* C = A * B */ + /* Multiply the inputs and store the result in the destination buffer */ + *pDst++ = (q7_t) __SSAT((((q15_t) (*pSrcA++) * (*pSrcB++) + NN_ROUND(out_shift)) >> out_shift), 8); + + /* Decrement the blockSize loop counter */ + blkCnt--; + } +} + +/** + * @} end of NNBasicMath group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c new file mode 100644 index 0000000..cabd9b1 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_nntables.c @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_nntables.c + * Description: Converts the elements of the Q7 vector to Q15 vector without left-shift + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_nnsupportfunctions.h" + +/** + * @brief tables for various activation functions + * + * This file include the declaration of common tables. + * Most of them are used for activation functions + * + * Assumption: + * Unified table: input is 3.x format, i.e, range of [-8, 8) + * sigmoid(8) = 0.9996646498695336 + * tanh(8) = 0.9999997749296758 + * The accuracy here should be good enough + * + * 2-stage HL table: + * + * The entire input range is divided into two parts: + * + * Low range table: 0x000x xxxx or 0x111x xxxx + * table entry will be the binary number excluding the first + * two digits, i.e., 0x0x xxxx or 0x1x xxxx + * + * + * + * High range table 0x0010 0000 -- 0x0111 1111 + * 0x1000 0000 -- 0x1101 1111 + * + * For positive numbers, table entry will be + * 0x0010 0000 -- 0x0111 1111 minus 0x0010 0000 + * i.e., 0x0000 0000 - 0x0101 11111 + * + * same thing for the negative numbers, table entry will be + * 0x1000 0000 -- 0x1101 1111 minux 0x0010 0000 + * i.e., 0x0110 0000 - 0x1011 1111 + */ + +const q7_t sigmoidTable_q7[256] = { + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, + 0x50, 0x52, 0x53, 0x55, 0x57, 0x59, 0x5a, 0x5c, + 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x65, 0x66, 0x67, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x72, 0x73, 0x74, 0x74, 0x75, 0x76, + 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, + 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, + 0x7c, 0x7c, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7e, + 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x06, + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, + 0x0a, 0x0a, 0x0b, 0x0c, 0x0c, 0x0d, 0x0e, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x19, 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x21, + 0x22, 0x24, 0x26, 0x27, 0x29, 0x2b, 0x2d, 0x2e, + 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, +}; + +const q15_t sigmoidTable_q15[256] = { + 0x4000, 0x4200, 0x43ff, 0x45fc, 0x47f5, 0x49eb, 0x4bdc, 0x4dc8, + 0x4fad, 0x518a, 0x5360, 0x552c, 0x56ef, 0x58a8, 0x5a57, 0x5bfb, + 0x5d93, 0x5f20, 0x60a1, 0x6216, 0x637f, 0x64db, 0x662b, 0x676f, + 0x68a6, 0x69d2, 0x6af1, 0x6c05, 0x6d0d, 0x6e09, 0x6efb, 0x6fe2, + 0x70be, 0x7190, 0x7258, 0x7316, 0x73cc, 0x7478, 0x751b, 0x75b7, + 0x764a, 0x76d6, 0x775b, 0x77d8, 0x784f, 0x78c0, 0x792a, 0x798f, + 0x79ee, 0x7a48, 0x7a9d, 0x7aed, 0x7b39, 0x7b80, 0x7bc4, 0x7c03, + 0x7c3f, 0x7c78, 0x7cad, 0x7ce0, 0x7d0f, 0x7d3c, 0x7d66, 0x7d8d, + 0x7db3, 0x7dd6, 0x7df7, 0x7e16, 0x7e33, 0x7e4f, 0x7e69, 0x7e81, + 0x7e98, 0x7eae, 0x7ec2, 0x7ed5, 0x7ee7, 0x7ef8, 0x7f08, 0x7f17, + 0x7f25, 0x7f32, 0x7f3e, 0x7f4a, 0x7f55, 0x7f5f, 0x7f69, 0x7f72, + 0x7f7b, 0x7f83, 0x7f8a, 0x7f91, 0x7f98, 0x7f9e, 0x7fa4, 0x7faa, + 0x7faf, 0x7fb4, 0x7fb8, 0x7fbd, 0x7fc1, 0x7fc5, 0x7fc8, 0x7fcc, + 0x7fcf, 0x7fd2, 0x7fd5, 0x7fd7, 0x7fda, 0x7fdc, 0x7fde, 0x7fe0, + 0x7fe2, 0x7fe4, 0x7fe6, 0x7fe7, 0x7fe9, 0x7fea, 0x7feb, 0x7fed, + 0x7fee, 0x7fef, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff4, + 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0015, 0x0016, 0x0017, 0x0019, 0x001a, 0x001c, + 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002b, 0x002e, + 0x0031, 0x0034, 0x0038, 0x003b, 0x003f, 0x0043, 0x0048, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0068, 0x006f, 0x0076, 0x007d, + 0x0085, 0x008e, 0x0097, 0x00a1, 0x00ab, 0x00b6, 0x00c2, 0x00ce, + 0x00db, 0x00e9, 0x00f8, 0x0108, 0x0119, 0x012b, 0x013e, 0x0152, + 0x0168, 0x017f, 0x0197, 0x01b1, 0x01cd, 0x01ea, 0x0209, 0x022a, + 0x024d, 0x0273, 0x029a, 0x02c4, 0x02f1, 0x0320, 0x0353, 0x0388, + 0x03c1, 0x03fd, 0x043c, 0x0480, 0x04c7, 0x0513, 0x0563, 0x05b8, + 0x0612, 0x0671, 0x06d6, 0x0740, 0x07b1, 0x0828, 0x08a5, 0x092a, + 0x09b6, 0x0a49, 0x0ae5, 0x0b88, 0x0c34, 0x0cea, 0x0da8, 0x0e70, + 0x0f42, 0x101e, 0x1105, 0x11f7, 0x12f3, 0x13fb, 0x150f, 0x162e, + 0x175a, 0x1891, 0x19d5, 0x1b25, 0x1c81, 0x1dea, 0x1f5f, 0x20e0, + 0x226d, 0x2405, 0x25a9, 0x2758, 0x2911, 0x2ad4, 0x2ca0, 0x2e76, + 0x3053, 0x3238, 0x3424, 0x3615, 0x380b, 0x3a04, 0x3c01, 0x3e00, +}; + +const q15_t sigmoidLTable_q15[128] = { + 0x4000, 0x4100, 0x4200, 0x42ff, 0x43ff, 0x44fd, 0x45fc, 0x46f9, + 0x47f5, 0x48f1, 0x49eb, 0x4ae5, 0x4bdc, 0x4cd3, 0x4dc8, 0x4ebb, + 0x4fad, 0x509c, 0x518a, 0x5276, 0x5360, 0x5447, 0x552c, 0x560f, + 0x56ef, 0x57cd, 0x58a8, 0x5981, 0x5a57, 0x5b2a, 0x5bfb, 0x5cc9, + 0x5d93, 0x5e5b, 0x5f20, 0x5fe2, 0x60a1, 0x615d, 0x6216, 0x62cc, + 0x637f, 0x642e, 0x64db, 0x6584, 0x662b, 0x66ce, 0x676f, 0x680c, + 0x68a6, 0x693d, 0x69d2, 0x6a63, 0x6af1, 0x6b7c, 0x6c05, 0x6c8a, + 0x6d0d, 0x6d8d, 0x6e09, 0x6e84, 0x6efb, 0x6f70, 0x6fe2, 0x7051, + 0x0f42, 0x0faf, 0x101e, 0x1090, 0x1105, 0x117c, 0x11f7, 0x1273, + 0x12f3, 0x1376, 0x13fb, 0x1484, 0x150f, 0x159d, 0x162e, 0x16c3, + 0x175a, 0x17f4, 0x1891, 0x1932, 0x19d5, 0x1a7c, 0x1b25, 0x1bd2, + 0x1c81, 0x1d34, 0x1dea, 0x1ea3, 0x1f5f, 0x201e, 0x20e0, 0x21a5, + 0x226d, 0x2337, 0x2405, 0x24d6, 0x25a9, 0x267f, 0x2758, 0x2833, + 0x2911, 0x29f1, 0x2ad4, 0x2bb9, 0x2ca0, 0x2d8a, 0x2e76, 0x2f64, + 0x3053, 0x3145, 0x3238, 0x332d, 0x3424, 0x351b, 0x3615, 0x370f, + 0x380b, 0x3907, 0x3a04, 0x3b03, 0x3c01, 0x3d01, 0x3e00, 0x3f00, +}; + +const q15_t sigmoidHTable_q15[192] = { + 0x70be, 0x7190, 0x7258, 0x7316, 0x73cc, 0x7478, 0x751b, 0x75b7, + 0x764a, 0x76d6, 0x775b, 0x77d8, 0x784f, 0x78c0, 0x792a, 0x798f, + 0x79ee, 0x7a48, 0x7a9d, 0x7aed, 0x7b39, 0x7b80, 0x7bc4, 0x7c03, + 0x7c3f, 0x7c78, 0x7cad, 0x7ce0, 0x7d0f, 0x7d3c, 0x7d66, 0x7d8d, + 0x7db3, 0x7dd6, 0x7df7, 0x7e16, 0x7e33, 0x7e4f, 0x7e69, 0x7e81, + 0x7e98, 0x7eae, 0x7ec2, 0x7ed5, 0x7ee7, 0x7ef8, 0x7f08, 0x7f17, + 0x7f25, 0x7f32, 0x7f3e, 0x7f4a, 0x7f55, 0x7f5f, 0x7f69, 0x7f72, + 0x7f7b, 0x7f83, 0x7f8a, 0x7f91, 0x7f98, 0x7f9e, 0x7fa4, 0x7faa, + 0x7faf, 0x7fb4, 0x7fb8, 0x7fbd, 0x7fc1, 0x7fc5, 0x7fc8, 0x7fcc, + 0x7fcf, 0x7fd2, 0x7fd5, 0x7fd7, 0x7fda, 0x7fdc, 0x7fde, 0x7fe0, + 0x7fe2, 0x7fe4, 0x7fe6, 0x7fe7, 0x7fe9, 0x7fea, 0x7feb, 0x7fed, + 0x7fee, 0x7fef, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff4, + 0x000b, 0x000c, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, + 0x0012, 0x0013, 0x0015, 0x0016, 0x0017, 0x0019, 0x001a, 0x001c, + 0x001e, 0x0020, 0x0022, 0x0024, 0x0026, 0x0029, 0x002b, 0x002e, + 0x0031, 0x0034, 0x0038, 0x003b, 0x003f, 0x0043, 0x0048, 0x004c, + 0x0051, 0x0056, 0x005c, 0x0062, 0x0068, 0x006f, 0x0076, 0x007d, + 0x0085, 0x008e, 0x0097, 0x00a1, 0x00ab, 0x00b6, 0x00c2, 0x00ce, + 0x00db, 0x00e9, 0x00f8, 0x0108, 0x0119, 0x012b, 0x013e, 0x0152, + 0x0168, 0x017f, 0x0197, 0x01b1, 0x01cd, 0x01ea, 0x0209, 0x022a, + 0x024d, 0x0273, 0x029a, 0x02c4, 0x02f1, 0x0320, 0x0353, 0x0388, + 0x03c1, 0x03fd, 0x043c, 0x0480, 0x04c7, 0x0513, 0x0563, 0x05b8, + 0x0612, 0x0671, 0x06d6, 0x0740, 0x07b1, 0x0828, 0x08a5, 0x092a, + 0x09b6, 0x0a49, 0x0ae5, 0x0b88, 0x0c34, 0x0cea, 0x0da8, 0x0e70, +}; + +const q7_t tanhTable_q7[256] = { + 0x00, 0x08, 0x10, 0x18, 0x1f, 0x27, 0x2e, 0x35, + 0x3b, 0x41, 0x47, 0x4c, 0x51, 0x56, 0x5a, 0x5e, + 0x61, 0x65, 0x68, 0x6a, 0x6d, 0x6f, 0x71, 0x72, + 0x74, 0x75, 0x76, 0x78, 0x78, 0x79, 0x7a, 0x7b, + 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, + 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, + 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x82, + 0x82, 0x82, 0x82, 0x82, 0x83, 0x83, 0x84, 0x84, + 0x85, 0x85, 0x86, 0x87, 0x88, 0x88, 0x8a, 0x8b, + 0x8c, 0x8e, 0x8f, 0x91, 0x93, 0x96, 0x98, 0x9b, + 0x9f, 0xa2, 0xa6, 0xaa, 0xaf, 0xb4, 0xb9, 0xbf, + 0xc5, 0xcb, 0xd2, 0xd9, 0xe1, 0xe8, 0xf0, 0xf8, +}; + +const q15_t tanhTable_q15[256] = { + 0x0000, 0x07fd, 0x0feb, 0x17b9, 0x1f59, 0x26bf, 0x2ddf, 0x34ae, + 0x3b27, 0x4142, 0x46fd, 0x4c56, 0x514d, 0x55e2, 0x5a1a, 0x5df6, + 0x617c, 0x64b0, 0x6797, 0x6a37, 0x6c95, 0x6eb5, 0x709e, 0x7254, + 0x73dc, 0x753a, 0x7672, 0x7788, 0x787f, 0x795b, 0x7a1e, 0x7acb, + 0x7b65, 0x7bee, 0x7c66, 0x7cd1, 0x7d30, 0x7d84, 0x7dce, 0x7e0f, + 0x7e49, 0x7e7d, 0x7eaa, 0x7ed2, 0x7ef5, 0x7f14, 0x7f30, 0x7f48, + 0x7f5e, 0x7f71, 0x7f82, 0x7f91, 0x7f9e, 0x7fa9, 0x7fb3, 0x7fbc, + 0x7fc4, 0x7fcb, 0x7fd1, 0x7fd7, 0x7fdc, 0x7fe0, 0x7fe4, 0x7fe7, + 0x7fea, 0x7fed, 0x7fef, 0x7ff1, 0x7ff3, 0x7ff4, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffc, 0x7ffd, + 0x7ffd, 0x7ffd, 0x7ffe, 0x7ffe, 0x7ffe, 0x7ffe, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8002, 0x8002, 0x8002, 0x8002, 0x8003, + 0x8003, 0x8003, 0x8004, 0x8004, 0x8005, 0x8006, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800c, 0x800d, 0x800f, 0x8011, 0x8013, + 0x8016, 0x8019, 0x801c, 0x8020, 0x8024, 0x8029, 0x802f, 0x8035, + 0x803c, 0x8044, 0x804d, 0x8057, 0x8062, 0x806f, 0x807e, 0x808f, + 0x80a2, 0x80b8, 0x80d0, 0x80ec, 0x810b, 0x812e, 0x8156, 0x8183, + 0x81b7, 0x81f1, 0x8232, 0x827c, 0x82d0, 0x832f, 0x839a, 0x8412, + 0x849b, 0x8535, 0x85e2, 0x86a5, 0x8781, 0x8878, 0x898e, 0x8ac6, + 0x8c24, 0x8dac, 0x8f62, 0x914b, 0x936b, 0x95c9, 0x9869, 0x9b50, + 0x9e84, 0xa20a, 0xa5e6, 0xaa1e, 0xaeb3, 0xb3aa, 0xb903, 0xbebe, + 0xc4d9, 0xcb52, 0xd221, 0xd941, 0xe0a7, 0xe847, 0xf015, 0xf803, +}; + +const q15_t tanhLTable_q15[128] = { + 0x0000, 0x0400, 0x07fd, 0x0bf7, 0x0feb, 0x13d7, 0x17b9, 0x1b90, + 0x1f59, 0x2314, 0x26bf, 0x2a58, 0x2ddf, 0x3151, 0x34ae, 0x37f6, + 0x3b27, 0x3e40, 0x4142, 0x442c, 0x46fd, 0x49b6, 0x4c56, 0x4edd, + 0x514d, 0x53a3, 0x55e2, 0x580a, 0x5a1a, 0x5c13, 0x5df6, 0x5fc4, + 0x617c, 0x6320, 0x64b0, 0x662d, 0x6797, 0x68f0, 0x6a37, 0x6b6e, + 0x6c95, 0x6dac, 0x6eb5, 0x6fb0, 0x709e, 0x717f, 0x7254, 0x731e, + 0x73dc, 0x7490, 0x753a, 0x75da, 0x7672, 0x7701, 0x7788, 0x7807, + 0x787f, 0x78f0, 0x795b, 0x79bf, 0x7a1e, 0x7a77, 0x7acb, 0x7b1b, + 0x849b, 0x84e5, 0x8535, 0x8589, 0x85e2, 0x8641, 0x86a5, 0x8710, + 0x8781, 0x87f9, 0x8878, 0x88ff, 0x898e, 0x8a26, 0x8ac6, 0x8b70, + 0x8c24, 0x8ce2, 0x8dac, 0x8e81, 0x8f62, 0x9050, 0x914b, 0x9254, + 0x936b, 0x9492, 0x95c9, 0x9710, 0x9869, 0x99d3, 0x9b50, 0x9ce0, + 0x9e84, 0xa03c, 0xa20a, 0xa3ed, 0xa5e6, 0xa7f6, 0xaa1e, 0xac5d, + 0xaeb3, 0xb123, 0xb3aa, 0xb64a, 0xb903, 0xbbd4, 0xbebe, 0xc1c0, + 0xc4d9, 0xc80a, 0xcb52, 0xceaf, 0xd221, 0xd5a8, 0xd941, 0xdcec, + 0xe0a7, 0xe470, 0xe847, 0xec29, 0xf015, 0xf409, 0xf803, 0xfc00, +}; + +const q15_t tanhHTable_q15[192] = { + 0x7b65, 0x7bee, 0x7c66, 0x7cd1, 0x7d30, 0x7d84, 0x7dce, 0x7e0f, + 0x7e49, 0x7e7d, 0x7eaa, 0x7ed2, 0x7ef5, 0x7f14, 0x7f30, 0x7f48, + 0x7f5e, 0x7f71, 0x7f82, 0x7f91, 0x7f9e, 0x7fa9, 0x7fb3, 0x7fbc, + 0x7fc4, 0x7fcb, 0x7fd1, 0x7fd7, 0x7fdc, 0x7fe0, 0x7fe4, 0x7fe7, + 0x7fea, 0x7fed, 0x7fef, 0x7ff1, 0x7ff3, 0x7ff4, 0x7ff6, 0x7ff7, + 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffc, 0x7ffd, + 0x7ffd, 0x7ffd, 0x7ffe, 0x7ffe, 0x7ffe, 0x7ffe, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, 0x7fff, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, + 0x8000, 0x8000, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001, + 0x8001, 0x8001, 0x8001, 0x8002, 0x8002, 0x8002, 0x8002, 0x8003, + 0x8003, 0x8003, 0x8004, 0x8004, 0x8005, 0x8006, 0x8006, 0x8007, + 0x8008, 0x8009, 0x800a, 0x800c, 0x800d, 0x800f, 0x8011, 0x8013, + 0x8016, 0x8019, 0x801c, 0x8020, 0x8024, 0x8029, 0x802f, 0x8035, + 0x803c, 0x8044, 0x804d, 0x8057, 0x8062, 0x806f, 0x807e, 0x808f, + 0x80a2, 0x80b8, 0x80d0, 0x80ec, 0x810b, 0x812e, 0x8156, 0x8183, + 0x81b7, 0x81f1, 0x8232, 0x827c, 0x82d0, 0x832f, 0x839a, 0x8412, +}; diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c new file mode 100644 index 0000000..e043b38 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_no_shift.c @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_no_shift.c + * Description: Converts the elements of the Q7 vector to Q15 vector without left-shift + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +/** + * @brief Converts the elements of the Q7 vector to Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none. + * + * \par Description: + * + * The equation used for the conversion process is: + * + *
    
+ * 	pDst[n] = (q15_t) pSrc[n];   0 <= n < blockSize.    
+ * 
+ * + */ + +void arm_q7_to_q15_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize) +{ + const q7_t *pIn = pSrc; /* Src pointer */ + uint32_t blkCnt; /* loop counter */ + +#ifndef ARM_MATH_CM0_FAMILY + q31_t in; + q31_t in1, in2; + q31_t out1, out2; + + /* Run the below code for Cortex-M4 and Cortex-M3 */ + + /*loop Unrolling */ + blkCnt = blockSize >> 2u; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + in = *__SIMD32(pIn)++; + + /* rotatate in by 8 and extend two q7_t values to q15_t values */ + in1 = __SXTB16(__ROR(in, 8)); + + /* extend remainig two q7_t values to q15_t values */ + in2 = __SXTB16(in); + +#ifndef ARM_MATH_BIG_ENDIAN + + out2 = __PKHTB(in1, in2, 16); + out1 = __PKHBT(in2, in1, 16); + +#else + + out1 = __PKHTB(in1, in2, 16); + out2 = __PKHBT(in2, in1, 16); + +#endif + + *__SIMD32(pDst)++ = out1; + *__SIMD32(pDst)++ = out2; + + /* Decrement the loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4u; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Loop over blockSize number of values */ + blkCnt = blockSize; + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + *pDst++ = (q15_t) * pIn++; + + /* Decrement the loop counter */ + blkCnt--; + } + +} + +/** + * @} end of nndata_convert group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c new file mode 100644 index 0000000..52f5f8e --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/NNSupportFunctions/arm_q7_to_q15_reordered_no_shift.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_q7_to_q15_reordered_no_shift.c + * Description: Converts the elements of the Q7 vector to reordered Q15 vector without left-shift + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_nnsupportfunctions.h" + +/** + * @ingroup groupSupport + */ + +/** + * @addtogroup nndata_convert + * @{ + */ + +/** + * @brief Converts the elements of the Q7 vector to reordered Q15 vector without left-shift + * @param[in] *pSrc points to the Q7 input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none. + * + * @details + * + * This function does the q7 to q15 expansion with re-ordering + * + *
+ *                          |   A1   |   A2   |   A3   |   A4   |
+ *
+ *                           0      7 8     15 16    23 24    31
+ * 
+ * + * is converted into: + * + *
+ *  |       A1       |       A3       |   and  |       A2       |       A4       |
+ *
+ *   0             15 16            31          0             15 16            31
+ * 
+ * + * + * This looks strange but is natural considering how sign-extension is done at + * assembly level. + * + * The expansion of other other oprand will follow the same rule so that the end + * results are the same. + * + * The tail (i.e., last (N % 4) elements) will still be in original order. + * + */ + +void arm_q7_to_q15_reordered_no_shift(const q7_t * pSrc, q15_t * pDst, uint32_t blockSize) +{ + const q7_t *pIn = pSrc; /* Src pointer */ + uint32_t blkCnt; /* loop counter */ + +#ifndef ARM_MATH_CM0_FAMILY + q31_t in; + q31_t in1, in2; + + /* Run the below code for Cortex-M4 and Cortex-M3 */ + + /*loop Unrolling */ + blkCnt = blockSize >> 2u; + + /* First part of the processing with loop unrolling. Compute 4 outputs at a time. + ** a second loop below computes the remaining 1 to 3 samples. */ + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + in = *__SIMD32(pIn)++; + + /* rotatate in by 8 and extend two q7_t values to q15_t values */ + in1 = __SXTB16(__ROR(in, 8)); + + /* extend remainig two q7_t values to q15_t values */ + in2 = __SXTB16(in); + +#ifndef ARM_MATH_BIG_ENDIAN + *__SIMD32(pDst)++ = in2; + *__SIMD32(pDst)++ = in1; +#else + *__SIMD32(pDst)++ = in1; + *__SIMD32(pDst)++ = in2; +#endif + + /* Decrement the loop counter */ + blkCnt--; + } + + /* If the blockSize is not a multiple of 4, compute any remaining output samples here. + ** No loop unrolling is used. */ + blkCnt = blockSize % 0x4u; + +#else + + /* Run the below code for Cortex-M0 */ + + /* Loop over blockSize number of values */ + blkCnt = blockSize; + +#endif /* #ifndef ARM_MATH_CM0_FAMILY */ + + while (blkCnt > 0u) + { + /* C = (q15_t) A << 8 */ + /* convert from q7 to q15 and then store the results in the destination buffer */ + *pDst++ = (q15_t) * pIn++; + + /* Decrement the loop counter */ + blkCnt--; + } + +} + +/** + * @} end of q7_to_x group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c new file mode 100644 index 0000000..2759731 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/PoolingFunctions/arm_pool_q7_HWC.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_pool_q7_HWC.c + * Description: Pooling function implementations + * + * $Date: 17. January 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +#if defined (ARM_MATH_DSP) + +/** + * @brief A few utility functions used by pooling functions + * + * + */ + +static void buffer_scale_back_q15_to_q7(q15_t * buffer, q7_t * target, uint16_t length, uint16_t scale) +{ + int i; + + for (i = 0; i < length; i++) + { + target[i] = (q7_t) (buffer[i] / scale); + } +} + +static void compare_and_replace_if_larger_q7(q7_t * base, // base data + q7_t * target, // compare target + const uint16_t length // data length + ) +{ + q7_t *pIn = base; + q7_t *pCom = target; + union arm_nnword in; + union arm_nnword com; + uint16_t cnt = length >> 2; + + while (cnt > 0u) + { + in.word = *__SIMD32(pIn); + com.word = *__SIMD32(pCom)++; + + // if version + if (com.bytes[0] > in.bytes[0]) + in.bytes[0] = com.bytes[0]; + if (com.bytes[1] > in.bytes[1]) + in.bytes[1] = com.bytes[1]; + if (com.bytes[2] > in.bytes[2]) + in.bytes[2] = com.bytes[2]; + if (com.bytes[3] > in.bytes[3]) + in.bytes[3] = com.bytes[3]; + + *__SIMD32(pIn)++ = in.word; + + cnt--; + } +} + +static void accumulate_q7_to_q15(q15_t * base, q7_t * target, const uint16_t length) +{ + q15_t *pCnt = base; + q7_t *pV = target; + q31_t v1, v2, vo1, vo2; + uint16_t cnt = length >> 2; + q31_t in; + + while (cnt > 0u) + { + q31_t value = *__SIMD32(pV)++; + v1 = __SXTB16(__ROR(value, 8)); + v2 = __SXTB16(value); +#ifndef ARM_MATH_BIG_ENDIAN + + vo2 = __PKHTB(v1, v2, 16); + vo1 = __PKHBT(v2, v1, 16); + +#else + + vo1 = __PKHTB(v1, v2, 16); + vo2 = __PKHBT(v2, v1, 16); + +#endif + + in = *__SIMD32(pCnt); + *__SIMD32(pCnt)++ = __QADD16(vo1, in); + + in = *__SIMD32(pCnt); + *__SIMD32(pCnt)++ = __QADD16(vo2, in); + + cnt--; + } + cnt = length & 0x3; + while (cnt > 0u) + { + *pCnt++ += *pV++; + cnt--; + } +} + +#endif // ARM_MATH_DSP + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Pooling + * @{ + */ + + /** + * @brief Q7 max pooling function + * @param[in, out] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + * @details + * + * Buffer size: + * + * bufferA size: 0 + * + * The pooling function is implemented as split x-pooling then + * y-pooling. + * + * This pooling function is input-destructive. Input data is undefined + * after calling this function. + * + */ + +void +arm_maxpool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + int16_t i_x, i_y; + + /* first does the pooling along x axis */ + for (i_y = 0; i_y < dim_im_in; i_y++) + { + + for (i_x = 0; i_x < dim_im_out; i_x++) + { + /* for each output pixel */ + q7_t *target = Im_in + (i_y * dim_im_in + i_x) * ch_im_in; + q7_t *win_start; + q7_t *win_stop; + if (i_x * stride - padding < 0) + { + win_start = target; + } else + { + win_start = Im_in + (i_y * dim_im_in + i_x * stride - padding) * ch_im_in; + } + + if (i_x * stride - padding + dim_kernel >= dim_im_in) + { + win_stop = Im_in + (i_y * dim_im_in + dim_im_in) * ch_im_in; + } else + { + win_stop = Im_in + (i_y * dim_im_in + i_x * stride - padding + dim_kernel) * ch_im_in; + } + + /* first step is to copy over initial data */ + /* arm_copy_q7(win_start, target, ch_im_in); */ + memmove(target, win_start, ch_im_in); + + /* start the max operation from the second part */ + win_start += ch_im_in; + for (; win_start < win_stop; win_start += ch_im_in) + { + compare_and_replace_if_larger_q7(target, win_start, ch_im_in); + } + } + } + + /* then does the pooling along y axis */ + for (i_y = 0; i_y < dim_im_out; i_y++) + { + + /* for each output row */ + q7_t *target = Im_out + i_y * dim_im_out * ch_im_in; + q7_t *row_start; + q7_t *row_end; + /* setting the starting row */ + if (i_y * stride - padding < 0) + { + row_start = Im_in; + } else + { + row_start = Im_in + (i_y * stride - padding) * dim_im_in * ch_im_in; + } + /* setting the stopping row */ + if (i_y * stride - padding + dim_kernel >= dim_im_in) + { + row_end = Im_in + dim_im_in * dim_im_in * ch_im_in; + } else + { + row_end = Im_in + (i_y * stride - padding + dim_kernel) * dim_im_in * ch_im_in; + } + + /* copy over the first row */ + /* arm_copy_q7(row_start, target, dim_im_out * ch_im_in); */ + memmove(target, row_start, dim_im_out * ch_im_in); + + /* move over to next row */ + row_start += ch_im_in * dim_im_in; + + for (; row_start < row_end; row_start += dim_im_in * ch_im_in) + { + compare_and_replace_if_larger_q7(target, row_start, dim_im_out * ch_im_in); + } + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int max = -129; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + if (Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)] > max) + { + max = Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + } + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = max; + } + } + } + +#endif /* ARM_MATH_DSP */ + +} + + /** + * @brief Q7 average pooling function + * @param[in,out] Im_in pointer to input tensor + * @param[in] dim_im_in input tensor dimention + * @param[in] ch_im_in number of input tensor channels + * @param[in] dim_kernel filter kernel size + * @param[in] padding padding sizes + * @param[in] stride convolution stride + * @param[in] dim_im_out output tensor dimension + * @param[in,out] bufferA pointer to buffer space for input + * @param[in,out] Im_out pointer to output tensor + * @return none. + * + * @details + * + * Buffer size: + * + * bufferA size: 2*dim_im_out*ch_im_in + * + * The pooling function is implemented as split x-pooling then + * y-pooling. + * + * This pooling function is input-destructive. Input data is undefined + * after calling this function. + * + */ + +void +arm_avepool_q7_HWC(q7_t * Im_in, + const uint16_t dim_im_in, + const uint16_t ch_im_in, + const uint16_t dim_kernel, + const uint16_t padding, + const uint16_t stride, const uint16_t dim_im_out, q7_t * bufferA, q7_t * Im_out) +{ + +#if defined (ARM_MATH_DSP) + /* Run the following code for Cortex-M4 and Cortex-M7 */ + + q15_t *buffer = (q15_t *) bufferA; + int16_t i_x, i_y; + int16_t count = 0; + + /* first does the pooling along x axis */ + for (i_y = 0; i_y < dim_im_in; i_y++) + { + + for (i_x = 0; i_x < dim_im_out; i_x++) + { + /* for each output pixel */ + q7_t *target = Im_in + (i_y * dim_im_in + i_x) * ch_im_in; + q7_t *win_start; + q7_t *win_stop; + if (i_x * stride - padding < 0) + { + win_start = target; + } else + { + win_start = Im_in + (i_y * dim_im_in + i_x * stride - padding) * ch_im_in; + } + + if (i_x * stride - padding + dim_kernel >= dim_im_in) + { + win_stop = Im_in + (i_y * dim_im_in + dim_im_in) * ch_im_in; + } else + { + win_stop = Im_in + (i_y * dim_im_in + i_x * stride - padding + dim_kernel) * ch_im_in; + } + + /* first step is to copy over initial data */ + arm_q7_to_q15_no_shift(win_start, buffer, ch_im_in); + count = 1; + + /* start the max operation from the second part */ + win_start += ch_im_in; + for (; win_start < win_stop; win_start += ch_im_in) + { + accumulate_q7_to_q15(buffer, win_start, ch_im_in); + count++; + } + buffer_scale_back_q15_to_q7(buffer, target, ch_im_in, count); + } + } + + /* then does the pooling along y axis */ + for (i_y = 0; i_y < dim_im_out; i_y++) + { + /* for each output row */ + q7_t *target = Im_out + i_y * dim_im_out * ch_im_in; + q7_t *row_start; + q7_t *row_end; + /* setting the starting row */ + if (i_y * stride - padding < 0) + { + row_start = Im_in; + } else + { + row_start = Im_in + (i_y * stride - padding) * dim_im_in * ch_im_in; + } + /* setting the stopping row */ + if (i_y * stride - padding + dim_kernel >= dim_im_in) + { + row_end = Im_in + dim_im_in * dim_im_in * ch_im_in; + } else + { + row_end = Im_in + (i_y * stride - padding + dim_kernel) * dim_im_in * ch_im_in; + } + + /* copy over the first row */ + arm_q7_to_q15_no_shift(row_start, buffer, dim_im_out * ch_im_in); + count = 1; + + /* move over to next row */ + row_start += ch_im_in * dim_im_in; + + for (; row_start < row_end; row_start += dim_im_in * ch_im_in) + { + accumulate_q7_to_q15(buffer, row_start, dim_im_out * ch_im_in); + count++; + } + buffer_scale_back_q15_to_q7(buffer, target, dim_im_out * ch_im_in, count); + } + +#else + /* Run the following code as reference implementation for Cortex-M0 and Cortex-M3 */ + + int16_t i_ch_in, i_x, i_y; + int16_t k_x, k_y; + + for (i_ch_in = 0; i_ch_in < ch_im_in; i_ch_in++) + { + for (i_y = 0; i_y < dim_im_out; i_y++) + { + for (i_x = 0; i_x < dim_im_out; i_x++) + { + int sum = 0; + int count = 0; + for (k_y = i_y * stride - padding; k_y < i_y * stride - padding + dim_kernel; k_y++) + { + for (k_x = i_x * stride - padding; k_x < i_x * stride - padding + dim_kernel; k_x++) + { + if (k_y >= 0 && k_x >= 0 && k_y < dim_im_in && k_x < dim_im_in) + { + sum += Im_in[i_ch_in + ch_im_in * (k_x + k_y * dim_im_in)]; + count++; + } + } + } + Im_out[i_ch_in + ch_im_in * (i_x + i_y * dim_im_out)] = sum / count; + } + } + } + +#endif /* ARM_MATH_DSP */ + +} + +/** + * @} end of Pooling group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c new file mode 100644 index 0000000..22fa62b --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q15.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_q15.c + * Description: Q15 softmax function + * + * $Date: 20. February 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + + /** + * @brief Q15 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * @return none. + * + * @details + * + * Here, instead of typical e based softmax, we use + * 2-based softmax, i.e.,: + * + * y_i = 2^(x_i) / sum(2^x_j) + * + * The relative output will be different here. + * But mathematically, the gradient will be the same + * with a log(2) scaling factor. + * + */ + +void arm_softmax_q15(const q15_t * vec_in, const uint16_t dim_vec, q15_t * p_out) +{ + q31_t sum; + int16_t i; + uint8_t shift; + q31_t base; + base = -1 * 0x100000; + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + base = vec_in[i]; + } + } + + /* we ignore really small values + * anyway, they will be 0 after shrinking + * to q15_t + */ + base = base - 16; + + sum = 0; + + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + shift = (uint8_t)__USAT(vec_in[i] - base, 5); + sum += 0x1 << shift; + } + } + + /* This is effectively (0x1 << 32) / sum */ + int64_t div_base = 0x100000000LL; + int output_base = (int32_t)(div_base / sum); + + /* Final confidence will be output_base >> ( 17 - (vec_in[i] - base) ) + * so 32768 (0x1<<15) -> 100% confidence when sum = 0x1 << 16, output_base = 0x1 << 16 + * and vec_in[i]-base = 16 + */ + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + /* Here minimum value of 17+base-vec[i] will be 1 */ + shift = (uint8_t)__USAT(17+base-vec_in[i], 5); + p_out[i] = (q15_t) __SSAT((output_base >> shift), 16); + } else + { + p_out[i] = 0; + } + } + +} + +/** + * @} end of Softmax group + */ diff --git a/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c b/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c new file mode 100644 index 0000000..06a69e1 --- /dev/null +++ b/fw/hid-dials/Drivers/CMSIS/NN/Source/SoftmaxFunctions/arm_softmax_q7.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010-2018 Arm Limited or its affiliates. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* ---------------------------------------------------------------------- + * Project: CMSIS NN Library + * Title: arm_softmax_q7.c + * Description: Q7 softmax function + * + * $Date: 20. February 2018 + * $Revision: V.1.0.0 + * + * Target Processor: Cortex-M cores + * + * -------------------------------------------------------------------- */ + +#include "arm_math.h" +#include "arm_nnfunctions.h" + +/** + * @ingroup groupNN + */ + +/** + * @addtogroup Softmax + * @{ + */ + + /** + * @brief Q7 softmax function + * @param[in] vec_in pointer to input vector + * @param[in] dim_vec input vector dimention + * @param[out] p_out pointer to output vector + * @return none. + * + * @details + * + * Here, instead of typical natural logarithm e based softmax, we use + * 2-based softmax here, i.e.,: + * + * y_i = 2^(x_i) / sum(2^x_j) + * + * The relative output will be different here. + * But mathematically, the gradient will be the same + * with a log(2) scaling factor. + * + */ + +void arm_softmax_q7(const q7_t * vec_in, const uint16_t dim_vec, q7_t * p_out) +{ + q31_t sum; + int16_t i; + uint8_t shift; + q15_t base; + base = -257; + + /* We first search for the maximum */ + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + base = vec_in[i]; + } + } + + /* + * So the base is set to max-8, meaning + * that we ignore really small values. + * anyway, they will be 0 after shrinking to q7_t. + */ + base = base - 8; + + sum = 0; + + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + shift = (uint8_t)__USAT(vec_in[i] - base, 5); + sum += 0x1 << shift; + } + } + + /* This is effectively (0x1 << 20) / sum */ + int output_base = 0x100000 / sum; + + /* + * Final confidence will be output_base >> ( 13 - (vec_in[i] - base) ) + * so 128 (0x1<<7) -> 100% confidence when sum = 0x1 << 8, output_base = 0x1 << 12 + * and vec_in[i]-base = 8 + */ + for (i = 0; i < dim_vec; i++) + { + if (vec_in[i] > base) + { + /* Here minimum value of 13+base-vec_in[i] will be 5 */ + shift = (uint8_t)__USAT(13+base-vec_in[i], 5); + p_out[i] = (q7_t) __SSAT((output_base >> shift), 8); + } else { + p_out[i] = 0; + } + } +} + +/** + * @} end of Softmax group + */ -- cgit