<commit_before>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, 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 the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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.
*/

// $Id$
// $URL$

/*! \file force_compute_bmark.cc
	\brief Executable for benchmarking all of the various ForceCompute classes
	\details This is intended as a quick test to check the performance of ForceComputes 
		on various machines and after performance tweaks have been made. It allows for a
		number of command line options to change settings, but will most likely just
		be run with the default settings most of the time.
	\ingroup benchmarks
*/

#ifdef WIN32
#include <windows.h>
#endif

#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <string>

#include "BondForceCompute.h"
#include "LJForceCompute.h"

#include "BinnedNeighborList.h"
#include "Initializers.h"
#include "SFCPackUpdater.h"

#ifdef USE_CUDA
#include "LJForceComputeGPU.h"
#include "BondForceComputeGPU.h"
#endif

#include "HOOMDVersion.h"

#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost::program_options;
using namespace boost;
using namespace std;

// options from command line
//! quite mode: only display time per compute and nothing else
bool quiet = false;
//! number of threads (for applicable computes)
unsigned int nthreads = 1;
//! cutoff radius for pair forces (for applicable computes)
Scalar r_cut = 3.0;
//! buffer radius for pair forces (for applicable computes)
Scalar r_buff = 0.8;
//! block size for calculation (for applicable computes)
unsigned int block_size = 128;
//! number of particles to benchmark
unsigned int N = 100000;
//! Should the particles be sorted with SFCPACK?
bool sort_particles = true;
//! number of seconds to average over
unsigned int nsec = 10;
//! Activate profiling?
bool profile_compute = true;
//! Use half neighborlist?
bool half_nlist = true;
//! Specify packing fraction of particles for the benchmark (if applicable)
Scalar phi_p = 0.2;

//! Helper function to initialize bonds
void init_bond_tables(shared_ptr<BondForceCompute> bf_compute)
	{
	const unsigned int nbonds = 2;
	for (unsigned int j = 0; j < N-nbonds/2; j++)
		{
		for (unsigned int k = 1; k <= nbonds/2; k++)
			bf_compute->addBond(j,j+k);
		}
	}	

//! Initialize the force compute from a string selecting it
shared_ptr<ForceCompute> init_force_compute(const string& fc_name, shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist)
	{
	shared_ptr<ForceCompute> result;
	
	// handle creation of the various lennard=jones computes
	if (fc_name == "LJ")
		result = shared_ptr<ForceCompute>(new LJForceCompute(pdata, nlist, r_cut));
	#ifdef USE_CUDA
	if (fc_name == "LJ.GPU")
		{
		shared_ptr<LJForceComputeGPU> tmp = shared_ptr<LJForceComputeGPU>(new LJForceComputeGPU(pdata, nlist, r_cut));
		tmp->setBlockSize(block_size);
		result = tmp;
		}
	#endif
	
	// handle the various bond force computes
	if (fc_name == "Bond")
		{
		shared_ptr<BondForceCompute> tmp = shared_ptr<BondForceCompute>(new BondForceCompute(pdata, 150, 1.0));
		init_bond_tables(tmp);
		result = tmp;
		}
	#ifdef USE_CUDA
	if (fc_name == "Bond.GPU")
		{
		shared_ptr<BondForceComputeGPU> tmp = shared_ptr<BondForceComputeGPU>(new BondForceComputeGPU(pdata, 150, 1.0));
		init_bond_tables(tmp);
		tmp->setBlockSize(block_size);
		result = tmp;
		}
	#endif
		
	return result;
	}
	

//! Initializes the particle data to a random set of particles
shared_ptr<ParticleData> init_pdata()
	{
	RandomInitializer rand_init(N, phi_p, 0.0, "A");
	shared_ptr<ParticleData> pdata(new ParticleData(rand_init));
	if (sort_particles)
		{
		SFCPackUpdater sorter(pdata, Scalar(1.0));
		sorter.update(0);
		}
		
	return pdata;
	}

