Closing the Parallelism Gap with the Chapel Language
Chapel is a high-level parallel programming language being developed by Cray for DARPA’s High Productivity Computing Systems (HPCS) program. The goal of the language is to increase programmer productivity for large-scale computing platforms.
An all-day Chapel tutorial and a joint PGAS tutorial with X10 and UPC were conducted this week at SC08 by Brad Chamberlain, the technical lead for the Chapel language project, along with Steven Deitz, David Iten and Samuel Figueroa. We asked Chamberlain to give us an overview of the language, the rational behind its design, and an update on the current state of the Chapel effort.
HPCwire: What problem is Chapel designed to solve?
Chamberlain: In the broadest terms, Chapel is being designed to make parallel programmers more productive. In designing the language, our goal is to support the elegant expression of parallel algorithms without sacrificing the performance and portability enjoyed by MPI programmers today. This is obviously a challenging goal, yet it’s one that we have had successes with previously, and it’s a primary motivator in our work with Chapel.
More specifically, we are designing Chapel to be a very general parallel language. If you have any parallel algorithm in mind, you ought to be able to express it in Chapel without running into some limitation in the language that forces you to go back to the parallel programming model that you were using previously. This is a fairly significant departure from many of the previous parallel languages that have inspired our work, in that most of them have tended to address only one specific portion of the parallel computing space — data parallelism, say — without offering much for algorithms that require other styles of parallelism such as task-parallelism, concurrent programming, or a combination of all three. Focusing on a restricted problem domain is a reasonable (and wise) approach to take in an academic project, but in order to create a parallel language with any chance of being broadly adopted and used, we believe that greater generality and applicability is necessary.
Chapel’s support for general parallel programming also means that the language is applicable to general levels of parallelism within software and hardware. Most applications contain opportunities for parallelism at multiple levels within the program’s structure: modules, functions, statements, and expressions. Yet most existing parallel programming models only support a single level of software parallelism — say, cooperating executables — requiring the user to mix in additional programming models and notations in order to express parallelism at other levels. This raises a significant barrier to expressing and exposing all of the parallelism within an application. Similarly, parallel computers support concurrency at many levels: across machines, across multiple nodes within a machine, across the processor cores within a node, and even within the core in the form of vector instructions, multithreading, or other forms of instruction-level parallelism. We are designing Chapel’s features so that an application’s parallelism can take advantage of all of these levels of architectural parallelism.
Finally, Chapel is being designed to solve the generation gap that exists between mainstream and parallel languages. Students today graduate with experience in languages like Java, C#, Perl, Python, and MATLAB, yet if they enter the HPC workforce, they are likely to find themselves programming in Fortran, C, and, if they are lucky, C++. Chapel is being designed to bring some of the concepts and philosophies found in modern mainstream languages into the HPC arena, and to do so without disenfranchising programmers who are most comfortable in traditional languages like C and Fortran. This is a bit of a balancing act, but based on comments from both camps, we are optimistic that we’ve designed a language that’s palatable to both perspectives.
HPCwire: In layman’s terms, can you give us a brief overview of the language?
Chamberlain: Chapel has four main feature areas: the base language, its task-parallel features, its data-parallel features, and features for controlling locality. The base language consists of all of the features that you would traditionally expect to find in a sequential programming language: types, variables, expressions, statements, functions, and so forth. We very intentionally decided not to make Chapel an extension of an existing language, yet the base language features should be familiar to anyone who has programmed in languages like C, C++, Java, or Fortran. It’s worth mentioning a few of the departures from these languages as well: Chapel has support for iterators in the CLU or Ruby sense of the term — functions that generate a stream of values during their execution rather than a single return value, making them useful for driving loops. Chapel also supports the option to elide type specifications in many contexts such as variable declarations or formal argument lists. This supports code reuse and exploratory programming as in most scripting languages. Unlike scripting languages, all Chapel variables have a fixed, static type in order to avoid runtime overheads.
Chapel’s task-parallel features support the ability to create a number of tasks running concurrently in structured and unstructured ways. These tasks can coordinate with one another through the use of synchronization variables which support a “full/empty” state in addition to their normal value. By default, reads and writes on these synchronization variables block until the variable is full/empty, providing a more elegant means of coordinating than traditional locks and semaphores. Chapel’s data parallel features are built around a rich set of array types including multidimensional, strided, sparse, and associative arrays. Parallel loops can be used to iterate over an array’s indices or elements, and scalar functions can be promoted which applies them to array values in parallel.
Finally, since the placement of data and tasks can be so critical to achieving performance on large-scale systems, Chapel supports a set of locality features that permit users to reason about the machine resources on which their programs are executing. This is supported through the concept of a locale — a built-in type in Chapel that represents a unit of architectural locality such as an SMP node or multicore processor in a commodity cluster. Users can specify the locale on which each variable is stored, and can direct tasks to execute on a specific locale either explicitly or in a data-driven manner. Finally, Chapel’s arrays can be distributed across multiple locales, causing any data parallel operations on the array to automatically be executed in parallel by all of the locales owning a piece of it.
HPCwire: What are the major differences between Chapel and the other two original HPCS languages, X10 and Fortress?
Chamberlain: Chapel has similarities to X10 and Fortress, but there are numerous differences between the three languages as well. Compared to X10, Chapel tends to make less of a distinction between remote and local data. For example, if a Chapel task running on locale 0 wants to access a variable stored on locale 1, it can do so simply by naming the variable, relying on the compiler and runtime to provide the communication necessary to implement the remote reference. In contrast, X10’s semantics were designed to make such communications very explicit in the language’s syntax in order to keep the programmer aware of the cost involved. This is a reasonable approach, and it’s similar to the one we took in our previous work on a language called ZPL. However, in that work we found that such syntactic distinctions were a barrier to code reuse and so decided that in Chapel we would support transparent remote accesses in the name of productivity. Even so, Chapel programmers have complete control over the locality of their variables, and performance-minded programmers can query, assert, and reason about the placement of their data values.
Other differences between X10 and Chapel stem from X10’s Java heritage. This has caused X10 to have more of an inherent object-oriented flavor which shows up in a number of ways. As one example, an assignment between two X10 array variables is interpreted as a pointer assignment resulting in an array alias as a Java programmer would expect. In contrast, Chapel’s array assignments result in an assignment of one array’s elements to the other as in Fortran, MATLAB, and arguably mathematics.
In designing Fortress, Sun’s team chose to tackle a very fundamental and challenging question in programming language design: Given that it is difficult to anticipate how a language will need to evolve over time, how can the language be designed to minimally restrict its flexibility, permitting library developers to define things that we typically consider to be “part of the language” such as the data types, the parallel implementation of operators, and even operator precedence. Fortress is an implicitly parallel language that makes the evaluation of many constructs, like loop iterations, parallel by default. Fortress also supports a mathematically oriented syntax through the use of Unicode symbols and operators to express a computation. While we believe Fortress to be a very important and promising language effort, we also believe that the main productivity challenges facing parallel programmers today are caused more by the low-level expression of parallelism rather than the lack of implicitly parallel loops and mathematical syntax. To this end, our approach could be viewed as being more evolutionary, trying to build on the lessons learned from the parallel languages of the 1990’s while improving on their deficits and striving for more generality. That said, our approach also has some similarities to Fortress. Most notably, Chapel is striving to provide user-defined distributions that would allow an advanced user to write their own low-level implementation of a distributed parallel array in Chapel. This is similar to the Fortress theme of permitting library authors to specify such details, providing the end-user with a higher-level view of these complex data structures. As a final note, our recent conversations with the Fortress team have suggested that they are primarily focused on shared-memory platforms for the time being while the Chapel team continues to focus predominantly on large-scale distributed memory machines.
HPCwire: What is the status of the language today?
Chamberlain: Chapel is very much a work-in-progress and our status today reveals that. We have a reasonably complete draft of the language specification available, but it is a document that continues to evolve as we gain more experience with the language, receive feedback from the community, and find and address flaws in our own assumptions. Most of our team’s day-to-day effort is spent implementing the Chapel compiler. Our compiler takes a source-to-source compilation approach, translating Chapel into C with calls to portable communication and threading libraries that implement the inter- and intra-locale parallelism. This approach makes our implementation very portable, allowing us to compile and run Chapel programs on a range of platforms from desktop multicore machines to commodity clusters; from the deskside Cray CX1 to the high-end Cray X2, XMT, and petascale XT5 systems; and even on our competitors’ systems.
Looking at the Chapel compiler today, the base language is in reasonable shape, to the extent that we find ourselves implementing more and more of the language in Chapel itself and enjoying its productivity benefits. The task parallel features are also quite stable and support the creation and synchronization of tasks within a locale or across multiple locales. Our data parallel features have been supported in a single-threaded reference implementation for some time now, permitting early users to experiment with the various array types and their parallel operators in a sequential execution. In the past few months we have just started getting our first parallel distributed arrays up and running, though additional work is required there before those features could be considered stable.
The primary deficit in our current implementation is performance. While performance has been a primary factor throughout Chapel’s design, our implementation efforts to date have focused almost exclusively on providing a correct reference implementation in order to get feedback from early users and correct any missteps as quickly as possible. In recent months we have started to focus increasingly on performance and looking toward 2009, we anticipate focusing our efforts on adding performance optimizations and fleshing out the implementation of distributed parallel arrays.
HPCwire: What are the future plans for Chapel and how does it fit into DARPA’s HPCS program?
Chamberlain: In 2009, Cray’s HPCS productivity team will start a focused effort to study Chapel’s productivity by writing a number of benchmarks and mini-applications in Chapel with the goal of spanning a wide range of computational idioms in HPC. In the short-term these studies will focus on programmability and code flexibility, but as the Chapel compiler continues to mature they will also include performance studies relative to MPI. To this end, Chapel is an important part of Cray’s HPCS productivity story, striving to make Cray’s HPCS architecture — and all parallel computers — more programmable without sacrificing the portability or performance enjoyed by MPI users today. Not surprisingly, Chapel is just one part of Cray’s HPCS program, and other efforts focus on the hardware architecture and the rest of the software stack.
HPCwire: The adoption rate of new programming languages is quite low. Is there any strategy being developed to try to overcome this challenge?
Chamberlain: Historically, users have been most inclined to adopt new programming languages when a complementary technology shift has made the change compelling. Looking to the near future, the parallel programming community is facing petascale machines for the first time as well as increasingly heterogeneous system architectures. Simultaneously, in the mainstream and open-source communities, a growing interest in parallel programming is anticipated due to the emergence of multicore processors. We believe that these challenges could lead parallel programmers to adopt new programming languages — particularly ones like Chapel that do a better job of separating the concerns of expressing a parallel algorithm from managing the low-level details required to implement it. In designing Chapel, we have done what we can to minimize barriers to adoption, including the design of the language features themselves and our decision to pursue a portable implementation. During the past two years, we have also made a number of limited releases of our compiler available to users in government labs, academia, and industry in order to get their early feedback and address their concerns. We also decided at Chapel’s inception that we would release our compiler as open-source software in order to reduce barriers to adoption and collaboration. We view Cray’s role with Chapel as an inventor and incubator, but ultimately hope that the language will grow in popularity to the extent that it can make the transition from a Cray-controlled language to more of a broad-community effort.
HPCwire: Is there a way for interested users to start experimenting with Chapel today?
Chamberlain: Yes, we will be performing our first-ever public release of Chapel in the SC08 timeframe under the BSD open source license. This release will contain our source-to-source compiler, allowing users to compile and run Chapel programs on their desktops, commodity clusters, and Cray systems. The release will be a snapshot of our work in progress, and it is being made available in order to get feedback from the community and make Chapel more useful to a broader set of users. The release will not be a complete implementation of Chapel, nor is it intended to support performance studies. To obtain the release, keep an eye on our public Web site at http://chapel.cs.washington.edu.
We conducted two Chapel tutorials at SC08 — a standalone tutorial on Sunday and a joint PGAS tutorial with X10 and UPC on Monday. Each tutorial featured a hands-on session in which participants experimented with the Chapel language and compiler with the development team standing by to answer questions.
HPCwire: Will you be able to run both Chapel and other programming models on the same system?
Chamberlain: Of course. Nothing about Chapel precludes the use of other programming models on a system, and Cray systems will continue to support MPI, OpenMP, UPC, and CAF for the foreseeable future. The more interesting question is whether a single application will be able to use Chapel in combination with other programming models like C, Fortran, MPI, UPC, and CAF. We believe that such interoperability is of the utmost importance in order to preserve legacy code that would be prohibitively expensive to rewrite from scratch. Calling between Chapel and C/Fortran is something that we anticipate supporting in the near future. The more challenging question is, how can a user make calls from an MPI program into a Chapel program, or vice-versa, without having to copy or redistribute their large, distributed data structures? We believe that Chapel’s user-defined distributions could serve as a crucial tool in addressing this challenge, and we are fostering some strategic collaborations to explore this topic, but at this point it is still very much an open research question.