Portability is a measure of the ease with which software can be moved between heterogeneous computing platforms. Software with a high degree of portability is valuable because it reaches more users. Commercial developers expend a considerable effort to make software that can run on multiple platforms. Scientific programmers have the same motivation to make their software portable, but their requirements differ in some respects from those of commercial software. Scientists have a unique need for collaboration and the independent replication of results at geographically diverse sites. Scientific algorithms tend to be expensive computationally, so scientific developers are more likely to use parallel computing. The fast pace of evolution for High-Performance Computing (HPC) systems affects scientific organizations inordinately, causing diversity in their computing platforms. These factors combine to make portability a critical issue for scientific computing. In addition, scientific institutions may also lack the resources which are available to commercial developers, and this can influence selection of a portability strategy. In this paper we propose criteria for evaluating the portability of a scientific application and we survey existing portability techniques with respect to those criteria. We identify the set of portability methods which are most applicable to scientific computing, and we identify future research problems. 1. Introduction Modern scientific research depends on computer technology to organize and analyze large data sets. Computers provide the ability to process the complex models that are common in the scientific domain. Scientific inquiry requires that information be shared with other scientists. It follows that software used for scientific purposes should be distributable to the widest possible base of potential users, in other words it should be made portable. In practice, portability is a difficult goal for the scientific developer [4,13]. The great diversity of computer hardware and software poses a fundamental threat to software portability [1,4]. Advances in hardware platforms and operating systems, and the evolution of programming languages and programming standards inhibit portability. Scientific computing imposes unique constraints of its own, including large computational demands which have made parallel programming of critical importance to scientific developers [3,12]. HPC systems used for scientific computing evolve quickly, so scientific organizations often accumulate extremely heterogeneous computing environments [2,3,4,5,8]. These concerns interact to increase the importance of code and performance portability for scientific applications. Many scientific applications are developed using open source environments such as Linux [4,17]. Binary compatibility is not an attribute of Linux, so applications are customarily released as source code packages. Scientific developers often lack the time and resources needed to port and verify their software in multiple environments. As a result, end users can become responsible for making programs run on their own systems. In essence they must take on the task of porting the software. This problem is very well known in the scientific community [4,5,7,8]. Portability is frequently ignored by scientific developers [13]. In the rare case where portability is addressed, it is done in an ad hoc manner, despite the availability of better methods. The lack of information on portability makes the problem worse. The current literature has no comprehensive survey of existing portability techniques, nor is there a systematic comparison of the costs and benefits of the various portability methods. In this paper we make the following contributions: A portability model based on hardware and software configuration spaces. Expanded criteria for evaluating the portability of scientific applications. A comprehensive survey of portability techniques used for cross-platform development. The introduction of the concept of environmental adaptation for software portability. A process for selecting a portability strategy early in the development process. Our paper is organized as follows: Section 2 summarizes our research references and introduces a portability model, Section 3 describes the unique requirements of scientific computing, and Section 4 presents our criteria for evaluating portability. Section 5 surveys existing portability techniques. Section 6 evaluates these techniques against our criteria, and Section 7 discusses the selection of a portability strategy and presents our conclusions. Section 8 explores future research topics. 2. Portability Overview Software which can run on diverse platforms is more valuable because it is available to more users, and portable software has increased longevity because it can migrate from older to newer platforms [1]. We define software portability as the ability to move between computing environments that differ in a significant way. Software with a high degree of portability is transportable to a more diverse set of platforms. The system components with the greatest impact on portability include the hardware platform, operating system, and compilers [7]. Other development tools, system libraries, and build processes have a lesser effect. Portability has been a longstanding goal of software developers, but no single solution has been proposed that comprehensively solves the problem [1].