144 lines
5.3 KiB
C++
144 lines
5.3 KiB
C++
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "Converter.h"
|
|
|
|
#include <algorithm>
|
|
#include <random>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace android::nn::fuzz {
|
|
namespace {
|
|
|
|
using namespace test_helper;
|
|
using namespace android_nn_fuzz;
|
|
|
|
constexpr uint32_t kMaxSize = 65536;
|
|
|
|
TestOperandType convert(OperandType type) {
|
|
return static_cast<TestOperandType>(type);
|
|
}
|
|
|
|
TestOperationType convert(OperationType type) {
|
|
return static_cast<TestOperationType>(type);
|
|
}
|
|
|
|
TestOperandLifeTime convert(OperandLifeTime lifetime) {
|
|
return static_cast<TestOperandLifeTime>(lifetime);
|
|
}
|
|
|
|
std::vector<float> convert(const Scales& scales) {
|
|
const auto& repeatedScale = scales.scale();
|
|
return std::vector<float>(repeatedScale.begin(), repeatedScale.end());
|
|
}
|
|
|
|
TestSymmPerChannelQuantParams convert(const SymmPerChannelQuantParams& params) {
|
|
std::vector<float> scales = convert(params.scales());
|
|
const uint32_t channelDim = params.channel_dim();
|
|
return {.scales = std::move(scales), .channelDim = channelDim};
|
|
}
|
|
|
|
std::vector<uint32_t> convert(const Dimensions& dimensions) {
|
|
const auto& repeatedDimension = dimensions.dimension();
|
|
return std::vector<uint32_t>(repeatedDimension.begin(), repeatedDimension.end());
|
|
}
|
|
|
|
TestBuffer convert(bool makeEmpty, const Buffer& buffer) {
|
|
if (makeEmpty) {
|
|
return TestBuffer();
|
|
}
|
|
const uint32_t randomSeed = buffer.random_seed();
|
|
std::default_random_engine generator{randomSeed};
|
|
std::uniform_int_distribution<uint32_t> dist{0, kMaxSize};
|
|
const uint32_t size = dist(generator);
|
|
return TestBuffer::createFromRng<uint32_t>(size, &generator);
|
|
}
|
|
|
|
TestOperand convert(const Operand& operand) {
|
|
const TestOperandType type = convert(operand.type());
|
|
std::vector<uint32_t> dimensions = convert(operand.dimensions());
|
|
const float scale = operand.scale();
|
|
const int32_t zeroPoint = operand.zero_point();
|
|
const TestOperandLifeTime lifetime = convert(operand.lifetime());
|
|
auto channelQuant = convert(operand.channel_quant());
|
|
const bool isIgnored = false;
|
|
const bool makeEmpty = (lifetime == TestOperandLifeTime::NO_VALUE ||
|
|
lifetime == TestOperandLifeTime::TEMPORARY_VARIABLE);
|
|
TestBuffer data = convert(makeEmpty, operand.data());
|
|
return {.type = type,
|
|
.dimensions = std::move(dimensions),
|
|
.numberOfConsumers = 0,
|
|
.scale = scale,
|
|
.zeroPoint = zeroPoint,
|
|
.lifetime = lifetime,
|
|
.channelQuant = std::move(channelQuant),
|
|
.isIgnored = isIgnored,
|
|
.data = std::move(data)};
|
|
}
|
|
|
|
std::vector<TestOperand> convert(const Operands& operands) {
|
|
std::vector<TestOperand> testOperands;
|
|
testOperands.reserve(operands.operand_size());
|
|
const auto& repeatedOperand = operands.operand();
|
|
std::transform(repeatedOperand.begin(), repeatedOperand.end(), std::back_inserter(testOperands),
|
|
[](const auto& operand) { return convert(operand); });
|
|
return testOperands;
|
|
}
|
|
|
|
std::vector<uint32_t> convert(const Indexes& indexes) {
|
|
const auto& repeatedIndex = indexes.index();
|
|
return std::vector<uint32_t>(repeatedIndex.begin(), repeatedIndex.end());
|
|
}
|
|
|
|
TestOperation convert(const Operation& operation) {
|
|
const TestOperationType type = convert(operation.type());
|
|
std::vector<uint32_t> inputs = convert(operation.inputs());
|
|
std::vector<uint32_t> outputs = convert(operation.outputs());
|
|
return {.type = type, .inputs = std::move(inputs), .outputs = std::move(outputs)};
|
|
}
|
|
|
|
std::vector<TestOperation> convert(const Operations& operations) {
|
|
std::vector<TestOperation> testOperations;
|
|
testOperations.reserve(operations.operation_size());
|
|
const auto& repeatedOperation = operations.operation();
|
|
std::transform(repeatedOperation.begin(), repeatedOperation.end(),
|
|
std::back_inserter(testOperations),
|
|
[](const auto& operation) { return convert(operation); });
|
|
return testOperations;
|
|
}
|
|
|
|
TestModel convert(const Model& model) {
|
|
std::vector<TestOperand> operands = convert(model.operands());
|
|
std::vector<TestOperation> operations = convert(model.operations());
|
|
std::vector<uint32_t> inputIndexes = convert(model.input_indexes());
|
|
std::vector<uint32_t> outputIndexes = convert(model.output_indexes());
|
|
const bool isRelaxed = model.is_relaxed();
|
|
return {.main = {.operands = std::move(operands),
|
|
.operations = std::move(operations),
|
|
.inputIndexes = std::move(inputIndexes),
|
|
.outputIndexes = std::move(outputIndexes)},
|
|
.isRelaxed = isRelaxed};
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
TestModel convertToTestModel(const Test& model) {
|
|
return convert(model.model());
|
|
}
|
|
|
|
} // namespace android::nn::fuzz
|