Commit 755e1436 authored by berenger-bramas's avatar berenger-bramas

Change "int" or "long" by FSize wich is a "long long".

Because without this, we cannot load a file with 200.000.000 particles and sort it.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/scalfmm/scalfmm/trunk@190 2616d619-271b-44dc-8df4-d4a8f33a7222
parent 1032efb7
......@@ -17,11 +17,11 @@
*/
template< class Object >
class FList {
/** A list node */
struct Node {
Object target; //< Object of the node
Node* next; //< Next node
};
/** A list node */
struct Node {
Object target; //< Object of the node
Node* next; //< Next node
};
Node* root; //< Root node, NULL if size is 0
int size; //< Elements in the list
......@@ -30,77 +30,77 @@ class FList {
* Copy a list into current object
* The current list has to be empty when this function is called
*/
void copy(const FList& other){
void copy(const FList& other){
const Node* FRestrict otherRoot = other.root;
Node * FRestrict * myRoot = &this->root;
while(otherRoot){
(*myRoot) = new Node;
(*myRoot)->target = otherRoot->target;
while(otherRoot){
(*myRoot) = new Node;
(*myRoot)->target = otherRoot->target;
myRoot = &(*myRoot)->next;
otherRoot = otherRoot->next;
}
*myRoot = 0;
this->size = other.size;
}
myRoot = &(*myRoot)->next;
otherRoot = otherRoot->next;
}
*myRoot = 0;
this->size = other.size;
}
public:
/** Constructor (of an empty list) */
FList() : root(0) , size(0) {
}
FList() : root(0) , size(0) {
}
/** Desctructor */
/** Desctructor */
virtual ~FList(){
clear();
}
clear();
}
/**
* Copy operator
* This will clear the current list before copying
* @param other the source list
/**
* Copy operator
* This will clear the current list before copying
* @param other the source list
* @return the current list as a reference
*/
FList& operator=(const FList& other){
*/
FList& operator=(const FList& other){
if(this != &other){
clear();
copy(other);
clear();
copy(other);
}
return *this;
}
}
/**
* Copy constructor
/**
* Copy constructor
* @param other the source/original list
*/
FList(const FList& other): root(0) , size(0) {
copy(other);
}
/**
* To clear the list
* Size is 0 after calling this function
*/
void clear(){
while(this->root){
*/
FList(const FList& other): root(0) , size(0) {
copy(other);
}
/**
* To clear the list
* Size is 0 after calling this function
*/
void clear(){
while(this->root){
Node*const FRestrict next = this->root->next;
delete this->root;
this->root = next;
}
this->size = 0;
}
delete this->root;
this->root = next;
}
this->size = 0;
}
/**
/**
* Push an element in the head of the list
* @param inObject the object to insert
*/
*/
void push(const Object& inObject){
Node* newNode = new Node;
newNode->target = inObject;
newNode->next = this->root;
newNode->target = inObject;
newNode->next = this->root;
this->root = newNode;
this->root = newNode;
++this->size;
}
}
/**
......@@ -143,13 +143,13 @@ public:
return value;
}
/**
* To get the number of elements in the list
* @return size
*/
int getSize() const{
/**
* To get the number of elements in the list
* @return size
*/
int getSize() const{
return this->size;
}
}
/**
* This iterator allow accessing list's elements
......
......@@ -31,7 +31,7 @@ public:
* Get the number of particles for this simulation
* @return number of particles that the loader can fill
*/
virtual long getNumberOfParticles() const = 0;
virtual FSize getNumberOfParticles() const = 0;
/**
* Get the center of the simulation box
......
......@@ -80,8 +80,8 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
return this->nbParticles;
FSize getNumberOfParticles() const{
return FSize(this->nbParticles);
}
/**
......
......@@ -42,7 +42,7 @@ protected:
FILE* const file; //< The file to read
F3DPosition centerOfBox; //< The center of box read from file
FReal boxWidth; //< the box width read from file
int nbParticles; //< the number of particles read from file
FSize nbParticles; //< the number of particles read from file
int removeWarning;
......@@ -61,7 +61,7 @@ public:
FDEBUG( FDebug::Controller.writeFromLine("Warning type size between file and FReal are differents\n", __LINE__, __FILE__); )
printf("%d sizeofelement\n",sizeOfElement);
FDEBUG(})
removeWarning += fread(&this->nbParticles, sizeof(int), 1, file);
removeWarning += fread(&this->nbParticles, sizeof(FSize), 1, file);
removeWarning += fread(&this->boxWidth, sizeof(FReal), 1, file);
this->boxWidth *= 2;
......@@ -97,7 +97,7 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
FSize getNumberOfParticles() const{
return this->nbParticles;
}
......
......@@ -83,8 +83,8 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
return this->nbParticles;
FSize getNumberOfParticles() const{
return FSize(this->nbParticles);
}
/**
......
......@@ -91,8 +91,8 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
return this->nbParticles;
FSize getNumberOfParticles() const{
return FSize(this->nbParticles);
}
/**
......
......@@ -83,8 +83,8 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
return this->nbParticles;
FSize getNumberOfParticles() const{
return FSize(this->nbParticles);
}
/**
......
......@@ -94,8 +94,8 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
return this->nbParticles;
FSize getNumberOfParticles() const{
return FSize(this->nbParticles);
}
/**
......
......@@ -42,8 +42,8 @@ class FMpiFmaLoader : public FAbstractLoader<ParticleClass> {
protected:
F3DPosition centerOfBox; //< The center of box read from file
FReal boxWidth; //< the box width read from file
int totalNbParticles; //< the number of particles read from file
int nbParticles; //< the number of particles read from file
FSize totalNbParticles; //< the number of particles read from file
FSize nbParticles; //< the number of particles read from file
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
......@@ -65,7 +65,7 @@ public:
MPI_Status status;
if( MPI_File_read(file, &sizeOfElement, 1, MPI_INT, &status) == MPI_SUCCESS
&& MPI_File_read(file, &this->totalNbParticles, 1, MPI_INT, &status) == MPI_SUCCESS
&& MPI_File_read(file, &this->totalNbParticles, 1, MPI_LONG_LONG, &status) == MPI_SUCCESS
&& MPI_File_read(file, xyzBoxWidth, 4, MPI_FLOAT, &status) == MPI_SUCCESS ){
FDEBUG(if(sizeOfElement != sizeof(FReal)){)
......@@ -78,28 +78,28 @@ public:
this->isOpenFlag = true;
// load my particles
MPI_Offset headDataOffSet;
MPI_Offset headDataOffSet(0);
MPI_File_get_position(file, &headDataOffSet);
MPI_Offset filesize(0);
MPI_File_get_size(file, &filesize); /* in bytes */
filesize = (filesize - headDataOffSet) / sizeof(FReal);
if(filesize/4 != this->totalNbParticles){
printf("Error fileSize %lld, nbPart %d\n",filesize/4, this->totalNbParticles);
printf("Error fileSize %lld, nbPart %lld\n",filesize/4, this->totalNbParticles);
}
// in number of floats
const long startPart = app.getLeft(this->totalNbParticles);
const long endPart = app.getRight(this->totalNbParticles);
const FSize startPart = app.getLeft(this->totalNbParticles);
const FSize endPart = app.getRight(this->totalNbParticles);
nbParticles = (endPart - startPart);
const int bufsize = nbParticles * 4;
const FSize bufsize = nbParticles * 4;
// local number to read
particles = new FReal[bufsize];
if( sizeof(FReal) == sizeof(float) ){
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, bufsize, MPI_FLOAT, &status);
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_FLOAT, &status);
}
else{
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, bufsize, MPI_DOUBLE, &status);
MPI_File_read_at(file, headDataOffSet + startPart * 4 * sizeof(FReal), particles, int(bufsize), MPI_DOUBLE, &status);
}
......@@ -142,7 +142,7 @@ public:
* To get the number of particles from this loader
* @param the number of particles the loader can fill
*/
long getNumberOfParticles() const{
FSize getNumberOfParticles() const{
return this->nbParticles;
}
......
......@@ -3,6 +3,7 @@
#include "../Utils/FQuickSort.hpp"
#include "../Utils/FMemUtils.hpp"
/** This class manage the loading of particles
......@@ -95,7 +96,7 @@ class FMpiTreeBuilder{
};
char* intervals;
int nbLeavesInIntervals;
FSize nbLeavesInIntervals;
private:
// Forbid copy
......@@ -124,11 +125,11 @@ public:
//
IndexedParticle* outputArray = 0;
long outputSize = 0;
FSize outputSize = 0;
{
// create particles
IndexedParticle*const realParticlesIndexed = new IndexedParticle[loader.getNumberOfParticles()];
memset(realParticlesIndexed, 0, sizeof(IndexedParticle)* loader.getNumberOfParticles());
FMemUtils::memset(realParticlesIndexed, 0, sizeof(IndexedParticle) * loader.getNumberOfParticles());
F3DPosition boxCorner(loader.getCenterOfBox() - (loader.getBoxWidth()/2));
FTreeCoordinate host;
......@@ -193,11 +194,11 @@ public:
if(sendByOther){
sendByOther /= sizeof(IndexedParticle);
const IndexedParticle* const reallocOutputArray = outputArray;
const long reallocOutputSize = outputSize;
const FSize reallocOutputSize = outputSize;
outputSize += sendByOther;
outputArray = new IndexedParticle[outputSize];
memcpy(&outputArray[sendByOther], reallocOutputArray, reallocOutputSize * sizeof(IndexedParticle));
FMemUtils::memcpy(&outputArray[sendByOther], reallocOutputArray, reallocOutputSize * sizeof(IndexedParticle));
delete[] reallocOutputArray;
MPI_Recv(outputArray, sizeof(IndexedParticle) * sendByOther, MPI_BYTE, rank - 1, 0, MPI_COMM_WORLD, &probStatus);
......@@ -209,11 +210,11 @@ public:
if(rank != nbProcs - 1){
long idxPart = outputSize - 1 ;
FSize idxPart = outputSize - 1 ;
while(idxPart >= 0 && outputArray[idxPart].index == otherFirstIndex){
--idxPart;
}
const long toSend = outputSize - 1 - idxPart;
const int toSend = int(outputSize - 1 - idxPart);
MPI_Isend( &outputArray[idxPart + 1], toSend * sizeof(IndexedParticle), MPI_BYTE, rank + 1, 0, MPI_COMM_WORLD, &req[reqiter++]);
if( rank != 0 && !needToRecvBeforeSend && (rank != nbProcs - 1)){
......@@ -233,11 +234,11 @@ public:
reqiter = 0;
const IndexedParticle* const reallocOutputArray = outputArray;
const long reallocOutputSize = outputSize;
const FSize reallocOutputSize = outputSize;
outputSize += sendByOther;
outputArray = new IndexedParticle[outputSize];
memcpy(&outputArray[sendByOther], reallocOutputArray, reallocOutputSize * sizeof(IndexedParticle));
FMemUtils::memcpy(&outputArray[sendByOther], reallocOutputArray, reallocOutputSize * sizeof(IndexedParticle));
delete[] reallocOutputArray;
memcpy(outputArray, tempBuffer, sendByOther * sizeof(IndexedParticle));
delete[] tempBuffer;
......@@ -260,7 +261,7 @@ public:
char* writeIndex = intervals;
int* writeCounter = 0;
for( int idxPart = 0; idxPart < outputSize ; ++idxPart){
for( FSize idxPart = 0; idxPart < outputSize ; ++idxPart){
if( outputArray[idxPart].index != previousIndex ){
previousIndex = outputArray[idxPart].index;
++nbLeavesInIntervals;
......@@ -294,41 +295,41 @@ public:
// We inform the master proc about the data we have
//////////////////////////////////////////////////////////////////////////////////
int nbLeafs = nbLeavesInIntervals;
FSize nbLeafs = nbLeavesInIntervals;
// receive from left and right
if((rank == 0)){
MPI_Send(&nbLeafs, sizeof(int), MPI_BYTE , 1, 0, MPI_COMM_WORLD);
MPI_Send(&nbLeafs, sizeof(FSize), MPI_BYTE , 1, 0, MPI_COMM_WORLD);
}
else if(rank == nbProcs - 1){
MPI_Send(&nbLeafs, sizeof(int), MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD);
MPI_Send(&nbLeafs, sizeof(FSize), MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD);
}
// receive
int leftLeafs = 0;
int rightLeafs = 0;
FSize leftLeafs = 0;
FSize rightLeafs = 0;
if(!(rank == 0) && rank != nbProcs - 1){
for(int idxToReceive = 0 ; idxToReceive < 2 ; ++idxToReceive){
int source(0);
int temp = 0;
receiveDataFromTag(sizeof(int), 0, &temp, &source);
FSize temp = 0;
receiveDataFromTag(sizeof(FSize), 0, &temp, &source);
if(source < rank){ // come from left
leftLeafs = temp;
temp += nbLeafs;
MPI_Send(&temp, sizeof(int), MPI_BYTE , rank + 1, 0, MPI_COMM_WORLD);
MPI_Send(&temp, sizeof(FSize), MPI_BYTE , rank + 1, 0, MPI_COMM_WORLD);
}
else { // come from right
rightLeafs = temp;
temp += nbLeafs;
MPI_Send(&temp, sizeof(int), MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD);
MPI_Send(&temp, sizeof(FSize), MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD);
}
}
}
else {
if((rank == 0)){ // come from right
receiveDataFromTag(sizeof(int), 0, &rightLeafs);
receiveDataFromTag(sizeof(FSize), 0, &rightLeafs);
}
else { // come from left
receiveDataFromTag(sizeof(int), 0, &leftLeafs);
receiveDataFromTag(sizeof(FSize), 0, &leftLeafs);
}
}
......@@ -337,9 +338,9 @@ public:
// We balance the data
//////////////////////////////////////////////////////////////////////////////////
const int totalNbLeafs = (leftLeafs + nbLeafs + rightLeafs);
const int myLeftLeaf = GetLeft(totalNbLeafs);
const int myRightLeaf = GetRight(totalNbLeafs);
const FSize totalNbLeafs = (leftLeafs + nbLeafs + rightLeafs);
const FSize myLeftLeaf = GetLeft(totalNbLeafs);
const FSize myRightLeaf = GetRight(totalNbLeafs);
const bool iNeedToSendToLeft = leftLeafs < myLeftLeaf;
const bool iNeedToSendToRight = myRightLeaf < leftLeafs + nbLeafs;
......@@ -351,25 +352,25 @@ public:
const bool iDoNotHaveEnoughtToSendLeft = leftLeafs + nbLeafs < myLeftLeaf;
const int iNeedToSendLeftCount = myLeftLeaf - leftLeafs;
const int iCanSendToLeft = nbLeafs;
const FSize iNeedToSendLeftCount = myLeftLeaf - leftLeafs;
const FSize iCanSendToLeft = nbLeafs;
const int iNeedToSendRightCount = leftLeafs + nbLeafs - myRightLeaf;
const int iCanSendToRight = nbLeafs;
const FSize iNeedToSendRightCount = leftLeafs + nbLeafs - myRightLeaf;
const FSize iCanSendToRight = nbLeafs;
MPI_Request requests[2];
MPI_Status status[2];
int iterRequest = 0;
int hasBeenSentToLeft = 0;
int hasBeenSentToRight = 0;
FSize hasBeenSentToLeft = 0;
FSize hasBeenSentToRight = 0;
char* particlesToSend = 0;
printf("on my left %d on my right %d\n",leftLeafs, rightLeafs);
printf("iNeedToSendLeftCount %d iCanSendToLeft %d\n",iNeedToSendLeftCount, iCanSendToLeft);
printf("iNeedToSendRightCount %d iCanSendToRight %d \n",iNeedToSendRightCount, iCanSendToRight);
printf("on my left %lld on my right %lld\n",leftLeafs, rightLeafs);
printf("iNeedToSendLeftCount %lld iCanSendToLeft %lld\n",iNeedToSendLeftCount, iCanSendToLeft);
printf("iNeedToSendRightCount %lld iCanSendToRight %lld \n",iNeedToSendRightCount, iCanSendToRight);
printf("Elapsed %lf\n", counter.tacAndElapsed());
///////////////////////////////
......@@ -383,20 +384,20 @@ public:
//Send to Left (the first leaves
if(iNeedToSendToLeft){
for(int idxLeaf = 0 ; idxLeaf < iNeedToSendLeftCount && idxLeaf < iCanSendToLeft ; ++idxLeaf){
for(FSize idxLeaf = 0 ; idxLeaf < iNeedToSendLeftCount && idxLeaf < iCanSendToLeft ; ++idxLeaf){
currentLeafPosition += ((*(int*)&particlesToSend[currentLeafPosition]) * sizeof(ParticleClass)) + sizeof(int);
}
hasBeenSentToLeft = FMath::Min(iNeedToSendLeftCount, iCanSendToLeft);
MPI_Isend(particlesToSend, currentLeafPosition, MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD, &requests[iterRequest++]);
printf("I send to left %d bytes %d leaves\n", currentLeafPosition, hasBeenSentToLeft);
printf("I send to left %d bytes %lld leaves\n", currentLeafPosition, hasBeenSentToLeft);
}
printf("Elapsed %lf\n", counter.tacAndElapsed());
// Insert the particles I host and that belong to me
const int beginForMe = (iNeedToSendToLeft ? FMath::Min(iNeedToSendLeftCount,iCanSendToLeft) : 0);
const int endForMe = nbLeafs - (iNeedToSendToRight ? FMath::Min(iNeedToSendRightCount,iCanSendToRight) : 0);
printf("I insert my particles from %d to %d \n", beginForMe, endForMe);
for(int idxLeaf = beginForMe ; idxLeaf < endForMe ; ++idxLeaf){
const FSize beginForMe = (iNeedToSendToLeft ? FMath::Min(iNeedToSendLeftCount,iCanSendToLeft) : 0);
const FSize endForMe = nbLeafs - (iNeedToSendToRight ? FMath::Min(iNeedToSendRightCount,iCanSendToRight) : 0);
printf("I insert my particles from %lld to %lld \n", beginForMe, endForMe);
for(FSize idxLeaf = beginForMe ; idxLeaf < endForMe ; ++idxLeaf){
const int nbPartInLeaf = (*(int*)&particlesToSend[currentLeafPosition]);
ParticleClass* const particles = reinterpret_cast<ParticleClass*>(&particlesToSend[currentLeafPosition] + sizeof(int));
......@@ -412,15 +413,15 @@ public:
//Send to Right (the right-est leaves
if(iNeedToSendToRight){
const int beginWriteIndex = currentLeafPosition;
const FSize beginWriteIndex = currentLeafPosition;
for(int idxLeaf = 0 ; idxLeaf < iNeedToSendRightCount && idxLeaf < iCanSendToRight ; ++idxLeaf){
currentLeafPosition += (*(int*)&particlesToSend[currentLeafPosition]* sizeof(ParticleClass)) + sizeof(int);
}
hasBeenSentToRight = FMath::Min(iNeedToSendRightCount, iCanSendToRight);
MPI_Isend( &particlesToSend[beginWriteIndex], currentLeafPosition - beginWriteIndex, MPI_BYTE , rank + 1, 0, MPI_COMM_WORLD, &requests[iterRequest++]);
printf("I send to right %d bytes %d leaves\n", currentLeafPosition - beginWriteIndex, hasBeenSentToRight);
MPI_Isend( &particlesToSend[beginWriteIndex], int(currentLeafPosition - beginWriteIndex), MPI_BYTE , rank + 1, 0, MPI_COMM_WORLD, &requests[iterRequest++]);
printf("I send to right %d bytes %lld leaves\n", int(currentLeafPosition - beginWriteIndex), hasBeenSentToRight);
}
printf("Elapsed %lf\n", counter.tacAndElapsed());
}
......@@ -476,8 +477,8 @@ public:
// and transfer if needed
///////////////////////////////
// We have to receive from right and transfere to left
int hasToBeReceivedFromLeft = leftLeafs - myLeftLeaf;
int hasToBeReceivedFromRight = myRightLeaf - (leftLeafs + nbLeafs);
int hasToBeReceivedFromLeft = int(leftLeafs - myLeftLeaf);
int hasToBeReceivedFromRight = int(myRightLeaf - (leftLeafs + nbLeafs));
int arrayIdxRight = 0;
int arrayIdxLeft = 0;
......@@ -491,7 +492,7 @@ public:
--hasToBeReceivedFromRight;
++hasBeenSentToLeft;
}
printf("Send %d to left, total leaves sent %d / %d\n", arrayIdxRight, hasBeenSentToLeft, iNeedToSendLeftCount);
printf("Send %d to left, total leaves sent %lld / %lld\n", arrayIdxRight, hasBeenSentToLeft, iNeedToSendLeftCount);
printf("Elapsed %lf\n", counter.tacAndElapsed());
MPI_Send(toRecvFromRight, arrayIdxRight, MPI_BYTE , rank - 1, 0, MPI_COMM_WORLD);
if(hasBeenSentToLeft < iNeedToSendLeftCount){
......@@ -519,7 +520,7 @@ public:
--hasToBeReceivedFromLeft;
++hasBeenSentToRight;
}
printf("Send %d to right, total leaves sent %d / %d\n", arrayIdxLeft, hasBeenSentToRight, iNeedToSendRightCount);
printf("Send %d to right, total leaves sent %lld / %lld\n", arrayIdxLeft, hasBeenSentToRight, iNeedToSendRightCount);
printf("Elapsed %lf\n", counter.tacAndElapsed());
MPI_Send(toRecvFromLeft, arrayIdxLeft, MPI_BYTE , rank + 1, 0, MPI_COMM_WORLD);
if(hasBeenSentToRight < iNeedToSendRightCount){
......
......@@ -33,7 +33,8 @@
///////////////////////////////////////////////////////
typedef float FReal;
typedef long long FIndex;
typedef long long FSize;
///////////////////////////////////////////////////////
// Restrict
......
#ifndef FMEMUTILS_HPP
#define FMEMUTILS_HPP
#include "FGlobal.hpp"
// To get memcpy
#include <cstring>
#include <limits>
namespace FMemUtils {
static const FSize MaxSize_t = std::numeric_limits<std::size_t>::max();
static void* memcpy(void* const dest, const void* const source, const FSize nbBytes){
if( nbBytes < MaxSize_t){
return ::memcpy(dest, source, size_t(nbBytes));
}
else{
char* iterDest = static_cast<char*>(dest);
const char* iterSource = static_cast<const char*>(source);
for(FSize idx = 0 ; idx < nbBytes ; idx += MaxSize_t ){
::memcpy(iterDest, iterSource, size_t(MaxSize_t));
iterDest += MaxSize_t;
iterSource += MaxSize_t;
}
::memcpy(iterDest, iterSource, size_t(nbBytes%MaxSize_t));
return dest;
}
}
static void* memset(void* const dest, const int val, const FSize nbBytes){
if( nbBytes < MaxSize_t){
return ::memset(dest, val, size_t(nbBytes));
}
else{