diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 259af50902f562e8dac183b90138302e34e2f2a3..20dc724459392f59604c42f757e45a666c7808a5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,13 +10,17 @@ before_script: ENV HW_FLAGS="-Wl,--no-as-needed" ENV MPIRUN='mpirun --allow-run-as-root -n 2' ENV OMP_NUM_THREADS=2 - ARG USER - ARG PASS - RUN git config --global url."https://\${USER}:\${PASS}@www.ict.inaf.it/gitlab".insteadOf ssh://git@git.ia2.inaf.it + RUN apt-get install -y libgsl-dev libgsl27 + RUN pip install matplotlib + RUN apt-get install -y libfftw3-dev libfftw3-mpi-dev + RUN apt-get install -y wget + RUN pip install Jinja2 numpy PyYAML libclang numba + RUN git config --global url."https://${CI_REGISTRY_USER}:${CI_JOB_TOKEN}@www.ict.inaf.it/gitlab".insteadOf ssh://git@git.ia2.inaf.it WORKDIR /app COPY . /app EOF -testing: +install: script: - - docker run hwmd bash -c './test_install_octree.bash; ./test_checkup.bash; ./test_pip_all.bash; ./test_editable.bash; ./test_bulk.bash' \ No newline at end of file + - docker run hwmd bash -c 'set -xev; . test_install_octree.bash && . test_checkup.bash && . test_pip_all.bash && . test_editable.bash && . test_bulk.bash' + - docker run hwmd bash -c 'set -xev; . test_install_pm.bash && python3 test_dmo_NFW_fixed_timestep.py' diff --git a/run_pm_dmo_NFW_fixed_timestep.md b/run_pm_dmo_NFW_fixed_timestep.md index 9365f0b18846a18fc534face311e1146645260c1..da7cc74366cfce60336a10fdb0afc2f6c644ce41 100644 --- a/run_pm_dmo_NFW_fixed_timestep.md +++ b/run_pm_dmo_NFW_fixed_timestep.md @@ -8,92 +8,11 @@ Here is a first benefit of a modular code: since in `hotwheels `PM is a self-con Install the PM module (will install core,IO, and timestep as dependencies): ```bash -pip install 'howtheels_PM[tested] @ git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.0alpha' +::include{file=test_install_pm.bash} ``` And you can run this code: ```python -import numpy as np, os, matplotlib as plt -from hotwheels.utils import * -from hotwheels.wrap import * -from hotwheels.soas import * -from hotwheels.PM import * -from hotwheels.integrate import * -from hotwheels.io import * - -# -# Step 1: Configure components -# This stage configures components without allocating resources. -# Configurations are passed to constructors to compile the underlying C libraries. -# - -mpi = MPI().init() # Initialize MPI -mym = MyMalloc(alloc_bytes=int(2e9)) # Configure memory allocator with 2GB -p = SoA(maxpart=int(1e5), mem=mym) # Configure P to hold 1e5 particles -soas = SoAs(p) # Add P to a multi-type SoA container -# Set up a fixed time-step integrator from 0 to 1 Gyr -# Conversion factor for Gyr to internal units -gyr_to_cu = 3.086e+16 / (1e9 * 3600 * 24 * 365) -ts = FixedTimeStep( - soas, - G=43007.1, # Gravitational constant in specific units - t_from=0., - t_to=1. * gyr_to_cu, - MPI=mpi -) -# Initialize a NFW profile with scale radius `rs=100` and density `rho0=1e-6` -ic = NFWIC(r_s=100., rho_0=1e-6, r_max_f=10.) -# Configure a refined PM grid with 7 stacked high-resolution regions -pm = SuperHiResPM( #wrapper to the PM C library - soas=soas, - mem=mym, - TS=ts, #will use it to attach gravkick callback - MPI=mpi, - pmgrid=128, - grids=8, # number of grids to instantiate - dt_displacement_factor=0.25 #factor for DtDisplacement -) -build = make.Build('./', mpi, pm, ts, mym, *soas.values()) # Compile all modules in the current directory -headers = OnTheFly(build.build_name, *build.components, generate_user_c=True) # Generate SoA headers - -if mpi.rank == 0: # Master rank handles compilation - headers.write() - build.compile() - -# -# Step 2: Allocate resources -# - -with ( - Panic(Build=build) as panic, # Attach panic handler - Timer(Build=build) as timer, # Attach timer handler - build.enter(debug=mpi.rank == 0), # Parse compiled objects - mpi.enter(pm), # Initialize MPI in the PM module - mym.enter(*build.components), # Allocate 2GB memory - p, # Allocate particle data structure in MyMalloc - ic.enter(p, mpi.ranks, p.get_maxpart(), ts.G), # Sample NFW profile - pm, # Initialize PM and compute first accelerations - ts # Compute DriftTables if needed -): - - # - # Step 3: Main simulation loop - # - while ts.time < ts.time_end: - ts.find_timesteps() # Determine timesteps - ts.do_first_halfstep_kick() # First kick (includes drift/kick callbacks) - ts.drift() # Update particle positions - pm.compute_accelerations() # Recompute accelerations - ts.do_second_halfstep_kick() # Second kick - - # Occasionally, generate plots on the master rank - if mpi.rank == 0 and ts.steps % 10 == 0: - fig, ax = plt.subplots(1) - ax.hist2d(p['pos'][:, 0], p['pos'][:, 1], bins=128) - ax.set_aspect('equal') - fig.savefig(f'snap{ts.steps}_rank{mpi.rank}.png', bbox_inches='tight', dpi=200) - plt.close(fig) - -print('Simulation finished') +::include{file=test_dmo_NFW_fixed_timestep.py} ``` \ No newline at end of file diff --git a/test_dmo_NFW_fixed_timestep.py b/test_dmo_NFW_fixed_timestep.py new file mode 100644 index 0000000000000000000000000000000000000000..1a87a19abc58fa5619759b145ce62dc834bdb93b --- /dev/null +++ b/test_dmo_NFW_fixed_timestep.py @@ -0,0 +1,82 @@ +import numpy as np, os, matplotlib as plt +from hotwheels_core.utils import * +from hotwheels_core.wrap import * +from hotwheels_core.soas import * +from hotwheels_PM import * +from hotwheels_integrate import * +from hotwheels_io import * + +# +# Step 1: Configure components +# This stage configures components without allocating resources. +# Configurations are passed to constructors to compile the underlying C libraries. +# + +mpi = MPI().init() # Initialize MPI +mym = MyMalloc(alloc_bytes=int(2e9)) # Configure memory allocator with 2GB +p = SoA(maxpart=int(1e5), mem=mym) # Configure P to hold 1e5 particles +soas = SoAs(p) # Add P to a multi-type SoA container +# Set up a fixed time-step integrator from 0 to 1 Gyr +# Conversion factor for Gyr to internal units +gyr_to_cu = 3.086e+16 / (1e9 * 3600 * 24 * 365) +ts = FixedTimeStep( + soas, + G=43007.1, # Gravitational constant in specific units + t_from=0., + t_to=1. * gyr_to_cu, + MPI=mpi +) +# Initialize a NFW profile with scale radius `rs=100` and density `rho0=1e-6` +ic = NFWIC(r_s=100., rho_0=1e-6, r_max_f=10.) +# Configure a refined PM grid with 7 stacked high-resolution regions +pm = SuperHiResPM( #wrapper to the PM C library + soas=soas, + mem=mym, + TS=ts, #will use it to attach gravkick callback + MPI=mpi, + pmgrid=128, + grids=8, # number of grids to instantiate + dt_displacement_factor=0.25 #factor for DtDisplacement +) +build = make.Build('./', mpi, pm, ts, mym, *soas.values()) # Compile all modules in the current directory +headers = OnTheFly(build.build_name, *build.components, generate_user_c=True) # Generate SoA headers + +if mpi.rank == 0: # Master rank handles compilation + headers.write() + build.compile() + +# +# Step 2: Allocate resources +# + +with ( + Panic(Build=build) as panic, # Attach panic handler + Timer(Build=build) as timer, # Attach timer handler + build.enter(debug=mpi.rank == 0), # Parse compiled objects + mpi.enter(pm), # Initialize MPI in the PM module + mym.enter(*build.components), # Allocate 2GB memory + p, # Allocate particle data structure in MyMalloc + ic.enter(p, mpi.ranks, p.get_maxpart(), ts.G), # Sample NFW profile + pm, # Initialize PM and compute first accelerations + ts # Compute DriftTables if needed +): + + # + # Step 3: Main simulation loop + # + while ts.time < ts.time_end: + ts.find_timesteps() # Determine timesteps + ts.do_first_halfstep_kick() # First kick (includes drift/kick callbacks) + ts.drift() # Update particle positions + pm.compute_accelerations() # Recompute accelerations + ts.do_second_halfstep_kick() # Second kick + + # Occasionally, generate plots on the master rank + if mpi.rank == 0 and ts.steps % 10 == 0: + fig, ax = plt.subplots(1) + ax.hist2d(p['pos'][:, 0], p['pos'][:, 1], bins=128) + ax.set_aspect('equal') + fig.savefig(f'snap{ts.steps}_rank{mpi.rank}.png', bbox_inches='tight', dpi=200) + plt.close(fig) + +print('Simulation finished') diff --git a/test_editable.bash b/test_editable.bash index 42fe3c732542f4a3b9433667cd67c5569c091226..a44a640bd63600aad611b1b261052ba3d82c6a1a 100755 --- a/test_editable.bash +++ b/test_editable.bash @@ -1,8 +1,9 @@ -git clone ssh://git@git.ia2.inaf.it/hotwheels/timestep.git -cd timestep +git clone ssh://git@git.ia2.inaf.it/hotwheels/integrate.git +cd integrate # very IMPORTANT the -e will install in editable mode pip install -e . # # edit the files of your choice. Edits will take effect # without the need of re-installing the package # +cd .. diff --git a/test_install_pm.bash b/test_install_pm.bash new file mode 100644 index 0000000000000000000000000000000000000000..c240626b3c03e54a3eedaba6a62bc0dc15aedfef --- /dev/null +++ b/test_install_pm.bash @@ -0,0 +1 @@ +pip install 'hotwheels_PM[tested] @ git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.2alpha' diff --git a/test_pip_all.bash b/test_pip_all.bash index 356cabb80bd5101d69dc0995e52a6ed18f720aea..aff7760218360074048aaaf75d8de4587db35e2f 100755 --- a/test_pip_all.bash +++ b/test_pip_all.bash @@ -1,6 +1,6 @@ pip install git+ssh://git@git.ia2.inaf.it/hotwheels/core.git@v0.0.2alpha pip install git+ssh://git@git.ia2.inaf.it/hotwheels/io.git@v0.0.2alpha -pip install git+ssh://git@git.ia2.inaf.it/hotwheels/timestep.git@v0.0.2alpha +pip install git+ssh://git@git.ia2.inaf.it/hotwheels/integrate.git@v0.0.2alpha pip install git+ssh://git@git.ia2.inaf.it/hotwheels/octree.git@v0.0.2alpha pip install git+ssh://git@git.ia2.inaf.it/hotwheels/domain.git@v0.0.2alpha pip install git+ssh://git@git.ia2.inaf.it/hotwheels/PM.git@v0.0.2alpha