testBlockedUniformBench.cpp 9 KB
Newer Older
1 2 3 4

// ==== CMAKE =====
// @FUSE_BLAS
// @FUSE_FFT
Berenger Bramas's avatar
Berenger Bramas committed
5
// @FUSE_STARPU
6 7 8 9 10 11 12 13 14
// ================
// Keep in private GIT


#include "../../Src/Utils/FGlobal.hpp"

#include "../../Src/GroupTree/Core/FGroupTree.hpp"

#include "../../Src/Components/FSimpleLeaf.hpp"
15
#include "../../Src/Components/FSymbolicData.hpp"
16 17 18 19 20 21
#include "../../Src/Containers/FVector.hpp"

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

#include "Kernels/Interpolation/FInterpMatrixKernel.hpp"
#include "../../Src/Kernels/Uniform/FUnifKernel.hpp"
22
#include "../../Src/Kernels/Uniform/FUnifCell.hpp"
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

#include "../../Src/Utils/FMath.hpp"
#include "../../Src/Utils/FMemUtils.hpp"
#include "../../Src/Utils/FParameters.hpp"

#include "../../Src/Files/FRandomLoader.hpp"
#include "../../Src/Files/FFmaGenericLoader.hpp"

#include "../../Src/GroupTree/Core/FGroupSeqAlgorithm.hpp"
#include "../../Src/GroupTree/Core/FGroupTaskAlgorithm.hpp"
#ifdef SCALFMM_USE_OMP4
#include "../../Src/GroupTree/Core/FGroupTaskDepAlgorithm.hpp"
#endif
#ifdef SCALFMM_USE_STARPU
#include "../../Src/GroupTree/Core/FGroupTaskStarpuAlgorithm.hpp"
#include "../../Src/GroupTree/StarPUUtils/FStarPUKernelCapacities.hpp"
#endif
#include "../../Src/GroupTree/Core/FP2PGroupParticleContainer.hpp"

#include "../../Src/Utils/FParameterNames.hpp"

#include <memory>


#define RANDOM_PARTICLES

int main(int argc, char* argv[]){
    const FParameterNames LocalOptionBlocSize { {"-bs"}, "The size of the block of the blocked tree"};
    const FParameterNames LocalOptionValidate { {"-validation"}, "To compare with direct computation"};
    FHelpDescribeAndExit(argc, argv, "Perform Lagrange Kernel based simulation with StarPU",
                         FParameterDefinitions::OctreeHeight,
#ifdef RANDOM_PARTICLES
                         FParameterDefinitions::NbParticles,
#else
                         FParameterDefinitions::InputFile,
#endif
                         FParameterDefinitions::NbThreads,
                         LocalOptionBlocSize, LocalOptionValidate);

    // Initialize the types
    typedef double FReal;
    static const int ORDER = 5;
    typedef FInterpMatrixKernelR<FReal> MatrixKernelClass;

67 68 69 70
    using GroupCellClass     = FUnifCell<FReal, ORDER>;
    using GroupCellUpClass   = typename GroupCellClass::multipole_t;
    using GroupCellDownClass = typename GroupCellClass::local_expansion_t;
    using GroupCellSymbClass = FSymbolicData;
71 72

    typedef FP2PGroupParticleContainer<FReal>          GroupContainerClass;
73
    typedef FGroupTree< FReal, GroupCellSymbClass, GroupCellUpClass, GroupCellDownClass, GroupContainerClass, 1, 4, FReal>  GroupOctreeClass;
Berenger Bramas's avatar
Berenger Bramas committed
74

75 76
    typedef FStarPUAllCpuCapacities<FUnifKernel<FReal,GroupCellClass,GroupContainerClass,MatrixKernelClass,ORDER>> GroupKernelClass;
    typedef FStarPUCpuWrapper<typename GroupOctreeClass::CellGroupClass, GroupCellClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupContainerClass> GroupCpuWrapper;
Berenger Bramas's avatar
Berenger Bramas committed
77
    typedef FGroupTaskStarPUAlgorithm<GroupOctreeClass, typename GroupOctreeClass::CellGroupClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupCpuWrapper, GroupContainerClass > GroupAlgorithm;
Berenger Bramas's avatar
Berenger Bramas committed
78

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
    // Get params
    const int NbLevels      = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5);
    const int groupSize     = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 250);

    // Load the particles
#ifdef RANDOM_PARTICLES
    FRandomLoader<FReal> loader(FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, 2000), 1.0, FPoint<FReal>(0,0,0), 0);
#else
    const char* const filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, "../Data/test20k.fma");
    FFmaGenericLoader<FReal> loader(filename);
