Scholarly article on topic 'GPU Acceleration of a Cloud Resolving Model using CUDA'

GPU Acceleration of a Cloud Resolving Model using CUDA Academic research paper on "Earth and related environmental sciences"

Share paper
Academic journal
Procedia Computer Science
{GPU / CUDA / "parallel computing" / "climate modeling"}

Abstract of research paper on Earth and related environmental sciences, author of scientific article — Hong Zhang, Jose Garcia

Abstract The increasing computing power of graphics processing units (GPU) has motivated the use of GPUs to speed up climate models. Their low price in conjunction with C style parallel programming tools, like CUDA (Compute Unified Device Architecture), allow the programmers, even non-programmers, to exploit the fine grain parallelism power of GPU conveniently. In this paper, we report successful acceleration of a Cloud Resolving Model (CRM) by implementing the MPDATA algorithm on the GPU using CUDA. The results show the great speedup potential for GPU acceleration of CRM which could carry over to other atmospheric models.

Academic research paper on topic "GPU Acceleration of a Cloud Resolving Model using CUDA"

Available online at

SciVerse ScienceDirect

Procedia Computer Science 9 (2012) 1030 - 1038

International Conference on Computational Science, ICCS 2012

GPU acceleration of a Cloud Resolving Model using CUDA

Hong Zhanga, Jose Garcia^*

a Computational Science Laboratory, Department of Computer Science, Virginia Polytechnic Institute and State University, Blacksburg, VA 24061


b National Center for Atmospheric Research, Computational and Information System Laboratory. P.O. Box 3000, Boulder, CO. 80307

(jgarcia@ucar. edu)


The increasing computing power of graphics processing units (GPU) has motivated the use of GPUs to speed up climate models. Their low price in conjunction with C style parallel programming tools, like CUDA (Compute Unified Device Architecture), allow the programmers, even non-programmers, to exploit the fine grain parallelism power of GPU conveniently. In this paper, we report successful acceleration of a Cloud Resolving Model (CRM) by implementing the MPDATA algorithm on the GPU using CUDA. The results show the great speedup potential for GPU acceleration of CRM which could carry over to other atmospheric models.

Keywords: GPU, CUDA, parallel computing, climate modeling

1. Introduction

Current climate models seek to improve the quality of forecasts by improving the spatial resolution of the underlying grid and by adding new physics that describe phenomena previously treated via parametric functions. The improved modeling places a clear computational challenge as running a CRM within a global dynamics is very costly.

Emerging general purpose computing technology via Graphics Processing Units (GPUs) becomes promising to make large-scale simulations benefit from high performance computing. Compared to traditional HPC systems, GPUs are attractive due to high peak performance and inexpensive cost. Successful GPU porting of full or partial atmospheric models has already been reported. Previously Shimokawabe et al. [1] reported an 80-fold speedup of the Non-Hydrostatic Weather Model ASUCA by porting the full code to the 528 (NVIDIA GT200 Tesla) GPU TSUB-AME Supercomputer. Michalakes et al. [2] reported a twenty-fold speedup of computationally intensive portion of the Weather Research Forecast (WRF) model on a (NVIDIA 8800 GTX) GPU, resulting in an overall speedup of 1.3x. Linford et al. [3] reported a eight-fold speedup of RADM2 chemical kinetics mechanism from WRF model with Chemistry (WRF-Chem) on a Tesla C1060 GPU. Full GPU porting can avoid the overhead of data transfer between the host memory and the GPU memory, which is limited by the bandwidth of PCI Express lanes. Usually full GPU porting is expected to provide more significant speedups than partial GPU porting but requires more programming effort. And the achievable speedup through fully GPU porting for a given application depends on how work is spread

* corresponding author

1877-0509 © 2012 Published by Elsevier Ltd. doi:10.1016/j.procs.2012.04.111

throughout the code. Computationally intensive code is more likely to benefit from GPU acceleration while some other code may even become slower on GPU than CPU.

