Final Implementation of SPO600 Project - Stage III

Introduction:

Hi everyone, I am writing this blog about the stage III of my SPO600 Project. This project is about developing proof-of-concept tool to build the function using auto-vectorization. This is a follow up of stage II, in which I implemented initial version of the tool. The tool is written in python.

In Stage II, I was able to develop the tool which was able to successfully produced the working output binary file. But stage II had many bugs and limitations, in this final stage of the project, I fixed those bugs and solved those limitations. This is the final version of the tool which successfully builds the function. To learn more about the project or about the stage II implementation, please revisit my previous blog on this link.

Access to tool:

I updated the final version of tool on my previous github repository, which previously hosted stage II implementation. You can get the tool at https://github.com/NishanSingh6/SPO600-Project.

The tool is released under GPL version 2. Similar to stage II, final version has two main files - tool.py and template.txt. Both files must be present in the same directory for tool to work properly. Do not alter the content of template.txt, it will be break the tool. Content of template.txt is not updated since the stage II, it is almost same.

Improvements:

In the final version, I implemented solution and resolves to all the limitation listed in my previous blogs. However, I was not able to overcome the permitted limitations. You can read about these permitted limitations at this link.

The first limitation of the previous implementation was that it does not had exception handling. In the final version, tool supports exception handling and data validation. While reading the arguments, if invalid arguments are provided then tool will display appropriate message. Also, throughout the code while reading or writing files, tool handles various exceptions. Tool will check if template.txt file is missing or invalid and notify the user. This makes difficult for tool to break.

The second and most important limitation was that stage II only accepted function with the name "adjust_channels" and return type was void. Now this limitation is completely eliminated. Final version of tool accepts the function with any name and any return type, it is not limited to functions with name "adjust_channels". I was able to accomplish this by the guidance of my professor. I used makeheaders utility to produce header file and extract the name from there. I will talk about it, in upcoming sections.

The third limitation was that, stage II only accepted the parameters of built-in data type for the function which need to be vectorized. If there was any parameter with user defined data type then tool was not able to produce the successful ifunc.c file with working resolver. To eliminate this issue, I decided to use the user input. Now, tool will ask for user input to enter the user defined data types separated by ','.

By eliminating these limitations, now tool is more effective and it will run for any function with any name and any parameters. However, I did not had enough time to overcome permitted limitation such as make the tool working for x86_64 systems. 

About the tool:

Except fixing these limitations and bugs, I added many more features in the tool which will make it more easier for user to use it. 

First of all, working mechanism of the tool is almost similar to the stage II. 

  • At first tool will read the arguments (main.c and function.c), and it store the content of second argument in a local variable. 
  • Then it will run bash command "makeheaders", which will make header file for the function.c. This header file ("function.h") will contain the prototype of the function. 
  • It will read the header file and extract the prototype and function name and store them in the respective variables
  • The next step is to change the function name three times, each time for each SIMD implementation and save them three times. Then these updated functions are written in three separate files (function1.c function2.c function3.c)
  • Then similarly, three different versions of the function prototypes are created and saved in a ifunc.h file. Which is the header file for ifunc.
  • Now, in the next step ifunc.c (Resolver function is created). To do this, I first created template.txt which contains most of the resolver function (ifunc) with some place holders #. I replace these placeholders with three versions of function prototypes.
  • After updating the ifunc, I wrote it in ifunc.c file, this will be the resolver which will pick the best SIMD implementation at run time.
  • Then I wrote the gcc commands to build the three versions of the function
  • Then I wrote the gcc command to link all the output file and compile ifunc.c and build the main output binary file
  • Then I created a build.sh - bash script file, this file will contain all the gcc commands and I used bash command to run this script file to build the function.
To learn more about the functionality and buiding mechanism in-debth, please read my previous blog on stage II at this link. In previous blog, I have explained these gcc commands and other mechanism for building in depth.

I added additional features. When I was testing this tool it created several files after running, I found some of these files unnecessary and did not wanted them every time. So I decided to give the user a option to keep or remove some files after building the main output binary file. 

I gave them two options:

  1. In the first option, tool will ask for user input, if user want to keep function output files (function1.o, function2.o, function3.o). User will either enter Y or N. If user enters N, then tool will delete these files.
  2. In the second option, tool will ask for user input, if user want to keep three versions of function (function1.c, function2.c, function3.c ). User will either enter Y or N. If user enters N, then tool will delete these files.
So number of files produced will depend on user decisions, but I decided that build.sh is always be unnecessary, so tool will always remove it after building.

Almost all of the code in tool.py is written by me, however I used code for ifunc from https://github.com/ctyler/ifunc-aarch64-demo/blob/main/ifunc-test.c, which is available under GPL version 2+. For creating template.txt, I used code form above listed link, which was provided by professor. Also, idea for using makeheaders was also provide by professor which made it possible for me to overcome these limitation and finish this project.

Testing:

To test the tool please visit this link to read my other blog about testing.


Comments

Popular posts from this blog

Review of 2 Open Source Softwares

Testing for Stage II for Project