FMpiFmaLoader.hpp 8.13 KB
Newer Older
1
2
#ifndef FMPIFMALOADER_HPP
#define FMPIFMALOADER_HPP
3
4
5
6
7
8
9
10
11
12
13
14
// /!\ Please, you must read the license at the bottom of this page

#include <iostream>
#include <fstream>

#include "../Utils/FGlobal.hpp"
#include "FAbstractLoader.hpp"
#include "../Utils/F3DPosition.hpp"
#include "../Utils/FMpi.hpp"

/**
* @author Berenger Bramas (berenger.bramas@inria.fr)
15
* @class FMpiFmaLoader
16
17
18
19
20
21
22
* Please read the license
*
* Load a file with a format like :
* NB_particles Box_width Box_X Box_Y Box_Z // init
* X Y Z // one particle by line
* ....
* <code>
23
*    FMpiFmaLoader<FBasicParticle> loader("../FMB++/Tests/particles.basic.txt"); <br>
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
*    if(!loader.isOpen()){ <br>
*        std::cout << "Loader Error\n"; <br>
*        return 1; <br>
*    } <br>
* <br>
*    FOctree<FBasicParticle, TestCell, FSimpleLeaf> tree(loader.getBoxWidth(),loader.getCenterOfBox()); <br>
* <br>
*    for(int idx = 0 ; idx < loader.getNumberOfParticles() ; ++idx){ <br>
*        FBasicParticle* const part = new FBasicParticle(); <br>
*        loader.fillParticle(part); <br>
*        tree.insert(part); <br>
*    } <br>
* </code>
*
* Particle has to extend {FExtendPhysicalValue,FExtendPosition}
*/
template <class ParticleClass>
41
class FMpiFmaLoader : public FAbstractLoader<ParticleClass> {
42
43
44
protected:
    F3DPosition centerOfBox;    //< The center of box read from file
    FReal boxWidth;             //< the box width read from file
45
46
    FSize totalNbParticles;     //< the number of particles read from file
    FSize nbParticles;          //< the number of particles read from file
47
48
49
50
51
52
53
54
55
56
    bool isOpenFlag;            //< to knwo if the file is open now
    FReal* particles;           //< the particles loaded from the binary file
    MPI_Offset idxParticles;    //< to iterate on the particles array

public:
    /**
    * The constructor need the file name
    * @param filename the name of the file to open
    * you can test if file is successfuly open by calling hasNotFinished()
    */
57
    FMpiFmaLoader(const char* const filename, FMpi& app)
58
            : boxWidth(0), totalNbParticles(0), nbParticles(0), isOpenFlag(false), particles(0), idxParticles(0) {
59
        /*char nonConstFilename[512];
60
61
62
63
64
65
66
67
        strcpy(nonConstFilename,filename);
        MPI_File file;
        if(MPI_File_open(MPI::COMM_WORLD, nonConstFilename, MPI::MODE_RDONLY, MPI::INFO_NULL, &file) == MPI_SUCCESS){
            int sizeOfElement(0);
            FReal xyzBoxWidth[4];

            MPI_Status status;
            if( MPI_File_read(file, &sizeOfElement, 1, MPI_INT, &status) == MPI_SUCCESS
68
                && MPI_File_read(file, &this->totalNbParticles, 1, MPI_LONG_LONG, &status) == MPI_SUCCESS
69
70
71
72
73
74
75
76
77
78
79
80
                && MPI_File_read(file, xyzBoxWidth, 4, MPI_FLOAT, &status) == MPI_SUCCESS ){

                FDEBUG(if(sizeOfElement != sizeof(FReal)){)
                    FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
                FDEBUG(})

                this->boxWidth = xyzBoxWidth[3];
                this->centerOfBox.setPosition(xyzBoxWidth[0],xyzBoxWidth[1],xyzBoxWidth[2]);
                this->boxWidth *= 2;
                this->isOpenFlag = true;

                // load my particles
81
                MPI_Offset headDataOffSet(0);
82
83
84
                MPI_File_get_position(file, &headDataOffSet);

                MPI_Offset filesize(0);
85
                MPI_File_get_size(file, &filesize); // in bytes
86
87
                filesize = (filesize - headDataOffSet) / sizeof(FReal);
                if(filesize/4 != this->totalNbParticles){
88
                    printf("Error fileSize %lld, nbPart %lld\n",filesize/4, this->totalNbParticles);
89
90
                }
                // in number of floats
91
92
                const FSize startPart = app.getLeft(this->totalNbParticles);
                const FSize endPart   = app.getRight(this->totalNbParticles);
93
                nbParticles = (endPart - startPart);
94
                const FSize bufsize = nbParticles * 4;
95
96
                // local number to read
                particles = new FReal[bufsize];
97

98
                if( sizeof(FReal) == sizeof(float) ){
99
                    MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_FLOAT, &status);
100
101
                }
                else{
102
                    MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_DOUBLE, &status);
103
104
                }

105
106
107
108
109
110
111
112
113
114
115
116

                // check if needed
                int count(0);
                MPI_Get_count(&status, MPI_INT, &count);
                FDEBUG(if(count  / 4 != this->nbParticles){)
                    FDEBUG( FDebug::Controller<< "Error read " << count << " data, nbPart is " << this->nbParticles << __LINE__ << " " << __FILE__ << "\n"; )
                FDEBUG(})
            }
            else{
                this->totalNbParticles = 0;
            }
            MPI_File_close(&file);
117
118
119
120
121
122
123
124
125
126
127
128
        }*/

        FILE* file(fopen(filename, "rb"));
        int removeWarning(0);
        // test if open
        if(file != NULL) {
            int sizeOfElement(0);
            removeWarning += fread(&sizeOfElement, sizeof(int), 1, file);
            FDEBUG(if(sizeOfElement != int(sizeof(FReal)) ){)
                FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
                    printf("%d sizeofelement\n",sizeOfElement);
            FDEBUG(})
129
            removeWarning += fread(&this->totalNbParticles, sizeof(FSize), 1, file);
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

            removeWarning += fread(&this->boxWidth, sizeof(FReal), 1, file);
            this->boxWidth *= 2;

            FReal x,y,z;
            removeWarning += fread(&x, sizeof(FReal), 1, file);
            removeWarning += fread(&y, sizeof(FReal), 1, file);
            removeWarning += fread(&z, sizeof(FReal), 1, file);
            this->centerOfBox.setPosition(x,y,z);

            this->isOpenFlag = true;

            const long int headDataOffSet = ftell(file);
            fseek(file, 0L, SEEK_END);
            const long int filesize = (ftell(file) - headDataOffSet) / sizeof(FReal);

            if(filesize/4 != this->totalNbParticles){
                printf("Error fileSize %ld, nbPart %lld\n", filesize/4, this->totalNbParticles);
            }

            // in number of floats
            const FSize startPart = app.getLeft(this->totalNbParticles);
            const FSize endPart   = app.getRight(this->totalNbParticles);
            nbParticles = (endPart - startPart);
            const FSize bufsize = nbParticles * 4;
            // local number to read
            particles = new FReal[bufsize];

            fseek(file, long(headDataOffSet + startPart * 4 * sizeof(FReal)), SEEK_SET);

            removeWarning += fread(particles, sizeof(FReal), int(bufsize), file);

            fclose(file);
163
164
165
166
167
168
        }
    }

