Custom Docker Images#
In this tutorial, we will guide you through running simulations with custom Docker images. This can be particularly useful if you need to use a specific version of software that isn’t available on our Docker Hub. Using this feature, you can run your own Docker image on the platform.
This tutorial will focus on two main points:
The simulator you want to use
The inputs required by that simulator
CustomImage Simulator#
The CustomImage
simulator allows you to specify a container_image
pointing
to your custom Docker image. Besides the container_image
, this simulator
accepts a list of commands to run inside the container. These are the only
special parameters for this simulator. The rest are the same as other simulators.
Here’s an example of how to use the CustomImage
simulator:
import inductiva
# Instantiate machine group
machine_group = inductiva.resources.MachineGroup("c2-standard-4")
machine_group.start()
input_dir = inductiva.utils.download_from_url(
"https://storage.googleapis.com/inductiva-api-demo-files/fds-input-example.zip", unzip=True)
custom_simulator = inductiva.simulators.CustomImage(container_image="docker://inductiva/kutu:fds_v6.8")
task = custom_simulator.run(input_dir=input_dir, commands=["fds mccaffrey.fds"],
on=machine_group)
task.wait()
task.download_outputs()
machine_group.terminate()
This basic example demonstrates how to run a custom Docker image. To leverage
this feature fully, we introduce the Command
and MPIConfig
classes, which
enable you to run commands on MPI clusters supporting multiple MPI versions.
Command and MPIConfig#
In the previous example, commands
is a list of strings to be run inside the
container. For more advanced usage, such as running a command with a specific
MPI version, use the Command
and MPIConfig
classes. A list of commands
can
include Command
instances, each potentially having an MPIConfig
. Here’s an
example:
import inductiva
# Instantiate machine group
machine_group = inductiva.resources.MachineGroup("c2-standard-4")
machine_group.start()
input_dir = inductiva.utils.download_from_url(
"https://storage.googleapis.com/inductiva-api-demo-files/fds-input-example.zip", unzip=True)
custom_simulator = inductiva.simulators.CustomImage(container_image="docker://inductiva/kutu:fds_v6.8")
mpi_config = inductiva.commands.MPIConfig("4.1.6", np=4, use_hwthread_cpus=True)
command = inductiva.commands.Command("fds mccaffrey.fds", mpi_config=mpi_config)
task = custom_simulator.run(input_dir=input_dir, commands=[command],
on=machine_group)
task.wait()
task.download_outputs()
machine_group.terminate()
This example runs four instances of your image with the command fds mccaffrey.fds
using MPI version 4.1.6, equivalent to:
mpirun -np 4 -use_hwthread_cpus apptainer run ... fds mccaffrey.fds
Alternatively, you can run MPI directly inside your container with:
import inductiva
# Instantiate machine group
machine_group = inductiva.resources.MachineGroup("c2-standard-4")
machine_group.start()
input_dir = inductiva.utils.download_from_url(
"https://storage.googleapis.com/inductiva-api-demo-files/fds-input-example.zip", unzip=True)
custom_simulator = inductiva.simulators.CustomImage(container_image="docker://inductiva/kutu:fds_v6.8")
command = inductiva.commands.Command("mpirun -np 4 --use-hwthread-cpus fds mccaffrey.fds")
task = custom_simulator.run(input_dir=input_dir, commands=[command],
on=machine_group)
task.wait()
task.download_outputs()
machine_group.terminate()
This runs:
apptainer run ... mpirun -np 4 -use_hwthread_cpus fds mccaffrey.fds
Ensure the MPI version in your container matches the one specified in MPIConfig
.
For instance, if your container has OpenMPI 1.10.6, choose a compatible OpenMPI
version (like 1.10.7) in MPIConfig
.
Currently, we support OpenMPI versions 1.10.7 and 4.1.6. If you need a different version, please contact us at contact@inductiva.ai.
Advanced Tutorial: Running our Reef3D Advanced example#
Let’s now run a more advanced example. For this we will be using our
advanced tutorial on Reef3D
but we will be running it using our CustomImage
simulator.
We will be skipping some explenations related with Reef3D and will focus more on
the parts related with the CustomImage
simulator.
Aim of This Tutorial#
This tutorial will guide you through running a simulation on our platform using a custom Docker image so you can run your own docker images in the future.
Prerequisites#
Download Input Files: Get the input files from the Reef3D tutorials.
Directory Structure:
ls -lasgo . total 16 0 drwxrwxr-x@ 4 128 Sep 4 08:46 . 0 drwxrwxr-x@ 19 608 Nov 5 09:03 .. 8 -rw-rw-r--@ 1 142 Sep 4 08:46 control.txt 8 -rw-rw-r--@ 1 141 Sep 4 08:46 ctrl.txt
control.txt (for DiveMESH):
C 11 21 C 12 21 C 13 21 C 14 21 C 15 21 C 16 21 B 1 0.025 B 10 0.0 2.0 0.0 1.0 0.0 1.0 O 10 1.2 1.4 0.4 0.6 0.0 1.0 M 10 4 ---- defines the nr. of processors for parallel computations (4)
ctrl.txt (for Reef3D):
D 10 4 D 20 2 D 30 1 F 30 3 F 40 3 F 54 0.5 F 56 0.7 N 40 3 N 41 25.0 ---- set the maximum modeled time (25 seconds). N 45 50000 N 47 0.2 M 10 4 ---- defines the nr. of processors for parallel computations (4) P 10 1 P 30 0.01 ---- defines the rate of paraview results (1 frame per 0.01 s) T 10 0 W 22 -9.81
Overview#
Here’s the code you’ll be working on as we progress through the tutorial. Don’t worry if it doesn’t all make sense right now; everything will become clearer in the upcoming steps.
import inductiva
machine_group = inductiva.resources.MachineGroup(
machine_type="c2d-highcpu-112",
spot=True,
data_disk_gb=20,
auto_resize_disk_max_gb=250)
machine_group.start()
input_dir = "path/to/10_2 3D Dam Break with Obstacle"
#Choose your simulator
customImage = inductiva.simulators.CustomImage(
container_image="docker://inductiva/kutu:reef3d_v24.02")
# Define the MPI configuration
mpi_config = inductiva.commands.MPIConfig("4.1.6", np=56, use_hwthread_cpus=False)
# Define the commands to run with the MPI configuration
command = inductiva.commands.Command("/REEF3D/bin/REEF3D", mpi_config=mpi_config)
# List of commands to run our simulation
commands = [
"/DIVEMesh/bin/DiveMESH",
command
]
task = customImage.run(
input_dir=input_dir,
commands=commands,
on=machine_group,
n_vcpus=56,
use_hwthread=False,
storage_dir="3D_dam_break_with_obstacle")
task.wait()
machine_group.terminate()
task.print_summary()
Step 1: Adjust Simulation Parameters#
For a faster simulation, modify the following parameters in both files:
Level of parallelism (
M 10
): 56Simulation time (
N 41
): 25.0Paraview results rate (
P 30
): 0.01
Step 2: Running the Simulation#
a. Configure and Start Machine#
Pick your machine:
Our
CustomImage
simulator will work with any machine type. So, we decided to use the same machine as in the previous tutorial, thec2d-highcpu-112
with the same configuration.import inductiva machine_group = inductiva.resources.MachineGroup( machine_type="c2d-highcpu-112", spot=True, data_disk_gb=20, auto_resize_disk_max_gb=250)
Note:
spot
machines are a lot cheaper but can be terminated by the provider if needed.Start your machine
machine_group.start()
b. Define Simulation Inputs#
Specify Simulation Directory: Let’s start by defining a variable that points to the
10_2_3D_Dam_Break_with_Obstacle
folder where all your simulation files are located.input_dir = "./10_2_3D_Dam_Break_with_Obstacle"
Choose Your Simulator:
This step is straightforward. We will be using the CustomImage
simulator to
run our custom Docker image. The container_image
parameter points to the
Docker image we want to use.
customImage = inductiva.simulators.CustomImage(
container_image="docker://inductiva/kutu:reef3d_v24.02")
Define Commands: Our
CustomImage
simulator accepts a list of commands to run inside the container. We will be running two commands:DiveMESH
andREEF3D
, present in the Reef3D image.# Define the MPI configuration mpi_config = inductiva.commands.MPIConfig("4.1.6", np=56, use_hwthread_cpus=False) # Define the commands to run with the MPI configuration command = inductiva.commands.Command("/REEF3D/bin/REEF3D", mpi_config=mpi_config) # List of commands to run our simulation commands = [ "/DIVEMesh/bin/DiveMESH", command ]
Lets talk about the
MPIConfig
for a command. TheMPIConfig
class allows you to run your command with a specific MPI version. In this case, we are using OpenMPI version 4.1.6 with 56 processes. Creating your command with anMPIConfig
will parallelize said command across the specified number of processes.Note: Not all commands can be parallelized. Make sure the command you are running supports parallelization.
c. Run Your Simulation#
Run the simulation: We now have everything we need to run our simulation.
task = customImage.run( input_dir=input_dir, commands=commands, on=machine_group, n_vcpus=56, use_hwthread=False, storage_dir="3D_dam_break_with_obstacle")
As you can see, this is very similar to the Reef3D example. The only difference here is that we need to specify the specific commands required to run the simulation.
Wait for the simulation to finish: That is it. Our simulation is now running on the cloud. Every step from now on is the same as the Reef3D example.
task.wait()
Note: run
inductiva logs task_id
to check thestdout
of the simulation process in real time.Terminate Machine: Once our simulation completes, we can/should terminate our machine to save on costs. If you forget, don’t worry—we’ve got you covered. By default, the machine will automatically shut down if idle for 30 minutes with no simulation running.
machine_group.terminate()
Check your simulation summary: Now that our simulation is complete, we can print a summary with key details, including execution times, generated outputs, and more.
task.print_summary()
Conclusion#
Congratulations! You’ve successfully completed the advanced Reef3D example using a custom Docker image on our platform. Through this tutorial, you’ve gained practical experience in configuring and running simulations with custom container images, even setting up parallel computations with MPI.
With these skills, you’re now prepared to run your own custom Docker images in future simulations, tailoring the setup to suit different types of computational requirements. Don’t hesitate to explore other simulations and modify parameters to deepen your understanding of both Reef3D and our custom Docker-based simulator setup.
Happy simulations!