diff --git a/Makefile b/Makefile index eea5e2513a58da05708cb1dd96667da16b2f6658..d73e3a4eeae6873a2632eb2e2af59fdfe57ae525 100644 --- a/Makefile +++ b/Makefile @@ -121,15 +121,16 @@ LDSCRIPT= $(STARTUPLD)/STM32F411xE.ld # C sources that can be compiled in ARM or THUMB mode depending on the global # setting. -CSRC = $(ALLCSRC) \ - $(SRCDIR)/crc32.c \ - $(SRCDIR)/benchmarks.c \ - $(SRCDIR)/benchmarks/memory.c \ - $(SRCDIR)/benchmarks/blind_abstraction.c \ - $(SRCDIR)/main.c \ - $(SRCDIR)/random.c \ - $(SRCDIR)/serial.c \ - $(SRCDIR)/tests.c \ +CSRC = $(ALLCSRC) \ + $(SRCDIR)/crc32.c \ + $(SRCDIR)/benchmarks.c \ + $(SRCDIR)/benchmarks/memory.c \ + $(SRCDIR)/benchmarks/blind_abstraction.c \ + $(SRCDIR)/benchmarks/observer_abstraction.c \ + $(SRCDIR)/main.c \ + $(SRCDIR)/random.c \ + $(SRCDIR)/serial.c \ + $(SRCDIR)/tests.c \ $(SRCDIR)/usb.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global diff --git a/scripts/benchmarks/observer_abstraction.py b/scripts/benchmarks/observer_abstraction.py new file mode 100644 index 0000000000000000000000000000000000000000..e0780fbaaea88a5168bc61cf152d39ae9c4be397 --- /dev/null +++ b/scripts/benchmarks/observer_abstraction.py @@ -0,0 +1,82 @@ +## This file is part of the execution-time evaluation for the qronos observer abstractions. +## Copyright (C) 2022-2023 Tim Rheinfels <tim.rheinfels@fau.de> +## See https://gitlab.cs.fau.de/qronos-state-abstractions/execution-time +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see <https://www.gnu.org/licenses/>. + +### +### @file benchmarks/observer_abstraction.py +### +### @brief Provides @p observer_abstraction.ObserverAbstraction, the @p benchmark.Benchmark +### subclass for the observer abstraction benchmark +### +### @author Tim Rheinfels <tim.rheinfels@fau.de> +### + +import numpy as np +import json + +from benchmark import Benchmark +from data import decode + +### +### @brief Encapsulates the observer abstraction execution time benchmark +### +class ObserverAbstraction(Benchmark): + + ### + ### @brief Validates the computations performed on the STM32 by running them + ### again in numpy and comparing the results. + ### + ### @see benchmark.Benchmark._validate for parameters + ### + def _validate(self, benchmark, key): + n_y = int(key) + + for run in benchmark['tests']: + v = decode(run['setup']['v']) + rho = decode(run['setup']['rho']) + beta = decode(run['setup']['beta']) + + assert(isinstance(v, float)) + assert(isinstance(rho, float)) + assert(isinstance(beta, float)) + + M_sqrt_T = decode(run['setup']['M_sqrt_T']) + y = decode(run['setup']['y']) + + if n_y > 0: + assert(M_sqrt_T.shape == (n_y, n_y)) + for i in range(n_y): + for j in range(i): + assert(np.isclose(M_sqrt_T[i, j], 0.0)) + assert(np.all(np.linalg.eigvalsh(M_sqrt_T.T @ M_sqrt_T) > 0.0)) + else: + assert(M_sqrt_T.size == 0) + + assert(y.shape == (n_y,)) + + for i in range(benchmark['repetition_count']): + v = rho * v + beta + np.linalg.norm(M_sqrt_T @ y) + + v_p = decode(run['teardown']['v_p']) + assert(np.isclose(v, v_p)) + + ### + ### @brief Constructor + ### + ### @see benchmark.Benchmark.__init__ for parameters + ### + def __init__(self, data): + Benchmark.__init__(self, data, 'Observer Abstraction', r'observer_abstraction_([0-9]+)', lambda m: m.group(1)) diff --git a/src/benchmarks.c b/src/benchmarks.c index b9447988d7864c972dc411096edd2335a1632102..9fa7d76dfcbd616ac08964408977fac0b90181cc 100644 --- a/src/benchmarks.c +++ b/src/benchmarks.c @@ -28,6 +28,7 @@ #include <benchmarks/campaign.h> #include <benchmarks/blind_abstraction.h> +#include <benchmarks/observer_abstraction.h> void benchmarks_run(void) { @@ -41,5 +42,6 @@ void benchmarks_run(void) // Comparative execution time benchmarks benchmarks_run_blind_abstraction(); + benchmarks_run_observer_abstraction(); } diff --git a/src/benchmarks/memory.c b/src/benchmarks/memory.c index c8d2ef42a601d77de858e1cd74b2ee2fae60813f..84a95f59df5d4f06436cb1fb0df4acbed88c702b 100644 --- a/src/benchmarks/memory.c +++ b/src/benchmarks/memory.c @@ -29,6 +29,7 @@ #include <string.h> #include <benchmarks/blind_abstraction.h> +#include <benchmarks/observer_abstraction.h> /// /// @brief Size of the padding in bytes used for checking memory violations @@ -49,7 +50,8 @@ /// @brief Actual benchmark memory /// static float work[2u * PADDING - + BENCHMARKS_BLIND_ABSTRACTION_WORK_SIZE + + MAX(BENCHMARKS_BLIND_ABSTRACTION_WORK_SIZE, + BENCHMARKS_OBSERVER_ABSTRACTION_WORK_SIZE) ]; float * const benchmarks_memory = work + PADDING; diff --git a/src/benchmarks/observer_abstraction.c b/src/benchmarks/observer_abstraction.c new file mode 100644 index 0000000000000000000000000000000000000000..c04ecc0b5e982ce036699a9c2ce9979aa468006c --- /dev/null +++ b/src/benchmarks/observer_abstraction.c @@ -0,0 +1,153 @@ +// This file is part of the execution-time evaluation for the qronos observer abstractions. +// Copyright (C) 2022-2023 Tim Rheinfels <tim.rheinfels@fau.de> +// See https://gitlab.cs.fau.de/qronos-state-abstractions/execution-time +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +/// +/// @file benchmarks/observer_abstraction.c +/// +/// @brief Provides the implementation of the observer abstraction execution time benchmark +/// +/// @author Tim Rheinfels <tim.rheinfels@fau.de> +/// + +#include "observer_abstraction.h" + +#include <stdlib.h> +#include <string.h> + +#include <linalg.h> +#include <random.h> +#include <serial.h> +#include <benchmarks/campaign.h> + +static float *M_sqrt_T = NULL; ///< Triangular matrix chol(LtPL) for the measurement vector's norm +static float *y = NULL; ///< Measurement vector + +/// +/// @brief Configures the memory layout and randomly initializes the data +/// +static void setup_matrices(size_t n_y) +{ + M_sqrt_T = benchmarks_memory; + y = M_sqrt_T + n_y*n_y; + + random_matrix_cholesky(M_sqrt_T, n_y); + random_matrix(y, n_y, 1u); + + serial_print_matrix("M_sqrt_T", M_sqrt_T, n_y, n_y); + serial_print_vector("y", y, n_y); +} + +void benchmarks_run_observer_abstraction(void) +{ + volatile float v; + float rho; + float beta; + + #define SETUP(N_Y) { \ + v = random_float(); \ + rho = random_float(); \ + beta = random_float(); \ + serial_printf("\"v\": %u, \"rho\": %u, \"beta\": %u,\n", serial_encode(v), serial_encode(rho), serial_encode(beta)); \ + setup_matrices(N_Y); \ + } + + #define TEARDOWN { \ + serial_printf("\"v_p\": %u,\n", serial_encode(v)); \ + } + + #define CAMPAIGN(N_Y) { \ + BENCHMARKS_CAMPAIGN("observer_abstraction_" #N_Y, \ + { \ + float accu = 0.0f; \ + for(size_t i = 0u; i < N_Y; ++i) { \ + float accu_row = 0.0f; \ + for(size_t j = i; j < N_Y; ++j) { \ + accu_row += M_sqrt_T[(i*N_Y)+j] * y[j]; \ + } \ + accu += accu_row * accu_row; \ + } \ + v = rho*v + beta + sqrtf(accu); \ + }, \ + SETUP(N_Y), \ + TEARDOWN, \ + 10u, \ + 10u \ + ) \ + } + + CAMPAIGN(1); + CAMPAIGN(2); + CAMPAIGN(3); + CAMPAIGN(4); + CAMPAIGN(5); + CAMPAIGN(6); + CAMPAIGN(7); + CAMPAIGN(8); + CAMPAIGN(9); + CAMPAIGN(10); + CAMPAIGN(11); + CAMPAIGN(12); + CAMPAIGN(13); + CAMPAIGN(14); + CAMPAIGN(15); + CAMPAIGN(16); + CAMPAIGN(17); + CAMPAIGN(18); + CAMPAIGN(19); + CAMPAIGN(20); + CAMPAIGN(21); + CAMPAIGN(22); + CAMPAIGN(23); + CAMPAIGN(24); + CAMPAIGN(25); + CAMPAIGN(26); + CAMPAIGN(27); + CAMPAIGN(28); + CAMPAIGN(29); + CAMPAIGN(30); + CAMPAIGN(31); + CAMPAIGN(32); + CAMPAIGN(33); + CAMPAIGN(34); + CAMPAIGN(35); + CAMPAIGN(36); + CAMPAIGN(37); + CAMPAIGN(38); + CAMPAIGN(39); + CAMPAIGN(40); + CAMPAIGN(41); + CAMPAIGN(42); + CAMPAIGN(43); + CAMPAIGN(44); + CAMPAIGN(45); + CAMPAIGN(46); + CAMPAIGN(47); + CAMPAIGN(48); + CAMPAIGN(49); + CAMPAIGN(50); + CAMPAIGN(51); + CAMPAIGN(52); + CAMPAIGN(53); + CAMPAIGN(54); + CAMPAIGN(55); + CAMPAIGN(56); + CAMPAIGN(57); + CAMPAIGN(58); + CAMPAIGN(59); + CAMPAIGN(60); + +} diff --git a/src/benchmarks/observer_abstraction.h b/src/benchmarks/observer_abstraction.h new file mode 100644 index 0000000000000000000000000000000000000000..1a38d7687459f03b21af0b2b2c375d67b6f887c7 --- /dev/null +++ b/src/benchmarks/observer_abstraction.h @@ -0,0 +1,44 @@ +// This file is part of the execution-time evaluation for the qronos observer abstractions. +// Copyright (C) 2022-2023 Tim Rheinfels <tim.rheinfels@fau.de> +// See https://gitlab.cs.fau.de/qronos-state-abstractions/execution-time +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +/// +/// @file benchmarks/observer_abstraction.h +/// +/// @brief Provides the interface for the observer abstraction execution time benchmark +/// +/// @author Tim Rheinfels <tim.rheinfels@fau.de> +/// + +#ifndef BENCHMARKS_OBSERVERABSTRACTION_H +#define BENCHMARKS_OBSERVERABSTRACTION_H + +#include <benchmarks/memory.h> + +/// +/// @brief Memory required for running the observer abstraction execution time benchmark +/// +#define BENCHMARKS_OBSERVER_ABSTRACTION_WORK_SIZE (N_Y_MAX * N_Y_MAX + N_Y_MAX) + +/// +/// @brief Runs the observer abstraction execution time benchmark +/// +/// This function measures the execution time needed in order to update the +/// blind abstraction proposed in @cite ECRTS23-Rheinfels by equation (8a). +/// +void benchmarks_run_observer_abstraction(void); + +#endif // BENCHMARKS_OBSERVERABSTRACTION_H