aboutsummaryrefslogtreecommitdiff
path: root/Utils.hpp
blob: 42fef3fb1858bdfdab1bf25c0f5fe46defe496fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#pragma once

#include <armnn/ArmNN.hpp>

#include <CpuExecutor.h>
#include <HalInterfaces.h>
#include <NeuralNetworks.h>

#include <boost/format.hpp>
#include <log/log.h>

#include <vector>
#include <string>
#include <fstream>
#include <iomanip>

namespace V1_0 = ::android::hardware::neuralnetworks::V1_0;

namespace armnn_driver
{

extern const armnn::PermutationVector g_DontPermute;

class UnsupportedOperand: public std::runtime_error
{
public:
    UnsupportedOperand(const V1_0::OperandType type)
        : std::runtime_error("Operand type is unsupported")
        , m_type(type)
    {}

    V1_0::OperandType m_type;
};

/// Swizzles tensor data in @a input according to the dimension mappings.
void SwizzleAndroidNn4dTensorToArmNn(const armnn::TensorInfo& tensor, const void* input, void* output,
                                     const armnn::PermutationVector& mappings);

/// Returns a pointer to a specific location in a pool
void* GetMemoryFromPool(DataLocation location,
                        const std::vector<android::nn::RunTimePoolInfo>& memPools);

/// Can throw UnsupportedOperand
armnn::TensorInfo GetTensorInfoForOperand(const V1_0::Operand& operand);

std::string GetOperandSummary(const V1_0::Operand& operand);

template <typename HalModel>
std::string GetModelSummary(const HalModel& model)
{
    std::stringstream result;

    result << model.inputIndexes.size() << " input(s), " << model.operations.size() << " operation(s), " <<
        model.outputIndexes.size() << " output(s), " << model.operands.size() << " operand(s)" << std::endl;

    result << "Inputs: ";
    for (uint32_t i = 0; i < model.inputIndexes.size(); i++)
    {
        result << GetOperandSummary(model.operands[model.inputIndexes[i]]) << ", ";
    }
    result << std::endl;

    result << "Operations: ";
    for (uint32_t i = 0; i < model.operations.size(); i++)
    {
        result << toString(model.operations[i].type).c_str() << ", ";
    }
    result << std::endl;

    result << "Outputs: ";
    for (uint32_t i = 0; i < model.outputIndexes.size(); i++)
    {
        result << GetOperandSummary(model.operands[model.outputIndexes[i]]) << ", ";
    }
    result << std::endl;

    return result.str();
}

void DumpTensor(const std::string& dumpDir,
                const std::string& requestName,
                const std::string& tensorName,
                const armnn::ConstTensor& tensor);

void DumpJsonProfilingIfRequired(bool gpuProfilingEnabled,
                                 const std::string& dumpDir,
                                 armnn::NetworkId networkId,
                                 const armnn::IProfiler* profiler);

template <typename HalModel>
void ExportNetworkGraphToDotFile(const armnn::IOptimizedNetwork& optimizedNetwork,
                                 const std::string& dumpDir,
                                 const HalModel& model)
{
    // The dump directory must exist in advance.
    if (dumpDir.empty())
    {
        return;
    }

    // Get the memory address of the model and convert it to a hex string (of at least a '0' character).
    size_t modelAddress = uintptr_t(&model);
    std::stringstream ss;
    ss << std::uppercase << std::hex << std::setfill('0') << std::setw(1) << modelAddress;
    std::string modelAddressHexString = ss.str();

    // Set the name of the output .dot file.
    const std::string fileName = boost::str(boost::format("%1%/networkgraph_%2%.dot")
                                            % dumpDir
                                            % modelAddressHexString);

    ALOGV("Exporting the optimized network graph to file: %s", fileName.c_str());

    // Write the network graph to a dot file.
    std::ofstream fileStream;
    fileStream.open(fileName, std::ofstream::out | std::ofstream::trunc);

    if (!fileStream.good())
    {
        ALOGW("Could not open file %s for writing", fileName.c_str());
        return;
    }

    if (optimizedNetwork.SerializeToDot(fileStream) != armnn::Status::Success)
    {
        ALOGW("An error occurred when writing to file %s", fileName.c_str());
    }
}

} // namespace armnn_driver