Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 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
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
2 changes: 1 addition & 1 deletion cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ target_link_libraries(parallelfor_simd_x_test "${LDFLAGS}")
add_test(NAME YAKL_SIMD_X_TEST COMMAND ./check_output.sh ./parallelfor_simd_x_test 1e-9 4.5e-5 )


include(YAKL/yakl_utils.cmake)
include(YAKL/deprecated/yakl_utils.cmake)
yakl_process_target(serial)
yakl_process_target(serial_test)
yakl_process_target(mpi)
Expand Down
1 change: 0 additions & 1 deletion cpp/YAKL
Submodule YAKL deleted from 71a059
1 change: 1 addition & 0 deletions cpp/YAKL
Loading