I am working on MPI on C. I have this custom struct that I want to serialize and send to other nodes using MPI Collective communication (Gather, Scatter, Broadcast)
The struct is as following
typedef struct {
double x[2]; /* Old and new X-axis coordinates */
double y[2]; /* Old and new Y-axis coordinates */
double xf; /* force along X-axis */
double yf; /* force along Y-axis */
double xv; /* velocity along X-axis */
double yv; /* velocity along Y-axis */
double mass; /* Mass of the body */
double radius; /* width (derived from mass) */
} bodyType;
I have tried to understand serialization of custom structs on MPI but could not really understand the process. If some one can help me out here it would be great
Thank You
Your struct is just ten contiguous doubles. You don't need to inform MPI about your type, therefore, as it can be treated as an array. If you have an array of seven of your structs, just tell MPI you have an array of 70 doubles. You should tell your compiler to "pack" your struct (e.g. __attribute__((__packed__)) in GCC or Clang) so that it has no padding.
Ok so I was able to go through documents and wrote this
const int nitems=8;
int blocklengths[8] = {2,2,1,1,1,1,1,1};
MPI_Datatype types[8] = {MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE,MPI_DOUBLE};
MPI_Datatype mpi_body_type;
MPI_Aint offsets[8];
offsets[0] = offsetof(bodyType, x);
offsets[1] = offsetof(bodyType, y);
offsets[2] = offsetof(bodyType, xf);
offsets[3] = offsetof(bodyType, yf);
offsets[4] = offsetof(bodyType, xv);
offsets[5] = offsetof(bodyType, yv);
offsets[6] = offsetof(bodyType, mass);
offsets[7] = offsetof(bodyType, radius);
MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_body_type);
MPI_Type_commit(&mpi_body_type);
Related
I have point A(x1, y1), B(x2, y2).
And 4 declared structures:
struct Complex
{
float x;
float y;
};
struct Particle
{
struct Complex P; //Position
struct Complex V; //Motion
struct Complex F; //Gravitational Force
struct Complex Fel; //Elastic force
float m; //which I will use later
};
struct Spring
{
float k; // k is a constant factor characteristic of the spring
float lo; //initial length
int a; // Spring has 2 points added to it(the actual spring), which stores the indice position for struct Particle T[MAX]
int b;
};
struct World
{
struct Particle T[MAX];
struct Spring S[MAX];
int nb; //number of particles
int rs; //number of springs
};
And the compute force procedure:
void computeParticleForceSpring(struct World &w)
{
for(int g=0; g<w.rs; g++)
{
float D = Distance(w.T[w.S[g].a].P, w.T[w.S[g].b].P); //calculate distance between 2 points
struct Complex er1 = (w.T[w.S[g].b].P-w.T[w.S[g].a].P)*(1/D); // calculate unit vector(direction of elastic force for first particle
w.T[w.S[g].a].Fel = er1*w.S[g].k*(D-w.S[g].lo); // calculate elastic force of first particle
w.T[w.S[g].b].Fel = w.T[w.S[g].a].Fel*(-1); // calculate elastic force of second particle
}
}
And the procedure which changes the motion of particles:
void update(struct World &w, float dt) //where dt is like 0.0001
{
for(int g=0; g<w.nb; g++)
{
w.T[g].V = w.T[g].V + w.T[g].F + w.T[g].Fel;
w.T[g].P = w.T[g].P + w.T[g].V*dt;
}
}
My problem is that the line with the 2 points, keeps compressing and extending periodically because of the motion gained and I can't figure a way to find to stop compressing/extending of spring infinitely until it stops slowly when the distance between them is lo.
Is there a way around it, to add friction and if the spring is inert, and the points are moved, the process re-begins once more?
SOLUTION:
I added
struct Complex er
to the struct Particle to remember the unit vector of a point pointing in the opposite direction to the other point.
In the computeParticleForceSpring procedure I added:
w.T[w.S[g].a].er = er1*(-1);// to remember the unit vector of A
w.T[w.S[g].b].er = er1;// to remember the unit vector of B
In the update procedure I added:
w.T[g].er = w.T[g].V*FRICTION;
w.T[g].V = w.T[g].V - w.T[g].er;
I'm kinda new to c++, so sorry if it's a dumb question.
I have a struct that represents a particle in a particle system. Along with the standard stuff like position, velocity, and mass, I want to give it a list of forces, such that each force is a function, where I pass it the particle, and based on the current state of the particle (or not), this function returns a force vector. Ideally I would sum up the results of every such force vector to get a net force, which I could then use to calculate the velocity of the particle for the next tick.
This is what I want my particle to look like
struct particle {
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
std::list<function> forces;
};
Now my question is: Can I do this without implementing a generic force base class that implements a function to calculate a force? Is there a way I can just specify a list of functions with the same call signature?
If you can guarantee that all functions will have the same method signature, then you can use the templated function[cppreference.com] class. I've modified your sample to illustrate how to use it.
#include <functional>
#include <list>
#include <cmath>
using namespace std;
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
// A list of forces that take a particle and return a double
// The space between the two > symbols is needed in pre-c++11 compilers.
list<function<double(const particle&)> > forces;
};
// An example function to calculate the force due to gravity.
double gravity(const particle& p)
{
return p.mass * -9.8;
}
// Making something up for air resistance
double resistance(const particle& p)
{
return 0.1 * sqrt(p.dx * p.dx + p.dy * p.dy + p.dz * p.dz);
}
int main()
{
particle p;
p.mass = 10;
p.x = 0;
p.y = 100;
p.z = 0;
p.dx = 0;
p.dy = 0;
p.dz = 0;
p.forces.push_back(gravity);
p.forces.push_back(resistance);
}
If you're going to be dealing with three dimensional forces, you'll probably want more information in the return type than just a double, but this should be a good starting point. Also, if you have a c++11 compatible compiler, you may also want to lookup lambda functions so that the functions can be created in the same line.
You can use std::function. Something like this:
// define a type for the function
typedef std::function< void(particle const&, float *fxfyfz) > forcer_function;
std::vector< forcer_function > forces;
Now, some words with regards to performance. Since this is particles you're talking about, I'm assuming that you have a reasonably large number of particles (eg some hundreds at least). So I'm assuming that you have an interest in getting this code to run moderately fast.
So, first, using std::list for your container is not advised due to bad cache properties. It will make your code much slower. Therefore, the use of std::vector.
Second, adding the list of forces as a member of your particle structure is uncommon. Do you really want to use different forces per particle? Typically, there are <5 forces and >100-1000 particles. If you can use the same collection of forces for all of your particles, then moving the forces out of your particle class will give you a gain. For example,
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
};
struct particle_container
{
std::vector< particle > particles;
std::vector< forcer_function > forces;
void update();
};
void particle_container::update()
{
for(particle &p : particles) {
double rx, ry, rz;
rx = ry = rz = 0.0;
for(forcer_function fn : forces) {
double f[3];
fn(p, &f[0]);
rx += f[0];
ry += f[1];
rz += f[2];
}
// integrate resulting force, etc
// ...
}
}
If OTOH you really want to use per-particle forces, you can still use the approach I outlined above by grouping particles with the same force collection in different container objects. Then you can reuse all of the above, and adding one more class will fix it:
struct particle_groups
{
std::vector< particle_container > groups;
void update();
};
void particle_groups::update()
{
for(auto &g : groups) {
g.update();
}
};
If you really, really, want no grouping, then at least consider whether there's a way you can use particle members zeroing out inactive forces. Then you could still use the approach above. For example, like this:
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
// is gravity active? either 1.0 or 0.0
double grav;
// is player interaction active? either 1.0 or 0.0
double player;
// etc... for all possible forces
};
Then just multiply eg, your resulting gravity by the particle's grav member, and you effectively switch gravity off or on for that particle, according to whether particle.grav's value is 1.0 or 0.0.
Finally, std::function is slow. You can use a mix of the two approaches above and use a single function. Like this:
struct particle
{
double mass;
// position
double x, y, z;
// velocity
double dx, dy, dz;
};
struct force_settings
{
double grav;
double attractor;
double player;
//etc...
};
struct particle_container
{
// no need to keep pointers to functions
force_settings forces;
std::vector< particle > particles;
void update();
void compute_forces(particle const& p, double *rf) const
{
// zero resulting force
rf[0] = rf[1] = rf[2] = 0.0;
// compute gravity, (assume y axis)
rf[1] += forces.grav * 9.8; // will be either 9.8 or 0.0
// compute attractor
double ax = p.x - attractor.x;
double ay = p.y - attractor.y;
double az = p.z - attractor.z;
rf[0] += forces.attraction * ax*ax;
rf[1] += forces.attraction * ay*ay;
rf[2] += forces.attraction * az*az;
// etc... more forces here
}
};
void particle_container::update()
{
for(particle &p : particles) {
double rf[3];
compute_forces(p, &rf);
// integrate, etc...
}
}
It's been now days that I'm trying to figure out what is wrong but can't because mostly there are very limited documentation that I can find about error handling with the Dens() function in Mathgl. The following is my question. I'm trying to build a spectrogram from an input signal. I have created a M*N array which holds my DFT data. where M=no of rows=total no of windowing used for that signal and N= total no of samples in each Window. There is an X matrix which is of size(M,1) which holds the time data and another matrix /y of size(N,1) which holds normalized frquency data (in db) where least db is 0 and max db =1. The DFT data array of size (M,N) holds value ranging from 0-1 of datatype float. The following is my code.
vector fftstore = dSTFT(&signal, signalLength, windowSize,hopSize);
int num_rows=fftstore.size()/windowSize;
float *m_gl = new float[num_rows * windowSize];
memset( m_gl,0,num_rows*windowSize*sizeof(float));
float *m_glstart;
m_glstart=m_gl;
//t m_gl[num_rows][windowSize]={0};
float *begin_loc;
begin_loc=&fftstore[0];
float *end_loc;
end_loc=&fftstore[0]+windowSize;
//t *dest;
//st=m_gl;
float *offset;
for(int kk=0; kk<num_rows; kk++)
{
offset=m_glstart+(kk*windowSize+0);
//oat offset=&m_gl[kk*windowSize+0];
std::copy(begin_loc, end_loc, offset);
begin_loc+=windowSize;
end_loc+=windowSize;
}
//r(vector<float>::iterator it = fftstore.begin(); it != fftstore.end(); it++) {
//out << *it << endl;
//
//converting M_gl to double
double *m_gldob = new double[num_rows * windowSize];
memset( m_gldob,0,num_rows*windowSize*sizeof(double));
for (int id=0;id<num_rows;id++){
for(int ij=0;ij<4096;ij++){
m_gldob[id * windowSize + ij]=double(m_gl[id * windowSize + ij]);
}
}
//mgl plotting
double xdat[num_rows][1];
memset( xdat,0,num_rows*1*sizeof(int));
for (int xt=1;xt<=num_rows;xt++){
xdat[xt-1][1]=((100*(2*xt-1))/(2*xt));
}
double ydat[windowSize][1];
memset( ydat,0,windowSize*1*sizeof(int));
for (int yf=1;yf<=windowSize;yf++){
ydat[yf-1][1]=(yf*(1/windowSize));
}
double xst;
xst=xdat[0][0];
double xend=xdat[num_rows-1][1];
double yst=ydat[0][0];
double yend=ydat[windowSize-1][1];
double *px;
double *py;
double *pdat;
px=&xdat[0][0];
py=&ydat[0][0];
pdat=m_gldob;
mglGraph gr;
mglData mgl_x;
mglData mgl_y;
mglData mgl_dat;
mgl_dat.Link(m_gldob,num_rows*windowSize,1);//c *
mgl_dat.Rearrange(num_rows,windowSize);
mgl_x.Link(px,num_rows,1);
mgl_y.Link(py,windowSize,1);
mgl_x.Norm();//c
mgl_y.Norm();//c
gr.SetQuality(6);
gr.Alpha(true);
gr.SetRange('x',xst,xend);
gr.SetRange('y',yst,yend);
gr.SetRange('c',0.0, 1.0);
gr.Box();
gr.Dens(mgl_x,mgl_y,mgl_dat);
gr.Colorbar();
gr.WriteBMP("/home/koyel/test1.bmp");
delete[] m_gl;
return 0;
this code runs to give me an output which looks like the following:
http://i.stack.imgur.com/8uAq6.png
can you tell me whats going wrong? Thanks!
I'm creating new derived datatype for MPI to send data from Counter struct and you knew creating new type in MPI is painful and tricky because I need some help to if I am on right track and thank you ?
typedef struct Counter{
int range1,range2,range3,range4;
double preset1 ,preset2 ,preset3 ,preset4;
} countType;
MPI_Datatype createRecType()
{
// Set-up the arguments for the type constructor
MPI_Datatype new_type;
int count = 2;
int blocklens[] = { 4, 4 };
MPI_Aint indices[4];
indices[0] = 0;
MPI_Type_extent( MPI_DOUBLE, &indices[1] );
indices[1] *= 4; // There are 2 doubles
MPI_Datatype old_types[] = { MPI_INT ,MPI_DOUBLE};
// Call the data type constructor
MPI_Type_struct(count, blocklens, indices, old_types, &new_type);
MPI_Type_commit(&new_type);
return new_type;
}
If I guessed right, then see https://computing.llnl.gov/tutorials/mpi/#Derived_Data_Types and the section "Examples: Struct Derived Data Type". It presents how to describe a "particle" defined as:
typedef struct {
float x, y, z;
float velocity;
int n, type;
} Particle;
so that MPI can handle an array of them. The whole relevant snippet is:
/* Setup description of the 4 MPI_FLOAT fields x, y, z, velocity */
offsets[0] = 0;
oldtypes[0] = MPI_FLOAT;
blockcounts[0] = 4;
/* Setup description of the 2 MPI_INT fields n, type */
/* Need to first figure offset by getting size of MPI_FLOAT */
MPI_Type_extent(MPI_FLOAT, &extent);
offsets[1] = 4 * extent;
oldtypes[1] = MPI_INT;
blockcounts[1] = 2;
/* Now define structured type and commit it */
MPI_Type_struct(2, blockcounts, offsets, oldtypes, &particletype);
MPI_Type_commit(&particletype);
Your code seems to follow all of that. Unless you have some typos, your code seems OK. But I cannot guarantee it unless I try compiling and running that;)
One thing for sure, your indices is too large. [2] will be enough. But having it larger will not do anything bad. The count says 2, so MPI will not read those extra elements from that array.
I've implemented a 3D strange attractor explorer which gives float XYZ outputs in the range 0-100, I now want to implement a colouring function for it based upon the displacement between two successive outputs.
I'm not sure of the data structure to use to store the colour values for each point, using a 3D array I'm limited to rounding to the nearest int which gives a very coarse colour scheme.
I'm vaguely aware of octtrees, are they suitable in this siutation?
EDIT: A little more explanation:
to generate the points i'm repeatedly running this:
(a,b,c,d are random floats in the range -3 to 3)
x = x2;
y = y2;
z = z2;
x2 = sin(a * y) - z * cos(b * x);
y2 = z2 * sin(c * x) - cos(d * y);
z2 = sin(x);
parr[i][0]=x;
parr[i][1]=y;
parr[i][2]=z;
which generates new positions for each axis each run, to colour the render I need to take the distance between two successive results, if I just do this with a distance calculation between each run then the colours fade back and forth in equilibrium so I need to take running average for each point and store it, using a 3dimenrsionl array is too coarse a colouring and I'm looking for advice on how to store the values at much smaller increments.
Maybe you could drop the 2-dim array off and use an 1-dim array of
struct ColoredPoint {
int x;
int y;
int z;
float color;
};
so that the code would look like
...
parr[i].x = x;
parr[i].y = y;
parr[i].z = z;
parr[i].color = some_computed_color;
(you may also wish to encapsulate the fields and use class ColoredPoint with access methods)
I'd probably think bout some kind of 3-d binary search tree.
template <class KEY, class VALUE>
class BinaryTree
{
// some implementation, probably available in libraries
public:
VALUE* Find(const KEY& key) const
{
// real implementation is needed here
return NULL;
}
};
// this tree nodes wil actually hold color
class BinaryTree1 : public BinaryTree<double, int>
{
};
class BinaryTree2 : public BinaryTree<double, BinaryTree1>
{
};
class BinaryTree3 : public BinaryTree<double, BinaryTree2>
{
};
And you function to retreive the color from this tree would look like that
bool GetColor(const BinaryTree3& tree, double dX, double dY, double& dZ, int& color)
{
BinaryTree2* pYTree = tree.Find(dX);
if( NULL == pYTree )
return false;
BinaryTree1* pZTree = pYTree->Find(dY);
if( NULL == pZTree )
return false;
int* pCol = pZTree->Find(dZ);
if( NULL == pCol )
return false;
color = *pCol;
return true;
}
Af course you will need to write the function that would add color to this tree, provided 3 coordinates X, Y and Z.
std::map appears to be a good candidate for base class.