176cd09d0b73928883aed607dd1348a2359bab241Michael Butler/* 276cd09d0b73928883aed607dd1348a2359bab241Michael Butler * Copyright (C) 2017 The Android Open Source Project 376cd09d0b73928883aed607dd1348a2359bab241Michael Butler * 476cd09d0b73928883aed607dd1348a2359bab241Michael Butler * Licensed under the Apache License, Version 2.0 (the "License"); 576cd09d0b73928883aed607dd1348a2359bab241Michael Butler * you may not use this file except in compliance with the License. 676cd09d0b73928883aed607dd1348a2359bab241Michael Butler * You may obtain a copy of the License at 776cd09d0b73928883aed607dd1348a2359bab241Michael Butler * 876cd09d0b73928883aed607dd1348a2359bab241Michael Butler * http://www.apache.org/licenses/LICENSE-2.0 976cd09d0b73928883aed607dd1348a2359bab241Michael Butler * 1076cd09d0b73928883aed607dd1348a2359bab241Michael Butler * Unless required by applicable law or agreed to in writing, software 1176cd09d0b73928883aed607dd1348a2359bab241Michael Butler * distributed under the License is distributed on an "AS IS" BASIS, 1276cd09d0b73928883aed607dd1348a2359bab241Michael Butler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1376cd09d0b73928883aed607dd1348a2359bab241Michael Butler * See the License for the specific language governing permissions and 1476cd09d0b73928883aed607dd1348a2359bab241Michael Butler * limitations under the License. 1576cd09d0b73928883aed607dd1348a2359bab241Michael Butler */ 1676cd09d0b73928883aed607dd1348a2359bab241Michael Butler 1776cd09d0b73928883aed607dd1348a2359bab241Michael Butler#define LOG_TAG "android.hardware.neuralnetworks@1.0-impl-hvx" 1876cd09d0b73928883aed607dd1348a2359bab241Michael Butler 1976cd09d0b73928883aed607dd1348a2359bab241Michael Butler#include "Device.h" 20a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler#include <android-base/logging.h> 21a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler#include <memory> 22a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler#include <mutex> 23a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler#include <thread> 2476cd09d0b73928883aed607dd1348a2359bab241Michael Butler#include "HexagonModel.h" 2576cd09d0b73928883aed607dd1348a2359bab241Michael Butler#include "HexagonUtils.h" 2676cd09d0b73928883aed607dd1348a2359bab241Michael Butler#include "PreparedModel.h" 27cf8d45413b991a3af4a000c8742633a0e0fde54cJean-Luc Brouillet#include "ValidateHal.h" 2876cd09d0b73928883aed607dd1348a2359bab241Michael Butler 2976cd09d0b73928883aed607dd1348a2359bab241Michael Butlernamespace android { 3076cd09d0b73928883aed607dd1348a2359bab241Michael Butlernamespace hardware { 3176cd09d0b73928883aed607dd1348a2359bab241Michael Butlernamespace neuralnetworks { 3276cd09d0b73928883aed607dd1348a2359bab241Michael Butlernamespace V1_0 { 3376cd09d0b73928883aed607dd1348a2359bab241Michael Butlernamespace implementation { 3476cd09d0b73928883aed607dd1348a2359bab241Michael Butler 3576cd09d0b73928883aed607dd1348a2359bab241Michael ButlerDevice::Device() : mCurrentStatus(DeviceStatus::AVAILABLE) {} 3676cd09d0b73928883aed607dd1348a2359bab241Michael Butler 3776cd09d0b73928883aed607dd1348a2359bab241Michael ButlerDevice::~Device() {} 3876cd09d0b73928883aed607dd1348a2359bab241Michael Butler 3982d31136fb09dcd04542655553a9c0455b8f183dMichael Butlerstatic std::once_flag configure_nnlib; 4082d31136fb09dcd04542655553a9c0455b8f183dMichael Butlerstatic void configureHexagon() { 41a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler std::call_once(configure_nnlib, []() { 42a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler hexagon::Controller::getInstance().config(); 43a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler }); 4482d31136fb09dcd04542655553a9c0455b8f183dMichael Butler} 4576cd09d0b73928883aed607dd1348a2359bab241Michael Butler 4676cd09d0b73928883aed607dd1348a2359bab241Michael ButlerReturn<void> Device::getCapabilities(getCapabilities_cb _hidl_cb) { 4782d31136fb09dcd04542655553a9c0455b8f183dMichael Butler configureHexagon(); 4876cd09d0b73928883aed607dd1348a2359bab241Michael Butler 495fa00618520f8d7e394f9d5b2866b6cded835308Jean-Luc Brouillet // These numbers are approximations for this release. 505fa00618520f8d7e394f9d5b2866b6cded835308Jean-Luc Brouillet // TODO Change with the actual number. 5176cd09d0b73928883aed607dd1348a2359bab241Michael Butler PerformanceInfo float32Performance = { 52a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler .execTime = 30.0f, .powerUsage = 2.0f, 5376cd09d0b73928883aed607dd1348a2359bab241Michael Butler }; 5476cd09d0b73928883aed607dd1348a2359bab241Michael Butler 5576cd09d0b73928883aed607dd1348a2359bab241Michael Butler PerformanceInfo quantized8Performance = { 56a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler .execTime = 0.7f, .powerUsage = 0.7f, 5776cd09d0b73928883aed607dd1348a2359bab241Michael Butler }; 5876cd09d0b73928883aed607dd1348a2359bab241Michael Butler 5976cd09d0b73928883aed607dd1348a2359bab241Michael Butler Capabilities capabilities = { 60a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler .float32Performance = float32Performance, .quantized8Performance = quantized8Performance, 6176cd09d0b73928883aed607dd1348a2359bab241Michael Butler }; 6276cd09d0b73928883aed607dd1348a2359bab241Michael Butler 6382d31136fb09dcd04542655553a9c0455b8f183dMichael Butler ErrorStatus status = 64a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler hexagon::isHexagonAvailable() ? ErrorStatus::NONE : ErrorStatus::DEVICE_UNAVAILABLE; 6582d31136fb09dcd04542655553a9c0455b8f183dMichael Butler 6682d31136fb09dcd04542655553a9c0455b8f183dMichael Butler _hidl_cb(status, capabilities); 6776cd09d0b73928883aed607dd1348a2359bab241Michael Butler return Void(); 6876cd09d0b73928883aed607dd1348a2359bab241Michael Butler} 6976cd09d0b73928883aed607dd1348a2359bab241Michael Butler 7076cd09d0b73928883aed607dd1348a2359bab241Michael ButlerReturn<void> Device::getSupportedOperations(const Model& model, 7176cd09d0b73928883aed607dd1348a2359bab241Michael Butler getSupportedOperations_cb _hidl_cb) { 7282d31136fb09dcd04542655553a9c0455b8f183dMichael Butler configureHexagon(); 7376cd09d0b73928883aed607dd1348a2359bab241Michael Butler 7476cd09d0b73928883aed607dd1348a2359bab241Michael Butler if (!nn::validateModel(model)) { 7582d31136fb09dcd04542655553a9c0455b8f183dMichael Butler _hidl_cb(ErrorStatus::INVALID_ARGUMENT, std::vector<bool>{}); 7682d31136fb09dcd04542655553a9c0455b8f183dMichael Butler return Void(); 7782d31136fb09dcd04542655553a9c0455b8f183dMichael Butler } 7882d31136fb09dcd04542655553a9c0455b8f183dMichael Butler if (!hexagon::isHexagonAvailable()) { 7982d31136fb09dcd04542655553a9c0455b8f183dMichael Butler _hidl_cb(ErrorStatus::DEVICE_UNAVAILABLE, std::vector<bool>{}); 8076cd09d0b73928883aed607dd1348a2359bab241Michael Butler return Void(); 8176cd09d0b73928883aed607dd1348a2359bab241Michael Butler } 8276cd09d0b73928883aed607dd1348a2359bab241Michael Butler 8376cd09d0b73928883aed607dd1348a2359bab241Michael Butler hexagon::Model hexagonModel(model); 8476cd09d0b73928883aed607dd1348a2359bab241Michael Butler std::vector<bool> supported = hexagonModel.supportedOperations(); 8576cd09d0b73928883aed607dd1348a2359bab241Michael Butler 8676cd09d0b73928883aed607dd1348a2359bab241Michael Butler _hidl_cb(ErrorStatus::NONE, supported); 8776cd09d0b73928883aed607dd1348a2359bab241Michael Butler return Void(); 8876cd09d0b73928883aed607dd1348a2359bab241Michael Butler} 8976cd09d0b73928883aed607dd1348a2359bab241Michael Butler 9025d8e8714c120716b2982790818dad502693e2f4Michael Butlerstatic void asyncPrepare(const Model& model, const sp<IPreparedModelCallback>& callback) { 9120a5bcaf2e2776f4f4050a0de00ba9710a242019Michael Butler std::shared_ptr<hexagon::Model> hexagonModel = std::make_shared<hexagon::Model>(model); 9282d31136fb09dcd04542655553a9c0455b8f183dMichael Butler 939001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler Return<void> ret; 940f4cdac298cbf691540154154c223db02425b3d0Michael Butler if (hexagonModel->prepare()) { 959001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler ret = callback->notify(ErrorStatus::NONE, new PreparedModel(model, hexagonModel)); 96a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler } else { 979001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler ret = callback->notify(ErrorStatus::GENERAL_FAILURE, nullptr); 989001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler } 999001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler if (!ret.isOk()) { 1009001cd5bf64977f6f61112a37052a03c87ee9550Michael Butler LOG(ERROR) << "Error in callback's return type: " << ret.description(); 10182d31136fb09dcd04542655553a9c0455b8f183dMichael Butler } 10282d31136fb09dcd04542655553a9c0455b8f183dMichael Butler} 10382d31136fb09dcd04542655553a9c0455b8f183dMichael Butler 10476cd09d0b73928883aed607dd1348a2359bab241Michael ButlerReturn<ErrorStatus> Device::prepareModel(const Model& model, 10576cd09d0b73928883aed607dd1348a2359bab241Michael Butler const sp<IPreparedModelCallback>& callback) { 10682d31136fb09dcd04542655553a9c0455b8f183dMichael Butler configureHexagon(); 10782d31136fb09dcd04542655553a9c0455b8f183dMichael Butler 10876cd09d0b73928883aed607dd1348a2359bab241Michael Butler if (callback.get() == nullptr) { 10976cd09d0b73928883aed607dd1348a2359bab241Michael Butler LOG(ERROR) << "invalid callback passed to prepareModel"; 11076cd09d0b73928883aed607dd1348a2359bab241Michael Butler return ErrorStatus::INVALID_ARGUMENT; 11176cd09d0b73928883aed607dd1348a2359bab241Michael Butler } 11276cd09d0b73928883aed607dd1348a2359bab241Michael Butler if (!nn::validateModel(model)) { 11376cd09d0b73928883aed607dd1348a2359bab241Michael Butler callback->notify(ErrorStatus::INVALID_ARGUMENT, nullptr); 11476cd09d0b73928883aed607dd1348a2359bab241Michael Butler return ErrorStatus::INVALID_ARGUMENT; 11576cd09d0b73928883aed607dd1348a2359bab241Michael Butler } 11682d31136fb09dcd04542655553a9c0455b8f183dMichael Butler if (!hexagon::isHexagonAvailable()) { 11782d31136fb09dcd04542655553a9c0455b8f183dMichael Butler callback->notify(ErrorStatus::DEVICE_UNAVAILABLE, nullptr); 11882d31136fb09dcd04542655553a9c0455b8f183dMichael Butler return ErrorStatus::DEVICE_UNAVAILABLE; 11982d31136fb09dcd04542655553a9c0455b8f183dMichael Butler } 12076cd09d0b73928883aed607dd1348a2359bab241Michael Butler 1210f4cdac298cbf691540154154c223db02425b3d0Michael Butler // TODO: once nnlib hanging issue is resolved, make this function 1220f4cdac298cbf691540154154c223db02425b3d0Michael Butler // asynchronous again 1230f4cdac298cbf691540154154c223db02425b3d0Michael Butler asyncPrepare(model, callback); 12476cd09d0b73928883aed607dd1348a2359bab241Michael Butler 12576cd09d0b73928883aed607dd1348a2359bab241Michael Butler return ErrorStatus::NONE; 12676cd09d0b73928883aed607dd1348a2359bab241Michael Butler} 12776cd09d0b73928883aed607dd1348a2359bab241Michael Butler 12876cd09d0b73928883aed607dd1348a2359bab241Michael ButlerReturn<DeviceStatus> Device::getStatus() { 12982d31136fb09dcd04542655553a9c0455b8f183dMichael Butler configureHexagon(); 13082d31136fb09dcd04542655553a9c0455b8f183dMichael Butler mCurrentStatus = 131a6e68df59d64fceb115b91c69d472f0eebbe6400Michael Butler hexagon::isHexagonAvailable() ? DeviceStatus::AVAILABLE : DeviceStatus::OFFLINE; 13276cd09d0b73928883aed607dd1348a2359bab241Michael Butler return mCurrentStatus; 13376cd09d0b73928883aed607dd1348a2359bab241Michael Butler} 13476cd09d0b73928883aed607dd1348a2359bab241Michael Butler 13576cd09d0b73928883aed607dd1348a2359bab241Michael Butler} // namespace implementation 13676cd09d0b73928883aed607dd1348a2359bab241Michael Butler} // namespace V1_0 13776cd09d0b73928883aed607dd1348a2359bab241Michael Butler} // namespace neuralnetworks 13876cd09d0b73928883aed607dd1348a2359bab241Michael Butler} // namespace hardware 13976cd09d0b73928883aed607dd1348a2359bab241Michael Butler} // namespace android 140