我几乎完成了这个程序,我只需要循环一个特定的部分很多次。其目的是说,如果“旧能量”在“新能源”的某一范围内(程序中的oldE和E),那么循环将终止并打印新的能量。也就是说,这是一种能量优化。现在我只是尝试循环它,所以我做了一个y循环,运行了三次。然而,当我运行程序,它只是停留在终端。我不太清楚问题出在哪里。我认为这与内存分配有关,所以我试着释放内存,并在似乎最合理的地方重新分配内存。
我贴上// MAIN LOOP //标签的中间区域是问题所在。如果尝试将这么多内容放入循环中似乎不合理,那么我如何修改它,比如将它的大块变成函数呢?我试着把MPI调用转换成函数,但这对我没有用。
以下是节目:
#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"
#include "assert.h"
int main(int argc, char **argv) {
int N = 32;
int dim = 3;
float a = 10.0; // size of 3D box
int size, rank, i, j, k, q;
float **C, **Csend, **Crecv;
float rijx, rijy, rijz, rij, Vij, E, oldE;
float stepsize = 0.05;
double Start_time, End_time, Elapse_time;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Request requests[2];
float energies[size];
float calc_energy(float **matrix) {
E = 0;
for(i = 1; i < N-1; i++) {
for(j = i+1; j < N; j++) {
rijx = pow((matrix[i][0] - matrix[j][0]),2);
rijy = pow((matrix[i][1] - matrix[j][1]),2);
rijz = pow((matrix[i][2] - matrix[j][2]),2);
rij = pow((rijx + rijy + rijz),0.5);
Vij = pow((1/rij),12) - pow((1/rij),6);
E = E + Vij;
}
}
return E;
}
float **alloc_2d_float(int N, int dim) {
float *data = (float *)malloc(N*dim*sizeof(float));
float **array= (float **)malloc(N*sizeof(float*));
for(i=0; i<N; i++) {
array[i] = &(data[dim*i]);
}
return array;
}
Csend = alloc_2d_float(N,dim);
Crecv = alloc_2d_float(N,dim);
C = alloc_2d_float(N,dim);
if(rank==0){
for (i = 0; i < N; i++) {
for (j = 0; j < dim; j++) {
Csend[i][j] = (float)rand()/(float)(RAND_MAX/a);
}
}
}
// This function is to take a random number of matrix elements and change them slightly, but with a catch which is that it should be different for each processor.
float **randomsteps(float **matrix) {
float **newmatrix;
newmatrix = alloc_2d_float(N,dim);
for(i = 0; i < N; i = i++) {
for (j = 0; j < dim; j++) {
newmatrix[i][j] = matrix[i][j];
}
}
int n = rand()%dim;
for(i = 0; i < N; i = i+n) {
for (j = 0; j < dim; j++) {
int n = rand() % dim;
if(i%2 == 0) {
newmatrix[i][j] = matrix[i][j]+((rank+1)*stepsize);
if(newmatrix[i][j] > 10) {
newmatrix[i][j] = matrix[i][j] + (stepsize) - 10;
}
} else {
newmatrix[i][j] = matrix[i][j]-((rank+1)*stepsize);
if(newmatrix[i][j] < 0) {
newmatrix[i][j] = matrix[i][j] - (stepsize) + 10;
}
}
}
}
return newmatrix;
}
// MAIN LOOP //
int y; // var for big loop
for(y=0;y<3;y++) {
for (i = 1; i < size; i++) {
if (rank == 0) {
MPI_Send(&(Csend[0][0]), N*dim, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD);
}
if (rank == i) {
MPI_Recv(&(Crecv[0][0]), N*dim, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD, &status);
}
}
if(rank==0){
C = randomsteps(Csend);
E = calc_energy(C);
oldE = calc_energy(C);
energies[0]=E;
} else {
C = randomsteps(Crecv);
E = calc_energy(C);
}
MPI_Barrier(MPI_COMM_WORLD);
for (i = 1; i < size; i++) {
if (rank == i) {
MPI_Send(&E, 1, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD);
}
if (rank == 0) {
MPI_Recv(&energies[i], size-1, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD, &status);
}
}
MPI_Barrier(MPI_COMM_WORLD);
int location;
int findmin(float *energies) {
int location = 1;
float minimum = energies[0];
for (i = 1 ; i < size ; i++ ) {
if ( energies[i] < minimum ) {
minimum = energies[i];
location = i;
}
}
return location;
}
if(rank==0){
location = findmin(energies);
}
MPI_Bcast(&location, 1, MPI_FLOAT, 0, MPI_COMM_WORLD);
if(rank==0){
MPI_Recv(&(C[0][0]), N*dim, MPI_FLOAT, location, 1, MPI_COMM_WORLD, &status);
}
if(rank == location){
MPI_Send(&(C[0][0]), N*dim, MPI_FLOAT, 0, 1, MPI_COMM_WORLD);
}
MPI_Barrier(MPI_COMM_WORLD);
if(rank==0){
printf("%f\n",calc_energy(C));
free(Csend);
Csend = alloc_2d_float(N,dim);
for(i=0;i<N;i++){
for(j=0;j<dim;j++){
Csend[i][j] = C[i][j];
}}
}
MPI_Barrier(MPI_COMM_WORLD);
free(C);
free(Crecv);
C = alloc_2d_float(N,dim);
Crecv = alloc_2d_float(N,dim);
MPI_Barrier(MPI_COMM_WORLD);
}
//END MAIN LOOP
free(C);
free(Csend);
free(Crecv);
MPI_Finalize();
return 0;
}除了那个大的y循环外,代码是有效的。如果你把它去掉,它就会打印一个值。
提前感谢您的帮助!
编辑:我试着打印了一堆语句,它似乎被困在了这一点上:
if(rank==0){
C = randomsteps(Csend);
E = calc_energy(C);
oldE = calc_energy(C);
energies[0]=E;
if(y==1){
printf("yummy");
}
} else{
C = randomsteps(Crecv);
E = calc_energy(C);
if(y==1){
printf("yummy");
}
}它被困在云端之间
edit2:更具体地说,问题似乎是C = randomsteps(Crecv);
edit3:在随机步骤中注释这段代码可以解决问题,所以这似乎就是原因。还在努力弄清楚为什么
int n = rand()%dim;
for(i = 0; i < N; i = i+n) {
for (j = 0; j < dim; j++) {
int n = rand() % dim;
if(i%2 == 0) {
newmatrix[i][j] = matrix[i][j]+((rank+1)*stepsize);
if(newmatrix[i][j] > 10) {
newmatrix[i][j] = matrix[i][j] + (stepsize) - 10;
}
} else {
newmatrix[i][j] = matrix[i][j]-((rank+1)*stepsize);
if(newmatrix[i][j] < 0) {
newmatrix[i][j] = matrix[i][j] - (stepsize) + 10;
}
}
}
}该代码试图在矩阵中获取随机元素,并对每个处理器的值进行轻微和唯一的修改(例如,增加0.05*秩)。
edit4:啊,我想出来了。我只需要用dim在int n = rand() % dim;中切换N。一个愚蠢的错误引起了我三个小时的恐慌。-_-
也许我现在应该删除这篇文章?还是会被关闭?我不知道在这种情况下会做些什么
发布于 2015-11-20 23:31:54
您的程序挂起只是因为您最终陷入了死锁。
之所以发生这种情况,是因为您的发送/recv是不平衡的,请执行第一个循环:
for (i = 1; i < size; i++) {
if (rank == 0) {
MPI_Send(&(Csend[0][0]), N*dim, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD);
}
if (rank == i) {
MPI_Recv(&(Crecv[0][0]), N*dim, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD, &status);
}
}Rank #0进行size MPI_Send操作,每一个进程都有一个排名#1-N do size MPI_Recv (因此(N-1)*大小recvs正在等待)!这些size接收到的只有一个将被排名0匹配!
因此,当Rank 0可以继续执行其余的代码时,所有其他进程都被卡在接收到的代码上。当等级#0在稍后遇到障碍时,您将陷入死锁。
您要做的是:
if (rank == 0) {
for (i = 1; i < size; i++)
MPI_Send(&(Csend[0][0]), N*dim, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD);
}
if (rank == i) {
MPI_Recv(&(Crecv[0][0]), N*dim, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD, &status);
}也相应地更改循环结束时的发送/recv代码。
https://stackoverflow.com/questions/33816397
复制相似问题