Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
ScalFMM
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
5
Issues
5
List
Boards
Labels
Service Desk
Milestones
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
solverstack
ScalFMM
Commits
ac4a7f0e
Commit
ac4a7f0e
authored
Jan 06, 2015
by
COULAUD Olivier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add scalability test in Utils/noDist
Fill variable SCALFMMCompileFlags and SCALFMMCompileLibs
parent
38606790
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
584 additions
and
34 deletions
+584
-34
CMakeLists.txt
CMakeLists.txt
+32
-32
Src/ScalFmmConfig.h.cmake
Src/ScalFmmConfig.h.cmake
+2
-2
Utils/noDist/stamp2Fma.cpp
Utils/noDist/stamp2Fma.cpp
+223
-0
Utils/noDist/testAccuracyChebFMM.cpp
Utils/noDist/testAccuracyChebFMM.cpp
+270
-0
Utils/noDist/testSCalibilityOpenMP.sh
Utils/noDist/testSCalibilityOpenMP.sh
+57
-0
No files found.
CMakeLists.txt
View file @
ac4a7f0e
...
...
@@ -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
"S
caLFMM_CXX_FLAGS
=
${
ScaLFMM_CXX_FLAGS
}
"
)
MESSAGE
(
STATUS
"CMAKE_CXX_FLAGS
=
${
CMAKE_CXX_FLAGS
}
"
)
MESSAGE
(
STATUS
"S
CALFMM_CXX_FLAGS
=
${
ScaLFMM_CXX_FLAGS
}
"
)
MESSAGE
(
STATUS
"SCALFMM_LIBRARIES =
${
SCALFMM_LIBRARIES
}
"
)
MESSAGE
(
STATUS
"SCALFMM_INCLUDES =
${
SCALFMM_INCLUDES
}
"
)
##################################################################
...
...
Src/ScalFmmConfig.h.cmake
View file @
ac4a7f0e
...
...
@@ -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
Utils/noDist/stamp2Fma.cpp
0 → 100644
View file @
ac4a7f0e
/*
* 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
;
}
Utils/noDist/testAccuracyChebFMM.cpp
0 → 100644
View file @
ac4a7f0e
// ===================================================================================
// 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
<<
"
\t
Height : "
<<
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
<<
"
\n
Chebyshev 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
]);