Skip to Content.
Sympa Menu

charm - [charm] Execution flow of charm++ code

charm AT lists.cs.illinois.edu

Subject: Charm++ parallel programming system

List archive

[charm] Execution flow of charm++ code


Chronological Thread 
  • From: Yogesh Sonawane <sonawane.yogesh19 AT gmail.com>
  • To: charm AT cs.uiuc.edu
  • Subject: [charm] Execution flow of charm++ code
  • Date: Thu, 14 Jul 2011 12:04:44 +0530
  • List-archive: <http://lists.cs.uiuc.edu/pipermail/charm>
  • List-id: CHARM parallel programming system <charm.cs.uiuc.edu>

hello,
     I just started learning charm++ and have done some small sample codes. Now i am doing a code regarding MD just to calculate a energy of water system. whatever i have done up till now, i have attached it with the mail. I cant send input files as it makes mail size larger, beyond the limit. Actually i am not getting the flow in which the program is executing. 
    I have created a array of 4 chares. i want to distribute those 4 chares ont 4 processors one on each so that they will work parallel on their respective processors. i didnt use message object. I have just tried to transfer normal object during communication. so please help me for it. 
    I am not getting, whether my concept about execution is wrong or my logic is wrong.
    Please look at this, 
   Thank you very much  
------- Progarm files.....................

1. energyModule.ci............

mainmodule energyModule
{
readonly CProxy_Main mainProxy;
readonly long total_atoms;
readonly long atoms_per_process;
readonly double energy_sum;
readonly long process_size[4];
readonly long process_offset[4];

mainchare Main
{
entry Main(CkArgMsg *msg);
entry void done();
entry void finalResult(CkReductionMsg* msg);

};

array [1D] Object{
entry Object(CProxy_Main mainProxy);
entry void recvData(SendArray *temp);
};
};

2. main.h ..............................

#include "Atom.h"
#include "sendarray.h"

class SendArray;
void recvData(SendArray *temp);

#include "energyModule.decl.h"

#ifndef __MAIN_H__
#define __MAIN_H__


class Main : public CBase_Main
{
public:
Main(CkArgMsg *msg);
void done();
void finalResult(CkReductionMsg* msg);
private:
void calculateOffset(int size);
void processCommandline(CkArgMsg *msg);
long getTotalAtoms(const char* filename);
int _count;
};

/*class SendArray : public CMessage_SendArray
{
public:
SendArray();
SendArray(long atom_count);
SendArray(const SendArray&);

~SendArray();

long getSize();
Atom* getList();
int getRank();

void setSize(long size);
void setList(Atom *List);
void setRank(int rank);
friend class Object;

Atom *_tempList;
private:
long _size;
int _rank;

};*/

class Object : public CBase_Object
{
public:
Object(CProxy_Main mainProxy);
Object(CkMigrateMessage *msg);
void recvData(SendArray *temp);

private:
double _sum_on_proc;

int _size;
Atom *_atomList;


long _recvSize;
Atom* _recvList;

void readAtoms(long offset, long count);
void calculate_energy_self();
void communicate();
};

#endif


3. atom.h ...................

class Atom
{
private:
long atom_num;
char type[4];
double x, y, z, q;

public:
Atom();
Atom(const Atom&);
void displayAtom();

friend class Object;
};

4. sendarray.h ...................

class SendArray
{
public:
SendArray();
SendArray(long atom_count);
SendArray(const SendArray&);

~SendArray();

long getSize();
Atom* getList();
int getRank();

void setSize(long size);
void setList(Atom *List);
void setRank(int rank);
//void pup(PUP::er &p);

friend class Object;
//void setAtom(int index, Atom atom);
Atom *_tempList;
private:
long _size;
int _rank;

};

5. Main.C .........................

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fstream>

#include "main.h"

#ifndef __ATOM_H__
#define __ATOM_H__

using namespace std;


CProxy_Main mainProxy;
long total_atoms = 0;
long atoms_per_process;
double energy_sum;
long process_size[4];
long process_offset[4];

