/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ /*! * \file tvm/runtime/vm/executable.h */ #ifndef TVM_RUNTIME_VM_EXECUTABLE_H_ #define TVM_RUNTIME_VM_EXECUTABLE_H_ #include #include #include #include #include #include #include #include "./bytecode.h" // Convention: this version should set to minimum TVM version it support // NOTE: this file only changes if we change relax vm format // for example if relax vm format do not change in 0.15, this should remain as 0.14 // if it changes in 0.16, we will change it to 0.16 #define VM_VERSION "0.14" namespace tvm { namespace runtime { namespace vm { /*! * \brief Information entry in executable function table. * * Contains metadata about the compiled function, as * well as the compiled VM instructions. */ struct VMFuncInfo { /*! \brief kind of the function. */ enum class FuncKind : int { /*! \brief system level packed function */ kPackedFunc = 0, /*! \brief VM function. */ kVMFunc = 1, /*! \brief VMTIR function. */ kVMTIRFunc = 2, }; /*! \brief The kind of function. */ FuncKind kind; /*! \brief The function's name, global symbol */ std::string name; /*! \brief The start instruction index of the function. */ Index start_instr = 0; /*! \brief The end instruction index of the function. */ Index end_instr = 0; /*! \brief The number of arguments of the function. */ Index num_args = 0; /*! \brief The register file size of the function. */ Index register_file_size = 0; /*! \brief The function parameter names.*/ std::vector param_names; // defined customized loader save void Save(support::Stream* writer) const; bool Load(support::Stream* reader); }; /*! * \brief The virtual machine executable emitted by the VM compiler. * * The executable contains information (e.g. data in different memory regions) * to run in a virtual machine. */ class TVM_RUNTIME_DLL VMExecutable : public ffi::ModuleObj { public: /*! \brief Get the property of the runtime module .*/ int GetPropertyMask() const final { return ffi::Module::kBinarySerializable; }; /*! * \brief Print the detailed statistics of the given code, i.e. number of * globals and constants, etc. * \return The statistics represented by a string. */ std::string Stats() const; /*! * \brief Get the i-th instruction from the executable. * \param i The index of the instruction to be fetched. * \return The instruction. */ Instruction GetInstruction(Index i) const; /*! * \brief Set j-th byte data of i-th instruction to val. * \param i The index of the instruction to be updated. * \param j The index of the byte data of the instruction to be updated. * \param val The value to be set */ void SetInstructionData(Index i, Index j, ExecWord val); /*! * \brief Print the instructions as text format. * \return The text format of the instructions. */ ffi::String AsText() const; /*! * \brief Print the instructions as python program. * \return The python program of the instructions, represented by a string. */ ffi::String AsPython() const; /*! * \brief Write the VMExecutable to the binary stream in serialized form. * \return The binary bytes that save the executable to. */ ffi::Bytes SaveToBytes() const final; /*! * \brief Load VMExecutable from the binary stream in serialized form. * \param bytes The binary bytes that load the executable from. * \return The loaded executable, in the form of a `runtime::Module`. */ static ffi::Module LoadFromBytes(const ffi::Bytes& bytes); /*! * \brief Write the VMExecutable to the provided path as a file containing its serialized content. * \param file_name The name of the file to write the serialized data to. * \param format The target format of the saved file. */ void WriteToFile(const ffi::String& file_name, const ffi::String& format) const final; /*! \brief Create a Relax virtual machine and load `this` as the executable. */ ffi::Module VMLoadExecutable() const; /*! \brief Check if the VMExecutable contains a specific function. */ bool HasFunction(const ffi::String& name) const; /*! * \brief Load VMExecutable from the file. * \param file_name The path of the file that load the executable from. * \return The loaded executable, in the form of a `runtime::Module`. */ static ffi::Module LoadFromFile(const ffi::String& file_name); /*! \brief The virtual machine's function table. */ std::vector func_table; /*! \brief A map from globals (as strings) to their index in the function map. */ std::unordered_map func_map; /*! \brief The global constant pool. */ std::vector constants; /*! \brief The VDevice memory scopes */ std::unordered_map memory_scopes; /*! \brief The offset of instruction. */ std::vector instr_offset; /*! \brief The byte data of instruction. */ std::vector instr_data; virtual ~VMExecutable() {} /*! \brief Module type key. */ const char* kind() const final; /*! * \brief Look up an exported function by name. * \param name The function name. * \return The function if found, otherwise std::nullopt. */ ffi::Optional GetFunction(const ffi::String& name) override; private: /*! * \brief Save the globals. * \param strm The input stream. */ void SaveGlobalSection(support::Stream* strm) const; /*! * \brief Save the memory scopes. * \param strm The output stream. */ void SaveMemoryScopeSection(support::Stream* strm) const; /*! * \brief Save the constant pool. * \param strm The input stream. */ void SaveConstantSection(support::Stream* strm) const; /*! * \brief Save the instructions. * \param strm The input stream. */ void SaveCodeSection(support::Stream* strm) const; /*! * \brief Save the packed functions. * \param strm The input stream. */ void SavePackedFuncNames(support::Stream* strm) const; /*! * \brief Load the globals. * \param strm The input stream. */ void LoadGlobalSection(support::Stream* strm); /*! * \brief Load the memory scopes. * \param strm The input stream. */ void LoadMemoryScopeSection(support::Stream* strm); /*! * \brief Load the constant pool. * \param strm The input stream. */ void LoadConstantSection(support::Stream* strm); /*! * \brief Load the instructions. * \param strm The input stream. */ void LoadCodeSection(support::Stream* strm); /*! * \brief Save the packed functions. * \param strm The input stream. */ void LoadPackedFuncNames(support::Stream* strm); }; } // namespace vm } // namespace runtime } // namespace tvm namespace tvm { namespace support { template <> struct Serializer<::tvm::runtime::vm::VMFuncInfo> { static constexpr bool enabled = true; static void Write(Stream* strm, const ::tvm::runtime::vm::VMFuncInfo& data) { data.Save(strm); } static bool Read(Stream* strm, ::tvm::runtime::vm::VMFuncInfo* data) { return data->Load(strm); } }; } // namespace support } // namespace tvm #endif // TVM_RUNTIME_VM_EXECUTABLE_H_