    /**
    * Default destructor, simply close the file
    */
169
    virtual ~FMpiFmaLoader(){
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
        if(isOpen()){
            delete [] particles;
        }
    }

    /**
      * To know if file is open and ready to read
      * @return true if loader can work
      */
    bool isOpen() const{
        return this->isOpenFlag;
    }

    /**
      * To get the number of particles from this loader
      * @param the number of particles the loader can fill
      */
187
    FSize getNumberOfParticles() const{
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
        return this->nbParticles;
    }

    /**
      * The center of the box from the simulation file opened by the loader
      * @return box center
      */
    F3DPosition getCenterOfBox() const{
        return this->centerOfBox;
    }

    /**
      * The box width from the simulation file opened by the loader
      * @return box width
      */
    FReal getBoxWidth() const{
        return this->boxWidth;
    }

    /**
      * Fill a particle
      * @warning to work with the loader, particles has to expose a setPosition method
      * @param the particle to fill
      */
    void fillParticle(ParticleClass& inParticle){
        inParticle.setPosition(particles[idxParticles],particles[idxParticles+1],particles[idxParticles+2]);
        inParticle.setPhysicalValue(particles[idxParticles+3]);
        idxParticles += 4;
    }

};


221
#endif //FMPIFMALOADER_HPP
222
223

// [--LICENSE--]