Main :: Main(CkArgMsg *msg)
{
total_atoms = 20;//getTotalAtoms("water.psf");
cout<<"Total Atoms : "<<total_atoms<<endl;
_count = CkNumPes();
mainProxy = thisProxy;

calculateOffset(_count);
CProxy_Object obj = CProxy_Object:: ckNew(thisProxy, _count);

CkCallback *cb=new
CkCallback(CkIndex_Main::finalResult(NULL),mainProxy);
obj.ckSetReductionClient(cb);



};

void Main :: processCommandline(CkArgMsg *msg)
{

};


void Main :: calculateOffset(int _size)
{
long atom_per_process = total_atoms / _size ;
int i;

string line;

ifstream pdb_in("water.pdb");
char *temp = NULL;
do
{
getline(pdb_in,line);
temp = &line[0];
}while(strstr(temp, "ATOM"));

int base = pdb_in.tellg();

printf("\noffset : %d",base);
pdb_in.close();


for(i = 0; i < _size; i++)
{
// process_size[i] =new long();
process_size[i] = atom_per_process;
}

if(total_atoms % _size != 0)
process_size[0] += total_atoms % _size;


for(i = 0; i < _size; i++)
printf("\n _size of processor %d is %ld", i, process_size[i]);


//process_offset = new long[_size];

process_offset[0]= base;
for(i = 1; i < _size; i++)
process_offset[i] = (process_offset[i-1] +
(process_size[i-1] * 79));

for(i = 0; i < _size; i++)
printf("\n OFFSET on %d processor %ld is %ld
(%ld)", i, process_size[i],
process_offset[i], process_offset[i] /
79 );

};

long Main :: getTotalAtoms(const char* filename)
{

string line;
long total_atoms = 0;
ifstream psf_in (filename);

while(getline(psf_in, line))
{
//printf("\n IN while loop...");
char *temp = &line[0];
if(strstr(temp, "!NATOM"))
{
char *str = strtok(&line[0]," ");
cout<<endl <<"token :"<< str << endl;
total_atoms = atoi(str);
break;
}
}

psf_in.close();
return total_atoms;
};

void Main::finalResult(CkReductionMsg* msg)
{
int reducedArrSize=msg->getSize()/sizeof(double);
double* output=(double*)msg->getData();

CkPrintf("\n");
double finalResult=(*output)/2;
cout<<"Result is "<<finalResult;

delete msg;

}

/*void Main::copyDone()
{
_count--;
if(_count == 0)
{
_count = CkNumPes();
}
}*/

void Main::done()
{
_count --;

if(_count == 0)
CkExit();
}
//----------------------------------------------------------------------------------------

Atom::Atom(){};

Atom::Atom(const Atom &a)
{
//type = new char[4];
strcpy(type, a.type);
}
void Atom::displayAtom()
{
printf("\n %ld, %f, %f, %f", atom_num, x,y,z);
}


//-----------------------------------------------------------------------------------------

/*void Object::pup(PUP::er &p)
{
p|_size;
p|_sum_on_proc;
p|_recvSize

if(p.isUnpacking())
atomList=new Atom[_size];

PUParray(p,atomList,_size);
}
*/
Object :: Object(CProxy_Main mainProxy)
{

// whta i think about this object is, its on a processor like the
other three objects are. and these all running seperatly on respective
processors.


int rank = CkMyPe();
_size = process_size[CkMyPe()];
long offset = process_offset[CkMyPe()];
_atomList = new Atom[_size];
CkPrintf("\nobject [%d] from (%d) _size : %ld offset : %ld \n",
thisIndex, CkMyPe(), process_size[CkMyPe()], process_offset[CkMyPe()]);
readAtoms(offset, _size);
calculate_energy_self();
printf("Energy on self( %d ) : %f", rank, _sum_on_proc);

contribute(sizeof(double),&_sum_on_proc,CkReduction::sum_double);

communicate();


mainProxy.done();


};
void Object :: communicate()
{

int i;
int rank = CkMyPe();
printf("\n in communicate....");
SendArray *tempArray = new SendArray(_size);
tempArray->setSize(_size);
tempArray->setRank(rank);

for(i = 0; i < _size; i++)
{
printf("\n atom num : %ld", _atomList[i].atom_num);
tempArray->_tempList[i] = _atomList[i];
}
printf("\n array copied on %d",rank);
printf("\n calling recvDAta.....");
thisProxy[(rank + 1)%CkNumPes()].recvData(tempArray);

}

