Season of Docs 2020 Report Rohit Goswami: SymEngine - sympy/sympy GitHub Wiki

GSoD 2020 Report Rohit Goswami: SymEngine

This page summarizes the work carried out during the second cycle of the Google Season of Docs program for the SymEngine documentation project.

About Me

I am many things (doctoral researcher, FOSS maintainer, developer); but primarily, I am a prospective SymEngine user looking to channel its excellence in code into a form of meaningful, sustainable, and readable documentation.

Project Goals

At the onset of this project, SymEngine had no appreciable web presence and the documentation was scattered across code and header files, issues, tests, etc. The project proposal included:

  • Generating an end-to-end workflow for building documentation sites
  • Making SymEngine more accessible
    • For API documentation
    • For tutorials
    • For contributors
  • Adding examples

With such a broad mandate, project completion was defined in terms of standardization and proof-of-concept documentation.

Work Completed

Discussions

For a code base such as SymEngine, with its many language bindings, the documentation may seem As a consequence of having a fresh pair of eyes on the code with an eye towards documentation; in the first meeting itself Ondrej bought the official SymEngine domain name (https://symengine.org) and we began discussing the use cases for SymEngine.

API Documentation Platforms

Our first rounds of discussion centered around getting the langugage binding documentation live. We decided to stick to the best practices of each language:

  • R bindings with pkgdown
  • Python bindings with Sphinx
  • C++ bindings with doxygen
  • Julia bindings with documenter.jl

Consolidation

Having generated the API bindings, we began to focus on the experience of a new user. SymEngine can be a daunting project. We opted to create a new homepage exclusively for tutorials, geared at novices. This also makes it easier for people who want to contribute new tutorials as it describes a dedicated workflow for the same. Making this site was also a natural point in time to go over the existing documentation, editing and fixing dead links where appropriate.

Guidelines

With all the web presences live and running, we turned to the issue of establishing standards for the main C++ repository, and this resulted in the Doxygen style guide and tutorial workflows.

  • Each tutorial is built and tested by the CI
  • Tutorials must be reviewed every X days (with sphinx-dust)

Continuous Integration

During the course of my involvement, the dominant CI was changed from Travis to GitHub Actions. The API documentation workflows I set up were among the first of these Github Actions.

False Starts and Dead Ends

There was an attempt in the middle to consolidate all language bindings in a single site. This led to an aborted repository for testing the use of Sphinx instead of Doxygen for the main C++ library. Tooling has not yet reached a stage where Sphinx-Doxygen is comparable in functionality to vanilla Doxygen, so the repository was abandoned and I began to work on making Doxygen more pleasant (which resulted in the doxyYoda theme).

Results

Over the course of this season of docs, I added to every active repository of SymEngine. These are grouped by the repository. As per the best practices; an attempt was made to ensure that the PRs were clean and atomic; which means that multiple commits were squashed to make each feature branch add the minimal logical number of commits at the end.

Language Bindings

I implemented API binding documentation with packages discussed above and added a CI task with GitHub actions for the same.

N Pull Request Live Site Repository
1 #101: R Docs R API symengine.R
2 #335: Py Docs Python API symengine.py
3 #226: Julia Docs Julia API symengine.jl

The Python bindings have a build error unrelated to the documentation, which is being worked on.

SymEngine Core

My main contributions were the addition of interactive tutorials, the addition of a style guide, and testing of aforementioned tutorials.

N Pull Request Live Site Comments
1 #1726: Building Doxygen C++ API Involved restructuring
2 #1727: Doxygen Style Guide Style Guide Vetted over weekly calls
3 #1728: API Documentation Add Class Reference implementation
4 #1729: Notebook Tests N/A Built on symengine.github.io
5 #1730: flint bugfix N/A Fixes part of symengine.py

Relevant Issues

  • Rekindled discussion on Logos (#635)
  • Documented blind-spots in current TeX printer (#1701)

SymEngine Homepage and Tutorials

Documents generated

The homepage, and every other page on the site with the following exceptions:

Taken together the site now has a reasonable introduction to part of SymEngine and also has clear steps on how to follow along with the tutorials.

Addenum: Doxygen Theme

Also, as part of the season of docs, since there are a lack of maintained Doxygen themes, I wrote and released one of my own, which is used in the current Doxygen API for SymEngine.

Future Work

Having demonstrated and codified guidelines for writing both API documentation and interactive tutorials; and having consolidated the build process, the future is largely a matter of enforcement. We are now in a position to solicit interactive tutorials and we can expect that traditional computer algebra system courses might also now be adapted for use with SymEngine. The Doxygen API guidelines, once fully enforced, will further enhance the ease-of development.

However, no documentation is ever complete, and though I extended my project into a long running one; some goals are still just over the horizon.

One notable aspect of documentation not covered by this project was the best representation of benchmarks. SymEngine is much faster than the competition and the best way to display these results is an ongoing discussion.

With the tooling merged in, Ondřej expressed interest in working through short examples of SymEngine, as would be normally done in Mathematica or other CAS software. Once some of the pretty printer issues are ironed out, this is a direction which must be explored. This requires some guile in that Jupyter does not currently support multiple kernels in one notebook and not being able to plot the results is taxing. However, this is not insurmountable, and images (with the code used to generate them) can be put in the myst.md files.

More prosaically, the future tasks shall be:

  • Use add.h, the Add class, add.cpp (as reference implementations) and the Style Guide to document the API for each of SymEngine’s files
  • Add interactive tutorials (like the one for Matrices)
  • Add Sphinx docstrings to symegine.py
    • Add vignettes
  • Add inline documentation for symegine.R
  • Add symengine.jl examples
  • Demonstrate an example of code generation (as a tutorial)
  • Go over the Pull Requests and Tests to develop interactive tutorials for the tutorial site
  • Add performance features and benchmarks to the site

Conclusions

Writing technical documentation requires slaying the many headed beast which is comprised of the code, the generating system, and the test suites. SymEngine will turn ten next year; and I am very glad to have been able to go over much of the code under the fantastic guidance of my project mentors and the rest of the community. In particular, my interactions with Aaron Meurer, Amit Kumar, Isuru Fernando, Nihkil Maan, and Ondřej Čertík were uniformly positive and pertinent to the project.

Many of the problems relating to documentation for a program like SymEngine are far from being solved and the exploration of these were fodder for many blog posts of mine. I can only hope that the best practices we applied to the documentation will be of use to both future contributors and users. This was my largest documentation project, both in terms of code-base age and in terms of the number of languages used. The weekly meetings gave me a great sense of belonging and I am glad to be able to be part of the foundational development of the SymEngine documentation. I look forward to continuing as an active contributor to and user of SymEngine.

⚠️ **GitHub.com Fallback** ⚠️