Climate modeling is very complicated in the sense that one must account for responses and interaction of the atmosphere, the oceans, the land, sea-ice, etc. Within each of these components multiple phenomena such as fluid dynamics, physics, chemistry and so on have to be modeled. Each of these phenomena may be equal contributions to the total cost of the model execution. As such, researchers wish to adapt full codes to GPUs. For a given model, adaptation to the target architecture may require modifications of the code or even changes of fundamental data structures. It has been realized that many of complex numerical routines are not easily changed as the underlying algorithm is not necessarily well documented, or that the process of validation and verification is not well defined. To fully realize the complexity and evaluate the potential associated with porting the codes to new platforms, we have chosen a relative isolated component of a complete climate simulation model, named Cloud Resolving Model (CRM). Since it is isolated from the rest of the climate model, we can test it separately if given proper inputs and avoid the danger of being overwhelmed by the complexity.

CRMs are realistic models capable of simulating the dynamics of clouds such as convective heating, moistening rates, convective mass flux, precipitation rates, etc., across a wide range of domain scales [4]. The output of CRMs could provide far more details than the highest quality observations with current technology. CRMs can also be applied to improve parameterization within large scale operational and general circulation models [5, 6]. The dominant component in CRM are the processes associated with the fluid dynamics, which can be best described by the compressible Navier-Stokes equations.

Clouds in the CRM are treated as three-dimensional objects, in which the full domain is partitioned along columns in the XY plane. Within each column, the solution is computed independently of all other columns. So CRM is an embarrassingly parallel model. Inside each column, CRM is dominated by one routine, the advection process that numerically is implemented by a positive definite advection scheme, named MPDATA [7, 8].

MPDATA can represent up to 70% o the total cost of execution of the model, depending on the size of the domain and the granularity in which the domain is partitioned. Hence, it is necessary to implement MPDATA for execution on a single GPU as a first step towards porting the model to a complete hybrid cluster of CPUs-GPUs. In this paper, we present the CUDA implementation of the MPDATA algorithm on an NVIDIA GPU, as well as the optimization techniques we used.

The overall computational process requires to transfer data between CPU and GPU via the PCI bus. The first challenge is to determine the proper size of the input data such that the transfers to and from the GPU are properly amortized by the reduced computing time on GPU. In this process we determined a heuristic set of dimensions whereas any experiment below size 64 x 64 x 64 in the XYZ dimensions is too small to be worth of computation on GPU. The second challenge is to properly being able to coordinate among blocks of threads in the MPDATA algorithm. This is also a well known problem within the language, CUDA does not provide an efficient mechanism for global synchronization. We achieve this goal by breaking the monolithic kernel into smaller kernels and launching them sequentially. The small kernel launch overhead associated is negligible compared with the computing time of the kernels.

The cloud resolving model we accelerated is the System for Atmospheric Modeling version 6.8 (SAM 6.8), developed by Marat Khairoutdinov [4]. It is a candidate to replace the current parametrizations in the full climate model-NCAR's Community Earth System Model (CESM). To the best of our knowledge, there is not yet any research on accelerating this model on GPU. The advection routine in SAM, named advect_scalar, consists mostly of stencil-based computations, in which each grid point is repeatedly updated by only using neighbor points, exhibiting regular spatial locality. Data parallelism is obtained by simply assigning a single thread to each element in the grid, in an effort to make the least changes possible to the original numerical algorithm for adaptation to GPU.

Other emerging platforms such as Intel's Many Integrated Core (MIC) platform, which can provide considerable floating-point power in an architecture that does not require codes to be rewritten in a new language, also seem to be beneficial for climate science. But yet utilizing MIC to accelerate climate models is at an initial stage. Some preliminary results on evaluating MIC [9] show that there is much work to be done performance-wise and its competency remains to be seen.

2. GPU Architecture and CUDA

