testBlockedWithOpenCLAlgorithm.cpp 8.21 KB
Newer Older
1 2 3 4 5
// Keep in private GIT

// @FUSE_STARPU
// @FUSE_OPENCL

6
#include "Utils/FGlobal.hpp"
7

8
#include "GroupTree/Core/FGroupTree.hpp"
9

10 11
#include "Components/FSimpleLeaf.hpp"
#include "Containers/FVector.hpp"
12 13


14 15 16
#include "Utils/FMath.hpp"
#include "Utils/FMemUtils.hpp"
#include "Utils/FParameters.hpp"
17

18
#include "Files/FRandomLoader.hpp"
19

20
#include "GroupTree/Core/FGroupSeqAlgorithm.hpp"
21

22
#include "GroupTree/Core/FGroupTaskStarpuAlgorithm.hpp"
23

24 25
#include "GroupTree/Core/FP2PGroupParticleContainer.hpp"
#include "GroupTree/Core/FGroupTaskAlgorithm.hpp"
26

27
#include "Utils/FParameterNames.hpp"
28

29 30
#include "GroupTree/StarPUUtils/FStarPUCpuWrapper.hpp"
#include "GroupTree/StarPUUtils/FStarPUOpenClWrapper.hpp"
31

32 33 34 35
#include "Components/FTestParticleContainer.hpp"
#include "Components/FTestCell.hpp"
#include "Components/FTestKernels.hpp"
#include "GroupTree/TestKernel/FGroupTestParticleContainer.hpp"
36

37 38
#include "Files/FFmaGenericLoader.hpp"
#include "Core/FFmmAlgorithm.hpp"
39

40 41
#include "GroupTree/StarPUUtils/FStarPUKernelCapacities.hpp"
#include "GroupTree/TestKernel/FTestOpenCLCode.hpp"
42
#include "Components/FTestCell.hpp"
43

44
#include "GroupTree/OpenCl/FOpenCLDeviceWrapper.hpp"
45

