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.
In order for tool to work both the files must be present under the same directory, do not alter or change the content of template.txt file because it is crucial in building the ifunc.c file.

Deliverables:

This tool is used to create the main output binary file. But along with it will also create several output files or c files. Following is the list of files created after the execution of tool

  • 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.
If these conditions are met properly then this tool will run properly and create the binary output file along with above described deliverables.

Working Mechanism:

This tool performs various tasks. We can divide the working mechanism of this tool into multiple steps.

Step 1

The first step is to read the function.c file which was given as the second argument. But before that this I used sys library to access array of arguments using sys.argv. By doing so I was able to get the filename for both first and second arguments. By doing this I stored name of both the files in two variables. Then I used open() function to read the function.c file (which contains the function)

Then I used string.find() and string.replace() to change the name of the function.

Step 2

After reading the function, I changed the function name along with print f function three times. For Advanced SIMD, I added _asimd suffix in function name ( which is "adjust_channels" in this case). Similarly I added _sve, and _sve2 for SVE and SVE2 respectively. Then I replaced the printf by writing appropriate message in each of the function.

After altering the function 3 times, I wrote it 3 times in files function1.c. function2.c and function3.c. By doing so, tool was able to create three versions of function.

Step 3

Next step was to create ifunc.h header file. To do this I needed the prototype for the functions. I extracted the prototype by using .find(). I extracted the prototype for all 3 functions and stored them in three variables. Then I concatenated all three prototypes and wrote them into new file "ifun.h". As a result header file ifunc.h was created.

Step 4

Now it time was to create ifunc.c file. To do this I first created a template. To create a template I used the open source code for the resolver which was provided by professor. This code was released under GPL version 2+. Here is the link to the code - https://github.com/ctyler/ifunc-aarch64-demo/blob/main/ifunc-test.c .

I used this some portion of this function created template and saved it in the "template.txt". Then I wrote some place holders for replacing them function prototypes later. 

Here is the template:
#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

Then in tool.py, I read this template.txt file to read the template and stored it in variables. Then I used .replace() to replace place holders which are prefixed by #. I modified the prototypes which I extracted earlier form all three functions and placed them in the template.

After placing all the data in the template, I wrote that in the ifunc.c. That way, I created ifunc.c which includes resolver function.

Step 6

Last step was to build three functions to produce three output files and then link those output files using ifunc to create the main binary output file. I decided to this by generating a bash script. I created "build.sh" file, this file contains gcc commands.

Following are the commands to build three versions of functions:

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.

Then I executed this "build.sh" to generate all the output files.

By using the listed mechanism, tool is able to use ifunc capability to generate output binary using best SIMD implementation.

Testing:

To test the tool please visit this link to read my other blog about 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

Popular posts from this blog

Review of 2 Open Source Softwares

Final Implementation of SPO600 Project - Stage III

Testing for Stage II for Project