标准 C 中的 MPI SEND / RECV 字符串数组
MPI SEND / RECV ARRAY OF STRINGS in standard C
好吧,这几天我一直在为这个问题苦苦挣扎。我正在尝试使用其最新版本的 openmpi 将字符串数组分发到我的 Raspberry Pi 4 计算集群中的各个节点。我认为这是了解聚类如何工作的完美方式,但此时我完全迷失了方向,没有方向。对于当前的代码集,我遇到了分段错误,但是当我按照其他指令集进行操作时,有时我只会收到第一个字符串的第一个字符,并且每隔一个字符为 null。那些时候第一个参数将是 &(NodeOne[0][0]) 而不是当前数组发送行。大多数这些指令集都是 6-9 岁的。
有没有人有任何想法让代码做的不仅仅是编译?
#include <stdlib.h>
#include <curl/curl.h>
#include <string.h>
#include <mpi.h>
#define NUMC 4
void *set_Stats(void *z);
struct Tickers {
char ** x;
int length;
};
struct Tickers getTickers()
{
CURL *curl = curl_easy_init();
char line[300];
struct Tickers tickers;
int length = 0;
char url[60] = "ftp://ftp.nasdaqtrader.com/symboldirectory/nasdaqtraded.txt";
if(curl)
{
FILE *temp = tmpfile();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)temp);
curl_easy_perform(curl);
if(temp)
{
rewind(temp);
char c = fgetc(temp);
while (fgets(line,sizeof(line),temp))
{
length++;
}
rewind(temp);
length = length - 2;
tickers.length = length;
tickers.x = malloc(length * sizeof(char*));
fgets(line, sizeof(line), temp);
fgets(line, sizeof(line), temp);
for(int count = 0; count < length; count++)
{
char *string = line + 2;
int tickLen = strstr(string, "|") - string;
char sub[tickLen];
tickers.x[count] = malloc(tickLen);
strncpy(sub, string, tickLen);
sub[tickLen] = '[=10=]';
strcpy(tickers.x[count], sub);
fgets(line, sizeof(line), temp);
}
fclose(temp);
}
}
curl_easy_cleanup(curl);
return tickers;
}
char ** allocate_DD(int rows, int cols)
{
char *data = (char *)malloc(rows*cols);
char **array= (char **)malloc(rows*sizeof(char*));
for(int i = 0; i < rows; i++)
array[i] = &(data[cols*i]);
return array;
}
int main() //Designed for one master, three slaves
{
int my_id;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
MPI_Status status;
int firstNodeLength;
if(my_id == 0) // meaning this process is a host job
{
struct Tickers tickers = getTickers();
int length = tickers.length / 3;
int remainder = tickers.length % 3;
char ** NodeOneTicks = allocate_DD(length + remainder, 6);
//char ** NodeTwoTicks = allocate_DD(length, 6);
//char ** NodeThrTicks = allocate_DD(length, 6);
int count = 0;
int x = 0;
while(count < length + remainder)
{
strcpy(NodeOneTicks[x], tickers.x[count]);
NodeOneTicks[x][5] = '[=10=]';
count++;
x++;
}
x = 0;
firstNodeLength = length + remainder;
printf("%d\n", firstNodeLength);
MPI_Send(&firstNodeLength,1, MPI_INT,1,1000,MPI_COMM_WORLD);
MPI_Send(NodeOneTicks,firstNodeLength,MPI_CHAR,1,1001,MPI_COMM_WORLD);
}
else // must be slave process
{
int myLen;
int x = 0;
int ierr = MPI_Recv(&myLen,1,MPI_INT,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
printf("%d\n", myLen);
char ** myTicks = allocate_DD(myLen,6);
ierr = MPI_Recv(myTicks[0], myLen,MPI_CHAR,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
myTicks[0][5] = '[=10=]';
printf("%s\n", myTicks[0]);
}
MPI_Finalize();
}
原来问题出在getTickers()返回的原始数组上。尽管当函数是非 mpi 时它打印得很好,但它在某些点溢出,使 MPI 数组成为垃圾。感谢@GillesGouaillardet 帮助/基本上解决了我的问题!
好吧,这几天我一直在为这个问题苦苦挣扎。我正在尝试使用其最新版本的 openmpi 将字符串数组分发到我的 Raspberry Pi 4 计算集群中的各个节点。我认为这是了解聚类如何工作的完美方式,但此时我完全迷失了方向,没有方向。对于当前的代码集,我遇到了分段错误,但是当我按照其他指令集进行操作时,有时我只会收到第一个字符串的第一个字符,并且每隔一个字符为 null。那些时候第一个参数将是 &(NodeOne[0][0]) 而不是当前数组发送行。大多数这些指令集都是 6-9 岁的。 有没有人有任何想法让代码做的不仅仅是编译?
#include <stdlib.h>
#include <curl/curl.h>
#include <string.h>
#include <mpi.h>
#define NUMC 4
void *set_Stats(void *z);
struct Tickers {
char ** x;
int length;
};
struct Tickers getTickers()
{
CURL *curl = curl_easy_init();
char line[300];
struct Tickers tickers;
int length = 0;
char url[60] = "ftp://ftp.nasdaqtrader.com/symboldirectory/nasdaqtraded.txt";
if(curl)
{
FILE *temp = tmpfile();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)temp);
curl_easy_perform(curl);
if(temp)
{
rewind(temp);
char c = fgetc(temp);
while (fgets(line,sizeof(line),temp))
{
length++;
}
rewind(temp);
length = length - 2;
tickers.length = length;
tickers.x = malloc(length * sizeof(char*));
fgets(line, sizeof(line), temp);
fgets(line, sizeof(line), temp);
for(int count = 0; count < length; count++)
{
char *string = line + 2;
int tickLen = strstr(string, "|") - string;
char sub[tickLen];
tickers.x[count] = malloc(tickLen);
strncpy(sub, string, tickLen);
sub[tickLen] = '[=10=]';
strcpy(tickers.x[count], sub);
fgets(line, sizeof(line), temp);
}
fclose(temp);
}
}
curl_easy_cleanup(curl);
return tickers;
}
char ** allocate_DD(int rows, int cols)
{
char *data = (char *)malloc(rows*cols);
char **array= (char **)malloc(rows*sizeof(char*));
for(int i = 0; i < rows; i++)
array[i] = &(data[cols*i]);
return array;
}
int main() //Designed for one master, three slaves
{
int my_id;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
MPI_Status status;
int firstNodeLength;
if(my_id == 0) // meaning this process is a host job
{
struct Tickers tickers = getTickers();
int length = tickers.length / 3;
int remainder = tickers.length % 3;
char ** NodeOneTicks = allocate_DD(length + remainder, 6);
//char ** NodeTwoTicks = allocate_DD(length, 6);
//char ** NodeThrTicks = allocate_DD(length, 6);
int count = 0;
int x = 0;
while(count < length + remainder)
{
strcpy(NodeOneTicks[x], tickers.x[count]);
NodeOneTicks[x][5] = '[=10=]';
count++;
x++;
}
x = 0;
firstNodeLength = length + remainder;
printf("%d\n", firstNodeLength);
MPI_Send(&firstNodeLength,1, MPI_INT,1,1000,MPI_COMM_WORLD);
MPI_Send(NodeOneTicks,firstNodeLength,MPI_CHAR,1,1001,MPI_COMM_WORLD);
}
else // must be slave process
{
int myLen;
int x = 0;
int ierr = MPI_Recv(&myLen,1,MPI_INT,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
printf("%d\n", myLen);
char ** myTicks = allocate_DD(myLen,6);
ierr = MPI_Recv(myTicks[0], myLen,MPI_CHAR,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
myTicks[0][5] = '[=10=]';
printf("%s\n", myTicks[0]);
}
MPI_Finalize();
}
原来问题出在getTickers()返回的原始数组上。尽管当函数是非 mpi 时它打印得很好,但它在某些点溢出,使 MPI 数组成为垃圾。感谢@GillesGouaillardet 帮助/基本上解决了我的问题!