183e24dc4706a5b7089881a55daf05b3924fab3b7David Gross/* 283e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * Copyright (C) 2017 The Android Open Source Project 383e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * 483e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * Licensed under the Apache License, Version 2.0 (the "License"); 583e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * you may not use this file except in compliance with the License. 683e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * You may obtain a copy of the License at 783e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * 883e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * http://www.apache.org/licenses/LICENSE-2.0 983e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * 1083e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * Unless required by applicable law or agreed to in writing, software 1183e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * distributed under the License is distributed on an "AS IS" BASIS, 1283e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1383e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * See the License for the specific language governing permissions and 1483e24dc4706a5b7089881a55daf05b3924fab3b7David Gross * limitations under the License. 1583e24dc4706a5b7089881a55daf05b3924fab3b7David Gross */ 1683e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 1783e24dc4706a5b7089881a55daf05b3924fab3b7David Gross#define LOG_TAG "CompilationBuilder" 1883e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 1983e24dc4706a5b7089881a55daf05b3924fab3b7David Gross#include "CompilationBuilder.h" 2083e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 213ced3cfd5b8f22b632c35f24e585c4847383b195David Gross#include "ExecutionBuilder.h" 220b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross#include "ExecutionPlan.h" 231f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross#include "Manager.h" 240b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross#include "ModelBuilder.h" 250b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross#include "Utils.h" 2683e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 2783e24dc4706a5b7089881a55daf05b3924fab3b7David Grossnamespace android { 2883e24dc4706a5b7089881a55daf05b3924fab3b7David Grossnamespace nn { 2983e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 3083e24dc4706a5b7089881a55daf05b3924fab3b7David GrossCompilationBuilder::CompilationBuilder(const ModelBuilder* model) : 31c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross mModel(model), mPartitioning(DeviceManager::get()->getPartitioning()) { 32820215d28bed6c90f696cde0f282445d16da432eMiao Wang VLOG(COMPILATION) << "CompilationBuilder::CompilationBuilder"; 3383e24dc4706a5b7089881a55daf05b3924fab3b7David Gross} 3483e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 3565aa556323f4a054f80a75b6c4c721b2a7ed3298David Grossint CompilationBuilder::finish() { 36c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross // Get the list of HAL devices. 37c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross return finish(DeviceManager::get()->getDrivers()); 38c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross} 39c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross 40c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Grossint CompilationBuilder::finish(const std::vector<std::shared_ptr<Device>>& devices) { 4165aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross if (mFinished) { 4265aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross LOG(ERROR) << "ANeuralNetworksCompilation_finish called more than once"; 4365aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross return ANEURALNETWORKS_BAD_STATE; 4465aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross } 45e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet // TODO validate the rest 4665aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross 4765aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross mFinished = true; 480b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross 49c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross if (mPartitioning) { 50def0a14aa77689f12120cfb4f136eea659038cc0David Gross int n = mModel->partitionTheWork(devices, mPreference, &mPlan); 51fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet switch (n) { 52fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet case ANEURALNETWORKS_NO_ERROR: 53fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet break; 54fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet case ANEURALNETWORKS_UNEXPECTED_NULL: 55fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet case ANEURALNETWORKS_BAD_DATA: 56fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // The two error codes above should only be used for errors in the user's 57fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // request. In case of a user error, we won't try any fallback. 58fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // TODO: Document this in NeuralNetworks.h and in the HAL. Make sure 59fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // driver writers know which code they can return. 60fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet return n; 61fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet default: 62fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // The error might be recoverable. Return the error only if falling back 63fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet // is not allowed. 64fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet if (!DeviceManager::partitioningAllowsFallback(mPartitioning)) { 65fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet return n; 66fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet } 67fc67d170972e9178f4c9bcec6c6d1b8e2c3161faJean-Luc Brouillet break; 681f4381539b7e89c42336ee7cd1addb9a4c317b34David Gross } 690b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross } 700b9453e41a544f9c780eaa15ad65136ad4662ccbDavid Gross 7165aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross return ANEURALNETWORKS_NO_ERROR; 7265aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross} 7365aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross 7465aa556323f4a054f80a75b6c4c721b2a7ed3298David Grossint CompilationBuilder::setPreference(int32_t preference) { 7565aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross if (mFinished) { 7665aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross LOG(ERROR) << 7765aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross "ANeuralNetworksCompilation_setPreference can't modify after compilation finished"; 7865aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross return ANEURALNETWORKS_BAD_STATE; 7965aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross } 80e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet if (preference >= kNumberOfPreferences) { 81e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet LOG(ERROR) << "ANeuralNetworksCompilation_setPreference invalid preference " << preference; 82e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet return ANEURALNETWORKS_BAD_DATA; 83e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet } 84e127e49e67b53c96eb79f6a9c58f956ad4761227Jean-Luc Brouillet 8565aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross mPreference = preference; 8683e24dc4706a5b7089881a55daf05b3924fab3b7David Gross return ANEURALNETWORKS_NO_ERROR; 8783e24dc4706a5b7089881a55daf05b3924fab3b7David Gross} 8883e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 89c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Grossint CompilationBuilder::setPartitioning(uint32_t partitioning) { 90c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross if (mFinished) { 91c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross LOG(ERROR) << 92c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross "ANeuralNetworksCompilation_setPartitioning can't modify after compilation finished"; 93c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross return ANEURALNETWORKS_BAD_STATE; 94c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross } 95c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross 96c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross mPartitioning = partitioning; 97c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross return ANEURALNETWORKS_NO_ERROR; 98c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross} 99c2f1c1198c84f5a75fc2305935155f33b8ff5db2David Gross 1003ced3cfd5b8f22b632c35f24e585c4847383b195David Grossint CompilationBuilder::createExecution(ExecutionBuilder **execution) { 10165aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross if (!mFinished) { 10265aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross LOG(ERROR) << "ANeuralNetworksExecution_create passed an unfinished compilation"; 10365aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross *execution = nullptr; 10465aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross return ANEURALNETWORKS_BAD_STATE; 10565aa556323f4a054f80a75b6c4c721b2a7ed3298David Gross } 106a144106df8f9b82251a5e584b1b083fb39d33b88Przemyslaw Szczepaniak *execution = new (std::nothrow) ExecutionBuilder(this); 1073ced3cfd5b8f22b632c35f24e585c4847383b195David Gross return (*execution ? ANEURALNETWORKS_NO_ERROR : ANEURALNETWORKS_OUT_OF_MEMORY); 10883e24dc4706a5b7089881a55daf05b3924fab3b7David Gross} 10983e24dc4706a5b7089881a55daf05b3924fab3b7David Gross 11083e24dc4706a5b7089881a55daf05b3924fab3b7David Gross} // namespace nn 11183e24dc4706a5b7089881a55daf05b3924fab3b7David Gross} // namespace android 112