46
int main(int argc, char* argv[]){
47 48 49 50 51 52 53 54 55
    if(getenv("HOSTNAME") && strcmp(getenv("HOSTNAME"),"berenger-HP-ProBook-640-G1") == 0){
        setenv("STARPU_NCPU","0",1);
        setenv("STARPU_NOPENCL","1",1);
        setenv("STARPU_OPENCL_ONLY_ON_CPUS","1",1);
        setenv("STARPU_OPENCL_ON_CPUS","1",1);

        setenv("STARPU_DISABLE_ASYNCHRONOUS_OPENCL_COPY","1",1);
        setenv("STARPU_OPENCL_PIPELINE","0",0); // synchronous task
    }
56

57 58 59 60
    const FParameterNames LocalOptionBlocSize {
        {"-bs"},
        "The size of the block of the blocked tree"
    };
BRAMAS Berenger's avatar
BRAMAS Berenger committed
61 62
    FHelpDescribeAndExit(argc, argv, "Test the blocked tree by counting the particles."
                         "Usually run with STARPU_NCPU=0 STARPU_NOPENCL=1 STARPU_OPENCL_ONLY_ON_CPUS=1 ./Tests/Release/testBlockedWithOpenCLAlgorithm",
63 64
                         FParameterDefinitions::OctreeHeight, FParameterDefinitions::NbThreads,
                         FParameterDefinitions::NbParticles, LocalOptionBlocSize);
65

66 67
    typedef double FReal;

68 69 70 71 72
    using GroupCellClass     = FTestCell<>;
    using GroupCellUpClass   = typename GroupCellClass::multipole_t;
    using GroupCellDownClass = typename GroupCellClass::local_expansion_t;
    using GroupCellSymbClass = FSymbolicData;

73

74 75
    typedef FGroupTestParticleContainer<FReal>                                     GroupContainerClass;
    typedef FGroupTree< FReal, GroupCellClass, GroupCellSymbClass, GroupCellUpClass, GroupCellDownClass,
76
            GroupContainerClass, 0, 1, long long int>  GroupOctreeClass;
77
    typedef FStarPUAllCpuOpenCLCapacities<FTestKernels< GroupCellClass, GroupContainerClass >>  GroupKernelClass;
78 79
    typedef FStarPUCpuWrapper<typename GroupOctreeClass::CellGroupClass, GroupCellClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupContainerClass> GroupCpuWrapper;
    typedef FGroupTaskStarPUAlgorithm<GroupOctreeClass, typename GroupOctreeClass::CellGroupClass, GroupKernelClass, typename GroupOctreeClass::ParticleGroupClass, GroupCpuWrapper
80
    #ifdef SCALFMM_ENABLE_CUDA_KERNEL
81
        , FStarPUCudaWrapper<KernelClass, FCudaEmptyCell, FCudaGroupOfCells<FCudaEmptyCell>, FCudaGroupOfParticles<0, int>, FCudaGroupAttachedLeaf<0, int>, FCudaEmptyKernel<>>
82
    #endif
BRAMAS Berenger's avatar
BRAMAS Berenger committed
83
        , FStarPUOpenClWrapper<GroupKernelClass, FOpenCLDeviceWrapper<GroupKernelClass, FTestOpenCLCode<FReal> > >
84 85 86
         > GroupAlgorithm;

    typedef FTestCell                   CellClass;
87 88 89
    typedef FTestParticleContainer<FReal>      ContainerClass;
    typedef FSimpleLeaf<FReal, ContainerClass >                     LeafClass;
    typedef FOctree<FReal, CellClass, ContainerClass , LeafClass >  OctreeClass;
90 91 92 93 94 95 96 97 98 99 100
    typedef FTestKernels< CellClass, ContainerClass >         KernelClass;

    // FFmmAlgorithmTask FFmmAlgorithmThread
    typedef FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass >     FmmClass;

    // Get params
    const int NbLevels      = FParameters::getValue(argc,argv,FParameterDefinitions::OctreeHeight.options, 5);
    const int groupSize      = FParameters::getValue(argc,argv,LocalOptionBlocSize.options, 250);

//#define LOAD_FILE
#ifndef LOAD_FILE
101
    const FSize NbParticles   = FParameters::getValue(argc,argv,FParameterDefinitions::NbParticles.options, FSize(20));
102
    FRandomLoader<FReal> loader(NbParticles, 1.0, FPoint<FReal>(0,0,0), 0);
103 104 105
#else
    // Load the particles
    const char* const filename = FParameters::getStr(argc,argv,FParameterDefinitions::InputFile.options, "../Data/test20k.fma");
106
    FFmaGenericLoader<FReal> loader(filename);
107 108 109 110 111 112
#endif
    FAssertLF(loader.isOpen());

    // Usual octree
    OctreeClass tree(NbLevels, 2, loader.getBoxWidth(), loader.getCenterOfBox());

BRAMAS Berenger's avatar
BRAMAS Berenger committed
113
    FTestParticleContainer<FReal> allParticles;
114
    for(FSize idxPart = 0 ; idxPart < loader.getNumberOfParticles() ; ++idxPart){
115
        FPoint<FReal> particlePosition;
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
#ifndef LOAD_FILE
        loader.fillParticle(&particlePosition);
#else
        FReal ph;
        loader.fillParticle(&particlePosition, &ph);
#endif
        allParticles.push(particlePosition);
        tree.insert(particlePosition);
    }

    // Put the data into the tree
    //GroupOctreeClass groupedTree(NbLevels, groupSize, &tree);
    GroupOctreeClass groupedTree(NbLevels, loader.getBoxWidth(), loader.getCenterOfBox(), groupSize, &allParticles);
    groupedTree.printInfoBlocks();

    // Check tree structure at leaf level
132
    groupedTree.forEachCellLeaf<GroupContainerClass>([&](GroupCellClass gcell, GroupContainerClass* gleaf){
133
        const ContainerClass* src = tree.getLeafSrc(gcell.getMortonIndex());
134
        if(src == nullptr){
135
            std::cout << "[PartEmpty] Error cell should not exist " << gcell.getMortonIndex() << "\n";
136 137 138
        }
        else {
            if(src->getNbParticles() != gleaf->getNbParticles()){
139
                std::cout << "[Part] Nb particles is different at index " << gcell.getMortonIndex() << " is " << gleaf->getNbParticles() << " should be " << src->getNbParticles() << "\n";
140 141 142 143 144 145 146
            }
        }
    });

    // Run the algorithm
    GroupKernelClass groupkernel;
    GroupAlgorithm groupalgo(&groupedTree,&groupkernel);
147
    groupalgo.execute(); // FFmmP2M TODO
148 149 150 151 152 153 154

    // Usual algorithm
    KernelClass kernels;            // FTestKernels FBasicKernels
    FmmClass algo(&tree,&kernels);  //FFmmAlgorithm FFmmAlgorithmThread
    algo.execute();

    // Validate the result
155
    groupedTree.forEachCellLeaf<GroupContainerClass>([&](GroupCellClass cell, GroupContainerClass* leaf){
156
        const FSize nbPartsInLeaf = leaf->getNbParticles();
157 158
        if(cell.getDataUp() != nbPartsInLeaf){
            std::cout << "[P2M] Error a Cell has " << cell.getDataUp() << " (it should be " << nbPartsInLeaf << ")\n";
159 160
        }
    });
161
    groupedTree.forEachCellLeaf<GroupContainerClass>([&](GroupCellClass cell, GroupContainerClass* leaf){
162
        const FSize nbPartsInLeaf = leaf->getNbParticles();
163
        const long long int* dataDown = leaf->getDataDown();
164
        for(FSize idxPart = 0 ; idxPart < nbPartsInLeaf ; ++idxPart){
165
            if(dataDown[idxPart] != loader.getNumberOfParticles()-1){
166
                std::cout << "[Full] Error a particle has " << dataDown[idxPart] << " (it should be " << (loader.getNumberOfParticles()-1) << ") at index " << cell.getMortonIndex() << "\n";
167 168 169 170
            }
        }
    });
    // Compare the results
171 172
    groupedTree.forEachCellWithLevel([&](GroupCellClass gcell, const int level){
        const CellClass* cell = tree.getCell(gcell.getMortonIndex(), level);
173
        if(cell == nullptr){
174
            std::cout << "[Empty] Error cell should not exist " << gcell.getMortonIndex() << "\n";
175 176
        }
        else {
177 178
            if(gcell.getDataUp() != cell->getDataUp()){
                std::cout << "[Up] Up is different at index " << gcell.getMortonIndex() << " level " << level << " is " << gcell.getDataUp() << " should be " << cell->getDataUp() << "\n";
179
            }
180 181
            if(gcell.getDataDown() != cell->getDataDown()){
                std::cout << "[Down] Down is different at index " << gcell.getMortonIndex() << " level " << level << " is " << gcell.getDataDown() << " should be " << cell->getDataDown() << "\n";
182 183 184 185 186 187
            }
        }
    });

    return 0;
}