Initial Implementation of SPO600 Project - Stage II
Introduction:
Hello everyone, I am writing this blog about the stage II of my SPO600 Project. In this stage, I implemented a initial version of proof-of-concept tool to setup and build the function using auto-vectorization.
This tool create three version of the function which is provided as second argument. Then this tool uses ifunc capability to choose the best method while building the main output file from these functions. To learn more about the purpose or concept of the tool please read my previous blog on this link.
I wrote the tool in python, while the ifunc resolver function itself is in the c language. I will explain the working mechanism and limitations of tool along with procedure to test the tool in this blog.
Access to Tool:
Tool is hosted at a github repository. You can get the tool at https://github.com/NishanSingh6/SPO600-Project. Tool is licensed under the terms of the GPL version 2.
There are two main files of the tool:
- tool.py: this is the main tool which is written in python and build the function and produce the output binary files using best SIMD implementation.
- template.txt: this is text file which contains the template for the ifunc function which also contains resolver function for the ifunc. This template is used to create ifunc.c file.
Deliverables:
- main: this is main the output binary file.
- ifunc.c: this is a c file which contains the ifunc function, this is the resolver which selects the best version SIMD implementation at run time.
- ifunc.h: this is the header file for ifunc.c, this contains prototypes of the functions.
- function1.c: this is the first version of function for ASIMD.
- function2.c: this is the second version of function for SVE.
- function3.c: this is the third version of function for SVE2.
- function1.o: output file created after building function1.c
- function2.o: output file created after building function2.c
- function3.o: output file created after building function3.c
- build.sh: bash script file which contains series of gcc commands for building function output files along with main binary output file. This is executed by tool to build and link all the output files.
Limitations:
This is initial implementation of the tool, due to which it have several bugs and limitations. I will fix these limitations and bugs in the final version of the tool in Stage III of project. Following are the limitations and conditions:- The very first limitation of the tool is that is accepts only two arguments. First argument must be main.c file and second argument must be .c file which contains the function which needs to be vectorized. This tool does not have proper exception handling or any input data validation, due to which if any arguments are invalid or they are in wrong order or second argument does not contains the single function then this tool will break and will not work properly.
- The second and most important limitation of the tool is that for now it only accepts the function with name "adjust_channels". The function which needs to be vectorized must be named adjust_channels. This tool will work only if function which needs to vectorized is void, it does not return anything. If second argument does not contain the function with name adjust_channels then the tool will not work properly.
- The third major limitation of the tool is that arguements of function which needs to be vectorized (adjust_channels for now) should be only built-in data types. These should not contain any user-defined data types such as structs or classes.
- Other than these, this tool has some minor bugs along with permitted limitations. These permitted limitations are described in my previous blog, you can find my previous blog on this link.
Working Mechanism:
Step 1
Step 2
Step 3
Step 4
#include "ifunc.h" | |
#include <sys/auxv.h> | |
#include <stdio.h> | |
## | |
__attribute__(( ifunc("resolver") )); | |
#sve2{ | |
#fsve2 | |
} | |
#sve{ | |
#fsve | |
} | |
#asimd{ | |
#fasimd | |
} | |
static void (*resolver(void)) { | |
long hwcaps = getauxval(AT_HWCAP); | |
long hwcaps2 = getauxval(AT_HWCAP2); | |
if (hwcaps2 & HWCAP2_SVE2){ | |
return sve2; | |
} else if (hwcaps & HWCAP_SVE){ | |
return sve; | |
} else { | |
return asimd; | |
} | |
}; |
Step 5
Step 6
gcc -g -O3 -march=armv8-a -c function1.c -o function1.o
gcc -g -O3 -march=armv8-a+sve -c function2.c -o function2.o
gcc -g -O3 -march=armv8-a+sve2 -c function3.c -o function3.o
And then I added last gcc command to link all the files to build final output binary file - main.Testing:
License:
This tool is released under the terms of the GPL version 2.
Gcc strings and commands were provided by professor.
I used code for ifunc.c to create template from the https://github.com/ctyler/ifunc-aarch64-demo/blob/main/ifunc-test.c which is released under GPL version 2+.
Rest of code in tool.py was completely written by me.
Comments
Post a Comment