testTreeBuilder.cpp 7.06 KB
Newer Older
1
// ===================================================================================
2 3 4 5
// Copyright ScalFmm 2016 INRIA, Olivier Coulaud, Bérenger Bramas,
// Matthias Messner olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the
// FMM.
6
//
7
// This software is governed by the CeCILL-C and LGPL licenses and
8
// abiding by the rules of distribution of free software.
9 10 11
// An extension to the license is given to allow static linking of scalfmm
// inside a proprietary application (no matter its license).
// See the main license file for more details.
12 13 14 15
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 17 18
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
19 20
// ===================================================================================

21 22 23
// Keep in private GIT
// @SCALFMM_PRIVATE

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

#include <iostream>

#include <cstdlib>
#include <string>
#include <stdexcept>
#include <algorithm>
#include <vector>

#include <cstdio>

#include "ScalFmmConfig.h"

#include "Files/FFmaGenericLoader.hpp"

#include "Components/FSimpleLeaf.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"

#include "../../Src/Kernels/P2P/FP2PParticleContainer.hpp"

#include "../../Src/Kernels/Rotation/FRotationKernel.hpp"
#include "../../Src/Kernels/Rotation/FRotationCell.hpp"

#include "../Src/BalanceTree/FLeafBalance.hpp"
#include "../Src/Files/FTreeBuilder.hpp"
#include "../Src/Containers/FTreeCoordinate.hpp"

#include "Utils/FTic.hpp"
#include "Utils/FQuickSort.hpp"
#include "Utils/FParameters.hpp"
#include "../../Src/Utils/FParameterNames.hpp"

#include "Containers/FOctree.hpp"
57
#include "Containers/FCoordinateComputer.hpp"
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

#ifdef _OPENMP
#include "Core/FFmmAlgorithmThread.hpp"
#else
#include "Core/FFmmAlgorithm.hpp"
#endif

#include "Utils/FTemplate.hpp"




/**
 * This program build a tree and insert the parts inside.
 * Time needed for the insert is outputed
 *
 */
int main(int argc, char** argv){

77
    typedef double FReal;
78 79 80 81

    struct TestParticle{
	MortonIndex index;
	FSize indexInFile;
82
    FPoint<FReal> position;
83
	FReal physicalValue;
84
    const FPoint<FReal>& getPosition()const{
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	    return position;
	}
	TestParticle& operator=(const TestParticle& other){
	    index=other.index;
	    indexInFile=other.indexInFile;
	    position=other.position;
	    physicalValue=other.physicalValue;
	    return *this;
	}
	bool operator<=(const TestParticle& rhs)const{
	    if(rhs.index < this->index){return false;}
	    else{
		if(rhs.index > this->index){return true;}
		else{
		    if(rhs.indexInFile == this->indexInFile){
			return true;
		    }
		    else {
			return rhs.indexInFile> this->indexInFile ;
		    }
		}
	    }
	}
    };



    static const int P = 9;

114
    typedef FRotationCell<FReal,P>               CellClass;
115
    typedef FP2PParticleContainer<FReal>          ContainerClass;
116

117 118
    typedef FSimpleLeaf<FReal, ContainerClass >                     LeafClass;
    typedef FOctree<FReal, CellClass, ContainerClass , LeafClass >  OctreeClass;
119
    //typedef FRotationKernel< FReal, CellClass, ContainerClass , P>   KernelClass;
120 121 122 123 124 125 126 127 128 129 130 131 132 133

    //typedef FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass > FmmClassThread;

    const int NbLevels = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5);
    const int SizeSubLevels = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeSubHeight.options, 3);

    const char* const filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, "../Data/test20k.fma");
    const unsigned int NbThreads = FParameters::getValue(argc, argv, FParameterDefinitions::NbThreads.options, omp_get_max_threads());

    omp_set_num_threads(NbThreads);
    std::cout << "Using " << omp_get_max_threads() <<" threads" << std::endl;
    std::cout << "Opening : " << filename << "\n";


