Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

OpenVINOのソースコードを覗いてみた(その1)


Modivius の推論エンジン部のソースコード解析。

myriad_executable_network.cppのExecutableNetwork::ExecutableNetworkメソッドの中で
ExecutableNetwork::ExecutableNetwork(ICNNNetwork &network, std::vector<DevicePtr> &devicePool,
                                     const std::map<std::string, std::string> &config) {
    _config = std::make_shared<MyriadConfig>(config);

    _log = std::make_shared<Logger>("MyriadPlugin", _config->logLevel, consoleOutput());

    _executor = std::make_shared<MyriadExecutor>(_config->forceReset, _config->vpuLogLevel, _log);
    _device = _executor->openDevice(devicePool, _config);

    // ignore hardware optimization config for MYRIAD2, it is always disabled
    if (_device->_platform == MYRIAD_2) {
        _config->compileConfig.hwOptimization = false;
    }
のように、MyriadExecutor という Executor を獲得して、openDevice でデバイスをオープンしています。

MyriadExecutorのopenDeviceにて、bootNextDevice メソッドを呼んでいます。
    ncStatus_t booted = bootNextDevice(devicePool, config->platform, config->watchdogInterval);

bootNextDevice メソッドでは、ncDeviceXXXを使っています。このncDeviceXXXは、inference-engine/thirdparty/movidius/mvnc/src/mvnc_api.cに中で定義されています。

これが Movidius を制御するための模様。

ホスト側とMovidiusが通信するためのコードは、XLink
この XLinkXLinkPlatform.c内で、USB と PCIe の通信用コードがあるよ。

getDeviceNameメソッドの中で、IPCとUSB_CDCはサポートされていないとあるが、これって、なんだろうか?
static int getDeviceName(int index, char* name, int nameSize , int pid)
{
    if (index < 0 ) {
        perror("Incorrect index value\n");
        return X_LINK_PLATFORM_ERROR;
    }
    switch (gl_protocol) {
        case PCIE: {
            return pcie_find_device_port(index, name, nameSize);
        }
        case IPC:
            perror("IPC not supported, switched to USB\n");
            break;
        case USB_CDC:
            perror("USB_CDC not supported, switch to USB\n");
            break;
        case USB_VSC:
            /*should have common device(temporary moved to 'default')*/
        default:
        {
            // At the moment there is no situation where you may need a non standard vid
            int vid = AUTO_PID;

#if (!defined(_WIN32) && !defined(_WIN64))
            uint16_t  bcdusb = -1;
            usbBootError_t rc = usb_find_device_with_bcd(index, name, nameSize, 0, vid, pid, &bcdusb);
#else
            usbBootError_t rc = usb_find_device(index, name, nameSize, 0, vid, pid);
#endif
            // TODO convert usb error to xLinkPlatformErrorCode
            return parseUsbBootError(rc);
        }
    }
    return X_LINK_PLATFORM_SUCCESS;
}

USB_CDCって、(Communication Device Class)なのかな?
VSCって、Virtual Serial XXXなのかな? つまり、通信用なのか。。

ここ
/*############################### FUNCTION ARRAYS #################################*/
/*These arrays hold the write/read/open/close operation functions
specific for each communication protocol.
Add more functions if adding another protocol*/
int (*write_fcts[NMB_OF_PROTOCOLS])(void*, void*, int, unsigned int) = \
                            {USBLinkWrite, USBLinkWrite, pcie_host_write};
int (*read_fcts[NMB_OF_PROTOCOLS])(void*, void*, int, unsigned int) = \
                            {USBLinkRead, XLinkRead, pcie_host_read};
int (*open_fcts[NMB_OF_PROTOCOLS])(const char*, const char*, void**) = \
                            {UsbLinkPlatformConnect, UsbLinkPlatformConnect, pcie_host_open};
int (*close_fcts[NMB_OF_PROTOCOLS])(void*) = \
                            {USBLinkPlatformResetRemote, USBLinkPlatformResetRemote, pcie_host_close};

みたら、3種類登録されていて、プロトコルのタイプ
typedef enum{
    USB_VSC = 0,
    USB_CDC,
    PCIE,
    IPC,
    NMB_OF_PROTOCOLS
} XLinkProtocol_t;
では、USB_VSC、USB_CDC、PCIEになっているね。

XLink で調べたら、ここに出てきました。Neural Compute SDKの中のものとはなんか違いますね。