void Object :: recvData(SendArray *temp)
{
printf("\n in recvData.....");
_recvSize = temp->getSize();

int i;
for(i = 0; i < _recvSize; i++)
{
printf("\nrecv size : %ld onr rank %d --- from rank : %d
, recv Atom num : %ld", _recvSize, CkMyPe(), temp->getRank(),
(temp->_tempList[i].atom_num));
}
delete temp;
//while(1);
}
Object::Object(CkMigrateMessage *msg)
{
CkPrintf("object [%d] from (%d) _size : %ld offset : %ld \n",
thisIndex, CkMyPe(), process_size[CkMyPe()], process_offset[CkMyPe()]);
printf("object migrated...");
};

void Object :: readAtoms(long offset, long atom_count)
{

char *token[11];
string line;

ifstream pdb_in("water.pdb");
pdb_in.seekg(offset,ios::cur);

long count = 0, token_index = 0;

while(count < _size)
{
getline(pdb_in, line);
char *str1 = strtok(&line[0], " ");
//printf("\n %s", &line[0]);
token_index = 0;
//printf("\n %s", line);

token[token_index++] = str1;

while ((str1 = strtok(NULL, " ")))
token[token_index++] = str1;
//printf("\n %s", token[1]);

_atomList[count].atom_num =
atol(token[1]);
strcpy(_atomList[count].type,
token[2]);

str1 = strtok(&line[31], " ");
_atomList[count].x = atof(str1);

str1 = strtok(&line[39], " ");
_atomList[count].y = atof(str1);

str1 = strtok(&line[47], " ");
_atomList[count].z = atof(str1);

char temp[100];



if(!strcmp(_atomList[count].type,"OH2"))
_atomList[count].q =
-0.834000;
else
if(!strcmp(_atomList[count].type,"H1"))
_atomList[count].q = 0.417000;
else
if(!strcmp(_atomList[count].type,"H2"))
_atomList[count].q = 0.417000;

count++;
//printf("...........count : %d",
count);
}
pdb_in.close();
printf("\n..rank %d ........count : %ld",
CkMyPe(), count);

}

void Object :: calculate_energy_self()
{
int i, j;
long op = 0;
//_size = 5;
int rank = CkMyPe();
for(i = 0; i < _size; i++)
{
for(j = i+1; j < _size; j++)
{

// printf("\n%d --- %d, * %d ---- %f , %f ,%f, %f", rank,
_atomList[i].atom_num, _atomList[j].atom_num, _atomList[i].x,
_atomList[j].x, _atomList[j].y, _atomList[j].z);

double dx = _atomList[j].x - _atomList[i].x;
double dy = _atomList[j].y - _atomList[i].y;
double dz = _atomList[j].z - _atomList[i].z;
double d = sqrt((dx * dx) + (dy * dy) +( dz * dz));

_sum_on_proc = _sum_on_proc + ((_atomList[j].q * _atomList[i].q)/d);
op++;
}
}
printf("\n %d, %d, %d", CkMyPe(), i, j);

}


//---------------------------------------------------------------------------------------------------------------

SendArray :: SendArray()
{
_size = 0;
// _tempList = NULL;
_rank = 0;
}


SendArray :: SendArray(long atom_count)
{
_size = atom_count;
_tempList = new Atom[_size];
_rank = 0;
}

SendArray::SendArray(const SendArray& Obj)
{
int i;
_size = Obj._size;

_tempList = new Atom[_size];

for(i = 0; i < _size; i++)
_tempList[i] = Obj._tempList[i];
}

long SendArray :: getSize()
{
return _size;
}

Atom* SendArray :: getList()
{
return _tempList;
}

int SendArray::getRank()
{
return _rank;
}

void SendArray::setRank(int rank)
{
_rank = rank;
}

void SendArray :: setSize(long size)
{
_size = size;
}

void SendArray :: setList(Atom *list)
{
_tempList = list;
}

SendArray :: ~SendArray()
{
delete[] _tempList;
}

//-----------------------------------------------------------------------------------------------------------
#include "energyModule.def.h"
#endif



Archive powered by MHonArc 2.6.16.

Top of Page