134
    FFmaGenericLoader<FReal> loaderRef(filename);
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
    if(!loaderRef.isOpen()){
	std::cout << "LoaderRef Error, " << filename << " is missing\n";
	return 1;
    }
    FTic regInsert;
    // -----------------------------------------------------
    {
	OctreeClass treeRef(NbLevels, SizeSubLevels, loaderRef.getBoxWidth(), loaderRef.getCenterOfBox());


	std::cout << "Creating & Inserting " << loaderRef.getNumberOfParticles() << " particles ..." << std::endl;
	std::cout << "\tHeight : " << NbLevels << " \t sub-height : " << SizeSubLevels << std::endl;

	regInsert.tic();

150
	for(FSize idxPart = 0 ; idxPart < loaderRef.getNumberOfParticles() ; ++idxPart){
151
        FPoint<FReal> particlePosition;
152 153 154 155 156 157 158 159 160 161
	    FReal physicalValue;
	    loaderRef.fillParticle(&particlePosition,&physicalValue);
	    treeRef.insert(particlePosition, physicalValue );
	}

	regInsert.tac();
	std::cout << "Time needed for regular insert : " << regInsert.elapsed() << " secondes" << std::endl;
    }

    //Second solution, parts must be sorted for that
162
    FFmaGenericLoader<FReal> loader(filename);
163 164 165 166 167 168 169 170
    if(!loader.isOpen()){
	std::cout << "Loader Error, " << filename << " is missing\n";
	return 1;
    }

    //Get the needed informations
    FReal boxWidth = loader.getBoxWidth();
    FReal boxWidthAtLeafLevel = boxWidth/FReal(1 << (NbLevels - 1));
171 172
    FPoint<FReal> centerOfBox = loader.getCenterOfBox();
    FPoint<FReal> boxCorner   = centerOfBox - boxWidth/2;
173 174 175 176 177 178 179
    FSize nbOfParticles = loader.getNumberOfParticles();

    //Temporary TreeCoordinate
    FTreeCoordinate host;
    TestParticle * arrayOfParts = new TestParticle[nbOfParticles];
    memset(arrayOfParts,0,sizeof(TestParticle)*nbOfParticles);

180
    for(FSize idxPart = 0 ; idxPart < nbOfParticles ; ++idxPart){
181 182
	loader.fillParticle(&arrayOfParts[idxPart].position,&arrayOfParts[idxPart].physicalValue);
	//Build temporary TreeCoordinate
183 184 185
    host.setX( FCoordinateComputer::GetTreeCoordinate<FReal>( arrayOfParts[idxPart].getPosition().getX() - boxCorner.getX(), boxWidth, boxWidthAtLeafLevel, NbLevels ));
    host.setY( FCoordinateComputer::GetTreeCoordinate<FReal>( arrayOfParts[idxPart].getPosition().getY() - boxCorner.getY(), boxWidth, boxWidthAtLeafLevel, NbLevels ));
    host.setZ( FCoordinateComputer::GetTreeCoordinate<FReal>( arrayOfParts[idxPart].getPosition().getZ() - boxCorner.getZ(), boxWidth, boxWidthAtLeafLevel, NbLevels ));
186 187

	//Set Morton index from Tree Coordinate
188
	arrayOfParts[idxPart].index = host.getMortonIndex();
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	arrayOfParts[idxPart].indexInFile = idxPart;

    }
    //std::sort(arrayOfParts,&arrayOfParts[nbOfParticles-1]);
    FQuickSort<TestParticle,MortonIndex>::QsOmp(arrayOfParts,nbOfParticles);
    OctreeClass tree(NbLevels, SizeSubLevels, loaderRef.getBoxWidth(), loaderRef.getCenterOfBox());

    //copy into a Container class
    ContainerClass parts;
    parts.reserve(nbOfParticles);

    for(FSize idxPart = 0;idxPart<nbOfParticles;++idxPart){
	parts.push(arrayOfParts[idxPart].getPosition(),arrayOfParts[idxPart].physicalValue);
    }

204
    FTreeBuilder<FReal,OctreeClass,LeafClass>::BuildTreeFromArray(&tree,parts,false);
205 206 207

    return 0;
}