Skip to content
Snippets Groups Projects
isolation.cu 5.71 KiB
Newer Older
Pietro Incardona's avatar
Pietro Incardona committed
#include <iostream>
#include <thread>

size_t debug_tot_call = 0;

#define PRINT_STACKTRACE
#define CHECKFOR_POSNAN
#define CHECKFOR_POSINF
#define CHECKFOR_PROPNAN
#define CHECKFOR_PROPINF

#define NO_WARNING
#include "Graph/CartesianGraphFactory.hpp"

void timeout_cycle()
{
	// 6 seconds
	std::this_thread::sleep_for (std::chrono::seconds(900));

	std::cout << "Time Out" << std::endl;
	std::exit(1);
}


#define BOOST_DISABLE_ASSERTS


#include "config.h"
#undef VERSION

#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include "VCluster/VCluster.hpp"
#include <Vector/vector_dist.hpp>
#include "Vector/tests/vector_dist_util_unit_tests.hpp"

// initialization function:
bool init_unit_test()
{
//  std::thread to (timeout_cycle);
//  to.detach();
  return true;
}

// entry point
int main(int argc, char* argv[])
{
	openfpm_init(&argc,&argv);

  return boost::unit_test::unit_test_main( &init_unit_test, argc, argv );
}



BOOST_AUTO_TEST_CASE( vector_dist_ghost_put_gpu )
{
	

	Vcluster<> & v_cl = create_vcluster();

	long int k = 25*25*25*create_vcluster().getProcessingUnits();
	k = std::pow(k, 1/3.);

	if (v_cl.getProcessingUnits() > 48)
		return;

	BOOST_TEST_CHECKPOINT( "Testing 3D periodic ghost put k=" << k );

	long int big_step = k / 30;
	big_step = (big_step == 0)?1:big_step;
	long int small_step = 21;

	// 3D test
	for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
	{
		float r_cut = 1.3 / k;
		float r_g = 1.5 / k;

		Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0});

		// Boundary conditions
		size_t bc[3]={PERIODIC,PERIODIC,PERIODIC};

		// ghost
		Ghost<3,float> ghost(r_g);

		typedef  aggregate<float,float,float> part_prop;

		// Distributed vector
		vector_dist_gpu<3,float, part_prop > vd(0,box,bc,ghost);

		auto it = vd.getGridIterator({(size_t)k,(size_t)k,(size_t)k});

		while (it.isNext())
		{
			auto key = it.get();

			vd.add();

			vd.getLastPosWrite()[0] = key.get(0)*it.getSpacing(0);
			vd.getLastPosWrite()[1] = key.get(1)*it.getSpacing(1);
			vd.getLastPosWrite()[2] = key.get(2)*it.getSpacing(2);

			// Fill some properties randomly

			vd.getLastPropWrite<0>() = 0.0;

			vd.getLastPropWrite<2>() = 0.0;

			++it;
		}

		vd.map();

		vd.hostToDevicePos();
		vd.template hostToDeviceProp<0,2>();
		// sync the ghost
		vd.ghost_get<0,2>(RUN_ON_DEVICE);
		vd.template deviceToHostProp<0,2>();
		vd.deviceToHostPos();

		{
			auto NN = vd.getCellList(r_cut);
			float a = 1.0f*k*k;

			// run trough all the particles + ghost

			auto it2 = vd.getDomainIterator();

			while (it2.isNext())
			{
				// particle p
				auto p = it2.get();
				Point<3,float> xp = vd.getPos(p);

				// Get an iterator over the neighborhood particles of p
				auto Np = NN.getNNIterator<NO_CHECK>(NN.getCell(xp));

				// For each neighborhood particle ...
				while (Np.isNext())
				{
					auto q = Np.get();
					Point<3,float> xq = vd.getPosRead(q);

					float dist = xp.distance(xq);

					if (dist < r_cut)
					{
						vd.getPropWrite<0>(q) += a*(-dist*dist+r_cut*r_cut);
						vd.getPropWrite<2>(q) += a*(-dist*dist+r_cut*r_cut);
					}

					++Np;
				}

				++it2;
			}

			vd.hostToDevicePos();
			vd.template hostToDeviceProp<0,2>();
			vd.template ghost_put<add_atomic_,0,2>(RUN_ON_DEVICE);
			vd.template deviceToHostProp<0,2>();
			vd.deviceToHostPos();

			bool ret = true;
			auto it3 = vd.getDomainIterator();

			float constant = vd.getProp<0>(it3.get());
			float eps = 0.001;

			while (it3.isNext())
			{
				float constant2 = vd.getProp<0>(it3.get());
				float constant3 = vd.getProp<2>(it3.get());
				if (fabs(constant - constant2)/constant > eps || fabs(constant - constant3)/constant > eps)
				{
					Point<3,float> p = vd.getPosRead(it3.get());

					std::cout << p.toString() << "    " <<  constant2 << "/" << constant << "/" << constant3 << "    " << v_cl.getProcessUnitID() << std::endl;
					ret = false;
					break;
				}

				++it3;
			}
			BOOST_REQUIRE_EQUAL(ret,true);
		}

		auto itp = vd.getDomainAndGhostIterator();
		while (itp.isNext())
		{
			auto key = itp.get();

			vd.getPropWrite<0>(key) = 0.0;
			vd.getPropWrite<2>(key) = 0.0;

			++itp;
		}

		{
			auto NN = vd.getCellList(r_cut);
			float a = 1.0f*k*k;

			// run trough all the particles + ghost

			auto it2 = vd.getDomainIterator();

			while (it2.isNext())
			{
				// particle p
				auto p = it2.get();
				Point<3,float> xp = vd.getPosRead(p);

				// Get an iterator over the neighborhood particles of p
				auto Np = NN.getNNIterator<NO_CHECK>(NN.getCell(xp));

				// For each neighborhood particle ...
				while (Np.isNext())
				{
					auto q = Np.get();
					Point<3,float> xq = vd.getPosRead(q);

					float dist = xp.distance(xq);

					if (dist < r_cut)
					{
						vd.getPropWrite<0>(q) += a*(-dist*dist+r_cut*r_cut);
						vd.getPropWrite<2>(q) += a*(-dist*dist+r_cut*r_cut);
					}

					++Np;
				}

				++it2;
			}

			vd.hostToDevicePos();
			vd.template hostToDeviceProp<0,2>();
			vd.template ghost_put<add_atomic_,0>(RUN_ON_DEVICE);
			vd.template ghost_put<add_atomic_,2>(RUN_ON_DEVICE);
			vd.template deviceToHostProp<0,2>();
			vd.deviceToHostPos();

			bool ret = true;
			auto it3 = vd.getDomainIterator();

			float constant = vd.getPropRead<0>(it3.get());
			float eps = 0.001;

			while (it3.isNext())
			{
				float constant2 = vd.getPropRead<0>(it3.get());
				float constant3 = vd.getPropRead<0>(it3.get());
				if (fabs(constant - constant2)/constant > eps || fabs(constant - constant3)/constant > eps)
				{
					Point<3,float> p = vd.getPosRead(it3.get());

					std::cout << p.toString() << "    " <<  constant2 << "/" << constant << "/" << constant3 << "  " << it3.get().getKey() << "    " << v_cl.getProcessUnitID() << std::endl;
					ret = false;
					break;
				}

				++it3;
			}
			BOOST_REQUIRE_EQUAL(ret,true);
		}
	}

	openfpm_finalize();
}