From ac4a7f0e708ccae1fe413e5defcace8de8e79d26 Mon Sep 17 00:00:00 2001 From: Olivier Coulaud <Olivier.Coulaud@inria.fr> Date: Tue, 6 Jan 2015 11:23:35 +0100 Subject: [PATCH] Add scalability test in Utils/noDist Fill variable SCALFMMCompileFlags and SCALFMMCompileLibs --- CMakeLists.txt | 64 +++--- Src/ScalFmmConfig.h.cmake | 4 +- Utils/noDist/stamp2Fma.cpp | 223 +++++++++++++++++++++ Utils/noDist/testAccuracyChebFMM.cpp | 270 ++++++++++++++++++++++++++ Utils/noDist/testSCalibilityOpenMP.sh | 57 ++++++ 5 files changed, 584 insertions(+), 34 deletions(-) create mode 100644 Utils/noDist/stamp2Fma.cpp create mode 100644 Utils/noDist/testAccuracyChebFMM.cpp create mode 100755 Utils/noDist/testSCalibilityOpenMP.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index af5d78871..3c5a9457c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,25 +70,23 @@ OPTION( ScalFMM_USE_STARPU "Set to ON to build ScaFMM with StarPU" OFF ) endif() # Set scalfmm to default libraries SET(SCALFMM_LIBRARIES "") -SET(ScaLFMM_CXX_FLAGS "") +SET(ScaLFMM_CXX_FLAGS "-std=c++11 -fpic -Wall") # # # Test if openmp is here # find_package (OpenMP) if(OPENMP_FOUND) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") -# SET(ScaLFMM_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +else(OPENMP_FOUND) MESSAGE(WARNING "OPENMP NOT FOUND") endif(OPENMP_FOUND) -MESSAGE(STATUS "ScalFMM_BUILD_DEBUG = ${ScalFMM_BUILD_DEBUG}" ) +MESSAGE(STATUS "ScalFMM_BUILD_DEBUG = ${ScalFMM_BUILD_DEBUG}" ) +# if(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(FLAGS_64bits "-m64") -else() - SET(FLAGS_64bits "") + SET(ScaLFMM_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} -m64") endif() ############################################################################## # Compile options # @@ -96,10 +94,8 @@ endif() # -xHost -mfpmath=sse # -Wall Wnosign-conversion # -SET(ScaLFMM_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} -std=c++11 -fpic -Wall ") -# if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - # INTEL +# INTEL IF (APPLE) SET(SSE_FLAGS "-msse4 -mfpmath=sse") # -mtune=native -march=native ELSE(APPLE) @@ -139,9 +135,9 @@ if( ScalFMM_BUILD_DEBUG ) SET(SCALFMM_FLAGS_OPTI_DEBUG "-m64 -funroll-loops" CACHE STRING "Set your optimization flags for debug mode.") ELSE(APPLE) if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - SET(SCALFMM_FLAGS_OPTI_DEBUG "${FLAGS_64bits} -fp-model strict -funroll-loops" CACHE STRING "Set your optimization flags for debug mode.") + SET(SCALFMM_FLAGS_OPTI_DEBUG "-fp-model strict -funroll-loops" CACHE STRING "Set your optimization flags for debug mode.") else() - SET(SCALFMM_FLAGS_OPTI_DEBUG "${FLAGS_64bits} -funroll-loops" CACHE STRING "Set your optimization flags for debug mode.") + SET(SCALFMM_FLAGS_OPTI_DEBUG "-funroll-loops" CACHE STRING "Set your optimization flags for debug mode.") endif() ENDIF(APPLE) # ADD_DEFINITIONS(${SCALFMM_FLAGS_OPTI_DEBUG}) @@ -164,24 +160,24 @@ else() ELSE(APPLE) # Not apple system - Check the compiler flags if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") - SET(SCALFMM_FLAGS_OPTI_RELEASE "${FLAGS_64bits} -fp-model precise -fp-model source -fimf-precision=low -funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") + SET(SCALFMM_FLAGS_OPTI_RELEASE "-fp-model precise -fp-model source -fimf-precision=low -funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") else() - SET(SCALFMM_FLAGS_OPTI_RELEASE "${FLAGS_64bits} -ffast-math -funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") + SET(SCALFMM_FLAGS_OPTI_RELEASE "-ffast-math -funroll-loops -ftree-vectorize" CACHE STRING "Set your optimization flags for release mode.") endif() ENDIF(APPLE) # SET(ScaLFMM_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} ${SCALFMM_FLAGS_OPTI_RELEASE}") endif() +# ############################################################################## # Attach source code to exec # ############################################################################## MESSAGE(STATUS "ScalFMM_ATTACHE_SOURCE = ${ScalFMM_ATTACHE_SOURCE}" ) if( ScalFMM_ATTACHE_SOURCE ) - MESSAGE( STATUS "Option -g is used, the code is attached to the binary." ) -# ADD_DEFINITIONS(-g) + MESSAGE( STATUS "Option -g is used, the code is attached to the binary." ) SET(ScaLFMM_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} -g") endif(ScalFMM_ATTACHE_SOURCE) - +# ############################################################################## # Blas option # ############################################################################## @@ -234,7 +230,6 @@ if( ScalFMM_USE_FFT ) SET(SCALFMM_INCLUDES "${SCALFMM_INCLUDES}; ${FFT_INCLUDES}") MESSAGE(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") MESSAGE(STATUS "SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") - endif(ScalFMM_USE_FFT) # Compile option @@ -259,7 +254,10 @@ IF(CMAKE_CXX_COMPILER_ID STREQUAL "Intel") endif() endif() endif() - +# +################################################################## +################################################################## +# if( ScalFMM_USE_STARPU ) SET(STARPU_LIBRARIES " -L$ENV{STARPU_LIB}; -lstarpu-1.1") # CACHE STRING "Set your STARPU flags" @@ -272,9 +270,7 @@ if( ScalFMM_USE_STARPU ) # SET(SCALFMM_INCLUDES "${SCALFMM_INCLUDES}; ${STARPU_INCLUDES}") include_directories(${STARPU_INCLUDES}) endif(ScalFMM_USE_STARPU) -############################################################################## -############################################################################## - +# ################################################################## # Use SSE # ################################################################## @@ -347,10 +343,12 @@ ENDIF() ################################################################## # ################################################################## - +# # Add CBLAS -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CBLAS_LIBRARIES}") - +#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CBLAS_LIBRARIES}") +# SI CBLAS necessaire utiliser la ligne cidessous +#SET(SCALFMM_LIBRARIES "${CBLAS_LIBRARIES} ${SCALFMM_LIBRARIES} ") +# ################################################################## # # # END SETTING VARIABLES # @@ -359,6 +357,8 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CBLAS_LIBRARIES}") # # Generate ScalFmmConfig.h # +SET(ScalFMM_COMPILE_FLAGS "${ScaLFMM_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") +SET(ScalFMM_COMPILE_LIBS "${SCALFMM_LIBRARIES} ") CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/Src/ScalFmmConfig.h.cmake ${CMAKE_BINARY_DIR}/Src/ScalFmmConfig.h ) # @@ -438,7 +438,7 @@ endif() # Build and export cmake files # # # ################################################################## - +# MESSAGE(STATUS "ScalFMM_BINARY_DIR: " ${ScalFMM_BINARY_DIR}) CONFIGURE_FILE(${ScalFMM_SOURCE_DIR}/ScalFMMConfig.cmake.in ${ScalFMM_BINARY_DIR}/ScalFMMConfig.cmake @@ -503,11 +503,11 @@ MESSAGE( STATUS "ScalFMM_USE_LOG = ${ScalFMM_USE_LOG}" ) # Use Assert MESSAGE( STATUS "ScalFMM_USE_ASSERT = ${ScalFMM_USE_ASSERT}" ) # - MESSAGE(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") - SET(CMAKE_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") + #MESSAGE(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") + #SET(CMAKE_CXX_FLAGS "${ScaLFMM_CXX_FLAGS} ${CMAKE_CXX_FLAGS}") -MESSAGE(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") -MESSAGE(STATUS "ScaLFMM_CXX_FLAGS = ${ScaLFMM_CXX_FLAGS}") +MESSAGE(STATUS "CMAKE_CXX_FLAGS = ${CMAKE_CXX_FLAGS}") +MESSAGE(STATUS "SCALFMM_CXX_FLAGS = ${ScaLFMM_CXX_FLAGS}") MESSAGE(STATUS "SCALFMM_LIBRARIES = ${SCALFMM_LIBRARIES}") MESSAGE(STATUS "SCALFMM_INCLUDES = ${SCALFMM_INCLUDES}") ################################################################## diff --git a/Src/ScalFmmConfig.h.cmake b/Src/ScalFmmConfig.h.cmake index 60c4df12a..3cce67a24 100755 --- a/Src/ScalFmmConfig.h.cmake +++ b/Src/ScalFmmConfig.h.cmake @@ -106,7 +106,7 @@ const std::string SCALFMMDataPath("@CMAKE_SOURCE_DIR@/Data/"); /////////////////////////////////////////////////////// // Flags and libs used to compile /////////////////////////////////////////////////////// -const std::string SCALFMMCompileFlags("@CMAKE_COMPILE_FLAGS@"); -const std::string SCALFMMCompileLibs("@CMAKE_COMPILE_LIBS@"); +const std::string SCALFMMCompileFlags("@ScalFMM_COMPILE_FLAGS@"); +const std::string SCALFMMCompileLibs("@ScalFMM_COMPILE_LIBS@"); #endif // CONFIG_H diff --git a/Utils/noDist/stamp2Fma.cpp b/Utils/noDist/stamp2Fma.cpp new file mode 100644 index 000000000..84cf307fb --- /dev/null +++ b/Utils/noDist/stamp2Fma.cpp @@ -0,0 +1,223 @@ +/* + * genarateDistributions.cpp + * + * Created on: 23 mars 2014 + * Author: Olivier Coulaud + */ + + +#include <iostream> +#include <fstream> +#include <string> +#include <cstdlib> +// +#include "Utils/FGlobal.hpp" +#include "Utils/FPoint.hpp" +#include "Files/FFmaGenericLoader.hpp" +#include "Files/FDlpolyLoader.hpp" +#include "Utils/FParameters.hpp" +#include "Utils/FGenerateDistribution.hpp" + +// +/// \file stamp2Fma.cpp +//! +//! \brief changeFormat: Driver to transform a stamp format to FMA format and to build a visualization file +//! +//! Driver to transform a FMA format and/or to build a visualization file<br> +//! For a description of the FMA format see FFmaGenericLoader<br> +//! <b> General arguments:</b> +//! \param -help (-h) to see the parameters available in this driver +//! \param -fin name: file name to convert (with extension .fma (ascii) or bfma (binary) +//! \param -fdlpoly name file coming from a DLpoly simulation +//! +//! \param -fout name: generic name for files (without extension) and save data +//! with following format in name.fma or name.bfma if -bin is set" +//! \param -bin save output in binary mode (name file name.bfma +//! \param -visufmt format for the visu file (vtk, vtp, cvs or cosmo). vtp is the default +//! +//! +//! \b examples +//! +//! Transform an ascii file in a binary file +//! +//! changeFormat -fin unitCubeXYZQ100.fma -fout unitCubeXYZQ100 -bin + + +// +// +void genDistusage() { + std::cout << "Driver to change the format of the input file" + << std::endl; + std::cout << "Options "<< std::endl + << " -help to see the parameters " << std::endl + << " Input: only one option is allowed" << std::endl + << " -fin name: file name to convert (with extension .fma (ascii) or bfma (binary) " <<std::endl + << " -fdlpoly name: file name to convert with extension (.bin if binary file) " <<std::endl + << " Output " << std::endl + << " -fout name: generic name for files (without extension) and save data" <<std::endl + << " with following format in name.fma or name.bfma if -bin is set" <<std::endl + << " -bin save output in binary mode (name file name.bfma)" <<std::endl + << " -visufmt vtk, vtp, cosmo or cvs format for visualization " <<std::endl; +} + +int main(int argc, char ** argv){ + // + if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")|| (argc < 3 )){ + genDistusage() ; + exit(-1); + } + FSize NbPoints; + FReal * particles = nullptr ; + FFmaGenericLoader * loader; + unsigned int nbData; + bool stampFile = false ; + if (FParameters::existParameter(argc, argv, "-fstamp")) { + stampFile = true ; + } + if (FParameters::existParameter(argc, argv, "-fin")) { + const std::string filename(FParameters::getStr(argc,argv,"-fin", "data.fma")); + if(stampFile) { + loader = new FFmaGenericLoader(filename,false); + } + else { + loader = new FFmaGenericLoader(filename) ; + } + // + // Allocation + // + NbPoints = loader->getNumberOfParticles(); + nbData = loader->getNbRecordPerline() ; + const unsigned int arraySize =nbData*NbPoints; + // + particles = new FReal[arraySize] ; + std::memset(particles,0,arraySize*sizeof(FReal)); + // + // Read Data + int j = 0 ; + for(int idxPart = 0 ; idxPart < NbPoints ;++idxPart, j+=nbData){ + // // + loader->fillParticle(&particles[j],nbData); + // std::cout << "idxPart "<< idxPart << " "; + // for (int jj= 0 ; jj<nbData ; ++jj, ++k){ + // std::cout << particles[k] << " "; + // } + // std::cout << std::endl; + } + if(stampFile) { + j=0 ; + FReal D= loader->getBoxWidth(); + for(int idxPart = 0 ; idxPart < NbPoints ;++idxPart, j+=nbData){ + particles[j] *= D ; + particles[j+1] *= D ; + particles[j+2] *= D ; + } + } + // if(FParameters::existParameter(argc, argv, "-fdlpoly")){ + // FDlpolyLoader *loader = nullptr ; + // // if(FParameters::existParameter(argc, argv, "-bin")){ + // // loader = new FDlpolyBinLoader(filenameEwaldIn.c_str()); + // // } + // // else { + // // loader = new FDlpolyAsciiLoader(filenameEwaldIn.c_str()); + // // } + // // NbPoints = loader->getNumberOfParticles() ; + // // particles = new FReal[arraySize] ; + // // std::memset(particles,0,arraySize*sizeof(FReal)); + // // for(int idxPart = 0 ; idxPart < NbPoints ; ++idxPart){ + // // + // // int index ; + // // FPoint P ; FReal t[3]; + // /// / loader->fillParticle(&P, t, &physicalValue,&index); + // // particles[(index-1)*] + // // + // // totalCharge += physicalValue ; + // } + } + else { + genDistusage() ; + return 0; + } + + + // + ///////////////////////////////////////////////////////////////////////// + // Save data + ///////////////////////////////////////////////////////////////////////// + // + // Generate file for ScalFMM FMAGenericLoader + // + if(FParameters::existParameter(argc, argv, "-fout")){ + std::string name(FParameters::getStr(argc,argv,"-fout", "output")); + std::string ext("."); + if(name.find(ext) !=std::string::npos) { + std::cout << "No file with extension permitted for output name : " << name << std::endl; + exit(-1); + } + if( FParameters::existParameter(argc, argv, "-bin")){ + name += ".bfma"; + } + else { + name += ".fma"; + } + FFmaGenericWriter writer(name) ; + writer.writeHeader( loader->getCenterOfBox(), loader->getBoxWidth() , NbPoints, sizeof(FReal), nbData) ; + writer.writeArrayOfReal(particles, nbData, NbPoints); + } + // + // Generate file for visualization purpose + // + if(FParameters::existParameter(argc, argv, "-visufmt")){ + std::string outfilename(FParameters::getStr(argc,argv,"-fout", "output")); + std::string visufile(""), fmt(FParameters::getStr(argc,argv,"-visufmt", "vtp")); + if( fmt == "vtp" ){ + visufile = outfilename + ".vtp" ; + } + else if( fmt == "vtk" ){ + visufile = outfilename + ".vtk" ; + } + else if( fmt == "cosmo" ){ + if(nbData !=4) { + std::cerr << "Cosmos export accept only 4 data per particles. here: "<<nbData<<std::endl; + std::exit(EXIT_FAILURE); + } + visufile = outfilename + ".cosmo" ; + } + else { + visufile = outfilename + ".csv" ; + } + std::ofstream file( visufile, std::ofstream::out); + if(!file) { + std::cout << "Cannot open file."<< std::endl; + exit(-1) ; + } // + // + // Export data in cvs format + // + if( fmt == "vtp" ){ + std::cout << "Writes in XML VTP format (visualization) in file "<< visufile <<std::endl ; + if(nbData==4){ + exportVTKxml( file, particles, NbPoints) ; + } + else { + exportVTKxml( file, particles, NbPoints,nbData) ; + } + } + else if( fmt == "vtk" ){ + std::cout << "Writes in VTK format (visualization) in file "<< visufile <<std::endl ; + exportVTK( file, particles, NbPoints,nbData) ; + } + else if( fmt == "cosmo" ){ + std::cout << "Writes in COSMO format (visualization) in file "<< visufile <<std::endl ; + exportCOSMOS( file, particles, NbPoints) ; + } + else { + std::cout << "Writes in CVS format (visualization) in file "<<visufile<<std::endl ; + exportCVS( file, particles, NbPoints,nbData) ; + } + } + // + delete particles ; + + // + return 1; +} diff --git a/Utils/noDist/testAccuracyChebFMM.cpp b/Utils/noDist/testAccuracyChebFMM.cpp new file mode 100644 index 000000000..bd1e1d9e1 --- /dev/null +++ b/Utils/noDist/testAccuracyChebFMM.cpp @@ -0,0 +1,270 @@ +// =================================================================================== +// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas +// 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". +// =================================================================================== + +// ==== CMAKE ===== +// @FUSE_BLAS +// ================ + +#include <iostream> + +#include <cstdio> +#include <cstdlib> +#include <string> + +#include "ScalFmmConfig.h" + +#include "Files/FFmaGenericLoader.hpp" + +#include "Kernels/Chebyshev/FChebCell.hpp" +#include "Kernels/Interpolation/FInterpMatrixKernel.hpp" +#include "Kernels/Chebyshev/FChebSymKernel.hpp" + +#include "Components/FSimpleLeaf.hpp" +#include "Kernels/P2P/FP2PParticleContainerIndexed.hpp" + +#include "Utils/FParameters.hpp" + +#include "Containers/FOctree.hpp" + +#ifdef _OPENMP +#include "Core/FFmmAlgorithmThread.hpp" +#else +#include "Core/FFmmAlgorithm.hpp" +#endif + +#include "Utils/FTemplate.hpp" + +/** + * This program runs the FMM Algorithm with the Chebyshev kernel and compares the results with a direct computation. + */ +/// \file ChebyshevInterpolationFMM.cpp +//! +//! \brief This program runs the FMM Algorithm with the interpolation kernel based on Chebyshev interpolation (1/r kernel) +//! \authors B. Bramas, O. Coulaud +//! +//! This code is a short example to use the Chebyshev Interpolation approach for the 1/r kernel +//! +//!@Algorithm +//! <b> General arguments:</b> +//! \param -help(-h) to see the parameters available in this driver +//! \param -depth The depth of the octree +//! \param -subdepth Specifies the size of the sub octree +//! \param -t The number of threads +//! +//! \param -f name Name of the particles file with extension (.fma or .bfma). The data in file have to be in our FMA format +//! +// + +void usage() { + std::cout << "Driver for Chebyshev interpolation kernel (1/r kernel)" << std::endl; + std::cout << "Options "<< std::endl + << " -help to see the parameters " << std::endl + << " -depth the depth of the octree "<< std::endl + << " -subdepth specifies the size of the sub octree " << std::endl + << " -f name name specifies the name of the particle distribution" << std::endl + << " -t n specifies the number of threads used in the computations" << std::endl; +} + +// Simply create particles and try the kernels +struct TempMainStruct{ +template <const unsigned int ORDER> +static void Run(int argc, char* argv[]) +{ + const std::string defaultFile(/*SCALFMMDataPath+*/"../Data/test20k.fma" ); + const std::string filename = FParameters::getStr(argc,argv,"-f", defaultFile.c_str()); + const unsigned int TreeHeight = FParameters::getValue(argc, argv, "-depth", 5); + const unsigned int SubTreeHeight = FParameters::getValue(argc, argv, "-subdepth", 2); + const unsigned int NbThreads = FParameters::getValue(argc, argv, "-t", 1); + if(FParameters::existParameter(argc, argv, "-h")||FParameters::existParameter(argc, argv, "-help")){ + usage() ; + exit(EXIT_SUCCESS); + } +#ifdef _OPENMP + omp_set_num_threads(NbThreads); + std::cout << "\n>> Using " << omp_get_max_threads() << " threads.\n" << std::endl; +#else + std::cout << "\n>> Sequential version.\n" << std::endl; +#endif + // + std::cout << "Parameters "<< std::endl + << " Octree Depth "<< TreeHeight <<std::endl + << " SubOctree depth " << SubTreeHeight <<std::endl + << " Input file name: " <<filename <<std::endl + << " Thread number: " << NbThreads <<std::endl + <<std::endl; + // + // init timer + FTic time; + + // open particle file + //////////////////////////////////////////////////////////////////// + // + FFmaGenericLoader loader(filename); + // + FSize nbParticles = loader.getNumberOfParticles() ; + FmaRWParticle<8,8>* const particles = new FmaRWParticle<8,8>[nbParticles]; + + loader.fillParticle(particles,nbParticles); + FReal energyD = 0.0 ; + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Compute direct energy + ///////////////////////////////////////////////////////////////////////////////////////////////// + + for(int idx = 0 ; idx < nbParticles ; ++idx){ + energyD += particles[idx].getPotential()*particles[idx].getPhysicalValue() ; + } + + // + //////////////////////////////////////////////////////////////////// + // begin Chebyshev kernel + + // accuracy + // typedefs + typedef FP2PParticleContainerIndexed<> ContainerClass; + typedef FSimpleLeaf< ContainerClass > LeafClass; + + typedef FChebCell<ORDER> CellClass; + typedef FOctree<CellClass,ContainerClass,LeafClass> OctreeClass; + // + typedef FInterpMatrixKernelR MatrixKernelClass; + typedef FChebSymKernel<CellClass,ContainerClass,MatrixKernelClass,ORDER> KernelClass; + // +#ifdef _OPENMP + typedef FFmmAlgorithmThread<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass; +#else + typedef FFmmAlgorithm<OctreeClass,CellClass,ContainerClass,KernelClass,LeafClass> FmmClass; +#endif + // init oct-tree + OctreeClass tree(TreeHeight, SubTreeHeight, loader.getBoxWidth(), loader.getCenterOfBox()); + + + { // ----------------------------------------------------- + std::cout << "Creating & Inserting " <<nbParticles + << " particles ..." << std::endl; + std::cout << "\tHeight : " << TreeHeight << " \t sub-height : " << SubTreeHeight << std::endl; + time.tic(); + // + for(int idxPart = 0 ; idxPart < nbParticles; ++idxPart){ + // + // Read particle per particle from file + // + // put particle in octree + tree.insert(particles[idxPart].getPosition() , idxPart, particles[idxPart].getPhysicalValue() ); + } + + time.tac(); + std::cout << "Done " << "(@Creating and Inserting Particles = " + << time.elapsed() << " s) ." << std::endl; + } // ----------------------------------------------------- + + { // ----------------------------------------------------- + std::cout << "\nChebyshev FMM (ORDER="<< ORDER << ") ... " << std::endl; + const MatrixKernelClass matrixClass; + time.tic(); + // + KernelClass kernels(TreeHeight, loader.getBoxWidth(), loader.getCenterOfBox(),&matrixClass); + // + FmmClass algorithm(&tree, &kernels); + // + algorithm.execute(); // Here the call of the FMM algorithm + // + time.tac(); + std::cout << "Done " << "(@Algorithm = " << time.elapsed() << " s) ." << std::endl; + } + // ----------------------------------------------------- + // + // Some output + // + // + { // ----------------------------------------------------- + FReal energy =0.0; + + // + // Loop over all leaves + // + std::cout <<std::endl<<" &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& "<<std::endl; + std::cout << std::scientific; + std::cout.precision(10) ; + + ///////////////////////////////////////////////////////////////////////////////////////////////// + // Compare + ///////////////////////////////////////////////////////////////////////////////////////////////// + printf("Compute Diff..."); + FMath::FAccurater potentialDiff; + FMath::FAccurater fx, fy, fz, f; + { // Check that each particle has been summed with all other + + tree.forEachLeaf([&](LeafClass* leaf){ + const FReal*const potentials = leaf->getTargets()->getPotentials(); + const FReal*const physicalValues = leaf->getTargets()->getPhysicalValues(); + 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(particles[indexPartOrig].getPotential(),potentials[idxPart]); + fx.add(particles[indexPartOrig].getForces()[0],forcesX[idxPart]); + // const std::string outputFile("accuracyChebyschev.txt") ; + fy.add(particles[indexPartOrig].getForces()[1],forcesY[idxPart]); + fz.add(particles[indexPartOrig].getForces()[2],forcesZ[idxPart]); + f.add(particles[indexPartOrig].getForces()[0],forcesX[idxPart]); + f.add(particles[indexPartOrig].getForces()[1],forcesY[idxPart]); + f.add(particles[indexPartOrig].getForces()[2],forcesZ[idxPart]); + energy += potentials[idxPart]*physicalValues[idxPart]; + } + }); + } + std::cout << energy << " " << energyD << std::endl; + delete[] particles; + + f.setNbElements(nbParticles); + std::cout << "FChebSymKernel Energy " << FMath::Abs(energy-energyD) << " Relative "<< FMath::Abs(energy-energyD) / FMath::Abs(energyD) <<std::endl; + std::cout << "FChebSymKernel Potential " << potentialDiff << std::endl; + std::cout << "FChebSymKernel Fx " << fx << std::endl; + std::cout << "FChebSymKernel Fy " << fy << std::endl; + std::cout << "FChebSymKernel Fz " << fz << std::endl; + std::cout << "FChebSymKernel F " << f << std::endl; + + const std::string outputFile("accuracyChebyschev.txt") ; + std::ofstream output(outputFile,std::fstream::out | std::fstream::app); + + output << ORDER << " " << FMath::Abs(energy-energyD) / FMath::Abs(energyD) + << " " << potentialDiff.getRelativeL2Norm() << " "<< potentialDiff.getRelativeInfNorm()<< " "<< potentialDiff.getRMSError() + << " " << f.getRelativeL2Norm() << " "<< f.getRelativeInfNorm() <<" "<< f.getRMSError() + << std::endl; + } + // ----------------------------------------------------- + + + //return 0; +} +}; + + +int main(int argc, char** argv){ +// const std::string outputFile("accuracyChebyschev.txt") ; +// std::ofstream output(outputFile,std::fstream::out | std::fstream::app); + + const unsigned int order = FParameters::getValue(argc, argv, "-order", 5); + std::cout << "Order given by user is : " << order << "\n"; + + // il faudrait un For ici + FRunIf::Run<unsigned int, 2, 13, 1, TempMainStruct>(order,argc, argv); + return 0; +} diff --git a/Utils/noDist/testSCalibilityOpenMP.sh b/Utils/noDist/testSCalibilityOpenMP.sh new file mode 100755 index 000000000..e8087e549 --- /dev/null +++ b/Utils/noDist/testSCalibilityOpenMP.sh @@ -0,0 +1,57 @@ +#!/bin/bash +project_dir=$HOME/Dev/src/ScalFMM/scalfmmT +# +# PlaFRIM environment +# +# +# +MaxCore=20 +# `cat /proc/cpuinfo |grep processor |wc -l` +# tester si linux alors +#MaxCore=`cat /proc/cpuinfo |grep processor |wc -l` +HOST=`hostname` +echo $HOST +EXEC="Examples/Release/ChebyshevInterpolationFMM" +REP="Test" +FILEPERF="RES_Chebyshev-openmpi-10M" +FILE="../Data/unitCubeXYZQ20k.bfma" +FILE="casTest-20000.fma" +FILE="/projets/scalfmm/benchPlafrim/unifCube_2_10000000.bfma" +echo "==================================================================" +echo "Run " +echo " pgm: ${EXEC}" +echo " file: ${FILE}" +echo " args -depth 7 -subdepth 4 " +echo " " +echo " Host: $HOST" +echo " MaxCore: $MaxCore" +echo "==================================================================" + +# +cd $project_dir/BuildOMP/ + +# +REP +pwd +#export OMP_PROC_BIND=true +export KMP_AFFINITY=verbose,scatter +echo $FILEPERF-${HOST}.out +echo "# Core TIME ENERGY Pot_0 Pot_5000000 Pot_9999999"> $FILEPERF-${HOST}.out +P0=1 +P1=1 +P2=2 +for l in `seq 1 $MaxCore `; +do + OUTPUT=${FILEPERF}-${HOST}-${l}.out + echo "Running per = " ${l} + $EXEC -f $FILE -depth 7 -subdepth 4 -t $l > $OUTPUT + # + TIME=`grep "@Algorithm" $OUTPUT | awk '{print $4}'` + Energy=`grep "Energy" $OUTPUT | awk '{print $2}'` + P0=`grep "Index 0 potential" $OUTPUT | awk '{print $4}'` + P1=`grep "Index 5000000 potential" $OUTPUT | awk '{print $4}'` + P2=`grep "Index 9999999 potential" $OUTPUT | awk '{print $4}'` + echo " " $l " " $TIME " " $Energy " " $P0 " " $P1 " " $P2 >> $FILEPERF-${HOST}.out +done + + -- GitLab