Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
c2190e6
Initial check-in of python/miniWeather.py
mhoemmen Mar 3, 2025
1a1120c
Progress on Python port; not done yet
mhoemmen Mar 4, 2025
609c239
Progress on porting to Python
mhoemmen Mar 4, 2025
bd6a3de
Progress on porting to Python
mhoemmen Mar 4, 2025
d5634d2
Progress on porting to Python (print statements)
mhoemmen Mar 4, 2025
3fe5584
All C++ code is now Python code
mhoemmen Mar 4, 2025
2967153
Run-time debugging of port
mhoemmen Mar 4, 2025
3d9794e
More run-time debugging
mhoemmen Mar 4, 2025
6762e76
More run-time debugging
mhoemmen Mar 4, 2025
880ee6a
It runs to completion without errors
mhoemmen Mar 5, 2025
01e45bc
Debugging Python (C is OK)
mhoemmen Mar 6, 2025
2d4f752
Remove some Python / C diffs
mhoemmen Mar 6, 2025
f9b94f6
Make Python flux like C flux
mhoemmen Mar 6, 2025
52e035b
Make direction_switch the same; verify
mhoemmen Mar 6, 2025
6506342
Reconcile more, but no change in results
mhoemmen Mar 6, 2025
53dbd0e
Reconcile more, but no change in results
mhoemmen Mar 6, 2025
4c6fd20
Reconcile collision; didn't help
mhoemmen Mar 6, 2025
8dd07fb
More reconciling: abs -> math.fabs in set_halo_values_x
mhoemmen Mar 6, 2025
5ae15b1
Remove superfluous comments
mhoemmen Mar 6, 2025
bc5c387
Change Python to run THERMAL not INJECTION
mhoemmen Mar 7, 2025
81ae53d
Fix MPI_Info_dup error in C output
mhoemmen Mar 10, 2025
da28c55
C: output updates
mhoemmen Mar 10, 2025
a3cdf1f
C: debug output to stderr not stdout
mhoemmen Mar 10, 2025
79212d0
C: Add build script that works for me
mhoemmen Mar 10, 2025
953601e
Python: Starting on netcdf output
mhoemmen Mar 10, 2025
185fcaf
Python: netcdf output 2
mhoemmen Mar 10, 2025
5c2206a
Python: netcdf output 3 (may have fixed it)
mhoemmen Mar 10, 2025
a1d2fc3
Fix Python output
mhoemmen Mar 10, 2025
07e0ccc
Update ncview home page
mhoemmen Mar 10, 2025
6cb325e
C: temporarily fix sim params
mhoemmen Mar 12, 2025
fc81e1e
C: output control (still need to test)
mhoemmen Mar 12, 2025
bb31b7b
C: Remove hard-coding of parameters
mhoemmen Mar 12, 2025
4303ec0
Python: x boundary injection hack
mhoemmen Mar 12, 2025
8c41a31
Build script: Change default model
mhoemmen Mar 17, 2025
74a519e
Python: Add option only to output theta (temp density)
mhoemmen Mar 17, 2025
9483925
Python: Remove injection boundary special case
mhoemmen Mar 17, 2025
a01bc20
Python: Restore default model
mhoemmen Mar 17, 2025
275067f
Add cpp-mdspan directory
mhoemmen Mar 20, 2025
dcdf428
Fix mdspan include path
mhoemmen Mar 20, 2025
0c62b3f
Fix mdspan build
mhoemmen Mar 21, 2025
50f71d0
Add unique_mdarray implementation
mhoemmen Mar 21, 2025
5c1cdde
Start mdspan port
mhoemmen Mar 24, 2025
4ad6128
C++-ify reductions
mhoemmen Mar 24, 2025
4ffd9a4
output: start using mdspan for state
mhoemmen Mar 24, 2025
709c087
Fix view_3d layout; mdspan-ify more
mhoemmen Mar 24, 2025
5bd6d57
mdspan-ify set_halo_values_x
mhoemmen Mar 24, 2025
be53e63
mdspan-ify set_halo_values_z
mhoemmen Mar 24, 2025
bc30d70
Start mdspan-ifying compute_tendencies_x
mhoemmen Mar 24, 2025
e6ac6b2
Fully mdspan-ify state
mhoemmen Mar 24, 2025
1c5da0b
Add make_unique_mdarray extents and IndexType... overloads
mhoemmen Mar 24, 2025
f89c27d
Finish mdspan-ifying state
mhoemmen Mar 24, 2025
1b57a07
mdspan-ify flux & tend in compute_tendencies_{x,z}
mhoemmen Mar 24, 2025
2c8c766
Add make_unique_mdarray tests
mhoemmen Mar 24, 2025
4e478b4
Add make_unique_mdarray taking index_type extents
mhoemmen Mar 24, 2025
9541d31
mdspan-ify flux and tend
mhoemmen Mar 24, 2025
ca60a5c
Make Python miniWeather comparable to C
mhoemmen Mar 24, 2025
160dae6
More C++-ification and reformatting
mhoemmen Mar 24, 2025
3e911e5
Remove most global state
mhoemmen Mar 25, 2025
32a0a3a
Remove num_out and direction_switch global state
mhoemmen Mar 25, 2025
c83a9c8
Separate const and nonconst arrays
mhoemmen Mar 25, 2025
5801600
De-globalize etime and output_counter
mhoemmen Mar 25, 2025
f143b94
Start abstracting global arrays
mhoemmen Mar 25, 2025
a6a30c7
Encapsulate storage for const arrays
mhoemmen Mar 25, 2025
351e529
Optimize extents and allocation
mhoemmen Mar 25, 2025
d7883a8
Separate const and nonconst scalars
mhoemmen Mar 26, 2025
204e8d1
More mutable state encapsulation
mhoemmen Mar 26, 2025
f526c70
Push temp arrays inside loops
mhoemmen Mar 26, 2025
f41e369
Add CUB_INCLUDE_DIR autodetection
mhoemmen Mar 26, 2025
5235234
Improve CUB include path autodetection
mhoemmen Mar 26, 2025
add7b15
Increase required CMake version for better NVHPC support
mhoemmen Mar 31, 2025
91446c9
Start adding Kokkos and OpenACC support
mhoemmen Mar 31, 2025
f765513
Simplify FetchContent use
mhoemmen Mar 31, 2025
7ef97ce
Abstract memory space (for allocations and deallocations)
mhoemmen Mar 31, 2025
4a8d84a
Use Kokkos' mdspan if available
mhoemmen Mar 31, 2025
581cd58
Clean up CMake build logic
mhoemmen Apr 1, 2025
9c2fc14
Refactor miniWeather
mhoemmen Apr 4, 2025
f02431e
Kokkos and serial builds now work
mhoemmen Apr 4, 2025
4825fae
Enable Kokkos OpenACC build
mhoemmen Apr 7, 2025
d94a521
Add stdpar implementation and builds
mhoemmen Apr 8, 2025
c9ac577
Add -Wall to NVHPC build
mhoemmen Apr 8, 2025
c4f3d66
Fix builds and disable builds that don't currently work
mhoemmen Apr 8, 2025
fa546d9
Factor out memory allocation into separate headers
mhoemmen Apr 16, 2025
a46d039
Finish factoring out memory allocation
mhoemmen Apr 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ Once the time tendency is computed, the fluid PDEs are essentially now cast as a

