API Reference
When applications that use Intel intrinsic instructions are ported from the x86 architecture to the Kunpeng architecture, the instructions need to be further developed because the names and functions of AArch64 instructions are different from those of x86 instructions. Therefore, a huge porting workload is generated. In this project, common AVX instructions are encapsulated as independent modules to reduce repeated development workload. Even when AVX instructions are replaced by the corresponding NEON or SVE SIMD instructions, the instruction names and functions remain unchanged. You can import related header files to application software to call corresponding instructions.
AVX Instruction Class
AVX instructions are Intel intrinsic instructions applicable to the x86 architecture only. The instruction names and functions implemented by the AVX2KI library remain identical to those of the AVX instructions.
Create a testavx.cpp file.
Press i to enter the insert mode and add the following content to the file:
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "avx2ki.h" void AvxExample() { int32_t a[4] = {-5, 13, 4, -20}; int32_t b[4] = {12, 3, 0, 7}; int32_t c[4] = {0}; __m128i t1 = _mm_load_epi32(a); __m128i t2 = _mm_load_epi32(b); __m128i dst = _mm_add_epi32(t1, t2); _mm_store_epi32(c, dst); printf("dst: %d %d %d %d\n", c[0], c[1], c[2], c[3]); } int main(void) { AvxExample(); return 0; }Press Esc, type :wq!, and press Enter to save the settings and exit.
Compile the testavx.cpp file and specify the name of the output executable file as testavx.
g++ testavx.cpp -o testavx -I/usr/local/ksl/include -L/usr/local/ksl/lib -lavx2kiRun the testavx executable file.
./testavxThe execution result is as follows:
dst: 7 16 4 -13
AVX Operator Overloading Class
AVX operator overloading performs overloaded operations between AVX vectors. These operations include addition, subtraction, multiplication, division, addition assignment, subtraction assignment, multiplication assignment, and division assignment.
Addition:
__m128i operator + (const __m128i &a, const __m128i &b);
__m256i operator + (const __m256i &a, const __m256i &b);
__m256 operator + (const __m256 &a, const __m256 &b);
__m256d operator + (const __m256d &a, const __m256d &b);
__m512i operator + (const __m512i &a, const __m512i &b);
__m512 operator + (const __m512 &a, const __m512 &b);
__m512d operator + (const __m512d &a, const __m512d &b);
Subtraction:
__m128i operator - (const __m128i &a, const __m128i &b);
__m256i operator - (const __m256i &a, const __m256i &b);
__m256 operator - (const __m256 &a, const __m256 &b);
__m256d operator - (const __m256d &a, const __m256d &b);
__m512i operator - (const __m512i &a, const __m512i &b);
__m512 operator - (const __m512 &a, const __m512 &b);
__m512d operator - (const __m512d &a, const __m512d &b);
Multiplication:
__m128i operator * (const __m128i &a, const __m128i &b);
__m256i operator * (const __m256i &a, const __m256i &b);
__m256 operator * (const __m256 &a, const __m256 &b);
__m256d operator * (const __m256d &a, const __m256d &b);
__m512i operator * (const __m512i &a, const __m512i &b);
__m512 operator * (const __m512 &a, const __m512 &b);
__m512d operator * (const __m512d &a, const __m512d &b);
Division:
__m128i operator / (const __m128i &a, const __m128i &b);
__m256i operator / (const __m256i &a, const __m256i &b);
__m256 operator / (const __m256 &a, const __m256 &b);
__m256d operator / (const __m256d &a, const __m256d &b);
__m512i operator / (const __m512i &a, const __m512i &b);
__m512 operator / (const __m512 &a, const __m512 &b);
__m512d operator / (const __m512d &a, const __m512d &b);
AND:
__m128i operator & (const __m128i &a, const __m128i &b);
__m256i operator & (const __m256i &a, const __m256i &b);
__m256 operator & (const __m256 &a, const __m256 &b);
__m256d operator & (const __m256d &a, const __m256d &b);
__m512i operator & (const __m512i &a, const __m512i &b);
__m512 operator & (const __m512 &a, const __m512 &b);
__m512d operator & (const __m512d &a, const __m512d &b);
OR:
__m128i operator | (const __m128i &a, const __m128i &b);
__m256i operator | (const __m256i &a, const __m256i &b);
__m256 operator | (const __m256 &a, const __m256 &b);
__m256d operator | (const __m256d &a, const __m256d &b);
__m512i operator | (const __m512i &a, const __m512i &b);
__m512 operator | (const __m512 &a, const __m512 &b);
__m512d operator | (const __m512d &a, const __m512d &b);
XOR:
__m128i operator ^ (const __m128i &a, const __m128i &b);
__m256i operator ^ (const __m256i &a, const __m256i &b);
__m256 operator ^ (const __m256 &a, const __m256 &b);
__m256d operator ^ (const __m256d &a, const __m256d &b);
__m512i operator ^ (const __m512i &a, const __m512i &b);
__m512 operator ^ (const __m512 &a, const __m512 &b);
__m512d operator ^ (const __m512d &a, const __m512d &b);
Addition assignment:
__m128i &operator += (__m128i &a, const __m128i &b);
__m256i &operator += (__m256i &a, const __m256i &b);
__m256 &operator += (__m256 &a, const __m256 &b);
__m256d &operator += (__m256d &a, const __m256d &b);
__m512i &operator += (__m512i &a, const __m512i &b);
__m512 &operator += (__m512 &a, const __m512 &b);
__m512d &operator += (__m512d &a, const __m512d &b);
Subtraction assignment:
__m128i &operator -= (__m128i &a, const __m128i &b);
__m256i &operator -= (__m256i &a, const __m256i &b);
__m256 &operator -= (__m256 &a, const __m256 &b);
__m256d &operator -= (__m256d &a, const __m256d &b);
__m512i &operator -= (__m512i &a, const __m512i &b);
__m512 &operator -= (__m512 &a, const __m512 &b);
__m512d &operator -= (__m512d &a, const __m512d &b);
Multiplication assignment:
__m128i &operator *= (__m128i &a, const __m128i &b);
__m256i &operator *= (__m256i &a, const __m256i &b);
__m256 &operator *= (__m256 &a, const __m256 &b);
__m256d &operator *= (__m256d &a, const __m256d &b);
__m512i &operator *= (__m512i &a, const __m512i &b);
__m512 &operator *= (__m512 &a, const __m512 &b);
__m512d &operator *= (__m512d &a, const __m512d &b);
Division assignment:
__m128i &operator /= (__m128i &a, const __m128i &b);
__m256i &operator /= (__m256i &a, const __m256i &b);
__m256 &operator /= (__m256 &a, const __m256 &b);
__m256d &operator /= (__m256d &a, const __m256d &b);
__m512i &operator /= (__m512i &a, const __m512i &b);
__m512 &operator /= (__m512 &a, const __m512 &b);
__m512d &operator /= (__m512d &a, const __m512d &b);
AND assignment:
__m128i &operator &= (__m128i &a, const __m128i &b);
__m256i &operator &= (__m256i &a, const __m256i &b);
__m256 &operator &= (__m256 &a, const __m256 &b);
__m256d &operator &= (__m256d &a, const __m256d &b);
__m512i &operator &= (__m512i &a, const __m512i &b);
__m512 &operator &= (__m512 &a, const __m512 &b);
__m512d &operator &= (__m512d &a, const __m512d &b);
OR assignment:
__m128i &operator |= (__m128i &a, const __m128i &b);
__m256i &operator |= (__m256i &a, const __m256i &b);
__m256 &operator |= (__m256 &a, const __m256 &b);
__m256d &operator |= (__m256d &a, const __m256d &b);
__m512i &operator |= (__m512i &a, const __m512i &b);
__m512 &operator |= (__m512 &a, const __m512 &b);
__m512d &operator |= (__m512d &a, const __m512d &b);
XOR assignment:
__m128i &operator ^= (__m128i &a, const __m128i &b);
__m256i &operator ^= (__m256i &a, const __m256i &b);
__m256 &operator ^= (__m256 &a, const __m256 &b);
__m256d &operator ^= (__m256d &a, const __m256d &b);
__m512i &operator ^= (__m512i &a, const __m512i &b);
__m512 &operator ^= (__m512 &a, const __m512 &b);
__m512d &operator ^= (__m512d &a, const __m512d &b);
| Parameter | Description | Value Range | Input/Output |
|---|---|---|---|
| a | Reference to the instruction vector data type. | Unrestricted | Input/Output |
| b | Reference to the instruction vector data type. | Unrestricted | Input |
Instruction vector data of the same type as the input parameters.
- The header file
operatoroverload.hmust be included to use the operator overloading functions. - Operator overloading functions support C++, while instruction functions support both C and C++.
Create a testavx.cpp file with the following content.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "avx2ki.h" #include "operatoroverload.h" void OperatorExample() { int64_t a[2] = {-5, 13}; int64_t b[2] = {12, 3}; int64_t c[2] = {0}; __m128i t1 = _mm_load_epi64(a); __m128i t2 = _mm_load_epi64(b); __m128i dst = t1 + t2; _mm_store_epi64(c, dst); printf("dst: %ld %ld\n", c[0], c[1]); } int main(void) { OperatorExample(); return 0; }Perform compilation.
g++ testavx.cpp -o testavx -I/usr/local/ksl/include -L/usr/local/ksl/lib -lavx2kiOutput:
dst: 7 16
Kunpeng System Class
Obtains the AVX2KI version information.
Avx2kiResult AVX2KI_GetProductVersion(Avx2kiProVersion *packageInfo);
| Parameter | Description | Value Range | Input/Output |
|---|---|---|---|
| packageInfo | Pointer to the product information structure. | Not null | Input/Output |
- Success: Returns
AVX2KI_STS_NO_ERR. - Failure: Returns an error code.
| Error Code | Description |
|---|---|
| AVX2KI_STS_NULL_PTR_ERR | Avx2kiProVersion is a null pointer. |
Create a testavx.cpp file with the following content.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include "avx2ki.h" #include "operatoroverload.h" void GetProductVersionExample() { Avx2kiProVersion versionGet; Avx2kiResult result = AVX2KI_GetProductVersion(&versionGet); if (result == AVX2KI_STS_NO_ERR) { printf("Product Name: %s\n", versionGet.productName); printf("Product Version: %s\n", versionGet.productVersion); printf("Component Name: %s\n", versionGet.componentName); printf("Component Version: %s\n", versionGet.componentVersion); printf("Component AppendInfo: %s\n", versionGet.componentAppendInfo); printf("Software Name: %s\n", versionGet.softwareName); printf("Software Version: %s\n", versionGet.softwareVersion); } } int main(void) { GetProductVersionExample(); return 0; }Perform compilation.
g++ testavx.cpp -o testavx -I/usr/local/ksl/include -L/usr/local/ksl/lib -lavx2kiOutput:
Product Name: Kunpeng Boostkit Product Version: 23.0.RC2 Component Name: BoostKit-ksl Component Version: 1.0.0 Component AppendInfo: gcc Software Name: boostkit-ksl-avx2neon Software Version: 1.0.0The version number and build time in the example above are for reference only.