A GPU is presented as a set of streaming multiprocessors (SM), each of which consists of multiple stream processors (SP). The SM employs a Single Instruction Multiple Threads (SIMT) model. Thus a large number of threads can be executed concurrently enabling GPUs to achieve a very high performance.

The device memory (also global memory in CUDA) can be accessed by all SMs but not cached by the hardware. Another memory layer, known as shared memory, is used as user-managed cache, and shared among threads on the same multiprocessor. The latency of device memory (typically 400 ~ 800 cycles) is much higher than that of shared memory (1 or 2 cycles). But the device memory size is relatively larger.

NVIDIA's CUDA [10], a parallel extension of C and C++ language, provides an easily accessible, general-purpose programming model for the GPU. CUDA programs, which are executed concurrently across many threads, are called kernel functions in the CUDA jargon. Threads are organized into thread blocks and thread blocks, together, constitute a grid structure on the GPU. Each thread is identified by its thread ID that indicates the thread place within a block. Each block also has an ID to indicate place within a grid. Moreover, an application can specify the blocks as 3D arrays and identify each thread using a three component index. The layout of a block is specified in a kernel call to the GPU by three integers defining the extensions in X, Y and Z that symbolize the dimensions for the CUDA grid structure.

The NVIDIA Quadro 4000 GPU contains 256 streaming processors, 2 GB global memory, 64 KB of shared memory. The theoretical peak performance is 486.4 GFlops in single precision and 243.2 GFlops in double precision. The theoretical global memory bandwidth is 89.6 GB/s. A CUDA block can contain 1024 threads at maximum. The maximum dimension of a block is 1024 x 1024 x 64 and maximum dimension of a grid is 65535 x 65535 x 65535.

Though the gap between single precision and double precision performance is getting smaller as hardware advances, single precision is still significantly faster than double precision on the GPU. For numerical applications, whether single precision suffice depends on not only the specific problem, but also the stability of numerical schemes applied. For example, solution of stiff systems of ordinary differential equations desires very high precision while single precision is usually sufficient for stable finite difference methods[11].

3. Governing Equations and Numerical Approach

MPDATA is a second-order accurate, positive definite, conservative finite-difference algorithm [8] for approximating the advective terms in fluid equations. The version of MPDATA we deal with is three-dimensional and consists of two iterative passes. The first pass is a simple positive definite upstream differencing but only first-order accurate. To increase the accuracy, the second pass estimates and compensates the (second-order) truncation error of the first pass. MPDATA can not only be used for generalized advective transport, which is needed by CRMs, but can also be applied to fluid dynamics without splitting [12]. Over the last two decades, MPDATA as a general solver for complex fluid problems has been implemented in numerous atmospheric and other models for both compressible and incompressible systems of equations [13, 14].

The basic continuity equation describing transport of a non-diffusive scalar quantity f in three-dimensional space

df d d d

i = - dX(fu) - dy(fv) - dZ(fw), (1)

where u,v, and w are velocity component in each dimension, and may vary in time t and space x = (x, y, z). The upstream differencing (or donor cell approximation) to the equation (1) is written in flux form