#endif
    FAssertLF(loader.isOpen());
    FTic timer;

    FP2PParticleContainer<FReal> allParticles;
    for(FSize idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
        FPoint<FReal> particlePosition;
        FReal physicalValue;
#ifdef RANDOM_PARTICLES
        physicalValue = 0.10;
        loader.fillParticle(&particlePosition);
#else
        loader.fillParticle(&particlePosition, &physicalValue);
#endif
        allParticles.push(particlePosition, physicalValue);
    }
    std::cout << "Particles loaded in " << timer.tacAndElapsed() << "s\n";

    // Put the data into the tree
    timer.tic();
    GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles);
    groupedTree.printInfoBlocks();
    std::cout << "Tree created in " << timer.tacAndElapsed() << "s\n";

    // Run the algorithm
    const MatrixKernelClass MatrixKernel;
    GroupKernelClass groupkernel(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), &MatrixKernel);
    GroupAlgorithm groupalgo(&groupedTree,&groupkernel);

    timer.tic();
    groupalgo.execute();
    timer.tac();
    std::cout << "@EXEC TIME = " << timer.elapsed() << "s\n";

    // Validate the result
    if(FParameters::existParameter(argc, argv, LocalOptionValidate.options) == true){
        FSize offsetParticles = 0;
        FReal*const allPhysicalValues = allParticles.getPhysicalValues();
        FReal*const allPosX = const_cast<FReal*>( allParticles.getPositions()[0]);
        FReal*const allPosY = const_cast<FReal*>( allParticles.getPositions()[1]);
        FReal*const allPosZ = const_cast<FReal*>( allParticles.getPositions()[2]);

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
        groupedTree.forEachCellLeaf<FP2PGroupParticleContainer<FReal> >(
            [&](GroupCellSymbClass* /*gsymb*/,
                GroupCellUpClass* /*gmul*/,
                GroupCellDownClass* /*gloc*/,
                FP2PGroupParticleContainer<FReal> * leafTarget)
            {
                const FReal*const physicalValues = leafTarget->getPhysicalValues();
                const FReal*const posX = leafTarget->getPositions()[0];
                const FReal*const posY = leafTarget->getPositions()[1];
                const FReal*const posZ = leafTarget->getPositions()[2];
                const FSize nbPartsInLeafTarget = leafTarget->getNbParticles();

                for(FSize idxPart = 0 ; idxPart < nbPartsInLeafTarget ; ++idxPart){
                    allPhysicalValues[offsetParticles + idxPart] = physicalValues[idxPart];
                    allPosX[offsetParticles + idxPart] = posX[idxPart];
                    allPosY[offsetParticles + idxPart] = posY[idxPart];
                    allPosZ[offsetParticles + idxPart] = posZ[idxPart];
                }

                offsetParticles += nbPartsInLeafTarget;
            });
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

        FAssertLF(offsetParticles == loader.getNumberOfParticles());

        FReal*const allDirectPotentials = allParticles.getPotentials();
        FReal*const allDirectforcesX = allParticles.getForcesX();
        FReal*const allDirectforcesY = allParticles.getForcesY();
        FReal*const allDirectforcesZ = allParticles.getForcesZ();

        for(int idxTgt = 0 ; idxTgt < offsetParticles ; ++idxTgt){
            for(int idxMutual = idxTgt + 1 ; idxMutual < offsetParticles ; ++idxMutual){
                FP2PR::MutualParticles(
                    allPosX[idxTgt],allPosY[idxTgt],allPosZ[idxTgt], allPhysicalValues[idxTgt],
                    &allDirectforcesX[idxTgt], &allDirectforcesY[idxTgt], &allDirectforcesZ[idxTgt], &allDirectPotentials[idxTgt],
                    allPosX[idxMutual],allPosY[idxMutual],allPosZ[idxMutual], allPhysicalValues[idxMutual],
                    &allDirectforcesX[idxMutual], &allDirectforcesY[idxMutual], &allDirectforcesZ[idxMutual], &allDirectPotentials[idxMutual]
                );
            }
        }

        FMath::FAccurater<FReal> potentialDiff;
        FMath::FAccurater<FReal> fx, fy, fz;
        offsetParticles = 0;
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
        groupedTree.forEachCellLeaf<FP2PGroupParticleContainer<FReal> >(
            [&](GroupCellSymbClass* /*gsymb*/,
                GroupCellUpClass* /*gmul*/,
                GroupCellDownClass* /*gloc*/,
                FP2PGroupParticleContainer<FReal> * leafTarget)
            {
                const FReal*const potentials = leafTarget->getPotentials();
                const FReal*const forcesX = leafTarget->getForcesX();
                const FReal*const forcesY = leafTarget->getForcesY();
                const FReal*const forcesZ = leafTarget->getForcesZ();
                const FSize nbPartsInLeafTarget = leafTarget->getNbParticles();

                for(int idxTgt = 0 ; idxTgt < nbPartsInLeafTarget ; ++idxTgt){
                    potentialDiff.add(allDirectPotentials[idxTgt + offsetParticles], potentials[idxTgt]);
                    fx.add(allDirectforcesX[idxTgt + offsetParticles], forcesX[idxTgt]);
                    fy.add(allDirectforcesY[idxTgt + offsetParticles], forcesY[idxTgt]);
                    fz.add(allDirectforcesZ[idxTgt + offsetParticles], forcesZ[idxTgt]);
                }

                offsetParticles += nbPartsInLeafTarget;
            });
195 196 197 198 199 200 201 202 203

        std::cout << "Error : Potential " << potentialDiff << "\n";
        std::cout << "Error : fx " << fx << "\n";
        std::cout << "Error : fy " << fy << "\n";
        std::cout << "Error : fz " << fz << "\n";
    }

    return 0;
}