aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Grohmann <davide.grohmann@arm.com>2021-06-01 15:03:51 +0200
committerKristofer Jonsson <kristofer.jonsson@arm.com>2021-06-10 14:58:49 +0000
commit35ce6c809ccf637c6bb8a00ad14b051b87d9884a (patch)
treee999250ca985ac5b00ba9162ee1782de02983c03
parent0c79f896caf1a0ac16dd92810c4b15bfff00bdb3 (diff)
downloadethos-u-linux-driver-stack-35ce6c809ccf637c6bb8a00ad14b051b87d9884a.tar.gz
Add support for handling capabilities requests
Change-Id: Id5aa197312c88b0c448dc085d8477ed67da24724
-rw-r--r--driver_library/include/ethosu.hpp100
-rw-r--r--driver_library/src/ethosu.cpp54
-rw-r--r--kernel/ethosu_core_interface.h30
-rw-r--r--kernel/ethosu_device.c166
-rw-r--r--kernel/ethosu_device.h14
-rw-r--r--kernel/ethosu_mailbox.c12
-rw-r--r--kernel/ethosu_mailbox.h8
-rw-r--r--kernel/uapi/ethosu.h51
-rw-r--r--utils/inference_runner/inference_runner.cpp15
9 files changed, 446 insertions, 4 deletions
diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp
index 70d0701..d3f7421 100644
--- a/driver_library/include/ethosu.hpp
+++ b/driver_library/include/ethosu.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2021 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
@@ -19,10 +19,25 @@
#pragma once
#include <algorithm>
+#include <iostream>
#include <memory>
#include <string>
#include <vector>
+/*
+ *The following undef are necessary to avoid clash with macros in GNU C Library
+ * if removed the following warning/error are produced:
+ *
+ * In the GNU C Library, "major" ("minor") is defined
+ * by <sys/sysmacros.h>. For historical compatibility, it is
+ * currently defined by <sys/types.h> as well, but we plan to
+ * remove this soon. To use "major" ("minor"), include <sys/sysmacros.h>
+ * directly. If you did not intend to use a system-defined macro
+ * "major" ("minor"), you should undefine it after including <sys/types.h>.
+ */
+#undef major
+#undef minor
+
namespace EthosU {
class Exception : public std::exception {
@@ -35,12 +50,95 @@ private:
std::string msg;
};
+/**
+ * Sematic Version : major.minor.patch
+ */
+class SemanticVersion {
+public:
+ SemanticVersion(uint32_t _major = 0, uint32_t _minor = 0, uint32_t _patch = 0) :
+ major(_major), minor(_minor), patch(_patch){};
+
+ bool operator==(const SemanticVersion &other);
+ bool operator<(const SemanticVersion &other);
+ bool operator<=(const SemanticVersion &other);
+ bool operator!=(const SemanticVersion &other);
+ bool operator>(const SemanticVersion &other);
+ bool operator>=(const SemanticVersion &other);
+
+ uint32_t major;
+ uint32_t minor;
+ uint32_t patch;
+};
+
+std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
+
+/*
+ * Hardware Identifier
+ * @versionStatus: Version status
+ * @version: Version revision
+ * @product: Product revision
+ * @architecture: Architecture revison
+ */
+struct HardwareId {
+public:
+ HardwareId(uint32_t _versionStatus,
+ const SemanticVersion &_version,
+ const SemanticVersion &_product,
+ const SemanticVersion &_architecture) :
+ versionStatus(_versionStatus),
+ version(_version), product(_product), architecture(_architecture) {}
+
+ uint32_t versionStatus;
+ SemanticVersion version;
+ SemanticVersion product;
+ SemanticVersion architecture;
+};
+
+/*
+ * Hardware Configuration
+ * @macsPerClockCycle: MACs per clock cycle
+ * @cmdStreamVersion: NPU command stream version
+ * @shramSize: SHRAM size
+ * @customDma: Custom DMA enabled
+ */
+struct HardwareConfiguration {
+public:
+ HardwareConfiguration(uint32_t _macsPerClockCycle,
+ uint32_t _cmdStreamVersion,
+ uint32_t _shramSize,
+ bool _customDma) :
+ macsPerClockCycle(_macsPerClockCycle),
+ cmdStreamVersion(_cmdStreamVersion), shramSize(_shramSize), customDma(_customDma) {}
+
+ uint32_t macsPerClockCycle;
+ uint32_t cmdStreamVersion;
+ uint32_t shramSize;
+ bool customDma;
+};
+
+/**
+ * Device capabilities
+ * @hwId: Hardware
+ * @driver: Driver revision
+ * @hwCfg Hardware configuration
+ */
+class Capabilities {
+public:
+ Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
+ hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
+
+ HardwareId hwId;
+ HardwareConfiguration hwCfg;
+ SemanticVersion driver;
+};
+
class Device {
public:
Device(const char *device = "/dev/ethosu0");
virtual ~Device();
int ioctl(unsigned long cmd, void *data = nullptr);
+ Capabilities capabilities();
private:
int fd;
diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp
index 1768271..ea1f7f4 100644
--- a/driver_library/src/ethosu.cpp
+++ b/driver_library/src/ethosu.cpp
@@ -112,6 +112,43 @@ const char *Exception::what() const throw() {
}
/****************************************************************************
+ * Semantic Version
+ ****************************************************************************/
+
+bool SemanticVersion::operator==(const SemanticVersion &other) {
+ return other.major == major && other.minor == minor && other.patch == patch;
+}
+
+bool SemanticVersion::operator<(const SemanticVersion &other) {
+ if (other.major > major)
+ return true;
+ if (other.minor > minor)
+ return true;
+ return other.patch > patch;
+}
+
+bool SemanticVersion::operator<=(const SemanticVersion &other) {
+ return *this < other || *this == other;
+}
+
+bool SemanticVersion::operator!=(const SemanticVersion &other) {
+ return !(*this == other);
+}
+
+bool SemanticVersion::operator>(const SemanticVersion &other) {
+ return !(*this <= other);
+}
+
+bool SemanticVersion::operator>=(const SemanticVersion &other) {
+ return !(*this < other);
+}
+
+ostream &operator<<(ostream &out, const SemanticVersion &v) {
+ return out << "{ major=" << unsigned(v.major) << ", minor=" << unsigned(v.minor) << ", patch=" << unsigned(v.patch)
+ << " }";
+}
+
+/****************************************************************************
* Device
****************************************************************************/
@@ -130,6 +167,23 @@ int Device::ioctl(unsigned long cmd, void *data) {
return eioctl(fd, cmd, data);
}
+Capabilities Device::capabilities() {
+ ethosu_uapi_device_capabilities uapi;
+ (void)eioctl(fd, ETHOSU_IOCTL_CAPABILITIES_REQ, static_cast<void *>(&uapi));
+
+ Capabilities capabilities(
+ HardwareId(uapi.hw_id.version_status,
+ 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,
+ uapi.hw_cfg.shram_size,
+ bool(uapi.hw_cfg.custom_dma)),
+ SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev));
+ return capabilities;
+}
+
/****************************************************************************
* Buffer
****************************************************************************/
diff --git a/kernel/ethosu_core_interface.h b/kernel/ethosu_core_interface.h
index 4e7a864..ad8311c 100644
--- a/kernel/ethosu_core_interface.h
+++ b/kernel/ethosu_core_interface.h
@@ -55,6 +55,8 @@ enum ethosu_core_msg_type {
ETHOSU_CORE_MSG_INFERENCE_RSP,
ETHOSU_CORE_MSG_VERSION_REQ,
ETHOSU_CORE_MSG_VERSION_RSP,
+ ETHOSU_CORE_MSG_CAPABILITIES_REQ,
+ ETHOSU_CORE_MSG_CAPABILITIES_RSP,
ETHOSU_CORE_MSG_MAX
};
@@ -129,6 +131,34 @@ struct ethosu_core_msg_version {
};
/**
+ * struct ethosu_core_capabilities_req - Message capabilities request
+ */
+struct ethosu_core_capabilities_req {
+ uint64_t user_arg;
+};
+
+/**
+ * struct ethosu_core_capabilities_rsp - Message capabilities response
+ */
+struct ethosu_core_msg_capabilities_rsp {
+ uint64_t user_arg;
+ uint32_t version_status;
+ uint32_t version_minor;
+ uint32_t version_major;
+ uint32_t product_major;
+ uint32_t arch_patch_rev;
+ uint32_t arch_minor_rev;
+ uint32_t arch_major_rev;
+ uint32_t driver_patch_rev;
+ uint32_t driver_minor_rev;
+ uint32_t driver_major_rev;
+ uint32_t macs_per_cc;
+ uint32_t cmd_stream_version;
+ uint32_t shram_size;
+ uint32_t custom_dma;
+};
+
+/**
* enum ethosu_core_msg_err_type - Error types
*/
enum ethosu_core_msg_err_type {
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index e82b4c0..7adc7a6 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -38,6 +38,7 @@
#include <linux/io.h>
#include <linux/of_reserved_mem.h>
#include <linux/uaccess.h>
+#include <linux/slab.h>
/****************************************************************************
* Defines
@@ -47,6 +48,8 @@
#define MINOR_COUNT 1 /* Allocate 1 minor version */
#define DMA_ADDR_BITS 32 /* Number of address bits */
+#define CAPABILITIES_RESP_TIMEOUT_MS 50
+
/****************************************************************************
* Types
****************************************************************************/
@@ -55,6 +58,71 @@
* Functions
****************************************************************************/
+static void ethosu_capabilities_destroy(struct kref *kref)
+{
+ struct ethosu_capabilities *cap =
+ container_of(kref, struct ethosu_capabilities, refcount);
+
+ list_del(&cap->list);
+
+ devm_kfree(cap->edev->dev, cap);
+}
+
+static int ethosu_capabilities_find(struct ethosu_capabilities *cap,
+ struct list_head *capabilties_list)
+{
+ struct ethosu_capabilities *cur;
+
+ list_for_each_entry(cur, capabilties_list, list) {
+ if (cur == cap)
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int ethosu_capability_rsp(struct ethosu_device *edev,
+ struct ethosu_core_msg_capabilities_rsp *msg)
+{
+ struct ethosu_capabilities *cap;
+ struct ethosu_uapi_device_capabilities *capabilities;
+ int ret;
+
+ cap = (struct ethosu_capabilities *)msg->user_arg;
+ ret = ethosu_capabilities_find(cap, &edev->capabilities_list);
+ if (0 != ret) {
+ dev_warn(edev->dev,
+ "Handle not found in capabilities list. handle=0x%p\n",
+ cap);
+
+ /* NOTE: do not call complete or kref_put on invalid data! */
+ return ret;
+ }
+
+ capabilities = cap->capabilities;
+
+ capabilities->hw_id.version_status = msg->version_status;
+ capabilities->hw_id.version_minor = msg->version_minor;
+ capabilities->hw_id.version_major = msg->version_major;
+ capabilities->hw_id.product_major = msg->product_major;
+ capabilities->hw_id.arch_patch_rev = msg->arch_patch_rev;
+ capabilities->hw_id.arch_minor_rev = msg->arch_minor_rev;
+ capabilities->hw_id.arch_major_rev = msg->arch_major_rev;
+ capabilities->driver_patch_rev = msg->driver_patch_rev;
+ capabilities->driver_minor_rev = msg->driver_minor_rev;
+ capabilities->driver_major_rev = msg->driver_major_rev;
+ capabilities->hw_cfg.macs_per_cc = msg->macs_per_cc;
+ capabilities->hw_cfg.cmd_stream_version = msg->cmd_stream_version;
+ capabilities->hw_cfg.shram_size = msg->shram_size;
+ capabilities->hw_cfg.custom_dma = msg->custom_dma;
+
+ complete(&cap->done);
+
+ kref_put(&cap->refcount, ethosu_capabilities_destroy);
+
+ return 0;
+}
+
/* Incoming messages */
static int ethosu_handle_msg(struct ethosu_device *edev)
{
@@ -62,9 +130,10 @@ static int ethosu_handle_msg(struct ethosu_device *edev)
struct ethosu_core_msg header;
union {
- struct ethosu_core_msg_err error;
- struct ethosu_core_inference_rsp inf;
- struct ethosu_core_msg_version version;
+ struct ethosu_core_msg_err error;
+ struct ethosu_core_inference_rsp inf;
+ struct ethosu_core_msg_version version;
+ struct ethosu_core_msg_capabilities_rsp capabilities;
} data;
/* Read message */
@@ -133,7 +202,35 @@ static int ethosu_handle_msg(struct ethosu_device *edev)
}
break;
+ case ETHOSU_CORE_MSG_CAPABILITIES_RSP:
+ if (header.length != sizeof(data.capabilities)) {
+ dev_warn(edev->dev,
+ "Msg: Capabilities response of incorrect size. size=%u, expected=%zu\n", header.length,
+ sizeof(data.capabilities));
+ ret = -EBADMSG;
+ break;
+ }
+ dev_info(edev->dev,
+ "Msg: Capabilities response ua%llx vs%hhu v%hhu.%hhu p%hhu av%hhu.%hhu.%hhu dv%hhu.%hhu.%hhu mcc%hhu csv%hhu ss%hhu cd%hhu\n",
+ data.capabilities.user_arg,
+ data.capabilities.version_status,
+ data.capabilities.version_major,
+ data.capabilities.version_minor,
+ data.capabilities.product_major,
+ data.capabilities.arch_major_rev,
+ data.capabilities.arch_minor_rev,
+ data.capabilities.arch_patch_rev,
+ data.capabilities.driver_major_rev,
+ data.capabilities.driver_minor_rev,
+ data.capabilities.driver_patch_rev,
+ data.capabilities.macs_per_cc,
+ data.capabilities.cmd_stream_version,
+ data.capabilities.shram_size,
+ data.capabilities.custom_dma);
+
+ ret = ethosu_capability_rsp(edev, &data.capabilities);
+ break;
default:
/* This should not happen due to version checks */
dev_warn(edev->dev, "Msg: Protocol error\n");
@@ -157,6 +254,64 @@ static int ethosu_open(struct inode *inode,
return nonseekable_open(inode, file);
}
+static int ethosu_send_capabilities_request(struct ethosu_device *edev,
+ void __user *udata)
+{
+ struct ethosu_uapi_device_capabilities uapi;
+ struct ethosu_capabilities *cap;
+ int ret;
+ int timeout;
+
+ cap = devm_kzalloc(edev->dev, sizeof(struct ethosu_capabilities),
+ GFP_KERNEL);
+ if (!cap)
+ return -ENOMEM;
+
+ cap->edev = edev;
+ cap->capabilities = &uapi;
+ kref_init(&cap->refcount);
+ init_completion(&cap->done);
+ list_add(&cap->list, &edev->capabilities_list);
+
+ ret = ethosu_mailbox_capabilities_request(&edev->mailbox, cap);
+ if (0 != ret)
+ goto put_kref;
+
+ /*
+ * Increase ref counter since we sent the pointer out to
+ * response handler thread. That thread is responsible to
+ * decrease the ref counter before exiting. So the memory
+ * can be freed.
+ *
+ * NOTE: if no response is received back, the memory is leaked.
+ */
+ kref_get(&cap->refcount);
+ /* Unlock the mutex before going to block on the condition */
+ mutex_unlock(&edev->mutex);
+ /* wait for response to arrive back */
+ timeout = wait_for_completion_timeout(&cap->done,
+ msecs_to_jiffies(
+ CAPABILITIES_RESP_TIMEOUT_MS));
+ /* take back the mutex before resuming to do anything */
+ ret = mutex_lock_interruptible(&edev->mutex);
+ if (0 != ret)
+ goto put_kref;
+
+ if (0 == timeout /* timed out*/) {
+ dev_warn(edev->dev,
+ "Msg: Capabilities response lost - timeout\n");
+ ret = -EIO;
+ goto put_kref;
+ }
+
+ ret = copy_to_user(udata, &uapi, sizeof(uapi)) ? -EFAULT : 0;
+
+put_kref:
+ kref_put(&cap->refcount, ethosu_capabilities_destroy);
+
+ return ret;
+}
+
static long ethosu_ioctl(struct file *file,
unsigned int cmd,
unsigned long arg)
@@ -176,6 +331,10 @@ static long ethosu_ioctl(struct file *file,
dev_info(edev->dev, "Ioctl: Send version request\n");
ret = ethosu_mailbox_version_request(&edev->mailbox);
break;
+ case ETHOSU_IOCTL_CAPABILITIES_REQ:
+ dev_info(edev->dev, "Ioctl: Send capabilities request\n");
+ ret = ethosu_send_capabilities_request(edev, udata);
+ break;
case ETHOSU_IOCTL_PING: {
dev_info(edev->dev, "Ioctl: Send ping\n");
ret = ethosu_mailbox_ping(&edev->mailbox);
@@ -257,6 +416,7 @@ int ethosu_dev_init(struct ethosu_device *edev,
edev->dev = dev;
edev->class = class;
mutex_init(&edev->mutex);
+ INIT_LIST_HEAD(&edev->capabilities_list);
INIT_LIST_HEAD(&edev->inference_list);
ret = of_reserved_mem_device_init(edev->dev);
diff --git a/kernel/ethosu_device.h b/kernel/ethosu_device.h
index 4e4f59d..0722814 100644
--- a/kernel/ethosu_device.h
+++ b/kernel/ethosu_device.h
@@ -25,6 +25,7 @@
* Includes
****************************************************************************/
+#include "uapi/ethosu.h"
#include "ethosu_mailbox.h"
#include <linux/device.h>
@@ -32,6 +33,7 @@
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
+#include <linux/completion.h>
/****************************************************************************
* Types
@@ -47,9 +49,21 @@ struct ethosu_device {
dev_t devt;
struct mutex mutex;
struct ethosu_mailbox mailbox;
+ struct list_head capabilities_list;
struct list_head inference_list;
};
+/**
+ * struct ethosu_capabilities - Capabilities internal struct
+ */
+struct ethosu_capabilities {
+ struct ethosu_device *edev;
+ struct completion done;
+ struct kref refcount;
+ struct ethosu_uapi_device_capabilities *capabilities;
+ struct list_head list;
+};
+
/****************************************************************************
* Functions
****************************************************************************/
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index f61c181..158a7f5 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -213,6 +213,18 @@ int ethosu_mailbox_version_request(struct ethosu_mailbox *mbox)
0);
}
+int ethosu_mailbox_capabilities_request(struct ethosu_mailbox *mbox,
+ void *user_arg)
+{
+ struct ethosu_core_capabilities_req req = {
+ .user_arg = (ptrdiff_t)user_arg
+ };
+
+ return ethosu_queue_write_msg(mbox, ETHOSU_CORE_MSG_CAPABILITIES_REQ,
+ &req,
+ sizeof(req));
+}
+
int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
void *user_arg,
uint32_t ifm_count,
diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h
index 0bc5ffb..5cd5e62 100644
--- a/kernel/ethosu_mailbox.h
+++ b/kernel/ethosu_mailbox.h
@@ -114,6 +114,14 @@ int ethosu_mailbox_pong(struct ethosu_mailbox *mbox);
int ethosu_mailbox_version_request(struct ethosu_mailbox *mbox);
/**
+ * ethosu_mailbox_capabilities_request() - Send capabilities request
+ *
+ * Return: 0 on success, else error code.
+ */
+int ethosu_mailbox_capabilities_request(struct ethosu_mailbox *mbox,
+ void *user_arg);
+
+/**
* ethosu_mailbox_inference() - Send inference
*
* Return: 0 on success, else error code.
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index 1e53c91..3e4e7a3 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -44,6 +44,7 @@ namespace EthosU {
#define ETHOSU_IOCTL_PING ETHOSU_IO(0x00)
#define ETHOSU_IOCTL_VERSION_REQ ETHOSU_IO(0x01)
+#define ETHOSU_IOCTL_CAPABILITIES_REQ ETHOSU_IO(0x02)
#define ETHOSU_IOCTL_BUFFER_CREATE ETHOSU_IOR(0x10, \
struct ethosu_uapi_buffer_create)
#define ETHOSU_IOCTL_BUFFER_SET ETHOSU_IOR(0x11, \
@@ -125,6 +126,56 @@ struct ethosu_uapi_pmu_counts {
};
/**
+ * struct ethosu_uapi_device_hw_id - Device hardware identification
+ * @version_status: Version status
+ * @version_minor: Version minor
+ * @version_major: Version major
+ * @product_major: Product major
+ * @arch_patch_rev: Architecture version patch
+ * @arch_minor_rev: Architecture version minor
+ * @arch_major_rev: Architecture version major
+ */
+struct ethosu_uapi_device_hw_id {
+ __u32 version_status;
+ __u32 version_minor;
+ __u32 version_major;
+ __u32 product_major;
+ __u32 arch_patch_rev;
+ __u32 arch_minor_rev;
+ __u32 arch_major_rev;
+};
+
+/**
+ * struct ethosu_uapi_device_hw_cfg - Device hardware configuration
+ * @macs_per_cc: MACs per clock cycle
+ * @cmd_stream_version: NPU command stream version
+ * @shram_size: SHRAM size
+ * @custom_dma: Custom DMA enabled
+ */
+struct ethosu_uapi_device_hw_cfg {
+ __u32 macs_per_cc;
+ __u32 cmd_stream_version;
+ __u32 shram_size;
+ __u32 custom_dma;
+};
+
+/**
+ * struct ethosu_uapi_capabilities - Device capabilities
+ * @hw_id: Hardware identification
+ * @hw_cfg: Hardware configuration
+ * @driver_patch_rev: Driver version patch
+ * @driver_minor_rev: Driver version minor
+ * @driver_major_rev: Driver version major
+ */
+struct ethosu_uapi_device_capabilities {
+ struct ethosu_uapi_device_hw_id hw_id;
+ struct ethosu_uapi_device_hw_cfg hw_cfg;
+ __u32 driver_patch_rev;
+ __u32 driver_minor_rev;
+ __u32 driver_major_rev;
+};
+
+/**
* struct ethosu_uapi_inference_create - Create network request
* @ifm_count: Number of IFM file descriptors
* @ifm_fd: IFM buffer file descriptors
diff --git a/utils/inference_runner/inference_runner.cpp b/utils/inference_runner/inference_runner.cpp
index 7ceec71..17969da 100644
--- a/utils/inference_runner/inference_runner.cpp
+++ b/utils/inference_runner/inference_runner.cpp
@@ -23,6 +23,7 @@
#include <iomanip>
#include <iostream>
#include <list>
+#include <stdio.h>
#include <string>
#include <unistd.h>
@@ -209,6 +210,20 @@ int main(int argc, char *argv[]) {
cout << "Send version request" << endl;
device.ioctl(ETHOSU_IOCTL_VERSION_REQ);
+ cout << "Send capabilities request" << endl;
+ Capabilities capabilities = device.capabilities();
+
+ cout << "Capabilities:" << endl
+ << "\tversion_status:" << unsigned(capabilities.hwId.versionStatus) << endl
+ << "\tversion:" << capabilities.hwId.version << endl
+ << "\tproduct:" << capabilities.hwId.product << endl
+ << "\tarchitecture:" << capabilities.hwId.architecture << endl
+ << "\tdriver:" << capabilities.driver << endl
+ << "\tmacs_per_cc:" << unsigned(capabilities.hwCfg.macsPerClockCycle) << endl
+ << "\tcmd_stream_version:" << unsigned(capabilities.hwCfg.cmdStreamVersion) << endl
+ << "\tshram_size:" << unsigned(capabilities.hwCfg.shramSize) << endl
+ << "\tcustom_dma:" << std::boolalpha << capabilities.hwCfg.customDma << endl;
+
/* Create network */
cout << "Create network" << endl;
shared_ptr<Buffer> networkBuffer = allocAndFill(device, networkArg);