fn+,1 = fj - [ F(ftjk> f+1, j,k> Ui+U2j,k) - F (f-j, fj, Ui+1/2,j,k) + F' (f j, VUi+H2k)

-F(f tj-Uk, fj, Vi,j+1/2,k) + F' (fllk, j, Wjk+1/2) - F ( j, fljk, W j+1/2) ] , (2)

where F is the flux function and defined in terms of the local Courant number by

F(fL, fR, u) = ([u]+fi + [u]-fff) St/Sx,

F (f L, fR, V) = ([u] + f L + [u]-f r) St/Sy, (3)

F(fL, fR, w) = ([u]+fL + [u]-fr) St/Sz.

Here the integer and half integer indices correspond to the cell centers and cell walls, respectively. [■]+ = max(0, ) and [ ]- = min(0, ) are the nonnegative and non-positive parts of the Courant number, respectively. Consider a donor cell estimate of the truncation error and subtract it from the difference equation (2), we can obtain a higher-order approximation. The derivation can be found in [8]. The resulting equation of the second pass is

t(j = t(1j,k - [A;+1/2,j,k - Ai-1, jk + Ai,j+1/2,k - Ai,j-1/2,k + Ai+,j,k+1/2 - Ai,j,k-1/2] , (4)

where A is an approximation of residual flux A which compensates the leading truncation-error term in low-order scheme, traditionally referred to as the "anti-diffusive" flux [7] and t(1) is the solution after the first pass. The explicit form of the approximated anti-diffusive fluxes in (4) is

Ai+j = min(1,/3lijk,l3^j+1jk )[A;+1/2,j,k]+ + mirtXfij ,pi+lJk)[Ai+1/2jk ]-, (5)

t^X - tn+1 tn+1 - tMIN

pj — i j,k i ,J,k pi — i ,J,k i ,J,k (fr\

= AINt + £ ' = A0UT + e • (6)

i, j,k i, j,k

AINk, AOUjT are absolute values of the total incoming and outgoing A-fluxes. e is a small constant value, e.g. 10-15.

The limiters tj* and are specified as i,j,k i,j,k

tMA = maxithjk, jk, tl,j,k±1, Cuk, j, tjL 1), (7)

tMIN = min(tl_ 1,j,k, tj 1k, ttjk± 1, tn+11,jk, tn+±1k, tn+,1±1). (8)

4. CUDA Implementation

All the code in SAM is written in Fortran. Though CUDA Fortran is available, CUDA Fortran doesn't support texture memory and is not as mature as CUDA C. So we prefer CUDA C to CUDA Fortran. Direct translation from Fortran code to CUDA C code is very error prone, since arrays need to be declared and indexed in different manners. For example, a 3D array A[i][j][k] is stored in ijk-order in Fortran while stored in kji-order in C. Moreover, Fortran allows the indices i, j, k to start from a negative integer, which is not permitted by C. Thus we separate the process into two steps. First we rewrite the portion of target code in C and test it by plugging the code back in the Fortran program. Then converting from C to CUDA C becomes relatively straightforward.

Generally by taking into account the unique architecture of the GPU, we take the following strategies to improve the performance of our CUDA C implementation:

• Transferring data between CPU host memory and GPU device memory can be costly. We should keep the data on the GPU as long as possible and exploit the possibility to reuse it.

• We should carefully organize the threads to allow threads within the same warp to access contiguous elements on the device memory. Coalesced memory access can significantly improve performance since the latency of device memory is very high.

• To reduce the access to the device memory, we take the advantage of texture memory and shared memory. Texture memory provides a small amount of on-chip cashing, but it only supports read-only data structures. Shared memory can be used to avoid redundant transfers from global memory and allows for read and write access with little latency.

Since the current version of CUDA provides no efficient reliable global synchronization, we split the computations performed in the advect_scalar routine (implemented with MPDATA algorithm) into multiple smaller kernels and launch them sequentially on GPU. Synchronous kernel execution can be achieved if we do not specify a stream and all kernels go to the default stream and are executed serially. The overhead of kernel launch is very low and usually much less than kernel running time. Considering the synchronization points required by our application, we separate the main procedure, described in previous section, into the following 6 steps, each of which is implemented in a standalone kernel:

Figure 1: Work flow for the accelerated part of the CRM in a time step. Advection procedure is called multiple times in a single cycle

L Compute j = max(fi±j, j, jj and fj = mir>W±j, ftj±w ft^ impute the flux functions used by first pass (2);

2. Perform the first pass (2) for the scalar quantity f at all grid points;

3. Compute pseudo-velocity components needed by anti-diffusive flux functions; Compute limiters defined in (7)

by j = maxffX fl+j, jr f lji±1) and fj = Mif™, f±j fl+Lk, j 1);

4. Compute fi]j k and.k according to (6);

5. Compute the approximated anti-diffusive fluxes in (5) by using the results from the previous two steps;

