Developing for ABINIT 5
This tutorial introduces ABINIT 5 to the new developers. We want here to give a first insight into the internals of ABINIT. In other words, you will look at what's under the cap. Being an ABINIT user is not required though it will help a lot, in particular when writing a test case for your contribution. However some experience in programming is necessary if you want to take maximum benefit from this lesson. In particular, some ease with Fortran 95 will be truly welcome. Familiarity with the command line will be wonderful too.
The ABINIT package is aimed at being used by different groups of people, without mandatory control by the main contributors of the ABINIT group. In the same way, the ABINIT development project is fundamentally open to the contributions of various persons, not located in Louvain-la-neuve or Corning. These external contributors are de facto members of the ABINIT group.
People using the code might consider adding their personal subroutines without trying to make them part of the official ABINIT package. However, this has two drawbacks for them: in subsequent versions, their modifications will not be incorporated, so that they might have to check and modify the interface for each new version; moreover, their addition is not tested by other users of the code, then some nasty bugs might remain unnoticed. Our opinion is that it would also be nicer from them to share the fruits of their coding efforts with other users of the code.
Of course, a collaborative effort has some drawbacks as well. In particular, the collaboration between distant developers should be carefully planned, since orthogonal modifications of the same piece of code by two different people at the same time is very likely to happen, generating "negative progress", i.e. a large waste of time when synchronization is to be done. It is also necessary to use a well-defined coding style, to provide test case files, and to comment the modifications and additions as much as possible, in order to facilitate the maintenance and the future modifications.
The procedure we usually follow is described on the web site in the "How to contribute" page, in the Developer's corner section.
The main goals of this lesson are to provide you with a useful understanding of the source tree structure and the build process, as well as sensibilize you to the rules and procedures followed for the development of ABINIT. In the example we have chosen, we will suppose that you want to add an input variable to the code and create the corresponding subroutine. For simplicity, we will now imagine that you have designed a new exchange-correlation functional and that you want to test it with ABINIT. Here are the steps we will take:
- Get the source and compile the code.
- Identify the subroutines to modify.
- Add the new input variable and its associated routine.
- Add a test to the test suite.
- Create a patch for the project leader.
For this lesson, your input variable will be a real number called "lesson". The task devoted to your routine is just to print this variable.
There are two ways of getting the source code of ABINIT:
- directly from the ABINIT web site (abinit.org/) by downloading the tarball;
- from the ABINIT forge, using Bazaar.
While the first method is straightforward, the second one requires you to know how to use BZR, Canonical's implementation of GNU Arch. There is a comprehensive tutorial for Bazaar on the ABINIT web site, in the Developer's corner section.
Once you have got the tarball, uncompress it by typing:
where <version> is the version number you downloaded, e.g. "5.3.2". Then go into the newly-created abinit-<version> directory and have a look at it. To get get more familiar with the source tree structure, have a closer look at the ~abinit/doc/developers/dirs_and_files file. You can alternatively consult it on the website (see "Developer's docs"). Then answer the following questions:
Q1. If you need off-line documentation, in which directories will you look for?
Q2. Where can be found the external libraries?
Q3. What do the numbers in the names of the "src" subdirectories stand for?
Q4. In the source subdirectories, what do the abinit.src files contain? In your opinion, what is their purpose?
Q5. What kind of tests are available? How important do you think they are?
Now you can try to build ABINIT. Information on how to do it is stored inside the INSTALL file. Please read it now.
Before actually starting the compilation, type:
The compilation will likely take more than 10 minutes. In the meantime, you can proceed to the next task.
At this point, you have to discover what parts of the code will have to be modified in order to have your contribution correctly integrated. First choose randomly a few subroutines in one of the "src/*" subdirectories and have a look at them, putting emphasis on their headers. Then try to answer the following questions:
Q6. How would you identify the subroutines involved in the treatment of input variables?
Q7. Where are the routines handling exchange-correlation? Which input variables are they strongly related to?
Q8. Which subroutine would you choose as a parent for yours?
Q9. Where is the wrtout subroutine? What is its purpose? How does it work?
Please read thoroughly the file ~abinit/doc/developers/programming_rules. This is an essential step before you start writing your own subroutine. To actually start, go to the subdirectory you've identified before and type:
Add treatment code for your input variable to the files you have identified previously. Then write your subroutine and add a call to it at a suitable place. When you're done, issue ./config/scripts/makemake from the top source directory, to have the build system aware of the presence of your new routine. Last but not least, rebuild abinit.
Since your contribution is to be integrated into the version 5 of ABINIT, all associated tests should go to the ~ABINIT/tests/v5/ directory. Wander a little bit around the subdirectories of tests/, and have a look at their content. Focus particularly on the README and tests.cnf files there. Each test is identified by an index, attributed after consulting the ABINIT coordinator. He decided that your contribution will be checked by test #999.
Q10. What do you need to do in order to have a new test added?
Implement your test and issue a make tests_v5 start=999 in the tests/ subdirectory, to check that it works fine.
There are two ways of creating a patch, depending on whether you are using Bazaar or not. If yes, you just have to register your new files, write a change log and commit your changes. This procedure is highly recommended, as it is very fast and as the project leader will be provided with a lot of flexibility and information to handle your contribution. If not, you have to create a patch with a full description of your changes and send it by email or ftp.
To get some comfort, the project leader needs a patch both in universal format and where new files are considered empty in the old version.
Q11. Which options will you give to the diff command to produce the patch ?
Q12. How will you proceed exactly to create it ?
> <h3><a name="solutions">Solutions<a>
Even if we provide you here with the answers to some of the questions, we highly recommend you to try by yourself before looking at them. Please read this section only as a last resort.
R1. In ~abinit/doc/, of course.
R2. ABINIT embeds a certain number of external libraries, which can all be found in ~abinit/lib/.
R3. According to ~abinit/doc/developers/dirs_and_files, they correspond to a hierarchical structuring of the dependencies within ABINIT. The higher the level, the more the dependencies on lower levels.
R4. They contain the list of source files to compile, and allow the developers to explore several ways at once by giving them the choice of what to put in ABINIT. Thanks to their presence, no developer needs know all the internals of the build system.
R5. The available documentation describes all tests in detail and stresses their importance quite enough. Just read the suggested files.
R6. First, I'll have a look at ~abinit/doc/developers/dirs_and_files, then I would issue a grep command for a random input variable in order to trace the handling of input variables throughout the code.
R7. These routines can be found in ~abinit/src/03xc, and are driven by the ixc input variable.
R8. The ~abinit/src/03xc/drivexc.F90 routine, for instance.
R9. Look in ~abinit/src/01managempi/wrtout.F90, the header contains detailed explanations.
R10. See self-documented ~abinit/tests/v5/tests.cnf for instance.
R11. "-u -r -N".
R12. Supposing that you have downloaded ABINIT 5.3.2, the following set of commands will do:
- cd /path/to/my/source/dir/abinit-5.3.2
- make distclean
- cd ..
- mv abinit-5.3.2 abinit-5.3.2-lesson
- tar xvzf /path/to/abinit/tarball/abinit-5.3.2.tar.gz
- mv abinit-5.3.2 abinit-5.3.2-orig
- diff -urN abinit-5.3.2-orig abinit-5.3.2-lesson > abinit-5.3.2-lesson.patch
- gzip --best abinit-5.3.2-lesson.patch
Note: in case you are using Bazaar, you will have to exclude the '.bzr*' files from the diff by adding "-x '.bzr*'" to the other options.