Platform-aware programming in Julia

07/28/2022, 7:00 PM — 7:30 PM UTC
Purple

Abstract:

Heterogeneous computing resources, such as GPUs, TPUs, and FPGAs, are widely used to accelerate computations, or make them possible, in scientific/technical computing. We will talk about how loose addressing of heterogeneous computing requirements in programming language designs affects portability and modularity. We propose contextual types to answer the underlying research questions, where programs are typed by their execution platforms and Julia's multiple dispatch plays an essential role.

Description:

The importance of heterogeneous computing in enabling computationally intensive solutions to problems addressed by scientific and technical computing applications is no longer new. In fact, heterogeneous computing plays a central role in the design of high-end parallel computing platforms for exascale computing. For this reason, the Julia community has concentrated efforts to support GPU programming through the JuliaGPU organization. Currently, there are packages that provide the functionality of existing GPU programming APIs, such as OpenCL, CUDA, AMD ROcm, and OneAPI, as well as high-level interfaces to launch common operations on GPUs (e.g. FFT). In particular, OneAPI is a recent cross-industry initiative to provide a unified, standards-based programming model for accelerators (XPUs).

In our work, it is convenient to distinguish between package developers and application programmers, where the former provide the high-level functionality necessary for later ones to solve problems of interest to them. Both are interested in performing computations as quickly as possible, taking advantage of hardware features often purchased by application programmers from IaaS cloud providers. Thus, since application programmers prefer packages enabled to exploit the capabilities of the target execution platform, package developers are interested in optimizing the performance of critical performance functions by noting the presence of multicore support, SIMD extensions, accelerators, and so on. In fact, considering hardware features in programming is a common practice among HPC programmers.

However, to deal with the large number of alternative heterogeneous computing resources available, package developers deal with portability, maintenance, and modularity issues. First, they need APIs that allow them to inspect hardware configurations during execution. However, there is no general alternative, as they alone do not cover all the architectural details that can influence programming decisions to accelerate the code. To avoid this, developers can give application programmers the responsibility of selecting the appropriate package version for the target architecture, or ask them to provide details about the target architecture through parameters, making programming interfaces more complex. Second, package developers are often required to interlace code for different architectures in the same function, making it difficult to make changes as accelerator technology evolves, such as when implementations should be provided to new accelerators. A common situation occurs when the programming API is deprecated, as has been the case with some Julia packages that use OpenCL.jl (e.g. https://github.com/JuliaEarth/ImageQuilting.jl/issues/16).

We argue that the traditional view of programming language designers that programs should be viewed as abstract entities dissociated from the target execution platform is not adequate to a context in which programs must efficiently exploit heterogeneous computing resources provided by IaaS cloud providers, eager to sell their services. In fact, these features may vary between runs of the same program, as application programmers try to meet their schedules and satisfy their budget constraints. So, the design of programming languages should follow the assumption that the software is now closely related to the hardware on which it will run, still making it possible to control the level of independence in relation to hardware assumptions through abstraction mechanisms (in fact, independence in relation to the hardware is still needed most of the time). For that, we propose typing programs with their target execution platforms through a notion of contextual types.

Contextual types are inspired by our previous work with HPC Shelf, a component-based platform to provide HPC services (http://www.hpcshelf.org). Surprisingly, they can free application programmers from making assumptions about target execution environments, focusing that responsibility on package developers in a modular and scalable way. In fact, contextual types help package developers write different, independent methods of the same function for different hardware configurations. In addition, other developers, as well as application programmers, can provide their own methods for specific hardware configurations not supported by the chosen package. To do this, the runtime system must be aware of the underlying features of the execution platform.

We chose Julia as the appropriate language to evaluate our proposal for two main reasons. Firstly, Julia was designed with HPC requirements in mind, as it is primarily focused on scientific and technical computing applications. Second, it implements a multiple dispatch approach that fits contextual types into the task of selecting methods for different hardware configurations. In fact, multiple dispatch has a close analogy with HPC Shelf's contextual contract resolution mechanism.

Platinum sponsors

Julia ComputingRelational AIJulius Technology

Gold sponsors

IntelAWS

Silver sponsors

Invenia LabsBeacon BiosignalsMetalenzASMLG-ResearchConningPumas AIQuEra Computing Inc.Jeffrey Sarnoff

Media partners

Packt PublicationGather TownVercel

Community partners

Data UmbrellaWiMLDS

Fiscal Sponsor

NumFOCUS