6. Perform the second pass (4) and the procedure is finished.

The execution flow is shown in Figure 1.

In the initialization stage, we allocate device memory on the GPU for all variables. And only the velocity components, read-only during the whole procedure, are transferred from host memory to device memory on the GPU and then bind to texture memory. After that the computations corresponding to advect_scalar are performed on the GPU. Note that the routine advect_scalar may be called multiple times in original serial code. It is still the same for the CUDA code. Before MPDATA kernels are invoked, necessary data, e.g. scalar quantities, are transferred to GPU and then can be used by all the following kernels. 6 MPDATA kernels, as well as two reduction kernels, are invoked in a sequential order. The two kernels for GPU reduction are trivial and will not be detailed here. The results of the reduction operations are not related to the MPDATA algorithm but might be useful for some other parts in the application.

We organize the threads on GPUs in such a way that each thread performs the calculations on each mesh point. The dimensions of 3D arrays of variables involved in these MPDATA kernels do not necessarily match the mesh size of the given model, because of extra points required to store halo data. For example, if we denote the size of a given problem set by (nx ny nz), the dimension of the 3D array corresponding to velocity component u is nx + 5 ny + 2 nz while the array storing v is of size ±x + 4 , ±y + 3, ±z. Therefore the grid settings for MPDATA kernels have to slightly differ from each other depending on the maximum size of 3D arrays involved in that kernel. The detailed information is given in Table 1.

To take advantage of coalesced memory access, we put threads accessing continuous data in the device memory into the same block as possible as we can. For brevity in description, we take a problem with grid size (±x, ±y , ±z) as an

grid block registers GPU time texture achieved kernels size size per thread (us) hit rate occupancy

MPDATA kernel 1 MPDATA kernel 2 MPDATA kernel 3 MPDATA kernel 4 MPDATA kernel 5 MPDATA kernel 6 Flux reduction 1 Flux reduction 2

