/* * 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. */ /*! * Copyright (c) 2018 by Contributors * \file test_lib.cpp * \brief Test library for the VTA design simulation and driver tests. */ #ifndef TESTS_HARDWARE_COMMON_TEST_LIB_H_ #define TESTS_HARDWARE_COMMON_TEST_LIB_H_ #include <assert.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <vta/hw_spec.h> #ifdef NO_SIM #include <vta/driver.h> #ifdef VTA_TARGET_PYNQ #include "../../../src/pynq/pynq_driver.h" #endif // VTA_TARGET_PYNQ typedef uint64_t axi_T; typedef uint32_t uop_T; typedef int8_t wgt_T; typedef int8_t inp_T; typedef int8_t out_T; typedef int32_t acc_T; uint64_t vta( uint32_t insn_count, VTAGenericInsn *insns, VTAUop *uops, inp_T *inputs, wgt_T *weights, acc_T *biases, inp_T *outputs); #else // NO_SIM #include "../../../hardware/xilinx/src/vta.h" #endif // NO_SIM /*! * \brief Returns opcode string. * \param opcode Opcode parameter (defined in vta_defines.h). * \param use_imm Boolean that indicates if the operation uses an immediate value. * \return The opcode string. */ const char* getOpcodeString(int opcode, bool use_imm); /*! * \brief Performs buffer data packing and tiling. * \param dst Pointer to the packed, and tiled destination 1D array (flattened). * \param src Pointer to the unpacked source 2D array. * \param y_size Number of rows. * \param x_size Number of columns. * \param y_block Inner tiling along row dimension. * \param x_block Inner tiling along column dimension. */ template <typename T, int T_WIDTH> void packBuffer(T *dst, T **src, int y_size, int x_size, int y_block, int x_block); /*! * \brief Performs buffer data unpacking. * \param dst Pointer to the unpacked destination 2D array. * \param src Pointer to the packed, and tiled source 1D array (flattened). * \param y_size Number of rows. * \param x_size Number of columns. * \param y_block Inner tiling along row dimension. * \param x_block Inner tiling along column dimension. */ template <typename T, int T_WIDTH> void unpackBuffer(T **dst, T *src, int y_size, int x_size, int y_block, int x_block); /*! * \brief Allocates and initializes a 2D array in the heap. * \param rows Number of rows. * \param cols Number of columns. * \return Pointer to the 2D array. */ template <typename T, int T_WIDTH> T ** allocInit2dArray(int rows, int cols); /*! * \brief Allocates a 2D array in the heap. * \param rows Number of rows. * \param cols Number of columns. * \return Pointer to the 2D array. */ template <typename T> T ** alloc2dArray(int rows, int cols); /*! * \brief Frees a 2D array. * \param array Pointer to the 2D array to be freed. * \param rows Number of rows. * \param cols Number of columns. */ template <typename T> void free2dArray(T **array, int rows, int cols); /*! * \brief Allocates a 3D array in the heap. * \param rows Number of rows (dim 0). * \param cols Number of columns (dim 1). * \param depth Depth of the array (dim 2). * \return Pointer to the 3D array. */ template <typename T> T *** alloc3dArray(int rows, int cols, int depth); /*! * \brief Frees a 3D array. * \param array Pointer to the 3D array. * \param rows Number of rows (dim 0). * \param cols Number of columns (dim 1). * \param depth Depth of the array (dim 2). */ template <typename T> void free3dArray(T *** array, int rows, int cols, int depth); /*! * \brief Performs memory allocation in a physically contiguous region of memory. * \param num_bytes Size of the buffer in bytes. * \return Pointer to the allocated buffer. */ void * allocBuffer(size_t num_bytes); /*! * \brief Frees buffer allocated in a physically contiguous region of memory. * \param buffer Pointer to the buffer to free. */ void freeBuffer(void * buffer); /*! * \brief Returns a VTA reset instruction on a 2D patch of the register file. * \param type On-chip memory target. * \param sram_offset Offset in SRAM. * \param y_size Number of rows to reset (y axis). * \param x_size Number of elements per row to reset (x axis). * \param x_stride Stride along the x axis. * \param pop_prev_dep Pop dependence from previous stage. * \param pop_next_dep Pop dependence from next stage. * \param push_prev_dep Push dependence to previous stage. * \param push_next_dep Push dependence to next stage. * \return A VTAGenericInsn for a reset op. */ VTAGenericInsn reset2DInsn(int type, int sram_offset, int y_size, int x_size, int x_stride, int pop_prev_dep, int pop_next_dep, int push_prev_dep, int push_next_dep); /*! * \brief Returns a VTA 2D load or store instruction. * \param opcode Type of operation. * \param type On-chip memory target. * \param sram_offset Offset in SRAM. * \param dram_offset Offset in DRAM. * \param y_size Number of rows to load/store (y axis). * \param x_size Number of elements per row to load/store (x axis). * \param x_stride Stride along the x axis. * \param y_pad Padding along the y axis. * \param x_pad Padding along the x axis. * \param pop_prev_dep Pop dependence from previous stage. * \param pop_next_dep Pop dependence from next stage. * \param push_prev_dep Push dependence to previous stage. * \param push_next_dep Push dependence to next stage. * \return A VTAGenericInsn for a 2D load or store op. */ VTAGenericInsn get2DLoadStoreInsn(int opcode, int type, int sram_offset, int dram_offset, int y_size, int x_size, int x_stride, int y_pad, int x_pad, int pop_prev_dep, int pop_next_dep, int push_prev_dep, int push_next_dep); /*! * \brief Returns a VTA 1D load or store instruction. * \param opcode Type of operation. * \param type On-chip memory target. * \param sram_offset Offset in SRAM. * \param dram_offset Offset in DRAM. * \param size Number of elements to load/store. * \param pop_prev_dep Pop dependence from previous stage. * \param pop_next_dep Pop dependence from next stage. * \param push_prev_dep Push dependence to previous stage. * \param push_next_dep Push dependence to next stage. * \return A VTAGenericInsn for a 1D load or store op. */ VTAGenericInsn get1DLoadStoreInsn(int opcode, int type, int sram_offset, int dram_offset, int size, int pop_prev_dep, int pop_next_dep, int push_prev_dep, int push_next_dep); /*! * \brief Returns a VTA matrix multiplication instruction of size (a, b) x (b, c). * \param uop_offset Offset of the micro-op in SRAM. * \param batch Batch size (a). * \param in_feat Input features (b). * \param out_feat Output features (c). * \param uop_compression Apply micro-op compression. * \param pop_prev_dep Pop dependence from previous stage. * \param pop_next_dep Pop dependence from next stage. * \param push_prev_dep Push dependence to previous stage. * \param push_next_dep Push dependence to next stage. * \return A VTAGenericInsn for a GEMM op. */ VTAGenericInsn getGEMMInsn(int uop_offset, int batch, int in_feat, int out_feat, bool uop_compression, int pop_prev_dep, int pop_next_dep, int push_prev_dep, int push_next_dep); /*! * \brief Returns a VTA ALU instruction for map type operation. * \param opcode Opcode of the ALU instruction. * \param vector_size Vector size of the ALU operation size. * \param use_imm Use immediate. * \param imm Immediate value (int16). * \param uop_compression Apply micro-op compression. * \param pop_prev_dep Pop dependence from previous stage. * \param pop_next_dep Pop dependence from next stage. * \param push_prev_dep Push dependence to previous stage. * \param push_next_dep Push dependence to next stage. * \return A VTAGenericInsn for a ALU op. */ VTAGenericInsn getALUInsn(int opcode, int vector_size, bool use_imm, int imm, bool uop_compression, int pop_prev_dep, int pop_next_dep, int push_prev_dep, int push_next_dep); /*! * \brief Returns a VTA finish instruction. * \param pop_prev Pop dependence from previous stage. * \param pop_next Pop dependence from next stage. * \return A VTAGenericInsn for a finish op. */ VTAGenericInsn getFinishInsn(bool pop_prev, bool pop_next); /*! * \brief Returns an allocated buffer of VTA micro-ops to implement a copy operation. * \param y_size Number of rows to load/store (y axis). * \param x_size Number of elements per row to load/store (x axis). * \param uop_compression Apply micro-op compression. * \return A VTAUop pointer to an allocated micro-op buffer. */ VTAUop * getCopyUops(int y_size, int x_size, int uop_compression); /*! * \brief Returns an allocated buffer of VTA micro-ops to implement a matrix multiplication * of size (a, b) x (b, c). * \param batch Batch size (a). * \param in_feat Input features (b). * \param out_feat Output features (c). * \param uop_compression Apply micro-op compression. * \param multi_threaded Generate micro-ops for two virtual execution threads. * \return A VTAUop pointer to an allocated micro-op buffer. */ VTAUop * getGEMMUops(int batch, int in_feat, int out_feat, bool uop_compression, bool multi_threaded); /*! * \brief Returns an allocated buffer of VTA micro-ops to implement a vector-vector map operation. * \param vector_size Vector size. * \param uop_compression Apply micro-op compression. * \return A VTAUop pointer to an allocated micro-op buffer. */ VTAUop * getMapALUUops(int vector_size, bool uop_compression); /*! * \brief Print out parameters of the VTA design (for debugging purposes). */ void printParameters(); /*! * \brief Print out instruction information (for debugging purposes). * \param num_insn Number of instructions. * \param insns Pointer to the instruction buffer. */ void printInstruction(int num_insn, VTAGenericInsn *insns); /*! * \brief Print out micro-op information (for debugging purposes). * \param num_insn Number of micro-ops. * \param insns Pointer to the micro-op buffer. */ void printMicroOp(int num_uop, VTAUop *uops); /*! * \brief VTA ALU unit test. * \param opcode The ALU opcode. * \param use_imm Use immediate. * \param batch Batch size. * \param vector_size Vector length of the ALU operation. * \param uop_compression Apply micro-op compression. * \return Number of errors from the test run. */ int alu_test(int opcode, bool use_imm, int batch, int vector_size, bool uop_compression); /*! * \brief VTA blocked GEMM unit test. * \param batch Batch size. * \param channels Channel width. * \param block Blocking size. * \param uop_compression Apply micro-op compression. * \return Number of errors from the test run. */ int blocked_gemm_test(int batch, int channels, int block, bool uop_compression, int virtual_threads); /*! * \brief VTA GEMM unit test. * \param batch Batch size. * \param in_channels Input channels. * \param out_channels Output channels. * \param uop_compression Apply micro-op compression. * \return Number of errors from the test run. */ int gemm_test(int batch, int in_channels, int out_channels, bool uop_compression); #endif // TESTS_HARDWARE_COMMON_TEST_LIB_H_