//
// SPDX-FileCopyrightText: Copyright 2020, 2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: Apache-2.0
//
%module driver
%{
#define SWIG_FILE_WITH_INIT
%}

//typemap definitions and other common stuff
%include "standard_header.i"

%{
#include "ethosu.hpp"
#include <fstream>
#include <list>
#include <string>
#include <cstring>
#include <sstream>
#include <linux/ioctl.h>

#define ETHOSU_IOCTL_BASE               0x01
#define ETHOSU_IO(nr)                   _IO(ETHOSU_IOCTL_BASE, nr)
#define ETHOSU_IOCTL_PING               ETHOSU_IO(0x00)

%}
%include <typemaps/buffer.i>

%shared_ptr(EthosU::Buffer);
%shared_ptr(EthosU::Network);


namespace std {
   %template(UintVector) vector<unsigned int>;
   %template(SizeTVector) vector<size_t>;
   %template(SharedBufferVector) vector<shared_ptr<EthosU::Buffer>>;
}

namespace EthosU
{

%feature("docstring",
"
Semantic Version : major.minor.patch
") SemanticVersion;
%nodefaultctor SemanticVersion;
class SemanticVersion {
public:
    SemanticVersion(uint32_t major = 0, uint32_t minor = 0, uint32_t patch = 0);

    uint32_t major;
    uint32_t minor;
    uint32_t patch;
};

%extend SemanticVersion {
    std::string __str__() const {
        std::ostringstream out;
        out << *$self;
        return out.str();
    }
}

%feature("docstring",
"
Hardware Identifier which consists of version status, version revision, product revision and architecture revision.
") HardwareId;
class HardwareId {
public:
    HardwareId(uint32_t versionStatus, SemanticVersion& version, SemanticVersion& product, SemanticVersion& arch);

    uint32_t versionStatus{0};
    SemanticVersion version{};
    SemanticVersion product{};
    SemanticVersion architecture{};
};

%extend HardwareId {
    std::string __str__() const {
        std::ostringstream out;
        out << "{versionStatus=" << $self->versionStatus <<
        ", version=" << EthosU_SemanticVersion___str__(&$self->version) <<
        ", product=" << EthosU_SemanticVersion___str__(&$self->product) <<
        ", architecture=" << EthosU_SemanticVersion___str__(&$self->architecture) << "}";
        return out.str();
    }
}

%feature("docstring",
"
Hardware Configuration object defines specific configuration including MACs per clock cycle and NPU command stream
version. This also specifies is custom DMA is enabled or not.
") HardwareConfiguration;
%nodefaultctor HardwareConfiguration;
class HardwareConfiguration {
    public:
    HardwareConfiguration(uint32_t macs = 0, uint32_t cmdStreamVersion = 0, bool customDma = false);

    uint32_t macsPerClockCycle;
    uint32_t cmdStreamVersion;
    bool customDma;
};

%extend HardwareConfiguration {
    std::string __str__() const {
        std::ostringstream out;
        out << "{macsPerClockCycle=" << $self->macsPerClockCycle <<
        ", cmdStreamVersion=" << $self->cmdStreamVersion <<
        ", customDma=" <<  ($self->customDma? "True": "False") << "}";
        return out.str();
    }
}

%feature("docstring",
"
Device capabilities object which specifies capabilities based on hardware ID, configuration and semantic version.
") Capabilities;
class Capabilities {
    public:
    Capabilities() {}
    Capabilities(const HardwareId& hwId, const HardwareConfiguration& hwCfg, const SemanticVersion& driverVersion);

    HardwareId hwId;
    HardwareConfiguration hwCfg;
    SemanticVersion driver;
};

%extend Capabilities {
    std::string __str__() const {
        std::ostringstream out;
        out << "{hwId=" << EthosU_HardwareId___str__(&$self->hwId) <<
        ", hwCfg=" << EthosU_HardwareConfiguration___str__(&$self->hwCfg) <<
        ", driver=" <<  EthosU_SemanticVersion___str__(&$self->driver) << "}";
        return out.str();
    }
}

%feature("docstring",
"
Device object represents Ethos-U device file descriptor and manages Ethos-U device lifecycle.
Constructor accepts device name and opens file descriptor with O_RDWR | O_NONBLOCK flags.
When the object is destroyed - device file descriptor is closed.
") Device;
%nodefaultctor Device;
class Device {
public:
    Device(const char *device);

    %feature("docstring",
    "
    Performs the I/O control operation on the Ethos-U device.

    Args:
        cmd: Command code
        data: Command data
    Returns:
        int: Return value depends on command. Usually -1 indicates error.
    ") ioctl;
    int ioctl(unsigned long cmd, void *data = nullptr) const;

    %feature("docstring",
    "
    Returns the capabilities of the Ethos-U device.

    Returns:
    Capabilities: Return capabilities of device.
    ") capabilities;
    Capabilities capabilities() const;
};

%extend Device {

    %feature("docstring",
    "
    Sends ping command to the Ethos-U device.

    See ETHOSU_IOCTL_PING from kernel module uapi/ethosu.h
    ") ping;
    void ping() {
        $self->ioctl(ETHOSU_IOCTL_PING);
    }
}

%feature("docstring",
    "
    Buffer object represents a RW mapping in the virtual address space of the caller.

    Created mapping is shareable, updates to the mapping are visible to other processes mapping the same region.
    Issues ETHOSU_IOCTL_BUFFER_CREATE I/O request to the device with given Maximum capacity.

    Buffer could be created for a device with given maximum capacity or instantiated directly from
    a file containing binary data.

    Examples:
        >>> import ethosu_driver as driver
        >>> # from file:
        >>> buf = driver.Buffer(device, '/path/to/file')
        >>> # Empty, with maximum capacity:
        >>> buf = driver.Buffer(device, 1024)
    ") Buffer;
%nodefaultctor Buffer;
class Buffer {
public:
    Buffer(const Device &device, const size_t capacity);

    %feature("docstring",
    "
    Returns maximum buffer capacity set during initialisation.

    Returns:
        int: maximum buffer capacity.
    ") capacity;
    size_t capacity() const;

    %feature("docstring",
    "
    Sets the size of the device buffer to 0.
    ") clear;
    void clear() const;

    %feature("docstring",
    "
    Returns a readonly view to the mapped memory.

    Returns:
        memoryview: readonly memory data.
    ") data;
    %driver_buffer_out;
    char* data() const;
    %clear_driver_buffer_out;

    %feature("docstring",
    "
    Sets a size of the memory buffer for the device.

    'offset + size' must not exceed the capacity of the buffer.
    Does not change the size of the mapped region.

    Issues ETHOSU_IOCTL_BUFFER_SET I/O request with a given size and offset.

    Args:
        size (int): Device buffer size.
        offset (int): Offset to where the data starts.
    ") resize;
    void resize(size_t size, size_t offset = 0) const;

    %feature("docstring",
    "
    Queries device and returns buffer data offset.

    Issues ETHOSU_IOCTL_BUFFER_GET I/O request.

    Returns:
        int: data offset
    ") offset;
    size_t offset() const;

    %feature("docstring",
    "
    Queries device and returns buffer data size.

    Issues ETHOSU_IOCTL_BUFFER_GET I/O request.

    Returns:
        int: current device buffer size.
    ") size;
    size_t size() const;

    %feature("docstring",
    "
    Returns buffer file descriptor id.

    Returns:
        int: file descriptor id.
    ") getFd;
    int getFd() const;
};

%extend Buffer {

    Buffer(const Device& device, const std::string& filename) {
        std::ifstream stream(filename, std::ios::binary);
        if (!stream.is_open()) {
            throw EthosU::Exception(std::string("Failed to open file: ").append(filename).c_str());
        }

        stream.seekg(0, std::ios_base::end);
        size_t size = stream.tellg();
        stream.seekg(0, std::ios_base::beg);

        auto buffer = new EthosU::Buffer(device, size);
        buffer->resize(size);
        stream.read(buffer->data(), size);

        return buffer;
    }

    %feature("docstring",
    "
    Fills the buffer from python buffer.

    Copies python buffer data to the mapped memory region.
    Input buffer size must be within `Buffer` maximum capacity.

    Args:
        buffer: data to be copied to the mapped memory.

    ") from_buffer;
    %mutable_buffer(char* buffer, size_t size);
    void from_buffer(char* buffer, size_t size) {
        self->resize(size);
        char* data = $self->data();
        std::memcpy(data, buffer, size);
    }
    %clear_mutable_buffer(char* buffer, size_t size);
}

%feature("docstring",
    "
    Represents the neural network file descriptor received from the Ethos-U device.

    `Network` is created providing `Device` object and a `Buffer` containing tflite file data.
    Network creation issues ETHOSU_IOCTL_NETWORK_CREATE I/O request with buffer file descriptor id.
    Provided `Buffer` data is parsed into tflite Model object and input/output feature maps sizes are saved.

    Destruction of the object closes network file descriptor.
    ") Network;
%nodefaultctor Network;
class Network {
public:

    %feature("docstring",
    "
    Performs the I/O control operation with network buffer device.

    Args:
        cmd: Command code
        data: Command data
    Returns:
        int: Return value depends on command. Usually -1 indicates error.
    ") ioctl;
    int ioctl(unsigned long cmd, void *data);

    %feature("docstring",
    "
    Returns associated memory buffer.

    Returns:
        `Buffer`: buffer object used during initialisation.
    ") getBuffer;
    std::shared_ptr<Buffer> getBuffer();

    %feature("docstring",
    "
    Returns saved sizes of the neural network model input feature maps.

    Returns:
        list: sizes of all input feature maps
    ") getIfmDims;
    const std::vector<size_t> &getIfmDims() const;

    %feature("docstring",
    "
    Returns total size of all input feature maps.

    Returns:
        int: total size of all input feature maps
    ") getIfmSize;
    size_t getIfmSize() const;

    %feature("docstring",
    "
    Returns saved sizes of the neural network model output feature maps.

    Returns:
        list: sizes of all output feature maps
    ") getOfmDims;
    const std::vector<size_t> &getOfmDims() const;

    %feature("docstring",
    "
    Returns total size of all output feature maps.

    Returns:
        int: total size of all output feature maps
    ") getOfmSize;
    size_t getOfmSize() const;
};

%extend Network {
    Network(const Device &device, std::shared_ptr<Buffer> &buffer)
    {
        if(buffer == nullptr){
            throw EthosU::Exception(std::string("Failed to create the network, buffer is nullptr.").c_str());
        }
        auto network = new EthosU::Network(device, buffer);
        return network;
    }
}

%extend Network {
    Network(const Device &device, const unsigned int index)
    {
        auto network = new EthosU::Network(device, index);
        return network;
    }
}

%feature("docstring",
    "
    InferenceStatus enumeration
    ") InferenceStatus;
enum class InferenceStatus {
    OK,
    ERROR,
    RUNNING,
    REJECTED,
    ABORTED,
    ABORTING
    };

%feature("docstring",
    "
    Represents the inference file descriptor received from the Ethos-U device.

    `Inference` is created providing `Network` object and lists of input and output feature maps buffers.
    Feature map buffers are copied.

    Inference creation issues ETHOSU_IOCTL_INFERENCE_CREATE I/O request with
    file descriptor ids for all input and output buffers.

    The number of input/output buffers must not exceed ETHOSU_FD_MAX value defined in the kernel module
    uapi/ethosu.h.

    Destruction of the object closes inference file descriptor.
    ") Inference;
%nodefaultctor Inference;
class Inference {
public:

    %feature("docstring",
    "
    Polls inference file descriptor for events.

    Args:
        timeoutNanos (int64_t): polling timeout in nanoseconds.

    Returns:
        bool: True for success, False otherwise.
    ") wait;
    void wait(int64_t timeoutNanos = -1) const;

    %feature("docstring",
    "
    Aborts the current inference job.

    Returns:
        bool: True if gracefully stopped, False otherwise.
    ") cancel;
    bool cancel() const;

    %feature("docstring",
    "
    Gets the current inference job status.

    Returns:
        InferenceStatus.
    ") status;
    EthosU::InferenceStatus status() const;

    %feature("docstring",
    "
    Returns inference file descriptor.

    Returns:
        int: file descriptor id
    ") getFd;
    int getFd() const;

    %feature("docstring",
    "
    Returns associated `Network` object.

    Returns:
        `Network`: network used during initialisation
    ") getNetwork;
    std::shared_ptr<Network> getNetwork() const;

    %feature("docstring",
    "
    Returns copied input feature maps buffers.

    Returns:
       list: input feature map buffers
    ") getIfmBuffers;
    std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();

    %feature("docstring",
    "
    Returns copied output feature maps buffers.

    Returns:
       list: output feature map buffers
    ") getOfmBuffers;
    std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();

    %feature("docstring",
    "
    Returns PMU event data.

    Returns:
        list: PMU event data
    ") getPmuCounters;
    const std::vector<uint32_t> getPmuCounters();

    %feature("docstring",
    "
    Returns the total cycle count, including idle cycles, as reported by the PMU.

    Returns:
        int: total cycle count
    ") getCycleCounter;
    uint64_t getCycleCounter();

    %feature("docstring",
    "
    Returns maximum supported number of PMU events.

    Returns:
        int: PMU event max
    ") getMaxPmuEventCounters;
    static uint32_t getMaxPmuEventCounters();
};

%extend Inference {
    Inference(const std::shared_ptr<Network> &network,
            const std::vector<std::shared_ptr<Buffer>> &ifm,
            const std::vector<std::shared_ptr<Buffer>> &ofm)
   {
        return new EthosU::Inference(network, ifm.begin(), ifm.end(), ofm.begin(), ofm.end());
   }
   Inference(const std::shared_ptr<Network> & network,
             const std::vector<std::shared_ptr<Buffer>> &ifm,
             const std::vector<std::shared_ptr<Buffer>> &ofm,
             const std::vector<unsigned int> &enabledCounters,
             bool enableCycleCounter)
   {
       return new EthosU::Inference(network, ifm.begin(), ifm.end(), ofm.begin(), ofm.end(), enabledCounters, enableCycleCounter);
   }
}

}
// Clear exception typemap.
%exception;