//! Actually performs the benchmark on the preconstructed force compute
void benchmark(shared_ptr<ForceCompute> fc)
	{
	// initialize profiling if requested
	shared_ptr<Profiler> prof(new Profiler());
	if (profile_compute && !quiet)
		fc->setProfiler(prof);
	
	// timer to count how long we spend at each point
	ClockSource clk;
	int count = 2;

	// do a warmup run so memory allocations don't change the benchmark numbers
	fc->compute(count++);

	int64_t tstart = clk.getTime();
	int64_t tend;
	// do at least one test, then repeat until we get at least 5s of data at this point
	int nrepeat = 0;
	do
		{
		fc->compute(count++);
		nrepeat++;
		tend = clk.getTime();
		} while((tend - tstart) < int64_t(nsec) * int64_t(1000000000) || nrepeat < 5);
	
	// make sure all kernels have been executed when using CUDA
	#ifdef USE_CUDA
	cudaThreadSynchronize();<commit_msg>Added dot printing to force compute benchmark to tell if it is running or not.<commit_after>/*
Highly Optimized Object-Oriented Molecular Dynamics (HOOMD) Open
Source Software License
Copyright (c) 2008 Ames Laboratory Iowa State University
All rights reserved.

Redistribution and use of HOOMD, 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 the copyright holder nor the names HOOMD's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER 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.
*/

// $Id$
// $URL$

/*! \file force_compute_bmark.cc
	\brief Executable for benchmarking all of the various ForceCompute classes
	\details This is intended as a quick test to check the performance of ForceComputes 
		on various machines and after performance tweaks have been made. It allows for a
		number of command line options to change settings, but will most likely just
		be run with the default settings most of the time.
	\ingroup benchmarks
*/

#ifdef WIN32
#include <windows.h>
#endif

#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <string>

#include "BondForceCompute.h"
#include "LJForceCompute.h"

#include "BinnedNeighborList.h"
#include "Initializers.h"
#include "SFCPackUpdater.h"

#ifdef USE_CUDA
#include "LJForceComputeGPU.h"
#include "BondForceComputeGPU.h"
#endif

#include "HOOMDVersion.h"

#include <boost/program_options.hpp>
#include <boost/shared_ptr.hpp>

using namespace boost::program_options;
using namespace boost;
using namespace std;

// options from command line
//! quite mode: only display time per compute and nothing else
bool quiet = false;
//! number of threads (for applicable computes)
unsigned int nthreads = 1;
//! cutoff radius for pair forces (for applicable computes)
Scalar r_cut = 3.0;
//! buffer radius for pair forces (for applicable computes)
Scalar r_buff = 0.8;
//! block size for calculation (for applicable computes)
unsigned int block_size = 128;
//! number of particles to benchmark
unsigned int N = 100000;
//! Should the particles be sorted with SFCPACK?
bool sort_particles = true;
//! number of seconds to average over
unsigned int nsec = 10;
//! Activate profiling?
bool profile_compute = true;
//! Use half neighborlist?
bool half_nlist = true;
//! Specify packing fraction of particles for the benchmark (if applicable)
Scalar phi_p = 0.2;

//! Helper function to initialize bonds
void init_bond_tables(shared_ptr<BondForceCompute> bf_compute)
	{
	const unsigned int nbonds = 2;
	for (unsigned int j = 0; j < N-nbonds/2; j++)
		{
		for (unsigned int k = 1; k <= nbonds/2; k++)
			bf_compute->addBond(j,j+k);
		}
	}	

//! Initialize the force compute from a string selecting it
shared_ptr<ForceCompute> init_force_compute(const string& fc_name, shared_ptr<ParticleData> pdata, shared_ptr<NeighborList> nlist)
	{
	shared_ptr<ForceCompute> result;
	
	// handle creation of the various lennard=jones computes
	if (fc_name == "LJ")
		result = shared_ptr<ForceCompute>(new LJForceCompute(pdata, nlist, r_cut));
	#ifdef USE_CUDA
	if (fc_name == "LJ.GPU")
		{
		shared_ptr<LJForceComputeGPU> tmp = shared_ptr<LJForceComputeGPU>(new LJForceComputeGPU(pdata, nlist, r_cut));
		tmp->setBlockSize(block_size);
		result = tmp;
		}
	#endif
	
	// handle the various bond force computes
	if (fc_name == "Bond")
		{
		shared_ptr<BondForceCompute> tmp = shared_ptr<BondForceCompute>(new BondForceCompute(pdata, 150, 1.0));
		init_bond_tables(tmp);
		result = tmp;
		}
	#ifdef USE_CUDA
	if (fc_name == "Bond.GPU")
		{
		shared_ptr<BondForceComputeGPU> tmp = shared_ptr<BondForceComputeGPU>(new BondForceComputeGPU(pdata, 150, 1.0));
		init_bond_tables(tmp);
		tmp->setBlockSize(block_size);
		result = tmp;
		}
	#endif
		
	return result;
	}
	

//! Initializes the particle data to a random set of particles
shared_ptr<ParticleData> init_pdata()
	{
	RandomInitializer rand_init(N, phi_p, 0.0, "A");
	shared_ptr<ParticleData> pdata(new ParticleData(rand_init));
	if (sort_particles)
		{
		SFCPackUpdater sorter(pdata, Scalar(1.0));
		sorter.update(0);
		}
		
	return pdata;
	}

//! Actually performs the benchmark on the preconstructed force compute
void benchmark(shared_ptr<ForceCompute> fc)
	{
	// initialize profiling if requested
	shared_ptr<Profiler> prof(new Profiler());
	if (profile_compute && !quiet)
		fc->setProfiler(prof);
	
	// timer to count how long we spend at each point
	ClockSource clk;
	int count = 2;

	// do a warmup run so memory allocations don't change the benchmark numbers
	fc->compute(count++);

	int64_t tstart = clk.getTime();
	int64_t tend;
	// do at least one test, then repeat until we get at least 5s of data at this point
	int nrepeat = 0;
	do
		{
		fc->compute(count++);
		nrepeat++;
		tend = clk.getTime();

		if (nrepeat % 500 == 0)
			{
			cout << ".";
			cout.flush();
			}

		} while((tend - tstart) < int64_t(nsec) * int64_t(1000000000) || nrepeat < 5);
	
	// make sure all kernels have been executed when using CUDA
	#ifdef USE_CUDA
	cudaThreadSynchronize();
{'fraction_non_alphanumeric': 0.08676470588235294, 'fraction_numerical': 0.011111111111111112, 'mean_word_length': 4.677643784786642, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '2255891', 'n_tokens_mistral': 4064, 'n_tokens_neox': 3721, 'n_words': 1431}