* Parallel-netcdf: https://github.com/Parallel-NetCDF/PnetCDF
* This is a dependency for two reasons: (1) NetCDF files are easy to visualize and convenient to work with; (2) The users of this code shouldn't have to write their own parallel I/O.
* Ncview: http://meteora.ucsd.edu/~pierce/ncview_home_page.html
* Ncview: https://cirrus.ucsd.edu/ncview/
* This is the easiest way to visualize NetCDF files.
* MPI
* For OpenACC: An OpenACC-capable compiler (PGI / Nvidia, Cray, GNU)
Expand Down
17 changes: 17 additions & 0 deletions c/build/cmake_kermit.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

PNETCDF_ROOT=/raid/mhoemmen/pkg/pnetcdf-1.14.0
SRC_ROOT=/raid/mhoemmen/src/miniWeather/c
OPT_FLAGS="-g -O2"

cmake \
-DCMAKE_CXX_COMPILER=mpic++ \
-DCMAKE_C_COMPILER=mpicc \
-DCMAKE_Fortran_COMPILER=mpif90 \
-DCXXFLAGS="${OPT_FLAGS} -I${PNETCDF_ROOT}/include" \
-DLDFLAGS="-L${PNETCDF_ROOT}/lib -lpnetcdf" \
-DNX=100 \
-DNZ=50 \
-DSIM_TIME=20 \
-DOUT_FREQ=10 \
${SRC_ROOT}
25 changes: 25 additions & 0 deletions c/build/cmake_linux_gnu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

SRC_ROOT=../../../src/miniWeather/c
OPT_FLAGS="-g -O2"

#PNETCDF_LIB=/usr/lib/x86_64-linux-gnu
#PNETCDF_LDFLAGS="-L${PNETCDF_LIB} -lpnetcdf"
PNETCDF_LDFLAGS="-lpnetcdf"
#PNETCDF_CXXFLAGS="-I$/usr/include"
PNETCDF_CXXFLAGS=""

