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