Why do scientific simulation software users put up with build-time configuration and environment assumptions that increase the complexity of debugging and complicate the installation? This is the question that researchers at Argonne National Laboratory and the University of Chicago recently posed in the journal Computing in Science & Engineering.
The authors argue that many common approaches to configuration and extensibility – setting the dataset sizes or number of processors to use in the computation at compile time (as opposed to runtime), for example, or hard-coding parameters into a model – create artificial bottlenecks that impede science goals.
“Application developers need to think more like library developers,” says Barry Smith, senior computational mathematician at Argonne.
What does that mean? Smith and his coauthors provide several suggestions, based on their experience developing and supporting PETSc, the Portable, Extensible Toolkit for Scientific Computation, as well as other packages. They note that users can allocate resources (e.g., memory) locally, use plug-ins to avoid source-level dependencies, and defer precise configuration to the runtime interface.
More contentious is deciding what model of object instantiation to use, that is, deciding when and how the specific types of the objects are set and whether they can be changed later. The authors consider several popular practices. For example, with typical C++ class usage implementation changes are often restricted to the time of object creation, that is, at compile time. Object factories introduce additional objects that produce the needed objects at runtime, allowing one to delay the decision making until runtime for what specific types of objects are used (e.g., from multigrid to a direct solve). But this approach introduces additional complexity (managing the various factories) and still imposes restrictions that require keeping track of dependencies between objects and reconfiguring the dependencies when replacing an existing object. An alternative, which has been used successfully in PETSc, is to allow objects to be able to change implementations at any time while retaining all information about the relationships (dependencies) between objects (in object-oriented programming languages this can be done using delegator objects).
Besides focusing on software development, the authors tackle the question of software maintenance. “Maintainers should nurture a community that can review contributions, advise about new development approaches, and test new features, with recognition for all forms of contribution,” says Jed Brown, an assistant computational mathematician at Argonne and an active PETSc developer. Of course, in such an open community, versatile extension points must be provided so that contributions can be made without affecting existing functionality and without degrading package maintainability. “This should be thought of as a technical prerequisite for maintainable extension,“ says Brown.
Scientific simulations are involving increasingly deeper levels of abstraction and deeper software stacks. To accommodate these needs, application developers must defer decisions about configuration and environment to run time. In short, says Smith, “The most effective way to increase scientific and engineering value is for application codes to become more library-like.”
For more information, see J. Brown, M. G. Knepley, and B. F. Smith, “Run-Time Extensibility and Librarization of Simulation Software,” Computing in Science and Engineering, 2014, DOI: 10.1109/MCSE.2014.95.