Issue
Okay, so I've been struggling with this problem for a few days. I'm trying to distribute an array of strings to various nodes in my Raspberry Pi 4 computing cluster using its most recent version of openmpi. I figured this was a perfect way to learn how clustering works, but I am completely lost at this point and have no direction. For the current set of code, I'm getting a segmentation fault, but when I follow other sets of instructions, I will sometimes receive only the first character of the first string, and null every other character. Those times are when instead of the current array send line, the first argument would be &(NodeOne[0][0]). Most of these sets of instructions are 6-9 years old. Does anyone have any ideas to make the code do more than compile?
#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] = '\0';
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] = '\0';
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] = '\0';
printf("%s\n", myTicks[0]);
}
MPI_Finalize();
}
Solution
It turned out that the problem came from the original array returned by getTickers(). Even though it printed fine when the function was non-mpi, it was overflowed at certain points, rendering the MPI array to be garbage. Thank you to @GillesGouaillardet for helping / basically solving the problem for me!
Answered By - Nicholas Leppert Answer Checked By - Willingham (WPSolving Volunteer)