From dc18ceaa54957d5ac05292b363a5ac6fe479f409 Mon Sep 17 00:00:00 2001 From: Mikael Olsson Date: Fri, 16 Feb 2024 11:04:46 +0100 Subject: Add NPU device type to capabilities In preparation to support the Linux kernel driver directly managing the NPU without a subsystem. A NPU device type has been added to the capabilities to be able to specify what kind of NPU is used. Change-Id: I45345b7d75d234f821d70b858453d3af2a99194e Signed-off-by: Mikael Olsson --- driver_library/include/ethosu.hpp | 27 +++++++++++++++++++--- .../python/src/ethosu_driver/swig/driver.i | 16 +++++++++++-- driver_library/python/test/test_capabilities.py | 12 ++++++---- driver_library/src/ethosu.cpp | 18 +++++++++++++-- kernel/include/uapi/ethosu.h | 15 ++++++++++++ kernel/rpmsg/ethosu_rpmsg_capabilities.c | 1 + tests/run_inference_test.cpp | 3 ++- utils/inference_runner/inference_runner.cpp | 3 ++- 8 files changed, 81 insertions(+), 14 deletions(-) diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp index 27f6828..d0e391c 100644 --- a/driver_library/include/ethosu.hpp +++ b/driver_library/include/ethosu.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2020-2024 Arm Limited and/or its affiliates * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -106,18 +106,39 @@ public: * Hardware Configuration * @macsPerClockCycle: MACs per clock cycle * @cmdStreamVersion: NPU command stream version + * @type: NPU device type * @customDma: Custom DMA enabled */ struct HardwareConfiguration { public: - HardwareConfiguration(uint32_t _macsPerClockCycle = 0, uint32_t _cmdStreamVersion = 0, bool _customDma = false) : - macsPerClockCycle(_macsPerClockCycle), cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) {} + HardwareConfiguration(uint32_t _macsPerClockCycle = 0, + uint32_t _cmdStreamVersion = 0, + uint32_t _type = static_cast(DeviceType::UNKNOWN), + bool _customDma = false) : + macsPerClockCycle(_macsPerClockCycle), + cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) { + + if (_type > static_cast(DeviceType::DIRECT)) { + throw EthosU::Exception(std::string("Invalid device type: ").append(std::to_string(_type)).c_str()); + } + + type = static_cast(_type); + } + + enum class DeviceType { + UNKNOWN = 0, + SUBSYSTEM, + DIRECT, + }; uint32_t macsPerClockCycle; uint32_t cmdStreamVersion; + DeviceType type; bool customDma; }; +std::ostream &operator<<(std::ostream &out, const HardwareConfiguration::DeviceType &deviceType); + /** * Device capabilities * @hwId: Hardware diff --git a/driver_library/python/src/ethosu_driver/swig/driver.i b/driver_library/python/src/ethosu_driver/swig/driver.i index a8db7c1..721e4d0 100644 --- a/driver_library/python/src/ethosu_driver/swig/driver.i +++ b/driver_library/python/src/ethosu_driver/swig/driver.i @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: Copyright 2020, 2022-2023 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: Copyright 2020, 2022-2024 Arm Limited and/or its affiliates // SPDX-License-Identifier: Apache-2.0 // %module driver @@ -117,10 +117,21 @@ version. This also specifies is custom DMA is enabled or not. %nodefaultctor HardwareConfiguration; class HardwareConfiguration { public: - HardwareConfiguration(uint32_t macs = 0, uint32_t cmdStreamVersion = 0, bool customDma = false); + HardwareConfiguration(uint32_t macs = 0, uint32_t cmdStreamVersion = 0, uint32_t type = static_cast(DeviceType::UNKNOWN), bool customDma = false); + + %feature("docstring", + " + DeviceType enumeration + ") DeviceType; + enum class DeviceType { + UNKNOWN = 0, + SUBSYSTEM, + DIRECT, + }; uint32_t macsPerClockCycle; uint32_t cmdStreamVersion; + DeviceType type; bool customDma; }; @@ -129,6 +140,7 @@ class HardwareConfiguration { std::ostringstream out; out << "{macsPerClockCycle=" << $self->macsPerClockCycle << ", cmdStreamVersion=" << $self->cmdStreamVersion << + ", type=" << $self->type << ", customDma=" << ($self->customDma? "True": "False") << "}"; return out.str(); } diff --git a/driver_library/python/test/test_capabilities.py b/driver_library/python/test/test_capabilities.py index ffb201c..7af1f0e 100644 --- a/driver_library/python/test/test_capabilities.py +++ b/driver_library/python/test/test_capabilities.py @@ -1,5 +1,5 @@ # -# SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates +# SPDX-FileCopyrightText: Copyright 2021-2022, 2024 Arm Limited and/or its affiliates # SPDX-License-Identifier: Apache-2.0 # from ethosu_driver._generated.driver import SemanticVersion @@ -37,13 +37,14 @@ def test_hardware_id(): def test_hw_configuration(): - hw_cfg = HardwareConfiguration(128, 1, True) + hw_cfg = HardwareConfiguration(128, 1, HardwareConfiguration.DeviceType_SUBSYSTEM, True) assert 1 == hw_cfg.cmdStreamVersion assert 128 == hw_cfg.macsPerClockCycle assert hw_cfg.customDma + assert HardwareConfiguration.DeviceType_SUBSYSTEM == hw_cfg.type - assert "{macsPerClockCycle=128, cmdStreamVersion=1, customDma=True}" == hw_cfg.__str__() + assert "{macsPerClockCycle=128, cmdStreamVersion=1, type=subsystem, customDma=True}" == hw_cfg.__str__() def test_capabilities(): @@ -51,7 +52,7 @@ def test_capabilities(): product = SemanticVersion(400, 500, 600) architecture = SemanticVersion(700, 800, 900) hw_id = HardwareId(1, version, product, architecture) - hw_cfg = HardwareConfiguration(256, 1000, False) + hw_cfg = HardwareConfiguration(256, 1000, HardwareConfiguration.DeviceType_SUBSYSTEM, False) driver_v = SemanticVersion(10, 20, 30) cap = Capabilities(hw_id, hw_cfg, driver_v) @@ -64,10 +65,11 @@ def test_capabilities(): assert 1000 == cap.hwCfg.cmdStreamVersion assert 256 == cap.hwCfg.macsPerClockCycle + assert HardwareConfiguration.DeviceType_SUBSYSTEM == cap.hwCfg.type assert not cap.hwCfg.customDma assert '{hwId={versionStatus=1, version={ major=100, minor=200, patch=300 }, ' \ 'product={ major=400, minor=500, patch=600 }, ' \ 'architecture={ major=700, minor=800, patch=900 }}, ' \ - 'hwCfg={macsPerClockCycle=256, cmdStreamVersion=1000, customDma=False}, ' \ + 'hwCfg={macsPerClockCycle=256, cmdStreamVersion=1000, type=subsystem, customDma=False}, ' \ 'driver={ major=10, minor=20, patch=30 }}' == cap.__str__() diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp index a4feef1..0166f0a 100644 --- a/driver_library/src/ethosu.cpp +++ b/driver_library/src/ethosu.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2020-2024 Arm Limited and/or its affiliates * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -269,11 +269,25 @@ Capabilities Device::capabilities() const { SemanticVersion(uapi.hw_id.version_major, uapi.hw_id.version_minor), SemanticVersion(uapi.hw_id.product_major), SemanticVersion(uapi.hw_id.arch_major_rev, uapi.hw_id.arch_minor_rev, uapi.hw_id.arch_patch_rev)), - HardwareConfiguration(uapi.hw_cfg.macs_per_cc, uapi.hw_cfg.cmd_stream_version, bool(uapi.hw_cfg.custom_dma)), + HardwareConfiguration( + uapi.hw_cfg.macs_per_cc, uapi.hw_cfg.cmd_stream_version, uapi.hw_cfg.type, bool(uapi.hw_cfg.custom_dma)), SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev)); return capabilities; } +ostream &operator<<(ostream &out, const HardwareConfiguration::DeviceType &deviceType) { + switch (deviceType) { + case HardwareConfiguration::DeviceType::UNKNOWN: + return out << "unknown"; + case HardwareConfiguration::DeviceType::SUBSYSTEM: + return out << "subsystem"; + case HardwareConfiguration::DeviceType::DIRECT: + return out << "direct"; + default: + throw Exception(string("Invalid device type: ").append(to_string(static_cast(deviceType))).c_str()); + } +} + /**************************************************************************** * Buffer ****************************************************************************/ diff --git a/kernel/include/uapi/ethosu.h b/kernel/include/uapi/ethosu.h index 58b9c34..699ef7e 100644 --- a/kernel/include/uapi/ethosu.h +++ b/kernel/include/uapi/ethosu.h @@ -193,16 +193,31 @@ struct ethosu_uapi_device_hw_id { __u32 arch_major_rev; }; +/** + * enum ethosu_dev_type - NPU device type + * @ETHOSU_DEV_UNKNOWN: Unknown NPU device type + * @ETHOSU_DEV_SUBSYSTEM: NPU managed by a subsystem communicated with via a + * mailbox + * @ETHOSU_DEV_DIRECT: NPU directly managed by the kernel driver + */ +enum ethosu_dev_type { + ETHOSU_DEV_UNKNOWN = 0, + ETHOSU_DEV_SUBSYSTEM, + ETHOSU_DEV_DIRECT, +}; + /** * struct ethosu_uapi_device_hw_cfg - Device hardware configuration * @macs_per_cc: MACs per clock cycle * @cmd_stream_version: NPU command stream version * @custom_dma: Custom DMA enabled + * @type: NPU device type */ struct ethosu_uapi_device_hw_cfg { __u32 macs_per_cc; __u32 cmd_stream_version; __u32 custom_dma; + __u32 type; }; /** diff --git a/kernel/rpmsg/ethosu_rpmsg_capabilities.c b/kernel/rpmsg/ethosu_rpmsg_capabilities.c index 3c21d3e..30a9aef 100644 --- a/kernel/rpmsg/ethosu_rpmsg_capabilities.c +++ b/kernel/rpmsg/ethosu_rpmsg_capabilities.c @@ -97,6 +97,7 @@ void ethosu_capability_rsp(struct ethosu_rpmsg_mailbox *mailbox, cap->uapi->hw_cfg.macs_per_cc = rsp->macs_per_cc; cap->uapi->hw_cfg.cmd_stream_version = rsp->cmd_stream_version; cap->uapi->hw_cfg.custom_dma = rsp->custom_dma; + cap->uapi->hw_cfg.type = ETHOSU_DEV_SUBSYSTEM; cap->errno = 0; complete(&cap->done); diff --git a/tests/run_inference_test.cpp b/tests/run_inference_test.cpp index 512a2a0..88fc691 100644 --- a/tests/run_inference_test.cpp +++ b/tests/run_inference_test.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2022-2023 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -68,6 +68,7 @@ void testCapabilties(const Device &device) { } catch (std::exception &e) { throw TestFailureException("Capabilities test: ", e.what()); } TEST_ASSERT(capabilities.hwId.architecture > SemanticVersion()); + TEST_ASSERT(capabilities.hwCfg.type == HardwareConfiguration::DeviceType::SUBSYSTEM); } void testBufferSeek(const Device &device) { diff --git a/utils/inference_runner/inference_runner.cpp b/utils/inference_runner/inference_runner.cpp index d2546e2..531bd4e 100644 --- a/utils/inference_runner/inference_runner.cpp +++ b/utils/inference_runner/inference_runner.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates + * SPDX-FileCopyrightText: Copyright 2020-2024 Arm Limited and/or its affiliates * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may @@ -227,6 +227,7 @@ int main(int argc, char *argv[]) { << "\tdriver:" << capabilities.driver << endl << "\tmacs_per_cc:" << unsigned(capabilities.hwCfg.macsPerClockCycle) << endl << "\tcmd_stream_version:" << unsigned(capabilities.hwCfg.cmdStreamVersion) << endl + << "\ttype:" << capabilities.hwCfg.type << endl << "\tcustom_dma:" << std::boolalpha << capabilities.hwCfg.customDma << endl; /* Create network */ -- cgit v1.2.1