As explained in the introduction, the lowest level of the libraries is a set of APIs which are created to create a closest mapping possible between NumPy and the C++ SIMD APIs of the AI Engine. The APIs resulted are a more comprehensive and easy interface for the user to create its own application using numpy-like interfaces. The APIs can be divided in two main groups:
- Element-wise operations between vectors and matrices. Those operations varies between basic operations (i.e. sum, multiplication etc…) to more complex ones (i.e. reciprocal, sign etc…);
- Vector managing and creation. Those operations are intended to be used by the user to create or modify the dimension of the vectorial operands. Two example of those operations are Tile and Ones.
The APIs are written in a templatic way, such that the user might parametrize the length of the operands or of the SIMD operations to suites the necessities of the customers. Last remark, before starting with the single kernels explanation, is the nomenclature used in the kernels. The kernels are thought to be used as the user would do in NumPy, but on contrary respect to what is possible in python, in C++ the dimensionality of the operands must be known a priori to write approriate and correct operations. For common DSP and BLAS application, such as Ultrasound Imaging, it is very important to control the dimensionality of the data, in order to build appropriate applications. For this reason the kernels have been written in the following way:
The first part of the name indicates the type of operation chosen. The second and the third parts of the names of the interface are optional, depending on the number of operands of the operation. Provided that they are two, the letter S/V/M indicates their dimensionality. S stands for Scalar, V for Vector and M for Matrix. To give an example, mulMV is the operation which multiplies (element-wise) the rows of a Matrix (as first operand, M) with a Vector of the same dimension (as second operand, V). Another example is diffSV which is the operation which substract a scalar value (as first operand, S) to every element of a Vector (as second operand, V).
We now detail every L1 kernel available in the library: