Commit 8d566ad0 authored by COULAUD Olivier's avatar COULAUD Olivier

Remove @SCALFMM_PRIVATE in some files

parent 6514e229
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// ===================================================================================
// Ce LOGICIEL "ScalFmm" est couvert par le copyright Inria 20xx-2012.
// Inria détient tous les droits de propriété sur le LOGICIEL, et souhaite que
// la communauté scientifique l'utilise afin de le tester et de l'évaluer.
// Inria donne gracieusement le droit d'utiliser ce LOGICIEL. Toute utilisation
// dans un but lucratif ou à des fins commerciales est interdite sauf autorisation
// expresse et préalable d'Inria.
// Toute utilisation hors des limites précisées ci-dessus et réalisée sans l'accord
// expresse préalable d'Inria constituerait donc le délit de contrefaçon.
// Le LOGICIEL étant un produit en cours de développement, Inria ne saurait assurer
// aucune responsabilité et notamment en aucune manière et en aucun cas, être tenu
// de répondre d'éventuels dommages directs ou indirects subits par l'utilisateur.
// Tout utilisateur du LOGICIEL s'engage à communiquer à Inria ses remarques
// relatives à l'usage du LOGICIEL
// ===================================================================================
// ==== CMAKE =====
// @FUSE_BLAS
// ================
// Keep in private GIT
// @SCALFMM_PRIVATE
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "../../Src/Utils/FTic.hpp"
#include "../../Src/Utils/FMath.hpp"
#include "../../Src/Utils/FPoint.hpp"
#include "../../Src/Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Kernels/Chebyshev/FChebRoots.hpp"
#include "../../Src/Kernels/Chebyshev/FChebTensor.hpp"
#include "../../Src/Kernels/Chebyshev/FChebSymM2LHandler.hpp"
#include "../../Src/Utils/FParameterNames.hpp"
#include "../../Src/Utils/FAca.hpp"
/**
* In this file we show how to use octree
*/
int main(int argc, char* argv[])
{
FHelpDescribeAndExit(argc, argv, "Look to the code.");
typedef double FReal;
typedef FInterpMatrixKernelR<FReal> MatrixKernelClass;
MatrixKernelClass MatrixKernel;
const unsigned int ORDER = 9;
const FReal epsilon = 1e-9;
const unsigned int nnodes = TensorTraits<ORDER>::nnodes;
// initialize timer
FTic time;
/*
//// width of cell X and Y
//FReal wx = FReal(2.);
//FReal wy = FReal(2.);
//// centers of cells X and Y
//FPoint<FReal> cx( 0., 0., 0.);
//FPoint<FReal> cy( 4., 0., 0.);
// width of cell X and Y
FReal wx = FReal(2.);
FReal wy = FReal(4.);
// centers of cells X and Y
FPoint<FReal> cx( 1.,-1.,-1.);
//FPoint<FReal> cy(-4., 0., 0.);
FPoint<FReal> cy(-4., 4., 4.);
std::cout << "[cx = " << cx << ", wx = " << wx
<< "] [cy = " << cy << ", wy = " << wy
<< "] -> dist = " << FPoint<FReal>(cx-cy).norm() << std::endl;
// compute Cheb points in cells X and Y
FPoint<FReal> rootsX[nnodes], rootsY[nnodes];
FChebTensor<FReal,ORDER>::setRoots(cx, wx, rootsX);
FChebTensor<FReal,ORDER>::setRoots(cy, wy, rootsY);
// fully pivoted ACA ///////////////////////////
std::cout << "Fully pivoted ACA of Acc(" << ORDER << ", " << epsilon << ")" << std::endl;
std::cout << "|- Assembling K" << std::flush;
FReal *const K = new FReal [nnodes * nnodes];
time.tic();
EntryComputer<FReal,MatrixKernelClass> Computer(nnodes, rootsX, nnodes, rootsY);
Computer(0, nnodes, 0, nnodes, K);
std::cout << ", finished in " << time.tacAndElapsed() << "s." << std::endl;
// generate right hand side vector
FReal *const w = new FReal [nnodes];
for (unsigned int j=0; j<nnodes; ++j)
w[j] = FReal(drand48());
// compute f0 = Kw
FReal *const f0 = new FReal [nnodes];
FBlas::gemv(nnodes, nnodes, FReal(1.), K, w, f0);
// allocate UV and k
FReal *U, *V;
unsigned int k;
// call fACA /////////////////////////////////
std::cout << "|- Computing fACA" << std::flush;
time.tic();
fACA(K, nnodes, nnodes, epsilon, U, V, k);
std::cout << " (k = " << k << "), finished in " << time.tacAndElapsed() << "s." << std::endl;
delete [] K;
// compute f1 = UV'w
FReal *const f1 = new FReal [nnodes];
FReal *const c1 = new FReal [k];
FBlas::gemtv(nnodes, k, FReal(1.), V, w, c1);
FBlas::gemv( nnodes, k, FReal(1.), U, c1, f1);
delete [] c1;
std::cout << "| |- L2 error = " << computeL2norm(nnodes, f0, f1) << std::endl;
delete [] U;
delete [] V;
delete [] f1;
// call pACA ///////////////////////////////////
std::cout << "|- Computing pACA" << std::flush;
time.tic();
pACA(Computer, nnodes, nnodes, epsilon, U, V, k);
std::cout << " (k = " << k << "), finished in " << time.tacAndElapsed() << "s." << std::endl;
// compute f1 = UV'w
FReal *const f2 = new FReal [nnodes];
FReal *const c2 = new FReal [k];
FBlas::gemtv(nnodes, k, FReal(1.), V, w, c2);
FBlas::gemv( nnodes, k, FReal(1.), U, c2, f2);
delete [] c2;
std::cout << "| |- L2 error = " << computeL2norm(nnodes, f0, f2) << std::endl;
delete [] U;
delete [] V;
delete [] w;
delete [] f0;
delete [] f2;
*/
// test different levels of multipole expansions
const FReal pw = FReal(4.);
const FReal cw = pw / FReal(2.);
const FPoint<FReal> cpx( 0., 0., 0.);
const FPoint<FReal> ccx(-1.,-1.,-1.);
// compute Cheb points in cells X and Y
FPoint<FReal> rootsX[nnodes], rootsY[nnodes];
FChebTensor<FReal,ORDER>::setRoots(ccx, cw, rootsX);
unsigned int all_counter = 0;
unsigned int ccounter = 0;
unsigned int pcounter = 0;
unsigned int overall_rank = 0;
unsigned int all_overall_rank = 0;
// allocate UV and k
FReal *U, *V;
unsigned int rank;
for (int i=-1; i<=1; ++i)
for (int j=-1; j<=1; ++j)
for (int k=-1; k<=1; ++k) {
const FPoint<FReal> cpy(FReal(i)*pw, FReal(j)*pw, FReal(k)*pw);
// exclude target cell itself
if ((FMath::Abs(i) + FMath::Abs(j) + FMath::Abs(k)) != 0) {
//////////////////////////////////////////////////////////////////////
// use all multipole expansions form child level
for (int ci=-1; ci<=1; ci+=2)
for (int cj=-1; cj<=1; cj+=2)
for (int ck=-1; ck<=1; ck+=2) {
const FPoint<FReal> ccy(cpy.getX() + FReal(ci)*cw/2., cpy.getY() + FReal(cj)*cw/2., cpy.getZ() + FReal(ck)*cw/2.);
// exclude near-field
if (FPoint<FReal>(ccx-ccy).norm() > FReal(3.5)) {
FChebTensor<FReal,ORDER>::setRoots(ccy, cw, rootsY);
EntryComputer<FReal,MatrixKernelClass> Computer(&MatrixKernel,nnodes, rootsX, nnodes, rootsY);
FAca::pACA(Computer, nnodes, nnodes, epsilon, U, V, rank);
//std::cout << "- Compress " << ccy << "\tof width " << cw << " to rank " << rank << std::endl;
all_counter++;
all_overall_rank += rank;
delete [] U;
delete [] V;
}
}
//////////////////////////////////////////////////////////////////////
// exclude source cells whose multipole expansion are taken from parent level
if (cpy.getX()*ccx.getX() >= 0 && cpy.getY()*ccx.getY() >= 0 && cpy.getZ()*ccx.getZ() >= 0) {
for (int ci=-1; ci<=1; ci+=2)
for (int cj=-1; cj<=1; cj+=2)
for (int ck=-1; ck<=1; ck+=2) {
const FPoint<FReal> ccy(cpy.getX() + FReal(ci)*cw/2., cpy.getY() + FReal(cj)*cw/2., cpy.getZ() + FReal(ck)*cw/2.);
// exclude near-field
if (FPoint<FReal>(ccx-ccy).norm() > FReal(3.5)) {
FChebTensor<FReal,ORDER>::setRoots(ccy, cw, rootsY);
EntryComputer<FReal,MatrixKernelClass> Computer(&MatrixKernel,nnodes, rootsX, nnodes, rootsY);
FAca::pACA(Computer, nnodes, nnodes, epsilon, U, V, rank);
//std::cout << "- Compress " << ccy << "\tof width " << cw << " to rank " << rank << std::endl;
ccounter++;
overall_rank += rank;
delete [] U;
delete [] V;
}
}
}
// remaining far-field: source cells whose multipole expansion is taken from parent level
else {
FChebTensor<FReal,ORDER>::setRoots(cpy, pw, rootsY);
EntryComputer<FReal,MatrixKernelClass> Computer(&MatrixKernel,nnodes, rootsX, nnodes, rootsY);
FAca::pACA(Computer, nnodes, nnodes, epsilon, U, V, rank);
//std::cout << "- Compress " << cpy << "\tof width " << pw << " to rank " << rank << std::endl;
pcounter++;
overall_rank += rank;
delete [] U;
delete [] V;
}
}
}
std::cout << "-- Overall low rank " << overall_rank
<< ", child cells = " << ccounter
<< ", parent cells = " << pcounter << std::endl;
std::cout << "-- Overall low rank " << all_overall_rank
<< ", child cells = " << all_counter << std::endl;
std::cout << "--- Ratio = " << FReal(overall_rank) / FReal(all_overall_rank) << std::endl;
return 0;
}
// [--END--]
This diff is collapsed.
This diff is collapsed.
// @FUSE_MPI
#include <iostream>
#include <string>
#include "Files/FMpiFmaDivider.hpp"
#include "testFMpiFmaDividerArgs.hpp"
using FReal = double;
int main(int argc, char** argv)
{
testFMpiFmaDividerArgs args(argc, argv);
FMpiFmaDivider<FReal>
divider(args.inFileName(),
args.outFileName() + "_" + args.dispatchPolicyString()
+ "_" + std::to_string(args.zoneCount())
+ "z_h" + std::to_string(args.treeHeight()),
args.outFileExt(),
args.zoneCount(),
args.treeHeight(),
FMpiFmaDivider<FReal>::DispatchPolicy(args.dispatchPolicy()));
}
// ==== CMAKE ====
// Keep in private GIT
// @SCALFMM_PRIVATE
#ifndef _TESTFMPIFMADIVIDERARGS_HPP_
#define _TESTFMPIFMADIVIDERARGS_HPP_
#include <string>
#include <omp.h>
#include "Utils/FParameters.hpp"
#include "Utils/FParameterNames.hpp"
class testFMpiFmaDividerArgs {
const int _treeHeightInit = 5;
const int _zoneCountInit = omp_get_max_threads();
const int _verboseInit = 0;
const char* _inFileNameInit = "";
const char* _outFileNameInit = "";
const char* _outFileNameExtInit = "";
const char* _dispatchPolicyInit = "particles";
int _argc;
char** _argv;
const FParameterNames OutputFileBasename =
{{"--output-file-basename", "-fout-base"},
"Output files' basename. One file is created for each level in "
"the tree. Each file has a level-in-tree based extension."};
const FParameterNames OutputFileExtension =
{{"--output-file-extention", "-fout-ext"},
"Output files extension. One file is created for each level in the"
" tree. Each file has a 'basename_$nbZones$z.$i$.extension' "
"extension where $i is the level."};
const FParameterNames ZoneCount =
{{"--zone-count","-z"},"Number of zones to create."};
const FParameterNames DispatchPolicy =
{{"--dispatch","-d"},"What should be counted to dispatch the work"
" ('particles' or 'boxes')."};
public:
int treeHeight() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, OctreeHeight.options, _treeHeightInit);
}
int zoneCount() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, ZoneCount.options, _zoneCountInit);
}
int verboseLevel() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, EnabledVerbose.options, _verboseInit);
}
std::string inFileName() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getStr(_argc, _argv, InputFile.options, _inFileNameInit);
}
std::string outFileName() const {
using namespace FParameterDefinitions;
using namespace FParameters;
if( ! existParameter(_argc, _argv, OutputFileBasename.options) ) {
std::string str(getStr(_argc, _argv, InputFile.options, _inFileNameInit));
return str.substr(0, str.find_last_of("."));
}
return getStr(_argc, _argv, OutputFileBasename.options, _outFileNameInit);
}
std::string outFileExt() const {
using namespace FParameterDefinitions;
using namespace FParameters;
if( ! existParameter(_argc, _argv, OutputFileExtension.options) ) {
std::string str(getStr(_argc, _argv, InputFile.options, _inFileNameInit));
return str.substr(str.find_last_of("."));
}
std::string ext = getStr(_argc, _argv, OutputFileExtension.options,
_outFileNameExtInit);
if ( ext.at(0) != '.' )
return '.' + ext;
return ext;
}
std::string dispatchPolicyString() const {
using namespace FParameterDefinitions;
using namespace FParameters;
std::string str = getStr(_argc, _argv, DispatchPolicy.options, _dispatchPolicyInit);
return str;
}
int dispatchPolicy() const {
std::string str = dispatchPolicyString();
if ( "particles" == str ) {
return 0;
} else {
return 1;
}
}
testFMpiFmaDividerArgs(int argc, char** argv) : _argc(argc), _argv(argv) {
parse();
}
int parse() {
using namespace FParameterDefinitions;
using namespace FParameters;
FHelpDescribeAndExit
(_argc, _argv,
"Loads an FMA file into a tree and runs a pseudo FMM algorithm "
"through it to compute load balancing.",
OctreeHeight,
InputFile,
OutputFileBasename,
OutputFileExtension,
ZoneCount,
DispatchPolicy
);
return 0;
}
};
#endif
// ==== CMAKE ====
// Keep in private GIT
// @SCALFMM_PRIVATE
#ifndef _LOADFMAANDRUNFMMARGS_HPP_
#define _LOADFMAANDRUNFMMARGS_HPP_
#include <string>
#include <omp.h>
#include "Utils/FParameters.hpp"
#include "Utils/FParameterNames.hpp"
class loadFMAAndRunFMMArgs {
const int _treeHeightInit = 5;
const int _subTreeHeightInit = 1;
const int _zoneCountInit = omp_get_max_threads();
const int _verboseInit = 0;
const char* _inFileNameInit = "";
const char* _outFileNameInit = "balancetest";
const char* _outFileNameExtInit = "csv";
int _argc;
char** _argv;
const FParameterNames OutputFileBasename =
{{"--output-file-basename", "-fout-base"},
"Output files' basename. One file is created for each level in "
"the tree. Each file has a level-in-tree based extension."};
const FParameterNames OutputFileExtension =
{{"--output-file-extention", "-fout-ext"},
"Output files extension. One file is created for each level in the"
" tree. Each file has a 'basename_$nbZones$z.$i$.extension' "
"extension where $i is the level."};
const FParameterNames ZoneCount =
{{"--zone-count","-z"},"Number of zones to create."};
public:
int treeHeight() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, OctreeHeight.options, _treeHeightInit);
}
int subTreeHeight() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, OctreeSubHeight.options,
_subTreeHeightInit);
}
int zoneCount() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, ZoneCount.options, _zoneCountInit);
}
int verboseLevel() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getValue(_argc, _argv, EnabledVerbose.options, _verboseInit);
}
std::string inFileName() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getStr(_argc, _argv, InputFile.options, _inFileNameInit);
}
std::string outFileName() const {
using namespace FParameterDefinitions;
using namespace FParameters;
return getStr(_argc, _argv, OutputFileBasename.options, _outFileNameInit);
}
std::string outFileExt() const {
using namespace FParameterDefinitions;
using namespace FParameters;
std::string ext = getStr(_argc, _argv, OutputFileExtension.options,
_outFileNameExtInit);
if ( ext.at(0) != '.' )
return '.' + ext;
return ext;
}
loadFMAAndRunFMMArgs(int argc, char** argv) : _argc(argc), _argv(argv) {
parse();
}
int parse() {
using namespace FParameterDefinitions;
using namespace FParameters;
FHelpDescribeAndExit
(_argc, _argv,
"Loads an FMA file into a tree and runs a pseudo FMM algorithm "
"through it to compute load balancing.",
OctreeHeight,
OctreeSubHeight,
InputFile,
OutputFileBasename,
OutputFileExtension,
ZoneCount,
EnabledVerbose
);
return 0;
}
};
#endif
// ==== CMAKE ====
// Keep in private GIT
// @SCALFMM_PRIVATE
#ifndef _LOADFMAANDRUNFMMUTILS_HPP_
#define _LOADFMAANDRUNFMMUTILS_HPP_
#include <fstream>
#include <memory>
#include <assert.h>
#include <array>
#include <vector>
/**
* \brief Saves the far field costzones to files.
*
* One file is created per level, one particle is stored per line in the form :
* x,y,z,zone.
*
* \param args The args that were given to the program
* \param costzones The CostZones object that was used get the tree balance.
*/
template<class OctreeClass, class CellClass>
void writeZones(const loadFMAAndRunFMMArgs& args, const FCostZones <OctreeClass,CellClass>& costzones)
{
const std::string outFileBaseName = args.outFileName();
const std::string outFileExt = args.outFileExt();
const int verboseLevel = args.verboseLevel();
const int treeHeight = args.treeHeight();
auto zones = costzones.getZones();
long unsigned int zoneCount = zones.size();//args.zoneCount();
std::cout << "Writing " << zoneCount << " zones." << std::endl;
// GCC versions before 5.0 have not implemented move constructors to streams
// we use unique pointers to get around this problem.
std::vector<std::unique_ptr<std::ofstream>> outfiles;
for ( int levelIdx = 0; levelIdx < treeHeight; levelIdx++ ) {
std::unique_ptr<std::ofstream> out(
new std::ofstream( outFileBaseName
+ "_" + std::to_string(zoneCount) + "z"
+ "." + std::to_string(levelIdx)
+ outFileExt));
*out << "x,y,z,zone" << std::endl;
outfiles.push_back(std::move(out));
}
int zoneIdx = 0;
for ( auto zone : zones) {
for ( auto cell : zone) {
*(outfiles[cell.first]) << cell.second->getCoordinate().getX() << ",";
*(outfiles[cell.first]) << cell.second->getCoordinate().getY() << ",";
*(outfiles[cell.first]) << cell.second->getCoordinate().getZ() << ",";
*(outfiles[cell.first]) << zoneIdx << std::endl;
}
zoneIdx++;
}
if ( verboseLevel > 0) {
auto& zonebounds = costzones.getZoneBounds();
zoneIdx = 0;
for ( auto zone : zonebounds ) {
std::cout << std::endl << "Zone " << zoneIdx << std::endl;
int level = 0;
for ( auto levelbounds : zone ) {
std::cout << "Level" << level << " : [" << levelbounds.first << ":" << levelbounds.second << "]\n";
level++;
}
zoneIdx++;
}
}
}
/**
* \brief Loads a tree from a loader.
* \param tree The the to load into.
* \param loader The loader to load from.
*/
template <typename FReal, class OctreeClass>
void loadTree(OctreeClass& tree, FFmaGenericLoader<FReal>& loader)
{
FReal physicalValue;
FPoint<FReal> particlePosition;
// insertion
for ( int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart ) {
loader.fillParticle(&particlePosition, &physicalValue);
tree.insert(particlePosition);
}
}
/**
* \brief Loads a tree from a loader.
* \param tree The the to load into.
* \param loader The loader to load from.
*/
template <typename FReal, class OctreeClass>
void loadTree(OctreeClass& tree, FRandomLoader<FReal>& loader)
{
FPoint<FReal> particlePosition;
// insertion
for ( int idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart ) {
loader.fillParticle(&particlePosition);
tree.insert(particlePosition);
}
}
/**
* \brief Prints the cost of each zone.
*
* This function prints the far-field and near-field costzones costs to stdout.
* The costs are printed using the format :
* zone_number far_field_cost near_field_cost
*
* \param tree The tree.
* \param costzones The FCostZones object that was used to compute the zones.
*/
template <typename OctreeClass, typename CellClass>
void printZonesCosts(OctreeClass& tree, FCostZones<OctreeClass, CellClass>& costzones)
{
using CostType = typename CellClass::costtype;
using TreeIterator = typename OctreeClass::Iterator;
//using BoundClass = typename FCostZones<OctreeClass, CellClass>::BoundClass;
auto zones = costzones.getZones();
// Zones costs (internal, leaf)
std::vector<std::tuple<CostType,CostType>> zonecosts(zones.size());
// Leaf colour zone costs
std::vector<std::array<CostType, FCoordColour::range>> zonecolourcosts(zones.size());
int zoneIdx = 0;
for(auto z : zones) {
for(auto cell : z) {
std::get<0>(zonecosts.at(zoneIdx)) += cell.second->getCost();
}
zoneIdx++;
}