Hey there. Welcome to the first of what is going to be a series of blog posts chronicling my journey as I participate in the Google Summer of Code this year with RADIS (registered as a sub-org under OpenAstronomy). This particular blog post, as the title suggests, is meant to give a quick introduction to GSoC as well as my organization and the project.
What is Google Summer of Code?
Borrowing straight from it’s landing page, Google Summer of Code is a global program focused on bringing more student developers into open source software development. Students work with an open source organization on a 3 month programming project during their break from school. In other words, GSoC (as it is more commonly referred to) is a program sponsored by Google which aims to connect university students around the world with open source organizations in order to promote the open-source culture. The students get an opportunity to peek into the world of open source development, learn new skills and also get compensated for the work, quite generously. In turn, the organizations benefit from a few extra pairs of helping hands, using them for a wide array of issues, from refactoring code, to fixing existing bugs, and ofcourse, to add new features to the existing code base. It’s a great program and any college student interested in software development should definitely check it out. The website contains a lot more information here.
Now that’s clear, let me talk a little about the specific organization that I will be working with.
RADIS ∈ OpenAstronomy
While the most commmon way for organizations to participate in the program and request slots for GSoC is to register directly, many organizations, for various reasons, often come together under an umbrella organization and register for GSoC as one single unit. This bundling of organizations can happen on various basis, but the most common reason is that these organizations often work towards the same goal, or operate in the same domain. In my case, this is true as well. I applied for and got selected for GSoC with the OpenAstronomy organization, which as the name suggests is an umbrella organization meant to act as a central hub for all the great number of ‘sub-organizations’ that operate within it. You can read more about OpenAstronomy and what it does here. One such sub-organization, with which I shall be working, happens to be RADIS.
RADIS is a radiation software, a fast line-by-line code for synthesizing and fitting infrared absorption and emission spectra such as encountered in laboratory plasmas or exoplanet atmospheres.
While RADIS was written with performance in mind, and performance it delivers, it is still limited by factors such as the speed offered by Python, and using a single CPU to carry out all its calculations. While the problem with a programming language can be solved (not so) easily by switching to other languages, such as C++, we’re still limited to using a single processing unit to carry out all the computations. This is the exact problem that my project tries to solve. The title of my project, “Accelerate Synthetic Spectra Calculations using CUDA”, is all about removing the restriction of a single CPU and instead allow RADIS to perform much faster by utilising the power of a GPU instead. I will not be going into the detail of the project here/yet, but the general idea is to switch certain parts of the pipeline in RADIS’ execution which slow it down to the GPU, which as people familiar with GPUs would know, is adept at executing a large volume of simple tasks.
The technicalities of the project, including how exactly the problem can be shifted to the GPU, how its being implemented on the GPU, or its integration with the RADIS will be discussed in the future blog posts. For now, I will like to keep this blog limited to the things that have already occured, as a part of the ‘Community Bonding Period’:
The Community Bonding Period
The Community Bonding Period is an almost 30-days long period meant to serve as a warm-up or a buffer before the actual coding period begins. It can be used for a wide variety of purposes, such as getting a better understanding of the codebase, figuring out the intricacies of your project et al. As such, the greater part of my community bonding period went into understanding the exact details of what I will be doing over the coming months and how I will be doing it. While the pre-selection period did include a fair amount of contributions being made by me towards the organization, it was mainly an attempt to understand the general architecture and codebase of RADIS more thoroughly, and did not involve anything specific to the project I had applied for. Once the selected projects were made public on 4th May 2020, that is when the community bonding period officially started and I started to focus exclusively on my project as well. The seed idea that eventually led to my project started when my mentors decided to play around with the code, and instead of using pure Python for the processing, decided to precompile some of the slower parts of the code into a DLL and imported it to Python instead. The results of this experiment were incredible, and paved the way for my mentor, Dirk van den Bekerom to write the first proof-of-work code demonstrating the use of GPUs to calculate the spectras that were previously being done entirely on the CPU. Benchmarking showed performance boosts of upto 10,000x compared to the naive implementation of spectra calculations on Python and upto 50x from the current implementation of RADIS.
After discussing with my mentors, the project timeline was decided and the work was done accordingly. Keeping in mind my objectives for the coming month, as a part of the first evaluation, I decided to spend a lot of time on understanding the existing code base of RADIS which focuses on the spectra calculations. Note that this is completely different from the code that I worked on earlier, which focussed on issues completely different from this, and mostly revolved around the post-processing of spectra instead of calculating it. This included a light reading of the original RADIS paper which talked about the general idea and logic behind RADIS. In addition to that, I also spent time on setting up the right environment for the development work that was to come. Since the project is about GPUs and CUDA, I had to ensure that CUDA was properly installed and running on my system. While this might seem like a trivial task, it can easily get very messy when working on a linux distribution. Fortunately, I already had a working installation of CUDA on my system so I didn’t have to spend much time on it except for testing and tuning it. Another major issue that this project entailed was the handling of vast amounts of data.
To keep it simple, in order to calculate the spectra, RADIS requires some data. This data includes information on various parameters such as positions, intensities, air- and self-broadened half-widths, et cetera for different molecules. For my project, for the time being, I was using the CDSD-4000 database, which is a high-temperature databank for CO2 molecule. The major issue this databank presented was the vast size of it. While the complete databank would have been incredibly huge (but fortunately not needed) the portion of the databank that we did focus on was not a small package either, occupying 30GB space unprocessed. Further processing of this data reduced it down to 8GB. While that might seem like a manageable size, the issue was that in order to compute the spectra efficiently and reduce the latency in loading the data, all of it had to be stored on the device RAM. This requirement was simply not possible for me to satisfy with just my personal computer which has a NVidia GTX 1650 with only 4GB of VRAM. Thus, I was left with two options. To either trim the database further and then work on it, or find another machine with specifications high enough to crunch the numbers without trimming it down. After discussing with my mentors and weighing the pros and cons, I decided to try out both. We used Google Colab with its free GPU access to process the entire 8GB data in one go. The major problem we faced with this method was loading the data onto the colab server. Since even the processed files were 8GB, and Colab did not offer persistent storage, we would have to upload 8GB of data every time we wanted to test the code out, which ofcourse would not have been practical. This was solved by using Google Drive, which can be mounted in colab and work as a persistent storage setup. So far, I have thoroughly enjoyed the convenience and power offered by Colab, and that too for no charge, and hope it continues to perform so wonderfully. In addition, I also trimmed the original database down to smaller sizes and tried to process them on my personal machine, which it did without any hassles.
Another interesting question that we faced was the tools to use. While it might seem like a no-brainer to use C with CUDA, it unfortunately was not an option as RADIS was written in Python. Therefore, we had to spend a fair amount of time trying to figure out additions to Python in the form of libraries which allow CUDA access. A few of the many different options that are available for such purposes include using Cython, PyCUDA, Cupy, Numba, PyOpenCL and many more. The decision to pick one over the other is a very subjective one, and the answer mostly depends on the kind of application you’re trying to produce. For our particular project, the only requirement was to have access to constant memory on the device which can be achieved using Cython or PyCUDA. While I personally enjoyed PyCUDA due to its extensive documentation and support from NVidia, my mentor seems to prefer Cython so the final decision is still not here!
Apart from all this, I also spent a good amount of time studying the proof-of-work code that already exists. That included the differences from pure CPU code, the division of work between host and the device, and way the the actual calculations are being done in order to compute the spectra. Finally, I also spent a fair amount of time on revising my CUDA concepts in order to ensure there were no knowledge gaps.
That pretty much sums up my community bonding period! Over the coming 4 weeks, my objectives include reproducing the proof of work, and figure out the implementation details with my mentors. That will be followed by implementing one of the broadening steps in Python and integrating it with the RADIS.
I am quite excited about the upcoming months and my journey with RADIS. I believe it will be a great learning experience and I would like to thank Google, OpenAstronomy, RADIS, but most importantly, my incredibly helpful and fun mentors Erwan Pannier, Dirk van den Bekerom and Minesi N for giving me this wonderful opportunity!