Commit 2a837120 authored by gsaxena's avatar gsaxena
Browse files

Cleaned the predator-prey-mpi example, compilation, execution successful,...

Cleaned the predator-prey-mpi example, compilation, execution successful, output file will contain number of EACH type of cells on EACH MPI process separately, BUT will not mention the type of the cell, have added a comment to this effect in custom.cpp of predator_prey_mpi, changed name of script_project.sh to script_pred_prey_mpi.sh, using the ppr notation now to execute.
parent d812f83d
......@@ -65,27 +65,39 @@
###############################################################################
*/
/*================================================================================
+ If you use PhysiCell-X in your project, we would really appreciate if you can +
+ +
+ [1] Cite the PhysiCell-X repository by giving its URL +
+ +
+ [2] Cite BioFVM-X: +
+ Saxena, Gaurav, Miguel Ponce-de-Leon, Arnau Montagud, David Vicente Dorca, +
+ and Alfonso Valencia. "BioFVM-X: An MPI+ OpenMP 3-D Simulator for Biological +
+ Systems." In International Conference on Computational Methods in Systems +
+ Biology, pp. 266-279. Springer, Cham, 2021. +
=================================================================================*/
#include "./custom.h"
#include "../DistPhy/DistPhy_Utils.h"
#include "../DistPhy/DistPhy_Collective.h"
using namespace DistPhy::mpi;
// declare cell definitions here
// Declare cell definitions here
Cell_Definition motile_cell;
void create_cell_types( void )
{
// set the random seed
// Set the random seed
SeedRandom( parameters.ints("random_seed") );
/*
Put any modifications to default cell definition here if you
want to have "inherited" by other cell types.
This is a good place to set default functions.
*/
/*----------------------------------------------------------------*/
/* Put any modifications to default cell definition here if you */
/* want to have "inherited" by other cell types. */
/* This is a good place to set default functions. */
/*----------------------------------------------------------------*/
cell_defaults.functions.volume_update_function = standard_volume_update_function;
cell_defaults.functions.update_velocity = standard_update_cell_velocity;
......@@ -99,51 +111,55 @@ void create_cell_types( void )
cell_defaults.functions.update_velocity_parallel = standard_update_cell_velocity;
cell_defaults.functions.update_migration_bias = NULL;
cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based;
cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based;
cell_defaults.functions.custom_cell_rule = NULL;
cell_defaults.functions.add_cell_basement_membrane_interactions = NULL;
cell_defaults.functions.calculate_distance_to_membrane = NULL;
/*
This parses the cell definitions in the XML config file.
*/
// The following parses the cell definitions in the XML config file
initialize_cell_definitions_from_pugixml();
/*
Put any modifications to individual cell definitions here.
This is a good place to set custom functions.
*/
/*-----------------------------------------------------------*/
/* Put any modifications to individual cell definitions here.*/
/* This is a good place to set custom functions. */
/*-----------------------------------------------------------*/
if( parameters.bools("predators_eat_prey") == true )
{ get_cell_definition("predator").functions.custom_cell_rule = predator_hunting_function; }
{
get_cell_definition("predator").functions.custom_cell_rule = predator_hunting_function;
}
if( parameters.bools("predators_cycle_if_big") == true )
{ get_cell_definition("predator").functions.update_phenotype = predator_cycling_function; }
{
get_cell_definition("predator").functions.update_phenotype = predator_cycling_function;
}
if( parameters.bools("prey_quorom_effect") == true )
{ get_cell_definition("prey").functions.update_phenotype = prey_cycling_function; }
{
get_cell_definition("prey").functions.update_phenotype = prey_cycling_function;
}
/*
This builds the map of cell definitions and summarizes the setup.
*/
// This builds the map of cell definitions and summarizes the setup.
build_cell_definitions_maps();
display_cell_definitions( std::cout );
//display_cell_definitions( std::cout ); <---- Will be printed out by all processes
/*---------------------------------------------------------------------------------------*/
/* display_cell_definitions(...) has been disabled above as the printing will be done by */
/* ALL processes. If you want to print (for checking, testing etc.) then create a new */
/* version of void create_cell_types(mpi_Environment &world, mpi_Cartesian &cart_topo) */
/* and then use the IOProcessor(world) function to print using ONLY the root process */
/*---------------------------------------------------------------------------------------*/
return;
}
void setup_microenvironment( void )
{
// set domain parameters
// put any custom code to set non-homogeneous initial conditions or
// extra Dirichlet nodes here.
// initialize BioFVM
// Set domain parameters, put any custom code to set non-homogeneous initial conditions or
// extra Dirichlet nodes here, initialize BioFVM
initialize_microenvironment();
......@@ -155,16 +171,8 @@ void setup_microenvironment( void )
/*==============================================*/
void setup_microenvironment( mpi_Environment &world, mpi_Cartesian &cart_topo )
{
// set domain parameters
// put any custom code to set non-homogeneous initial conditions or
// extra Dirichlet nodes here.
// initialize BioFVM
{
initialize_microenvironment(world, cart_topo);
return;
}
......@@ -188,11 +196,11 @@ void setup_tissue( void )
double Yrange = Ymax - Ymin;
double Zrange = Zmax - Zmin;
// create some of each type of cell
// Create some of each type of cells
Cell* pC;
// place prey
// Place the preys
for( int n = 0 ; n < parameters.ints("number_of_prey") ; n++ )
{
......@@ -205,7 +213,7 @@ void setup_tissue( void )
pC->assign_position( position );
}
// place predators
// Place the predators
for( int n = 0 ; n < parameters.ints("number_of_predators") ; n++ )
{
......@@ -245,23 +253,23 @@ void setup_tissue(Microenvironment &m, mpi_Environment &world, mpi_Cartesian &ca
double Yrange = Ymax - Ymin;
double Zrange = Zmax - Zmin;
// create some of each type of cell
// Create some of each type of cell
/* The following 3 temporary variables are common to both Prey and Predator sections */
// The following 3 temporary variables are common to both Prey and Predator sections
Cell* pCell;
std::vector<std::vector<double>> generated_positions_at_root;
std::vector<double> position = {0,0,0}; //Temporary buffer
/*------------------*/
/* Prey Section */
/*------------------*/
/*------------------*/
/* Prey Section */
/*------------------*/
mpi_CellPositions cp_prey; //To store cell positions, cell IDs, no. of cell IDs at root only (for all processes)
mpi_MyCells mc_prey; //To store cell positions, cell IDs, no. of cells at each process.
/* First Generate Prey positions on rank 0 */
// First Generate Prey positions on rank 0
if(world.rank == 0)
{
......@@ -293,7 +301,7 @@ void setup_tissue(Microenvironment &m, mpi_Environment &world, mpi_Cartesian &ca
distribute_cell_positions(cp_prey, mc_prey, world, cart_topo); //Distribute cell positions
/* Create preys at individual processes */
// Create preys at individual processes
for( int i=0; i < mc_prey.my_no_of_cell_IDs; i++ )
{
......@@ -309,9 +317,9 @@ void setup_tissue(Microenvironment &m, mpi_Environment &world, mpi_Cartesian &ca
generated_positions_at_root.clear();
/*------------------*/
/* Predator Section */
/*------------------*/
/*------------------*/
/* Predator Section */
/*------------------*/
mpi_CellPositions cp_pred; //To store cell positions, cell IDs, no. of cell IDs at root only (for all processes)
mpi_MyCells mc_pred; //To store cell positions, cell IDs, no. of cells at each process.
......@@ -345,6 +353,16 @@ void setup_tissue(Microenvironment &m, mpi_Environment &world, mpi_Cartesian &ca
pCell->assign_position(mc_pred.my_cell_coords[3*i],mc_pred.my_cell_coords[3*i+1],mc_pred.my_cell_coords[3*i+2],world, cart_topo); //pCell->assign_position( positions[i] );
}
/*---------------------------------------------------------------------------------*/
/* Please note that the Predator cells and Prey cells will be displayed separately */
/* in the output. For example if the initial number of preys is 20 and the no. of */
/* predators is 5, then you see an output like: */
// MPI Rank = 1 No of cells = 13 <---- Preys on MPI Rank 1
// MPI Rank = 0 No of cells = 7 <---- Preys on MPI Rank 0
// MPI Rank = 0 No of cells = 2 <---- Predators on Rank 0
// MPI Rank = 1 No of cells = 3 <---- Predators on Rank 1
/*---------------------------------------------------------------------------------*/
return;
}
......@@ -353,11 +371,11 @@ std::vector<std::string> my_coloring_function( Cell* pCell )
static int prey_type = get_cell_definition( "prey" ).type;
static int predator_type = get_cell_definition( "predator" ).type;
// start with flow cytometry coloring
// Start with flow cytometry coloring
std::vector<std::string> output = false_cell_coloring_cytometry(pCell);
// color live prey
// Color live prey
if( pCell->phenotype.death.dead == false && pCell->type == prey_type )
{
......@@ -365,7 +383,7 @@ std::vector<std::string> my_coloring_function( Cell* pCell )
output[2] = parameters.strings("prey_color");
}
// color live predators
// Color live predators
if( pCell->phenotype.death.dead == false && pCell->type == predator_type )
{
......@@ -387,11 +405,13 @@ void predator_hunting_function( Cell* pCell, Phenotype& phenotype, double dt )
for( int n=0; n < pCell->cells_in_my_container().size() ; n++ )
{
pTestCell = pCell->cells_in_my_container()[n];
// if it's not me, not dead, and not my type, eat it
// If it is not me, not dead, and not my type, eat it
if( pTestCell != pCell && pTestCell->type != pCell->type && pTestCell->phenotype.death.dead == false )
{
// only eat if I'm not full
// Only eat if I am not full
if( phenotype.volume.total < sated_volume )
{
pCell->ingest_cell(pTestCell);
......@@ -410,9 +430,13 @@ void predator_cycling_function( Cell* pCell, Phenotype& phenotype, double dt )
parameters.doubles("relative_sated_volume" );
if( phenotype.volume.total > sated_volume )
{ phenotype.cycle.data.transition_rate(0,1) = get_cell_definition("prey").phenotype.cycle.data.transition_rate(0,1) * 0.01; }
{
phenotype.cycle.data.transition_rate(0,1) = get_cell_definition("prey").phenotype.cycle.data.transition_rate(0,1) * 0.01;
}
else
{ phenotype.cycle.data.transition_rate(0,1) = 0; }
{
phenotype.cycle.data.transition_rate(0,1) = 0;
}
return;
}
......@@ -423,7 +447,9 @@ void prey_cycling_function( Cell* pCell , Phenotype& phenotype, double dt )
double threshold = parameters.doubles("prey_quorom_threshold" ) + 1e-16 ;
double factor = (threshold - pCell->nearest_density_vector()[signal_index] )/threshold;
if( factor < 0 )
{ factor = 0.0; }
{
factor = 0.0;
}
phenotype.cycle.data.transition_rate(0,1) = get_cell_definition("prey").phenotype.cycle.data.transition_rate(0,1);
phenotype.cycle.data.transition_rate(0,1) *= factor;
......
......@@ -65,6 +65,18 @@
###############################################################################
*/
/*================================================================================
+ If you use PhysiCell-X in your project, we would really appreciate if you can +
+ +
+ [1] Cite the PhysiCell-X repository by giving its URL +
+ +
+ [2] Cite BioFVM-X: +
+ Saxena, Gaurav, Miguel Ponce-de-Leon, Arnau Montagud, David Vicente Dorca, +
+ and Alfonso Valencia. "BioFVM-X: An MPI+ OpenMP 3-D Simulator for Biological +
+ Systems." In International Conference on Computational Methods in Systems +
+ Biology, pp. 266-279. Springer, Cham, 2021. +
=================================================================================*/
/*=======================================*/
/* Include mpi.h in the parallel version */
/*=======================================*/
......@@ -81,8 +93,6 @@
#include "./core/PhysiCell.h"
#include "./modules/PhysiCell_standard_modules.h"
// put custom code modules here!
#include "./custom_modules/custom.h"
using namespace BioFVM;
......@@ -96,14 +106,13 @@ using namespace DistPhy::mpi;
int main( int argc, char* argv[] )
{
// load and parse settings file(s)
/*=======================================================================================*/
/* Create mpi_Environment object, initialize it, then create Cartesian Topology */
/*=======================================================================================*/
mpi_Environment world; //object contains size of communicator, rank of process
world.Initialize(); //Initialize using MPI_THREAD_MULTIPLE, find comm. size and comm. rank
world.Initialize(); //Initialize using MPI_THREAD_FUNNELED, find comm. size and comm. rank
mpi_Cartesian cart_topo; //Contains dims[3], ccoords[3] array and MPI_Comm mpi_cart_comm
cart_topo.Build_Cartesian_Topology(world); //Create 1-D X decomposition by setting dims[1]=size.
cart_topo.Find_Cartesian_Coordinates(world); //Find Cartesian Topology coordinates of each process
......@@ -124,12 +133,14 @@ int main( int argc, char* argv[] )
XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml", world );
}
if( !XML_status )
{ exit(-1); }
{
exit(-1);
}
// OpenMP setup
// OpenMP setup <--- remember this will override OMP_NUM_THREADS
omp_set_num_threads(PhysiCell_settings.omp_num_threads);
// time setup
// Time setup
std::string time_units = "min";
/* Microenvironment setup */
......@@ -143,7 +154,7 @@ int main( int argc, char* argv[] )
/* PhysiCell setup */
// set mechanics voxel size, and match the data structure to BioFVM
// set mechanics voxel size, mechanical voxel size >= diffusion voxel size
double mechanics_voxel_size = 30;
/*---------------------------------------------------------*/
......@@ -156,74 +167,52 @@ int main( int argc, char* argv[] )
create_cell_types();
setup_tissue(microenvironment, world, cart_topo); //Send all three like create_cell_container_for_microenvironment above
setup_tissue(microenvironment, world, cart_topo);
/* Users typically stop modifying here. END USERMODS */
// set MultiCellDS save options
// Set MultiCellDS save options, these MUST all be "true" as of now
set_save_biofvm_mesh_as_matlab( true );
set_save_biofvm_data_as_matlab( true );
set_save_biofvm_cell_data( true );
set_save_biofvm_cell_data_as_custom_matlab( true );
// save a simulation snapshot
// Save a simulation snapshot
char filename[1024];
sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() );
/* Use the parallel version of the function now */
// Use the parallel version of the function to write XML file
save_PhysiCell_to_MultiCellDS_xml_pugi( filename , microenvironment , PhysiCell_globals.current_time, world, cart_topo );
// save a quick SVG cross section through z = 0, after setting its
// length bar to 200 microns
// Save a SVG cross section through z = 0, after setting its length bar to 200 microns
PhysiCell_SVG_options.length_bar = 200;
// for simplicity, set a pathology coloring function
// Set a pathology coloring function
std::vector<std::string> (*cell_coloring_function)(Cell*) = my_coloring_function;
sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() );
SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, world, cart_topo );
display_citations();
// set the performance timers
// Set the performance timers
BioFVM::RUNTIME_TIC();
BioFVM::TIC();
std::ofstream report_file;
if( PhysiCell_settings.enable_legacy_saves == true )
{
sprintf( filename , "%s/simulation_report.txt" , PhysiCell_settings.folder.c_str() );
report_file.open(filename); // create the data log file
report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"<<std::endl;
}
// main loop
// Main loop of the program
try
{
while( PhysiCell_globals.current_time < PhysiCell_settings.max_time + 0.1*diffusion_dt )
{
// save data if it's time.
// Save data if it is time
if( fabs( PhysiCell_globals.current_time - PhysiCell_globals.next_full_save_time ) < 0.01 * diffusion_dt )
{
display_simulation_status( std::cout );
if( PhysiCell_settings.enable_legacy_saves == true )
{
//GS commented it out
//log_output( PhysiCell_globals.current_time , PhysiCell_globals.full_output_index, microenvironment, report_file);
}
// Use the parallel version of the function now
display_simulation_status( std::cout, world, cart_topo );
if( PhysiCell_settings.enable_full_saves == true )
{
sprintf( filename , "%s/output%08u" , PhysiCell_settings.folder.c_str(), PhysiCell_globals.full_output_index );
/* Now use parallel version of the function */
// Now use parallel version of the function to write XML file
save_PhysiCell_to_MultiCellDS_xml_pugi( filename , microenvironment , PhysiCell_globals.current_time, world, cart_topo );
}
......@@ -231,7 +220,7 @@ int main( int argc, char* argv[] )
PhysiCell_globals.next_full_save_time += PhysiCell_settings.full_save_interval;
}
// save SVG plot if it's time
// Save SVG plot if it is time
if( fabs( PhysiCell_globals.current_time - PhysiCell_globals.next_SVG_save_time ) < 0.01 * diffusion_dt )
{
if( PhysiCell_settings.enable_SVG_saves == true )
......@@ -244,45 +233,42 @@ int main( int argc, char* argv[] )
}
}
// update the microenvironment
// Update the microenvironment i.e. solve diffusion equations
microenvironment.simulate_diffusion_decay( diffusion_dt, world, cart_topo );
// run PhysiCell
// Run PhysiCell/PhysiCell-X to update all cells
((Cell_Container *)microenvironment.agent_container)->update_all_cells( PhysiCell_globals.current_time, world, cart_topo );
/*
Custom add-ons could potentially go here.
............
Custom add-ons could potentially go here.
............
*/
PhysiCell_globals.current_time += diffusion_dt;
}
if( PhysiCell_settings.enable_legacy_saves == true )
{
//GS commented out
//log_output(PhysiCell_globals.current_time, PhysiCell_globals.full_output_index, microenvironment, report_file);
report_file.close();
}
}
}
catch( const std::exception& e )
{ // reference to the base of a polymorphic object
std::cout << e.what(); // information from length_error printed
{
// Reference to the base of a polymorphic object, information from length_error printed
std::cout << e.what();
}
// save a final simulation snapshot
//GS commented
// Save a final simulation snapshot
sprintf( filename , "%s/final" , PhysiCell_settings.folder.c_str() );
save_PhysiCell_to_MultiCellDS_xml_pugi( filename , microenvironment , PhysiCell_globals.current_time, world, cart_topo );
sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() );
SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, world, cart_topo );
// timer
std::cout << std::endl << "Total simulation runtime: " << std::endl;
BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() );
// Timer
if(IOProcessor(world))
{
std::cout << std::endl << "Total simulation runtime: " << std::endl;
BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() );
}
// Gracefully shut-down MPI
world.Finalize();
return 0;
......
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=2
#SBATCH --cpus-per-task=1
#SBATCH --cpus-per-task=24
#SBATCH -t 02:00:00
#SBATCH -o output-%j
#SBATCH -e error-%j
......@@ -19,14 +19,12 @@ export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_PROC_BIND=spread
export OMP_PLACES=threads
#export OMP_PLACES="{0:1}:48:1"
#export OMP_PLACES='cores(48)'
#--------------------------------------------
# Simplest Execution, can be used for testing
#--------------------------------------------
mpiexec ./project
# mpiexec ./project
#-------------------------------------------------------------
# Better to use --map-by ppr syntax when measuring performance
......@@ -35,7 +33,7 @@ export OMP_PLACES=threads
# (This is because we have 2 sockets with 24 cores each)
#-------------------------------------------------------------
# mpiexec --map-by ppr:1:socket:pe=1 --report-bindings ./project
mpiexec --map-by ppr:1:socket:pe=24 --report-bindings ./project
#-------------------------------------
# Uncomment if using DDT for debugging (1) if mpiexec doesn't connect then use (2) srun
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment