<commit_before>/*
Program testing the parallel speed of generic simulation cell with particles.

Copyright 2014, 2015 <NAME>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

* Neither the name of copyright holders nor the names of their contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "array"
#include "boost/lexical_cast.hpp"
#include "chrono"
#include "cmath"
#include "cstdlib"
#include "iostream"
#include "mpi.h"
#include "vector"

#include "dccrg.hpp"
#include "dccrg_cartesian_geometry.hpp"

#include "reference_cell.hpp"
#include "reference_initialize.hpp"
#include "reference_save.hpp"
#include "reference_solve.hpp"

int main(int argc, char* argv[])
{
	// the cell type used by this program
	using Cell = particle::Reference_Cell;

	/*
	Set up MPI
	*/
	if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
		std::cerr << "Couldn't initialize MPI." << std::endl;
		abort();
	}

	MPI_Comm comm = MPI_COMM_WORLD;


	// intialize Zoltan
	float zoltan_version;
	if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) {
		std::cerr << "Zoltan_Initialize failed." << std::endl;
		abort();
	}


	/*
	Set up the grid in which the simulation will run
	*/
	dccrg::Dccrg<Cell, dccrg::Cartesian_Geometry> grid;

	// initialize the grid
	std::array<uint64_t, 3> grid_length = {{20, 20, 20}};
	const unsigned int neighborhood_size = 1;
	if (not grid.initialize(
		grid_length,
		comm,
		"RANDOM",
		neighborhood_size,
		0,
		false, false, false
	)) {
		std::cerr << __FILE__ << ":" << __LINE__
			<< ": Couldn't initialize grid."
			<< std::endl;
		abort();
	}

	// set the grid's geometry
	dccrg::Cartesian_Geometry::Parameters geom_params;
	geom_params.start[0] =
	geom_params.start[1] =
	geom_params.start[2] = -1;
	geom_params.level_0_cell_length[0] =
	geom_params.level_0_cell_length[1] =
	geom_params.level_0_cell_length[2] = 2.0 / grid_length[0];
	if (not grid.set_geometry(geom_params)) {
		std::cerr << __FILE__ << ":" << __LINE__
			<< ": Couldn't set grid geometry."
			<< std::endl;
		abort();
	}

	grid.balance_load();

	/*
	Simulate
	*/
	particle::reference_initialize(grid);

	const std::vector<uint64_t>
		inner_cells = grid.get_local_cells_not_on_process_boundary(),
		outer_cells = grid.get_local_cells_on_process_boundary();

	double
		simulation_time = 0,
		time_step = 0;

	const auto time_start = std::chrono::high_resolution_clock::now();

	while (simulation_time < M_PI) {

		double next_time_step = std::numeric_limits<double>::max();

		/*
		Propagate particles in outer cells first so the number
		of external particles can be sent to other processes.
		*/
		next_time_step
			= std::min(
				next_time_step,
				particle::reference_solve(time_step, outer_cells, grid)
			);

		/*
		Update number of particles in external lists of outer cells
		so that receiving processes can allocate memory for coordinates.
		*/
		Cell::transfers |= Cell::transfer_types::nr_of_ext_particles;
		Cell::transfers
			&= ~Cell::transfer_types::vel
			& ~Cell::transfer_types::ext_particles;
		grid.start_remote_neighbor_copy_updates();

		/*
		Propagate particles in inner cells while number of
		particles in external lists of outer cells is transferred.
		*/
		next_time_step
			= std::min(
				next_time_step,
				particle::reference_solve(time_step, inner_cells, grid)
			);

		/*
		Wait for particle counts in external lists of
		outer cells to arrive and allocate memory required
		for particle coordinates.
		*/
		grid.wait_remote_neighbor_copy_update_receives();
		particle::reference_resize(grid);

		grid.wait_remote_neighbor_copy_update_sends();<commit_msg>Update comment in parallel reference particle program to match the gensimcell version.<commit_after>/*
Program testing the parallel speed of generic simulation cell with particles.

Copyright 2014, 2015 <NAME>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

* Neither the name of copyright holders nor the names of their contributors
  may be used to endorse or promote products derived from this software
  without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "array"
#include "boost/lexical_cast.hpp"
#include "chrono"
#include "cmath"
#include "cstdlib"
#include "iostream"
#include "mpi.h"
#include "vector"

#include "dccrg.hpp"
#include "dccrg_cartesian_geometry.hpp"

#include "reference_cell.hpp"
#include "reference_initialize.hpp"
#include "reference_save.hpp"
#include "reference_solve.hpp"

int main(int argc, char* argv[])
{
	// the cell type used by this program
	using Cell = particle::Reference_Cell;

	/*
	Set up MPI
	*/
	if (MPI_Init(&argc, &argv) != MPI_SUCCESS) {
		std::cerr << "Couldn't initialize MPI." << std::endl;
		abort();
	}

	MPI_Comm comm = MPI_COMM_WORLD;


	// intialize Zoltan
	float zoltan_version;
	if (Zoltan_Initialize(argc, argv, &zoltan_version) != ZOLTAN_OK) {
		std::cerr << "Zoltan_Initialize failed." << std::endl;
		abort();
	}


	/*
	Set up the grid in which the simulation will run
	*/
	dccrg::Dccrg<Cell, dccrg::Cartesian_Geometry> grid;

	// initialize the grid
	std::array<uint64_t, 3> grid_length = {{20, 20, 20}};
	const unsigned int neighborhood_size = 1;
	if (not grid.initialize(
		grid_length,
		comm,
		"RANDOM",
		neighborhood_size,
		0,
		false, false, false
	)) {
		std::cerr << __FILE__ << ":" << __LINE__
			<< ": Couldn't initialize grid."
			<< std::endl;
		abort();
	}

	// set the grid's geometry
	dccrg::Cartesian_Geometry::Parameters geom_params;
	geom_params.start[0] =
	geom_params.start[1] =
	geom_params.start[2] = -1;
	geom_params.level_0_cell_length[0] =
	geom_params.level_0_cell_length[1] =
	geom_params.level_0_cell_length[2] = 2.0 / grid_length[0];
	if (not grid.set_geometry(geom_params)) {
		std::cerr << __FILE__ << ":" << __LINE__
			<< ": Couldn't set grid geometry."
			<< std::endl;
		abort();
	}

	grid.balance_load();

	/*
	Simulate
	*/
	particle::reference_initialize(grid);

	const std::vector<uint64_t>
		inner_cells = grid.get_local_cells_not_on_process_boundary(),
		outer_cells = grid.get_local_cells_on_process_boundary();

	double
		simulation_time = 0,
		time_step = 0;

	const auto time_start = std::chrono::high_resolution_clock::now();

	while (simulation_time < M_PI) {

		double next_time_step = std::numeric_limits<double>::max();

		/*
		Propagate particles in outer cells first so the number
		of external particles can be sent to other processes.
		*/
		next_time_step
			= std::min(
				next_time_step,
				particle::reference_solve(time_step, outer_cells, grid)
			);

		/*
		Update number of particles in external lists of outer cells
		so that receiving processes can allocate memory for coordinates.
		*/
		Cell::transfers |= Cell::transfer_types::nr_of_ext_particles;
		Cell::transfers
			&= ~Cell::transfer_types::vel
			& ~Cell::transfer_types::ext_particles;
		grid.start_remote_neighbor_copy_updates();

		/*
		Propagate particles in inner cells while number of
		particles in external lists of outer cells is transferred.
		*/
		next_time_step
			= std::min(
				next_time_step,
				particle::reference_solve(time_step, inner_cells, grid)
			);

		/*
		Wait for particle counts in external lists of
		remote neighbors to arrive and allocate memory
		required for particle coordinates.
		*/
		grid.wait_remote_neighbor_copy_update_receives();
		particle::reference_resize(grid);

		grid.wait_remote_neighbor_copy_update_sends();
{'fraction_non_alphanumeric': 0.09396586753352296, 'fraction_numerical': 0.007314099959366111, 'mean_word_length': 4.727166957533449, 'pattern_counts': {'":': 8, '<': 71, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2650823', 'n_tokens_mistral': 3379, 'n_tokens_neox': 3018, 'n_words': 1000}