Commit d2bca29a authored by COULAUD Olivier's avatar COULAUD Olivier

New Fma reader and writer

parent 935a7bca
......@@ -62,8 +62,8 @@ SET(SCALFMM_LIBRARIES "")
SET(ScaLFMM_CXX_FLAGS "")
#
# Compile option
#
SET(ScaLFMM_CXX_FLAGS "-std=c++11 -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wconversion -fpic")
# -Wall Wnosign-conversion
SET(ScaLFMM_CXX_FLAGS "-std=c++11 -Wshadow -Wpointer-arith -Wcast-qual -Wconversion -fpic")
#
# Test if openmp is here
#
......
8 4
100 20 0 0 0
0.998298 0.0088693 0.576438 0.396465
0.107422 -0.2487 -9.62605 0.840485
......
8 4
20 10.002 0.0 0.0 0.0
-0.381596 -0.909478 -1.65028 7.82637e-06
-0.328097 -0.475796 -8.1607 0.131538
......
8 4
20000
0.5 0.5 0.5 0.5
0.840188 0.394383 0.783099 0.01 1
......
......@@ -25,18 +25,18 @@
#include "Files/FFmaGenericLoader.hpp"
#include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
#include "../../Src/Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
#include "Kernels/Chebyshev/FChebCell.hpp"
#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "Kernels/Chebyshev/FChebSymKernel.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "Components/FSimpleLeaf.hpp"
#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../../Src/Utils/FParameters.hpp"
#include "Utils/FParameters.hpp"
#include "../../Src/Containers/FOctree.hpp"
#include "Containers/FOctree.hpp"
#include "../../Src/Core/FFmmAlgorithmThread.hpp"
#include "Core/FFmmAlgorithmThread.hpp"
/**
* This program runs the FMM Algorithm with the Chebyshev kernel and compares the results with a direct computation.
......@@ -104,6 +104,7 @@ int main(int argc, char* argv[])
////////////////////////////////////////////////////////////////////
bool binaryMode = false;
if(FParameters::existParameter(argc, argv, "-bin")){
binaryMode = true;
}
......
......@@ -10,10 +10,13 @@
#include <fstream>
#include <sstream>
#include <string>
//
#include "Utils/FGlobal.hpp"
#include "Utils/FMath.hpp"
#include "Utils/FPoint.hpp"
#include "Utils/FGenerateDistribution.hpp"
#include "Files/FFmaGenericLoader.hpp"
//
/// \file generateDistributions.cpp
//!
......@@ -32,7 +35,7 @@
//! <b> General arguments:</b>
//! \param -help (-h) to see the parameters available in this driver
//! \param -N The number of points in the distribution (default 20000)
//! \param -filename name: generic name for files (without extension) and save data
//! \param -filename name: generic name for files (with extension) and save data
//! with following format in name.fma or name.bfma in -bin is set"
//! \param -visufmt format for the visu file (vtk, vtp, cvs or cosmo). vtp is the default
//! \param -extraLength value extra length to add to the boxWidth (default 0.0)
......@@ -65,7 +68,7 @@
//!
//! generateDistributions -cuboid 2:2:4 -filename cuboid -visufmt vtp -charge -zeromean
//!
//
//
//
......@@ -98,7 +101,6 @@ void genDistusage() {
<< " Output " << std::endl
<< " -filename name: generic name for files (without extension) and save data" <<std::endl
<< " with following format in name.fma or name.bfma in -bin is set" <<std::endl
<< " -bin save output in binary file name.txt" <<std::endl
<< " -visufmt vtk, vtp, cosmo or cvs format " <<std::endl;
}
......@@ -120,6 +122,8 @@ int main(int argc, char ** argv){
FReal * particles ;
particles = new FReal[4*NbPoints] ;
memset(particles,0,4*NbPoints*sizeof(FReal));
FmaBasicParticle *ppart = (FmaBasicParticle*)(&particles[0]);
//
// Generate physical values
//
......@@ -153,7 +157,7 @@ int main(int argc, char ** argv){
if(FParameters::existParameter(argc, argv, "-unitCube")){
unifRandonPointsOnUnitCube(NbPoints, particles) ;
Centre.setPosition(0.5,0.5,0.5);
BoxWith = 0.5 ;
BoxWith = 1.0 ;
}
else if(FParameters::existParameter(argc, argv, "-cuboid")){
std::string dd(":"),aspectRatio = FParameters::getStr(argc,argv,"-lengths", "1:1:2");
......@@ -162,13 +166,13 @@ int main(int argc, char ** argv){
pos = aspectRatio.find(":"); aspectRatio.replace(pos,1," ");
std::stringstream ss(aspectRatio); ss >>A >> B >> C ;
unifRandonPointsOnCube(NbPoints, A,B,C,particles) ;
BoxWith = 0.5*FMath::Max(A,FMath::Max(B,C) );
BoxWith = FMath::Max(A,FMath::Max(B,C) );
FReal halfBW = BoxWith;
Centre.setPosition(halfBW,halfBW,halfBW);
}
else if(FParameters::existParameter(argc, argv, "-unitSphere")){
unifRandonPointsOnUnitSphere(NbPoints, particles) ;
BoxWith = 1.0 ;
BoxWith = 2.0 ;
}
else if(FParameters::existParameter(argc, argv, "-sphere")){
const FReal Radius = FParameters::getValue(argc,argv,"-radius", 2.0);
......@@ -211,53 +215,28 @@ int main(int argc, char ** argv){
/////////////////////////////////////////////////////////////////////////
// Save data
/////////////////////////////////////////////////////////////////////////
//
// Generate file for ScalFMM Loader
// Generate FMA file for FFmaGenericLoader Loader
//
if(FParameters::existParameter(argc, argv, "-extraLength")){
extraRadius = FParameters::getValue(argc,argv,"-extraLength", 0.0);
BoxWith += 2*extraRadius ;
}
if( ! FParameters::existParameter(argc, argv, "-bin")){
std::string name( genericFileName+ ".fma");
std::ofstream outfileA(name.c_str(), std::ofstream::out);
if(!outfileA) {
std::cout << "Cannot open file."<< std::endl;
exit(-1) ;
}
std::cout << "Writes in ascii FMA format in file "<<name <<std::endl ;
std::cout << " Points are in a cube of size "<< BoxWith << " Centered in the Origin"<<std::endl;
//
outfileA << NbPoints << " " << BoxWith << " " << Centre.getX() << " " << Centre.getY() << " " << Centre.getZ() << std::endl;
j=0;
for(int i = 0 ; i< NbPoints; ++i, j+=4){
outfileA << particles[j] << " " << particles[j+1] << " " << particles[j+2] << " " << particles[j+3] <<std::endl;
}
bool binaryMode = false;
std::string name(genericFileName);
if( FParameters::existParameter(argc, argv, "-bin")){
binaryMode = true;
name += ".bfma";
}
else{
std::string name( genericFileName+ ".bfma");
std::fstream outfile(name.c_str(),std::ifstream::out| std::ios::binary| std::ios::trunc);
if(!outfile) {
std::cout << "Cannot open file."<< std::endl;
return 1;
}
std::cout << "Writes in binary FMA format in file "<< name<<std::endl ;
std::cout << " Points are in a cube of size "<< BoxWith << " Centered in the Origin"<<std::endl;
//
int typeFReal = sizeof(FReal) ;
outfile.write((char* )&typeFReal,sizeof(int));
outfile.write((char* )const_cast<int*>(&NbPoints),sizeof(FSize));
outfile.write((char*)&BoxWith,sizeof(BoxWith));
outfile.write((char*)Centre.getDataValue(),sizeof(FReal)*3);
//
outfile.write ((char* )&particles[0], 4*sizeof(FReal)*NbPoints);
outfile.flush();
//
else {
name += ".fma";
}
FFmaGenericWriter writer(name,binaryMode) ;
writer.writeHeader(Centre,BoxWith, NbPoints, *ppart) ;
writer.writeArrayOfParticles(ppart, NbPoints);
//
//
// Generate file for visualization
//
if(FParameters::existParameter(argc, argv, "-visufmt")){
std::string visufile(""), fmt(FParameters::getStr(argc,argv,"-visufmt", "vtp"));
......
......@@ -450,9 +450,9 @@ private:
FLOG( FLog::Controller << "\tFinished (@Upward Pass (M2M) = " << counterTime.tacAndElapsed() << " s)\n" );
FLOG( FLog::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
FLOG( FLog::Controller << "\t\t Prepare : " << prepareCounter.cumulated() << " s\n" );
FLOG( FLog::Controller << "\t\t Wait : " << waitCounter.cumulated() << " s\n" );
FLOG( FLog::Controller << "\t\t Computation : " << computationCounter.cumulated() << " s\n" );
FLOG( FLog::Controller << "\t\t Prepare : " << prepareCounter.cumulated() << " s\n" );
FLOG( FLog::Controller << "\t\t Wait : " << waitCounter.cumulated() << " s\n" );
}
......
This diff is collapsed.
#ifndef FP2P_HPP
#define FP2P_HPP
#include "../../Utils/FGlobal.hpp"
#include "../../Utils/FMath.hpp"
#include "Utils/FGlobal.hpp"
#include "Utils/FMath.hpp"
/**
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
......@@ -17,7 +17,7 @@
#ifdef ScalFMM_USE_TRACE
#if !defined (ScalFMM_USE_ITAC) && !defined (ScalFMM_USE_EZTRACE)
int FTrace::Deep = 0;
int FTrace::Deep = 0;
FTic FTrace::TimeSinceBegining;
#endif
......
......@@ -65,8 +65,8 @@ struct MDParticle {
// Simply create particles and try the kernels
int main(int argc, char ** argv){
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
#ifdef ScalFMM_USE_BLAS
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// 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
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
/**
*@author Cyrille Piacibello
*
* This exec will be used to store the result of direct computation in
* Binary Files. Then, a kernel (Chebyshev) is called on the same file, and
* results are compared.
*
* Format of result file :
* Each data is a FReal : posX,posY,posZ,physicalValue,forceX,forceY,forceZ,potential
*/
// ==== CMAKE =====
// // @FUSE_BLAS
// // ================
//
//
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include "ScalFmmConfig.h"
#include "../../Src/Utils/FTic.hpp"
#include "../../Src/Utils/FParameters.hpp"
#include "../../Src/Containers/FOctree.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Kernels/P2P/FP2P.hpp"
#include "../../Src/Kernels/P2P/FP2PParticleContainerIndexed.hpp"
#include "../../Src/Files/FFmaGenericLoader.hpp"
#include "../../Src/Files/FFmaBinLoaderResult.hpp"
#include "../../Src/Utils/FTic.hpp"
#include "../../Src/Kernels/Chebyshev/FChebCell.hpp"
#include "../../Src/Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Kernels/Chebyshev/FChebKernel.hpp"
#include "../../Src/Kernels/Chebyshev/FChebSymKernel.hpp"
#include "../../Src/Core/FFmmAlgorithm.hpp"
int main(int argc, char* argv[])
{
// get info from commandline
const char* const defaultFilename = (sizeof(FReal) == sizeof(float))?
"../Data/test20k.bin.fma.single":
"unitCubeXYZQ20k.bfma";
const char* const filename = FParameters::getStr(argc,argv,"-f", defaultFilename);
const char* const fileresult = FParameters::getStr(argc,argv,"-fr","testWResult20k.fma");;
//For Fmm Computation
const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-h", 5);
const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-sh", 2);
FTic time;
typedef FmaRPart TestParticle;
// struct TestParticle{
// FPoint position;
// FReal forces[3];
// FReal physicalValue;
// FReal potential;
// };
printf("Input is %s, \n Results will be stored in %s \n",filename,fileresult);
{
//First Part
//Direct Computation and Storage of result
//open particle file
FFmaGenericLoader loader(filename);
time.tic();
TestParticle* const particles = new TestParticle[loader.getNumberOfParticles()];
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
FPoint position;
FReal physicalValue = 0.0;
loader.fillParticle(&position,&physicalValue);
// get copy
particles[idxPart].position = position;
particles[idxPart].physicalValue = physicalValue;
particles[idxPart].potential = 0.0;
particles[idxPart].forces[0] = 0.0;
particles[idxPart].forces[1] = 0.0;
particles[idxPart].forces[2] = 0.0;
}
time.tac();
printf("Elapsed Time for Loading %lld particles from File: \t %f\n",loader.getNumberOfParticles(),time.elapsed());
//Direct Computation
time.tic();
for(int idxTarget = 0 ; idxTarget < loader.getNumberOfParticles() ; ++idxTarget){
for(int idxOther = idxTarget + 1 ; idxOther < loader.getNumberOfParticles() ; ++idxOther){
FP2P::MutualParticles(particles[idxTarget].position.getX(), particles[idxTarget].position.getY(),
particles[idxTarget].position.getZ(),particles[idxTarget].physicalValue,
&particles[idxTarget].forces[0],&particles[idxTarget].forces[1],
&particles[idxTarget].forces[2],&particles[idxTarget].potential,
particles[idxOther].position.getX(), particles[idxOther].position.getY(),
particles[idxOther].position.getZ(),particles[idxOther].physicalValue,
&particles[idxOther].forces[0],&particles[idxOther].forces[1],
&particles[idxOther].forces[2],&particles[idxOther].potential);
}
}
time.tac();
printf("Elapsed Time for Direct Computation: \t %f\n",time.elapsed());
//Write results in output file
FFmaGenericWriter writer(fileresult) ;
//Size of elements to be written
// int realSize = sizeof(FReal);
FSize nbPart = loader.getNumberOfParticles();
// FReal boxWidth = loader.getBoxWidth() / 2;
// FReal centerX = loader.getCenterOfBox().getX();
// FReal centerY = loader.getCenterOfBox().getY();
// FReal centerZ = loader.getCenterOfBox().getZ();
//
// fwrite(&realSize, sizeof(int), 1, fd);
// fwrite(&nbPart, sizeof(FSize), 1, fd);
// fwrite(&boxWidth, sizeof(FReal), 1, fd);
// fwrite(&centerX, sizeof(FReal), 1, fd);
// fwrite(&centerY, sizeof(FReal), 1, fd);
// fwrite(&centerZ, sizeof(FReal), 1, fd);
//
//
// for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart)
// {
// fwrite( particles[idxPart].position.getDataValue(),realSize,3,fd);
// fwrite(&particles[idxPart].physicalValue, realSize,1,fd);
// fwrite( particles[idxPart].forces, realSize,3,fd);
// fwrite(&particles[idxPart].potential, realSize,1,fd);
// }
writer.writeHeader(loader.getCenterOfBox(),BoxWith, nbPart,*particles) ;
writer.writeArrayOfParticles(particles, nbParticles);
delete [] particles;
fclose(fd);
}
//Second Part
{
//Fmm Computation and comparison to Stored results
// begin Chebyshev kernel
// accuracy
const unsigned int ORDER = 7;
// typedefs
typedef FP2PParticleContainerIndexed<> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FInterpMatrixKernelR MatrixKernelClass;
typedef FChebCell<ORDER> CellClass;
typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass;
typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass;
typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass;
time.tic();
//Open result file to fill octree for Chebyshev kernel AND compare results
FFmaBinLoaderResult loader2(fileresult);
// init oct-tree
OctreeClass tree(TreeHeight, SubTreeHeight, loader2.getBoxWidth(), loader2.getCenterOfBox());
TestParticle* const particles2 = new TestParticle[loader2.getNumberOfParticles()];
for(int idxPart = 0 ; idxPart < loader2.getNumberOfParticles() ; ++idxPart)
{
loader2.fillParticle(&particles2[idxPart].position,
&particles2[idxPart].physicalValue,
&particles2[idxPart].forces[0],
&particles2[idxPart].forces[1],
&particles2[idxPart].forces[2],
&particles2[idxPart].potential);
tree.insert(FPoint(particles2[idxPart].position),idxPart,particles2[idxPart].physicalValue);
}
time.tac();
printf("Elapsed Time for Reading File: \t %f\n",time.elapsed());
time.tic();
KernelClass kernels(TreeHeight, loader2.getBoxWidth(), loader2.getCenterOfBox());
FmmClass algorithm(&tree, &kernels);
algorithm.execute();
time.tac();
printf("Elapsed Time for Fmm Computation: \t %f\n",time.elapsed());
FMath::FAccurater potentialDiff;
FMath::FAccurater fx, fy, fz;
//Compare the kernel to the stored elements
{
tree.forEachLeaf([&](LeafClass* leaf){
const FReal*const potentials = leaf->getTargets()->getPotentials();
const FReal*const forcesX = leaf->getTargets()->getForcesX();
const FReal*const forcesY = leaf->getTargets()->getForcesY();
const FReal*const forcesZ = leaf->getTargets()->getForcesZ();
const int nbParticlesInLeaf = leaf->getTargets()->getNbParticles();
const FVector<int>& indexes = leaf->getTargets()->getIndexes();
for(int idxPart = 0 ; idxPart < nbParticlesInLeaf ; ++idxPart){
const int indexPartOrig = indexes[idxPart];
potentialDiff.add(particles2[indexPartOrig].potential,potentials[idxPart]);
fx.add(particles2[indexPartOrig].forces[0],forcesX[idxPart]);
fy.add(particles2[indexPartOrig].forces[1],forcesY[idxPart]);
fz.add(particles2[indexPartOrig].forces[2],forcesZ[idxPart]);
}
});
// Print for information
std::cout << "Potential " << potentialDiff << std::endl;
std::cout << "Fx " << fx << std::endl;
std::cout << "Fy " << fy << std::endl;
std::cout << "Fz " << fz << std::endl;
}
}
return 0;
}
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// 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
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <time.h>
#include "../../Src/Utils/FParameters.hpp"
#include "../../Src/Utils/FTic.hpp"
#include "../../Src/Containers/FOctree.hpp"
#include "../../Src/Containers/FVector.hpp"
#include "../../Src/Utils/FAssert.hpp"
#include "../../Src/Utils/FPoint.hpp"
#include "../../Src/Components/FBasicCell.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Files/FFmaGenericLoader.hpp"
#include "../../Src/Components/FBasicParticleContainer.hpp"
/**
* In this file we show an example of FBasicLoader use
* Inserting 2000000 particles ...
* Done (5.77996).
* Deleting particles ...
* Done (0.171918).
*/
int main(int argc, char ** argv ){
typedef FBasicParticleContainer<1> ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FOctree< FBasicCell, ContainerClass , LeafClass > OctreeClass;
///////////////////////What we do/////////////////////////////
std::cout << ">> This executable is useless to execute.\n";
std::cout << ">> It is only interesting to wath the code to understand\n";
std::cout << ">> how to use the FMA loader\n";
//////////////////////////////////////////////////////////////
// Use testLoaderFMABinCreate.exe to create this file
FTic counter;
const char* const filename = FParameters::getStr(argc,argv,"-f", "../Data/test20k.bin.fma.double.res");
std::cout << "Opening : " << filename << "\n";
// open basic result particles loader
FFmaBinLoaderResult loader(filename);
if(!loader.isOpen()){
std::cout << "Loader Error, " << filename << "is missing\n";
return 1;
}
{
// octree
OctreeClass tree(FParameters::getValue(argc,argv,"-h", 5), FParameters::getValue(argc,argv,"-sh", 3),
loader.getBoxWidth(), loader.getCenterOfBox());
// -----------------------------------------------------
std::cout << "Inserting " << loader.getNumberOfParticles() << " particles ..." << std::endl;
counter.tic();
FPoint particlePosition;
FReal physicalValue = 0.0;
FReal forces[3];
FReal potential;
for(int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
loader.fillParticle(&particlePosition,&physicalValue,forces,&forces[1],&forces[2],&potential);
tree.insert(particlePosition,physicalValue);
}
counter.tac();
std::cout << "Done " << "(" << counter.elapsed() << ")." << std::endl;
// -----------------------------------------------------
std::cout << "Deleting particles ..." << std::endl;
counter.tic();
}
counter.tac();
std::cout << "Done " << "(" << counter.elapsed() << ")." << std::endl;
// -----------------------------------------------------
return 0;
}
......@@ -62,7 +62,7 @@ class TestChebyshevDirect : public FUTester<TestChebyshevDirect> {
const int NbLevels = 4;
const int SizeSubLevels = 2;
const int PeriodicDeep = 2;
const int NbParticles = 500;
const int NbParticles = 250;
FRandomLoader loader(NbParticles);
......
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