/* * 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. */ #ifndef ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_FUZZING_OPERATION_MANAGER_H #define ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_FUZZING_OPERATION_MANAGER_H #include #include #include #include #include "TestHarness.h" #include "TestNeuralNetworksWrapper.h" #include "fuzzing/RandomGraphGenerator.h" #include "fuzzing/RandomVariable.h" namespace android { namespace nn { namespace fuzzing_test { struct OperandSignature { // Possible values are [INPUT | CONST | OUTPUT]. // If CONST, the generator will avoid feeding the operand with another operation’s output. RandomOperandType type; // The operand constructor is invoked before the operation constructor. This is for // setting the data type, quantization parameters, or optionally the scalar value. std::function constructor = nullptr; // The operand finalizer is invoked after the graph structure is frozen but before the operation // finalizer. This is for generating the buffer values for the operand. std::function finalizer = nullptr; }; // A filter applied to OperationSignatures. An OperationSignature is filtered out if the opType, all // of supportedDataTypes, all of supportedRanks, or the version does not match with any entry in the // corresponding vector in the filter. Use empty vector in the filter for "no filter". // // E.g. // - To get all 1.0 ADD operation signatures // {.opcodes = {TestOperationType::ADD}, .versions = {TestHalVersion::V1_0}} // // - To get all 1.0 and 1.1 operations with rank 2 or 4 // {.ranks = {2, 4}, .versions = {TestHalVersion::V1_0, TestHalVersion::V1_1}} // struct OperationFilter { std::vector opcodes; std::vector dataTypes; std::vector ranks; std::vector versions; }; struct OperationSignature { // Defines the basic metadata of an operation filterable by OperationFilter. // Upon generation, the random graph generator will randomly choose a supported data type and // rank, and pass the information to the constructors. test_helper::TestOperationType opType; std::vector supportedDataTypes; std::vector supportedRanks; test_helper::TestHalVersion version; // OperandSignatures for inputs and outputs. std::vector inputs; std::vector outputs; // The operation constructor is invoked after the inputs and outputs constructor. This is for // setting the dimension relationship of random operands, and/or generating parameter values at // the operation level, e.g. a parameter depends on or affects another operand in the same // operation. std::function constructor = nullptr; // The operation finalizer is invoked after the graph structure is frozen and inputs and outputs // constructors are invoked. This is for generating operand buffers at the operation level, e.g. // an operand buffer that depends on another operand in the same operation. std::function finalizer = nullptr; // Check if the OperationSignature matches with the filter. Shrink supported* if needed. bool matchFilter(const OperationFilter& filter); }; // A manager manages all available OperationSignatures. class OperationManager { public: // Returns the singleton manager. static OperationManager* get(); // Add the signature to the managed mOperationSignatures if matches with mFilter. void addSignature(const std::string& name, const OperationSignature& signature); // Reinitialize mFilteredSignatures by applying a filter to all of the operation signatures in // mOperationSignatures. void applyFilter(const OperationFilter& filter); // Randomly returns a valid OperationSignature. RandomGraphGenerator uses this method to // generate a random list of operations in the graph. const OperationSignature& getRandomOperation() const; protected: OperationManager() = default; // Contains all operation signatures defined in operation_signatures/*.cpp. // The signatures are sorted by name to ensure a predictable order. std::map mOperationSignatures; // A subset of mOperationSignatures using by the random graph generator. // This vector should be initialized by applyFilter() before generating the graph. std::vector mFilteredSignatures; }; } // namespace fuzzing_test } // namespace nn } // namespace android #endif // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_FUZZING_OPERATION_MANAGER_H