DATA_SPEC="DATA_SPEC_COLLISION"

cmake \
-DCMAKE_CXX_COMPILER=mpic++ \
-DCMAKE_C_COMPILER=mpicc \
-DCMAKE_Fortran_COMPILER=mpif90 \
-DCXXFLAGS="${OPT_FLAGS} ${PNETCDF_CXXFLAGS}" \
-DLDFLAGS="${PNETCDF_LDFLAGS}" \
-DNX=200 \
-DNZ=100 \
-DSIM_TIME=1000 \
-DOUT_FREQ=10 \
-DDATA_SPEC="${DATA_SPEC}" \
${SRC_ROOT}
82 changes: 64 additions & 18 deletions c/miniWeather_serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include "pnetcdf.h"
#include <chrono>

#define MINIWEATHER_ONLY_OUTPUT_THETA 1

constexpr double pi = 3.14159265358979323846264338327; //Pi
constexpr double grav = 9.8; //Gravitational acceleration (m / s^2)
constexpr double cp = 1004.; //Specific heat of dry air at constant pressure
Expand Down Expand Up @@ -56,8 +58,9 @@ constexpr double qweights[] = { 0.277777777777777777777777777779E0 , 0.444444444
///////////////////////////////////////////////////////////////////////////////////////
//The x-direction length is twice as long as the z-direction length
//So, you'll want to have nx_glob be twice as large as nz_glob
int constexpr nx_glob = _NX; //Number of total cells in the x-direction

int constexpr nz_glob = _NZ; //Number of total cells in the z-direction
int constexpr nx_glob = 2 * nz_glob; //Number of total cells in the x-direction
double constexpr sim_time = _SIM_TIME; //How many seconds to run the simulation
double constexpr output_freq = _OUT_FREQ; //How frequently to output data to file (in seconds)
int constexpr data_spec_int = _DATA_SPEC; //How to initialize the data
Expand Down Expand Up @@ -132,6 +135,10 @@ int main(int argc, char **argv) {

//Initial reductions for mass, kinetic energy, and total energy
reductions(mass0,te0);
{
fprintf(stderr, "mass0: %le\n" , mass0);
fprintf(stderr, "te0: %le\n" , te0 );
}

//Output the initial state
output(state,etime);
Expand All @@ -147,7 +154,7 @@ int main(int argc, char **argv) {
perform_timestep(state,state_tmp,flux,tend,dt);
//Inform the user
#ifndef NO_INFORM
if (mainproc) { printf( "Elapsed Time: %lf / %lf\n", etime , sim_time ); }
if (mainproc) { fprintf(stderr, "Elapsed Time: %lf / %lf\n", etime , sim_time ); }
#endif
//Update the elapsed time and output counter
etime = etime + dt;
Expand All @@ -157,18 +164,27 @@ int main(int argc, char **argv) {
output_counter = output_counter - output_freq;
output(state,etime);
}
#if 0
{
double mass = 0.0;
double te = 0.0;
reductions(mass, te);
fprintf(stderr, "mass: %le\n" , mass );
fprintf(stderr, "te: %le\n" , te );
}
#endif // 0
}
auto t2 = std::chrono::steady_clock::now();
if (mainproc) {
std::cout << "CPU Time: " << std::chrono::duration<double>(t2-t1).count() << " sec\n";
std::cerr << "CPU Time: " << std::chrono::duration<double>(t2-t1).count() << " sec\n";
}

//Final reductions for mass, kinetic energy, and total energy
reductions(mass,te);

if (mainproc) {
printf( "d_mass: %le\n" , (mass - mass0)/mass0 );
printf( "d_te: %le\n" , (te - te0 )/te0 );
fprintf(stderr, "d_mass: %le\n" , (mass - mass0)/mass0 );
fprintf(stderr, "d_te: %le\n" , (te - te0 )/te0 );
}

finalize();
Expand All @@ -183,6 +199,7 @@ int main(int argc, char **argv) {
// q** = q[n] + dt/2 * rhs(q* )
// q[n+1] = q[n] + dt/1 * rhs(q** )
void perform_timestep( double *state , double *state_tmp , double *flux , double *tend , double dt ) {
//fprintf(stderr, "direction_switch: %d\n", direction_switch);
if (direction_switch) {
//x-direction first
semi_discrete_step( state , state , state_tmp , dt / 3 , DIR_X , flux , tend );
Expand Down Expand Up @@ -523,9 +540,9 @@ void init( int *argc , char ***argv ) {

//If I'm the main process in MPI, display some grid information
if (mainproc) {
printf( "nx_glob, nz_glob: %d %d\n", nx_glob, nz_glob);
printf( "dx,dz: %lf %lf\n",dx,dz);
printf( "dt: %lf\n",dt);
fprintf(stderr, "nx_glob, nz_glob: %d %d\n", nx_glob, nz_glob);
fprintf(stderr, "dx,dz: %lf %lf\n",dx,dz);
fprintf(stderr, "dt: %lf\n",dt);
}
//Want to make sure this info is displayed before further output
ierr = MPI_Barrier(MPI_COMM_WORLD);
Expand Down Expand Up @@ -722,70 +739,92 @@ double sample_ellipse_cosine( double x , double z , double amp , double x0 , dou
//The file I/O uses parallel-netcdf, the only external library required for this mini-app.
//If it's too cumbersome, you can comment the I/O out, but you'll miss out on some potentially cool graphics
void output( double *state , double etime ) {
#if 1
int ncid, t_dimid, x_dimid, z_dimid, dens_varid, uwnd_varid, wwnd_varid, theta_varid, t_varid, dimids[3];
int i, k, ind_r, ind_u, ind_w, ind_t;
MPI_Offset st1[1], ct1[1], st3[3], ct3[3];
//Temporary arrays to hold density, u-wind, w-wind, and potential temperature (theta)
double *dens, *uwnd, *wwnd, *theta;
double *etimearr;
//Inform the user
if (mainproc) { printf("*** OUTPUT ***\n"); }
if (mainproc) { fprintf(stderr, "*** OUTPUT ***\n"); }
//Allocate some (big) temp arrays
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
dens = (double *) malloc(nx*nz*sizeof(double));
uwnd = (double *) malloc(nx*nz*sizeof(double));
wwnd = (double *) malloc(nx*nz*sizeof(double));
#endif
theta = (double *) malloc(nx*nz*sizeof(double));
etimearr = (double *) malloc(1 *sizeof(double));

// PNetCDF needs an MPI_Info object that is not MPI_INFO_NULL.
// It's possible that earlier PNetCDF versions tolerated MPI_INFO_NULL.
MPI_Info mpi_info;
auto info_err = MPI_Info_create(&mpi_info);
if (info_err != MPI_SUCCESS) {
fprintf(stderr, "Error creating MPI Info object\n");
MPI_Abort(MPI_COMM_WORLD, -1);
}

//If the elapsed time is zero, create the file. Otherwise, open the file
if (etime == 0) {
//Create the file
ncwrap( ncmpi_create( MPI_COMM_WORLD , "output.nc" , NC_CLOBBER , MPI_INFO_NULL , &ncid ) , __LINE__ );
ncwrap( ncmpi_create( MPI_COMM_WORLD , "output.nc" , NC_CLOBBER , mpi_info , &ncid ) , __LINE__ );
//Create the dimensions
ncwrap( ncmpi_def_dim( ncid , "t" , (MPI_Offset) NC_UNLIMITED , &t_dimid ) , __LINE__ );
ncwrap( ncmpi_def_dim( ncid , "x" , (MPI_Offset) nx_glob , &x_dimid ) , __LINE__ );
ncwrap( ncmpi_def_dim( ncid , "z" , (MPI_Offset) nz_glob , &z_dimid ) , __LINE__ );
//Create the variables
dimids[0] = t_dimid;
ncwrap( ncmpi_def_var( ncid , "t" , NC_DOUBLE , 1 , dimids , &t_varid ) , __LINE__ );
ncwrap( ncmpi_def_var( ncid , "t_var" , NC_DOUBLE , 1 , dimids , &t_varid ) , __LINE__ );
dimids[0] = t_dimid; dimids[1] = z_dimid; dimids[2] = x_dimid;
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
ncwrap( ncmpi_def_var( ncid , "dens" , NC_DOUBLE , 3 , dimids , &dens_varid ) , __LINE__ );
ncwrap( ncmpi_def_var( ncid , "uwnd" , NC_DOUBLE , 3 , dimids , &uwnd_varid ) , __LINE__ );
ncwrap( ncmpi_def_var( ncid , "wwnd" , NC_DOUBLE , 3 , dimids , &wwnd_varid ) , __LINE__ );
#endif
ncwrap( ncmpi_def_var( ncid , "theta" , NC_DOUBLE , 3 , dimids , &theta_varid ) , __LINE__ );
//End "define" mode
ncwrap( ncmpi_enddef( ncid ) , __LINE__ );
} else {
//Open the file
ncwrap( ncmpi_open( MPI_COMM_WORLD , "output.nc" , NC_WRITE , MPI_INFO_NULL , &ncid ) , __LINE__ );
ncwrap( ncmpi_open( MPI_COMM_WORLD , "output.nc" , NC_WRITE , mpi_info , &ncid ) , __LINE__ );
//Get the variable IDs
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
ncwrap( ncmpi_inq_varid( ncid , "dens" , &dens_varid ) , __LINE__ );
ncwrap( ncmpi_inq_varid( ncid , "uwnd" , &uwnd_varid ) , __LINE__ );
ncwrap( ncmpi_inq_varid( ncid , "wwnd" , &wwnd_varid ) , __LINE__ );
#endif
ncwrap( ncmpi_inq_varid( ncid , "theta" , &theta_varid ) , __LINE__ );
ncwrap( ncmpi_inq_varid( ncid , "t" , &t_varid ) , __LINE__ );
ncwrap( ncmpi_inq_varid( ncid , "t_var" , &t_varid ) , __LINE__ );
}

//Store perturbed values in the temp arrays for output
for (k=0; k<nz; k++) {
for (i=0; i<nx; i++) {
ind_r = ID_DENS*(nz+2*hs)*(nx+2*hs) + (k+hs)*(nx+2*hs) + i+hs;
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
ind_u = ID_UMOM*(nz+2*hs)*(nx+2*hs) + (k+hs)*(nx+2*hs) + i+hs;
ind_w = ID_WMOM*(nz+2*hs)*(nx+2*hs) + (k+hs)*(nx+2*hs) + i+hs;
#endif
ind_t = ID_RHOT*(nz+2*hs)*(nx+2*hs) + (k+hs)*(nx+2*hs) + i+hs;
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
dens [k*nx+i] = state[ind_r];
uwnd [k*nx+i] = state[ind_u] / ( hy_dens_cell[k+hs] + state[ind_r] );
wwnd [k*nx+i] = state[ind_w] / ( hy_dens_cell[k+hs] + state[ind_r] );
#endif
theta[k*nx+i] = ( state[ind_t] + hy_dens_theta_cell[k+hs] ) / ( hy_dens_cell[k+hs] + state[ind_r] ) - hy_dens_theta_cell[k+hs] / hy_dens_cell[k+hs];
}
}

//Write the grid data to file with all the processes writing collectively
st3[0] = num_out; st3[1] = k_beg; st3[2] = i_beg;
ct3[0] = 1 ; ct3[1] = nz ; ct3[2] = nx ;
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
ncwrap( ncmpi_put_vara_double_all( ncid , dens_varid , st3 , ct3 , dens ) , __LINE__ );
ncwrap( ncmpi_put_vara_double_all( ncid , uwnd_varid , st3 , ct3 , uwnd ) , __LINE__ );
ncwrap( ncmpi_put_vara_double_all( ncid , wwnd_varid , st3 , ct3 , wwnd ) , __LINE__ );
#endif
ncwrap( ncmpi_put_vara_double_all( ncid , theta_varid , st3 , ct3 , theta ) , __LINE__ );

//Only the main process needs to write the elapsed time
Expand All @@ -795,32 +834,39 @@ void output( double *state , double etime ) {
if (mainproc) {
st1[0] = num_out;
ct1[0] = 1;
etimearr[0] = etime; ncwrap( ncmpi_put_vara_double( ncid , t_varid , st1 , ct1 , etimearr ) , __LINE__ );
etimearr[0] = etime;
ncwrap( ncmpi_put_vara_double( ncid , t_varid , st1 , ct1 , etimearr ) , __LINE__ );
}
//End "independent" write mode
ncwrap( ncmpi_end_indep_data(ncid) , __LINE__ );

//Close the file
ncwrap( ncmpi_close(ncid) , __LINE__ );

#endif // 0
//Increment the number of outputs
num_out = num_out + 1;

#if 1
MPI_Info_free(&mpi_info);

//Deallocate the temp arrays
#if ! defined(MINIWEATHER_ONLY_OUTPUT_THETA)
free( dens );
free( uwnd );
free( wwnd );
#endif
free( theta );
free( etimearr );
#endif // 0
}


//Error reporting routine for the PNetCDF I/O
void ncwrap( int ierr , int line ) {
if (ierr != NC_NOERR) {
printf("NetCDF Error at line: %d\n", line);
printf("%s\n",ncmpi_strerror(ierr));
exit(-1);
fprintf(stderr, "NetCDF Error at line: %d\n", line);
fprintf(stderr, "%s\n", ncmpi_strerror(ierr));
MPI_Abort(MPI_COMM_WORLD, -1);
}
}

Expand Down
Loading