(64,69,1) (69,1

(64,68,1) (68,1

(64,67,1) (67,1

(64,66,1) (66,1

(64,65,1) (65,1

(64,64,1) (64,1

(64,1,1) (64,1

(64,1,1) (64,1

18 423.8

18 279.5

41 1512.6

34 551.4

18 319.5

18 237.1

10 48.0

10 48.3

78.1% 0.47

0 0.45

54.8% 0.49

0 0.47

0 0.36

0 0.31

0 0.33

0 0.33

Table 1: Threads organization and GPU resource usage of all kernels.

r / / / j

Figure 2: Grid settings for stencil computations

example without considering halo points. As shown in Figure 2, We configure the kernels to run with (nz, ny) blocks with nx threads per block if the data are stored in x, y, z ordering on the GPU. Each thread specifies an (x, y, z) point. And threads in each block deal with data only in x-direction, which is contentiously stored in the device memory. The maximum number of threads per block on Quadro 4000 is 1024, which is large enough for most existing models to our knowledge. If not, we can make each thread perform calculations for multiple points.

Our implementation gets considerable benefits from usage of texture memory. Large read-only data are loaded into texture memory only once and then shared by multiple kernels in the each time step of the model run. And also the small amount of cache attached to texture memory enables faster access. Shared memory can potentially be used in the first and third MPDATA kernels where each thread needs to load several adjacent points in the array i^. For example, in the third MPDATA kernel, 15 adjacent points have to be accessed for updating the current point in each thread. Assuming there are N points in each block and the array ^ is stored in global memory , 15N points in total will be loaded for one thread block. It can be seen that these points occupy 9 rows in the array ^ according to the algorithm. Thus we can load 9N points from global memory to shared memory and fetch them from shared memory. In our application, the benefit from latency reduction of shared memory is very limited since there are not too many redundant global memory accesses in each thread block. The usage of share memory reduces the execution time of MPDATA kernel 3 on GPU by 5.5% compared to the one without using shared memory. But it does not add any performance gain to MPDATA kernel 1.

5. Results and Validation

All the experiments were performed on a Linux (in CentOS release 5.6) computer, which has 4 16-core 6168 AMD Opteron(tm) processors and connected to an NVIDIA Quadro 4000 GPU through dual slot (2x8) PCI-e. The

■ kernel execution

■ memoty copying from CPU to GPU memory copying from GPU to CPU others

Figure 3: Timing breakdown for the CUDA C implementation of routine advect^scalar on the GPU

original Fortran code was compiled with mpif90 for MPICH2 version 1.4.1p1 and -O2 optimization. The C code was compiled using gcc 4.1.2 and -O2 option and the CUDA C code was compiled using nvcc (release 4.0,V 0.2.1221) with -O2 optimization and single precision mode.

A 3D CRM was configured to run over a 64 x 64 x 64 grid for a period of September 1 through September 7, 1974 during the Phase III of GATE (Global atmospheric research program's Atlantic Tropical Experiment). We chose this data set because its running time is relatively short compared with other cloud systems that may take several days or even months for the simulations to finish. GATE test case covers a real-world domain of 400 km x 400 km horizontally and 16 km vertically. For convenience, we collected only statistics results for the first 120 time steps with each step corresponding to 10 seconds in real world. We developed another version of the CUDA C code which was separated from the original model, as well as a standalone driver attached to it to facilitate validation and debug.

The validation of the results is essential to assure that the model output using singe precision computation on GPU is sufficiently accurate. We not only validated the correctness of the CUDA C code via standalone driver, but also validated the precision by comparing the output between our code and original serial code. We visualized and compared some important output variables using NCAR Command Language (NCL) scripts. Generally there are very small differences appeared at several points which are randomly distributed on these plots. An example of comparison results for pressure and surface flux is shown in Figure 4. Basically that numerical results based on single precision calculations on the GPU show acceptable accuracy.

The total time cost associated with executing original serial code is 91.223 seconds and the calls to routine ad-vect_scalar take 47.221 seconds. Our implementation reduces the execution time of routine advect_scalar down to 4.014 seconds, providing a speedup of 11.8x over the original implementation. The overall speedup for the whole model is roughly 1.8x. Note that the CUDA accelerated code is executed on a relatively small data set. The low occupancy shown in 1 is mainly caused by insufficient threads per block according to the analysis by the CUDA visual profiler. Much more performance gain can be obtained on models with higher resolution. Figure 3 shows the timing breakdown for the CUDA C implementation of routine advect_scalar on the GPU. The time for data transfer between CPU and GPU is as much as half of the time that kernel executions take. And other expenses including memory allocation and some code running on CPU occupy a large part of the total time.

6. Conclusions and Future Work

Regardless of the code translation and validation of results, the CRM is an ideal candidate for GPU acceleration because it is relatively simple to exploit data parallelism with a domain-based decomposition.

We reported on successfully implementing the MPDATA algorithm on GPU using CUDA C language. Experiments with the 'GATE' test case on a relatively small 3D domain 64 x 64 x 64 have demonstrated that our GPU implementation can offer considerable performance gain over CPU-based code with acceptable accuracy. Any data set below the size 64 x 64 x 64 does not merit GPU acceleration. And larger data set may benefit much more from GPU parallelism.

The next logical step is to port the accelerated CRM model to a cluster of hybrid CPU-GPU nodes. But complexity will be dramatically increased by using a hybrid cluster, where each computational node contains a few cores per


Surface flux

1200 i-u 1000 -

M 800 -

cl 600 -

! 400 -O 200 -

.......... Original .........-

-.......... ..........-


_i 0 I -0.5 5 -i

Our implementation


Figure 4: Surface flux and pressure before and after GPU acceleration

socket, one or two sockets and there are one or more GPU in each node. Besides, CRM is complicated to program for a full cluster because we may need MPI, OpenMP and CUDA to synchronize all. The complexity of adapting a CRM to fully utilize and perform in a hybrid CPU-GPU platform will be addressed in a following paper.

This initial work also makes us aware that development cost associated with porting such as code translation, algorithm adaptation and hardware specific optimization and the lack of well understood validation and verification cases for relative isolated pieces of code makes porting climate models to new HPC platforms expensive and time consuming.


The authors gratefully acknowledge support for this research from the Summer Internships in Parallel Computational Science Internship Program at the National Center for Atmospheric Research. NCAR is sponsored by the National Science Foundation.


[1] T. Shimokawabe, T. Aoki, C. Muroi, J. Ishida, K. Kawano, T. Endo, A. Nukada, N. Maruyama, S. Matsuoka, An 80-fold speedup, 15.0 tflops full gpu acceleration of non-hydrostatic weather model asuca production code, in: Proceedings of the 2010 ACM/IEEE International Conference for High Performance Computing, Networking, Storage and Analysis, SC '10, IEEE Computer Society, Washington, DC, USA, 2010, pp. 1-11. doi:

[2] J. Michalakes, M. Vachharajani, Gpu acceleration of numerical weather prediction, in: Parallel and Distributed Processing, 2008. IPDPS

2008. IEEE International Symposium on, 2008, pp. 1 -7. doi:10.1109/IPDPS.2008.4536351.

[3] J. C. Linford, J. Michalakes, M. Vachharajani, A. Sandu, Multi-core acceleration of chemical kinetics for simulation and prediction, in: Proceedings of the Conference on High Performance Computing Networking, Storage and Analysis, SC '09, ACM, New York, NY, USA,

2009, pp. 7:1-7:11. doi:

[4] M. F. Khairoutdinov, D. A. Randall, Cloud resolving modeling of the arm summer 1997 iop: Model formulation, results, uncertainties, and sensitivities, Journal of the Atmospheric Sciences 60 (4) (2003) 607-625.

[5] M. F. Khairoutdinov, D. A. Randall, A cloud resolving model as a cloud parameterization in the ncar community climate system model: Preliminary results, Geophysical Research Letters 28 (18) (2001) 3617-3620.

[6] P. N. Blossey, C. S. Bretherton, J. Cetrone, M. Kharoutdinov, Cloud-resolving model simulations of kwajex: Model sensitivities and comparisons with satellite and radar observations, Journal of the Atmospheric Sciences 64 (5) (2007) 1488-1508.

[7] P. K. Smolarkiewicz, W. W. Grabowski, The multidimensional positive definite advection transport algorithm: nonoscillatory option, Journal of Computational Physics 86 (2) (1990) 355 - 375. doi:10.1016/0021-9991(90)90105-A.

[8] P. K. Smolarkiewicz, L. G. Margolin, Mpdata: A finite-difference solver for geophysical flows, Journal of Computational Physics 140 (2) (1998) 459-480. doi:10.1006/jcph.1998.5901.

[9] T. Voran, J. Garcia, H. Tufo, Evaluating intels many integrated core architecture for climate science, submitted to the TACC-Intel Highly Parallel Computing Symposium, April 2012.

[10] NVIDIA CUDA Compute Unified Device Architecture - Programming Guide (2007).

[11] D. Egloff, High Performance Finite Difference PDE Solvers on GPUs (Feb. 2010).

[12] L. Margolin, P. K. Smolarkiewicz, Antidiffusive velocities for multipass donor cell advection, SIAM Journal on Scientific Computing 20 (3) (1998) 907-929. doi:10.1137/S106482759324700X.


[13] J. M. Prusa, P. K. Smolarkiewicz, An all-scale anelastic model for geophysical flows: dynamic grid deformation, Journal of Computational Physics 190 (2) (2003) 601 - 622. doi:10.1016/S0021-9991(03)00299-7.

[14] J. Iselin, J. M. Prusa, W. Gutowski, Dynamic grid adaptation using the mpdata scheme, Mon. Wea. Rev. 130.