aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorKristofer Jonsson <kristofer.jonsson@arm.com>2020-09-10 13:26:01 +0200
committerKristofer Jonsson <kristofer.jonsson@arm.com>2020-09-17 13:23:27 +0200
commitb74492c5aee3786b886951e87f4e5ea8d6032733 (patch)
tree76ef44dfdb68d68964877b0adba21cbce2416fe5 /kernel
parent116a635581f292cb4882ea1a086f842904f85c3c (diff)
downloadethos-u-linux-driver-stack-b74492c5aee3786b886951e87f4e5ea8d6032733.tar.gz
Support inferences with multiple inputs and outputs
Build flatbuffers library. Update network class to extract IFM and OFM dimensions from the tflite file. Update the uapi and core apis to support up to 16 IFM and OFM buffers per inference. Change-Id: I2f2f177aa4c2d5f9f50f23eb33c44e01ec2cbe09
Diffstat (limited to 'kernel')
-rw-r--r--kernel/ethosu_core_interface.h12
-rw-r--r--kernel/ethosu_device.c4
-rw-r--r--kernel/ethosu_inference.c70
-rw-r--r--kernel/ethosu_inference.h6
-rw-r--r--kernel/ethosu_mailbox.c18
-rw-r--r--kernel/ethosu_mailbox.h6
-rw-r--r--kernel/ethosu_network.c2
-rw-r--r--kernel/uapi/ethosu.h15
8 files changed, 93 insertions, 40 deletions
diff --git a/kernel/ethosu_core_interface.h b/kernel/ethosu_core_interface.h
index 827ce4f..0dd1996 100644
--- a/kernel/ethosu_core_interface.h
+++ b/kernel/ethosu_core_interface.h
@@ -27,6 +27,9 @@
#include <stdint.h>
#endif
+/** Maximum number of IFM/OFM buffers per inference */
+#define ETHOSU_CORE_BUFFER_MAX 16
+
/**
* enum ethosu_core_msg_type - Message types
*
@@ -79,14 +82,17 @@ struct ethosu_core_buffer {
struct ethosu_core_inference_req {
uint64_t user_arg;
- struct ethosu_core_buffer ifm;
- struct ethosu_core_buffer ofm;
+ uint32_t ifm_count;
+ struct ethosu_core_buffer ifm[ETHOSU_CORE_BUFFER_MAX];
+ uint32_t ofm_count;
+ struct ethosu_core_buffer ofm[ETHOSU_CORE_BUFFER_MAX];
struct ethosu_core_buffer network;
};
struct ethosu_core_inference_rsp {
uint64_t user_arg;
- uint32_t ofm_size;
+ uint32_t ofm_count;
+ uint32_t ofm_size[ETHOSU_CORE_BUFFER_MAX];
uint32_t status;
};
diff --git a/kernel/ethosu_device.c b/kernel/ethosu_device.c
index 5cdea2c..5301f86 100644
--- a/kernel/ethosu_device.c
+++ b/kernel/ethosu_device.c
@@ -79,8 +79,8 @@ static int ethosu_handle_msg(struct ethosu_device *edev)
break;
case ETHOSU_CORE_MSG_INFERENCE_RSP:
dev_info(edev->dev,
- "Msg: Inference response. user_arg=0x%llx, ofm_size=%u, status=%u\n",
- data.inf.user_arg, data.inf.ofm_size,
+ "Msg: Inference response. user_arg=0x%llx, ofm_count=%u, status=%u\n",
+ data.inf.user_arg, data.inf.ofm_count,
data.inf.status);
ethosu_inference_rsp(edev, &data.inf);
break;
diff --git a/kernel/ethosu_inference.c b/kernel/ethosu_inference.c
index 8efc22d..e9530cf 100644
--- a/kernel/ethosu_inference.c
+++ b/kernel/ethosu_inference.c
@@ -86,8 +86,10 @@ static int ethosu_inference_send(struct ethosu_inference *inf)
inf->status = ETHOSU_UAPI_STATUS_ERROR;
- ret = ethosu_mailbox_inference(&inf->edev->mailbox, inf, inf->ifm,
- inf->ofm, inf->net->buf);
+ ret = ethosu_mailbox_inference(&inf->edev->mailbox, inf,
+ inf->ifm_count, inf->ifm,
+ inf->ofm_count, inf->ofm,
+ inf->net->buf);
if (ret)
return ret;
@@ -126,8 +128,13 @@ static void ethosu_inference_kref_destroy(struct kref *kref)
inf, inf->status);
list_del(&inf->list);
- ethosu_buffer_put(inf->ifm);
- ethosu_buffer_put(inf->ofm);
+
+ while (inf->ifm_count-- > 0)
+ ethosu_buffer_put(inf->ifm[inf->ifm_count]);
+
+ while (inf->ofm_count-- > 0)
+ ethosu_buffer_put(inf->ofm[inf->ofm_count]);
+
ethosu_network_put(inf->net);
devm_kfree(inf->edev->dev, inf);
}
@@ -199,6 +206,7 @@ int ethosu_inference_create(struct ethosu_device *edev,
struct ethosu_uapi_inference_create *uapi)
{
struct ethosu_inference *inf;
+ uint32_t i;
int fd;
int ret = -ENOMEM;
@@ -213,18 +221,26 @@ int ethosu_inference_create(struct ethosu_device *edev,
kref_init(&inf->kref);
init_waitqueue_head(&inf->waitq);
- /* Get pointer to IFM buffer */
- inf->ifm = ethosu_buffer_get_from_fd(uapi->ifm_fd);
- if (IS_ERR(inf->ifm)) {
- ret = PTR_ERR(inf->ifm);
- goto free_inf;
+ /* Get pointer to IFM buffers */
+ for (i = 0; i < uapi->ifm_count; i++) {
+ inf->ifm[i] = ethosu_buffer_get_from_fd(uapi->ifm_fd[i]);
+ if (IS_ERR(inf->ifm[i])) {
+ ret = PTR_ERR(inf->ifm[i]);
+ goto put_ifm;
+ }
+
+ inf->ifm_count++;
}
/* Get pointer to OFM buffer */
- inf->ofm = ethosu_buffer_get_from_fd(uapi->ofm_fd);
- if (IS_ERR(inf->ofm)) {
- ret = PTR_ERR(inf->ofm);
- goto put_ifm;
+ for (i = 0; i < uapi->ofm_count; i++) {
+ inf->ofm[i] = ethosu_buffer_get_from_fd(uapi->ofm_fd[i]);
+ if (IS_ERR(inf->ofm[i])) {
+ ret = PTR_ERR(inf->ofm[i]);
+ goto put_ofm;
+ }
+
+ inf->ofm_count++;
}
/* Increment network reference count */
@@ -253,12 +269,15 @@ int ethosu_inference_create(struct ethosu_device *edev,
put_net:
ethosu_network_put(inf->net);
- ethosu_buffer_put(inf->ofm);
+
+put_ofm:
+ while (inf->ofm_count-- > 0)
+ ethosu_buffer_put(inf->ofm[inf->ofm_count]);
put_ifm:
- ethosu_buffer_put(inf->ifm);
+ while (inf->ifm_count-- > 0)
+ ethosu_buffer_put(inf->ifm[inf->ifm_count]);
-free_inf:
devm_kfree(edev->dev, inf);
return ret;
@@ -314,14 +333,21 @@ void ethosu_inference_rsp(struct ethosu_device *edev,
inf->pending = false;
- if (rsp->status == ETHOSU_CORE_STATUS_OK) {
+ if (rsp->status == ETHOSU_CORE_STATUS_OK &&
+ inf->ofm_count <= ETHOSU_CORE_BUFFER_MAX) {
+ uint32_t i;
+
inf->status = ETHOSU_UAPI_STATUS_OK;
- ret = ethosu_buffer_resize(inf->ofm,
- inf->ofm->size + rsp->ofm_size,
- inf->ofm->offset);
- if (ret)
- inf->status = ETHOSU_UAPI_STATUS_ERROR;
+ for (i = 0; i < inf->ofm_count; i++) {
+ struct ethosu_buffer *ofm = inf->ofm[i];
+
+ ret = ethosu_buffer_resize(
+ ofm, ofm->size + rsp->ofm_size[i],
+ ofm->offset);
+ if (ret)
+ inf->status = ETHOSU_UAPI_STATUS_ERROR;
+ }
} else {
inf->status = ETHOSU_UAPI_STATUS_ERROR;
}
diff --git a/kernel/ethosu_inference.h b/kernel/ethosu_inference.h
index b42f5ca..c0d8461 100644
--- a/kernel/ethosu_inference.h
+++ b/kernel/ethosu_inference.h
@@ -59,8 +59,10 @@ struct ethosu_inference {
struct file *file;
struct kref kref;
wait_queue_head_t waitq;
- struct ethosu_buffer *ifm;
- struct ethosu_buffer *ofm;
+ uint32_t ifm_count;
+ struct ethosu_buffer *ifm[ETHOSU_FD_MAX];
+ uint32_t ofm_count;
+ struct ethosu_buffer *ofm[ETHOSU_FD_MAX];
struct ethosu_network *net;
bool pending;
enum ethosu_uapi_status status;
diff --git a/kernel/ethosu_mailbox.c b/kernel/ethosu_mailbox.c
index 23a356e..47c4698 100644
--- a/kernel/ethosu_mailbox.c
+++ b/kernel/ethosu_mailbox.c
@@ -171,15 +171,25 @@ int ethosu_mailbox_ping(struct ethosu_mailbox *mbox)
int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
void *user_arg,
- struct ethosu_buffer *ifm,
- struct ethosu_buffer *ofm,
+ uint32_t ifm_count,
+ struct ethosu_buffer **ifm,
+ uint32_t ofm_count,
+ struct ethosu_buffer **ofm,
struct ethosu_buffer *network)
{
struct ethosu_core_inference_req inf;
+ uint32_t i;
inf.user_arg = (ptrdiff_t)user_arg;
- ethosu_core_set_size(ifm, &inf.ifm);
- ethosu_core_set_capacity(ofm, &inf.ofm);
+ inf.ifm_count = ifm_count;
+ inf.ofm_count = ofm_count;
+
+ for (i = 0; i < ifm_count; i++)
+ ethosu_core_set_size(ifm[i], &inf.ifm[i]);
+
+ for (i = 0; i < ofm_count; i++)
+ ethosu_core_set_capacity(ofm[i], &inf.ofm[i]);
+
ethosu_core_set_size(network, &inf.network);
return ethosu_queue_write_msg(mbox, ETHOSU_CORE_MSG_INFERENCE_REQ,
diff --git a/kernel/ethosu_mailbox.h b/kernel/ethosu_mailbox.h
index c5865d0..5a77b54 100644
--- a/kernel/ethosu_mailbox.h
+++ b/kernel/ethosu_mailbox.h
@@ -100,8 +100,10 @@ int ethosu_mailbox_ping(struct ethosu_mailbox *mbox);
*/
int ethosu_mailbox_inference(struct ethosu_mailbox *mbox,
void *user_arg,
- struct ethosu_buffer *ifm,
- struct ethosu_buffer *ofm,
+ uint32_t ifm_count,
+ struct ethosu_buffer **ifm,
+ uint32_t ofm_count,
+ struct ethosu_buffer **ofm,
struct ethosu_buffer *network);
#endif /* ETHOSU_MAILBOX_H */
diff --git a/kernel/ethosu_network.c b/kernel/ethosu_network.c
index 851d4b7..4d68f05 100644
--- a/kernel/ethosu_network.c
+++ b/kernel/ethosu_network.c
@@ -108,7 +108,7 @@ static long ethosu_network_ioctl(struct file *file,
dev_info(net->edev->dev,
"Ioctl: Inference. ifm_fd=%u, ofm_fd=%u\n",
- uapi.ifm_fd, uapi.ofm_fd);
+ uapi.ifm_fd[0], uapi.ofm_fd[0]);
ret = ethosu_inference_create(net->edev, net, &uapi);
break;
diff --git a/kernel/uapi/ethosu.h b/kernel/uapi/ethosu.h
index 2eca2c4..d790db4 100644
--- a/kernel/uapi/ethosu.h
+++ b/kernel/uapi/ethosu.h
@@ -51,6 +51,9 @@
struct ethosu_uapi_inference_create)
#define ETHOSU_IOCTL_INFERENCE_STATUS ETHOSU_IO(0x31)
+/* Maximum number of IFM/OFM file descriptors per network */
+#define ETHOSU_FD_MAX 16
+
/****************************************************************************
* Types
****************************************************************************/
@@ -93,12 +96,16 @@ struct ethosu_uapi_network_create {
/**
* struct ethosu_uapi_inference_create - Create network request
- * @ifm_fd: IFM buffer file descriptor
- * @ofm_fd: OFM buffer file descriptor
+ * @ifm_count: Number of IFM file descriptors
+ * @ifm_fd: IFM buffer file descriptors
+ * @ofm_count: Number of OFM file descriptors
+ * @ofm_fd: OFM buffer file descriptors
*/
struct ethosu_uapi_inference_create {
- __u32 ifm_fd;
- __u32 ofm_fd;
+ __u32 ifm_count;
+ __u32 ifm_fd[ETHOSU_FD_MAX];
+ __u32 ofm_count;
+ __u32 ofm_fd[ETHOSU_FD_MAX];
};
#endif