Ошибки MPI и сегментации - PullRequest
       34

Ошибки MPI и сегментации

0 голосов
/ 24 апреля 2020

Хорошо, так что эта программа предназначена для моделирования солнечной системы путем полуслучайного генерирования звезды, полуслучайного генерирования планет вокруг звезды, имитации времени (используя MPI для распределения вычислительной нагрузки) и определения обитаемости в результате планет. Я должен прокомментировать это для читабельности.

Однако у меня проблема с работой MPI. Насколько я могу судить, я делаю что-то неправильно, что мешает его правильной инициализации. Вот ошибки, которые я получаю.

OrbitPlus.cpp:323:50: error: invalid conversion from ‘char’ to ‘char**’ [-fpermissive]
     system1 = Time( system, n , dt , argc, **argv);
                                                  ^
OrbitPlus.cpp:191:33: error:   initializing argument 5 of ‘std::vector<std::vector<float> > Time(std::vector<std::vector<float> >, int, float, int, char**)’ [-fpermissive]
 std::vector<std::vector<float>> Time( std::vector<std::vector<float>> system , int n, float dt, int argc, char **argv){
                                 ^

Мне действительно интересно, что обе ошибки считаются ошибочными, если при компиляции с - mpic++ -std=c++11 -o OrbitPlus OrbitPlus.cpp

Так что, если я чувствую, Я могу просто запустить код с опцией -fpermissive и бросить кубик, но мне не хочется быть таким смелым. Ясно, что ошибки связаны друг с другом.

Вот мой код.

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <tuple>
#include <vector>
#include <stdio.h>
#include <math.h>
#include <complex>
#include <stdint.h>
#include <time.h>
#include <string.h>
#include <algorithm>

#include "mpi.h"

double MyRandom(){

  //////////////////////////
  //Random Number Generator
  //Returns number between 0-99
  //////////////////////////

  double y = 0;
  unsigned seed = time(0);
  std::srand(seed);
  uint64_t x = std::rand();

  x ^= x << 13;
  x ^= x >> 7;
  x ^= x << 17;

  x = (1070739 * x) % 2199023255530;
  y = x / 21990232555.31 ;
  return y;
}
////////////////////////

///////////////////////
std::tuple< char , float , float , float , int > Star(){

  ////////////////////////////
  //Star will generate a Star
  //Randomly or User Selected
  //Class, Luminosity, Probability, Radius, Mass, Temperature
  //Stars always take up 99% of the mass of the system.
  ///////////////////////////

  char Class;
  int choice = 8;
  float L, R, M, T;
  double y = 4;
  std::tuple< char , float , float , float , float > star( Class , L  , R , M , T) ;
  std::cout << "Select Star Class (OBAFGKM) or Select 8 for Random" << std::endl;
  std::cout << "1 = O, 2 = B, 3 = A, 4 = F, 5 = G, 6 = K, 7 = M : ";
  std::cin >> choice;
  if ( choice == 8 ) {
    y = MyRandom();
    if (y <= 0.003) choice = 1;
    if ((y > 0.003) && (y <= 0.133)) choice = 2;
    if ((y > 0.133) && (y <= 0.733)) choice = 3;
    if ((y > 0.733) && (y <= 3.733)) choice = 4;
    if ((y > 3.733) && (y <= 11.333)) choice = 5;
    if ((y > 11.333) && (y <= 23.433)) choice = 6;
    else choice = 7;
  }

  if (choice == 1) {
    Class = 'O';
    L = 30000;
    R = 0.0307;
    M = 16;
    T = 30000;
  }

  if (choice == 2) {
    Class = 'B';
    L = 15000;
    R = 0.0195;
    M = 9;
    T = 20000;
  }

  if (choice == 3) {
    Class = 'A';
    L = 15;
    R = 0.00744;
    M = 1.7;
    T = 8700;
  }

  if (choice == 4) {
    Class = 'F';
    L = 3.25;
    R = 0.00488;
    M = 1.2;
    T = 6750;
  }

  if (choice == 5) {
    Class = 'G';
    L = 1;
    R = 0.00465;
    M = 1;
    T = 5700;
  }

  if (choice == 6) {
    Class = 'K';
    L = 0.34;
    R = 0.00356;
    M = 0.62;
    T = 4450;
  }

  if (choice == 7) {
    Class = 'M';
    L = 0.08;
    R = 0.00326;
    M = 0.26;
    T = 3000;
  }

  return star;
}
////////////

///////////
std::vector< std::vector<float> > Planet( float L, float R, float M, int T, int n){

///////////////////////////
//Planet generates the Planets
//Random 1 - 10, Random distribution 0.06 - 6 JAU unless specified by User
//Frost line Calculated, First Planet after Frost line is the Jupiter
//The Jupiter will have the most mass of all Jovian worlds
//Otherwise divided into Jovian and Terrestrial Worlds, Random Masses within groups
//Also calculates if a planet is in the Habitable Zone
////////////////////////////

float frostline, innerCHZ, outerCHZ;
float a = 0.06; // a - albedo
float m = M / 100; //Mass of the Jupiter always 1/100th mass of the Star.
std::vector<float> sys;
std::vector<std::vector <float>> system;

for (int i = 0 ; i < n ; i++){
  sys.push_back( MyRandom()/10 * 3 ) ; //Distances in terms of Sol AU
                         }
  sort(sys.begin(), sys.end() );
  for (int i = 0 ; i < n ; i++){
    system[i].push_back(sys[i]);
    system[i].push_back(0); //system[i][0] is x, system[i][1] is y
}

frostline = (0.6 * T / 150) * (0.6 * T/150) * R / sqrt(1 - a);
innerCHZ = sqrt(L / 1.1);
outerCHZ = sqrt(L / 0.53);

for (int i = 0 ; i < n ; i++){
  if (system[i][0] <= frostline) {
    float tmass = m * 0.0003 * MyRandom();
    system[i].push_back(tmass) ; //system[i][2] is mass, [3] is marker for the Jupiter
    system[i].push_back(0) ;
  }

  if ((system[i][0] >= frostline) && (system[i-1][0] < frostline)){
      system[i].push_back(m) ;
      float J = 1;
      system[i].push_back(J) ;
  }

  if ((system[i][0] >= frostline) && (system[i-1][0] >= frostline)) {
      float jmass = m * 0.01 * MyRandom();
      system[i].push_back(jmass) ;
      system[i].push_back(0) ;
  }

  if ((system[i][0] >= innerCHZ) && (system[i][0] <= outerCHZ)){
      float H = 1;
      system[i].push_back(H);
  }
  else system[i].push_back(0); //[4] is habitable marker

  }

  return system;
}
////////////

////////////
std::vector<std::vector<float>> Time( std::vector<std::vector<float>> system , int n, float dt, int argc, char **argv){

  #define ASIZE 3 //Setup
  int MPI_Init(int *argc, char ***argv);
  int rank, numtasks = n, namelen, rc;
  char processor_name[MPI_MAX_PROCESSOR_NAME];
  MPI_Status status;

  MPI_Init( &argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Get_processor_name(processor_name, &namelen);

  rc = MPI_Bcast(&system, ASIZE, MPI_DOUBLE, 0, MPI_COMM_WORLD); //Master
  // Broadcast computed initial values to all other processes

  if (rc != MPI_SUCCESS) {
    fprintf(stderr, "Oops! An error occurred in MPI_Bcast()\n");
    MPI_Abort(MPI_COMM_WORLD, rc);
  }

  //Slaves
  const float pi = 4 * atan(1.0);
  const float G = 6.67 * pow(10,-11);
  float a_x, a_y;

  for (int i = 0 ; i < n; i++) {
    if (rank != i){
      a_x = G * system[i][2] * (system[i][0]-system[rank][0]) / ((system[i][0]-system[rank][0]) * (system[i][0]-system[rank][0]));
      a_y = G * system[i][2] * (system[i][1]-system[rank][1]) / ((system[i][1]-system[rank][1]) * (system[i][1]-system[rank][1]));
    }
    if (rank == i){
      a_x = G * system[i][2] * 100 * system[i][0] / (system[i][0] * system[i][0]);
      a_y = G * system[i][2] * 100 * system[i][1] / (system[i][1] * system[i][1]);
    }
    a_x += a_x;
    a_y += a_y;
  }

  for (int i=0; i < n; i++){
    system[i][0] += system[i][5] * dt + 0.5 * a_x * dt * dt;
    system[i][1] += system[i][6] * dt + 0.5 * a_y * dt * dt;
    system[i][5] += a_x * dt;
    system[i][6] += a_y * dt;
  }

  for(int i=0 ; i<n ; i++){
    for(int j=0 ; j<i ; j++){
      if (system[j][0] == 0 && system[j][1] == 0){
    system.erase(system.begin() + j);
      } // crash into star
      if (system[j][0] == system[i][0] && system[j][1] == system[i][1]){
    system[i][2] += system[j][2];
    system.erase(system.begin() + j);
      } // planet crash
    } //check co-ordinates
  } // planet destroy loop

  for(int i = 0 ; i < n ; i++){
    if (sqrt(system[i][0]*system[i][0] + system[i][1]*system[i][1]) >= 60) system.erase(system.begin() + i);
  }

  //Send results back to the first process
  if (rank != 0){// All processes except the one of rank 0
    MPI_Send(&system, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
  }
  else {
    for (int j = 1; j < numtasks; j++) {
      MPI_Recv(&system, 1, MPI_DOUBLE, MPI_ANY_SOURCE, 1,
           MPI_COMM_WORLD, &status);
    }
  }

  MPI_Finalize();

  ///////////////////////////
  //Time advances the solar system.
  //Plots the Orbits
  //Uses MPI to spread it's calculations.
  ///////////////////////////

  return system;
}
////////////

////////////
std::vector<bool> FinalCheck( std::vector<std::vector<float>> system, std::vector<bool> Water, int n){

///////////////////////////
//Final Checks
//Reports if a Planet spent the whole Time in the Habitable Zone
///////////////////////////

for (int i = 0 ; i < n ; i++){
  if (system[i][4] == 1.0) Water.push_back(true);
  else Water.push_back(false);
  }
return Water;
}
////////////

////////////
int main(int argc, char** argv){

  char Class;
  float L, R, M, T;

  std::tuple< char , float , float , float , float > star( Class , L , R , M , T );
  star = Star();

  int n = MyRandom()/10 + 1;

  std::vector<std::vector <float>> system ;
  std::vector<std::vector <float>> system1 ;
  system = Planet( L , R , M, T, n);

  float G = 6.67 * pow(10,-11), pi = 4 * atan(1.0), dt;
  for (int i = 0; i < n; i++){
    if (system[i][3] == 1){
      dt = 2 * pi * .01 * pow(system[i][0] * 1.5 * pow(10,8), 1.5) / sqrt(G * M * 2 * pow(10,30));
    }
    system[i].push_back(0.0); //system[i][5] is speed in x-axis                                                                                                                                
    system[i].push_back( sqrt(6.67 * pow(10,-11) * 2 * pow(10,30) * M / system[i][0])); //system[i][6] is speed in y-axis                                                                      
  }

  std::ofstream Finder;
  std::ofstream Report;
  Finder.open("plotdata.dat");
  Report.open("report.txt");
  Finder << "# Plot Co-ordinates" << std::endl;

  for (int i = 0 ; i < 1000 ; i++) {
    system1 = Time( system, n , dt , argc, argv);
    for (int j=0 ; j<n ; j++){
      Finder << "[color " << j << "] " << system[j][0] << " " << system[j][1] << std::endl;
      if((system[j][4] == 1.0) && ( (sqrt(system[j][0] * system[j][0] + system[j][1] * system[j][1]) < sqrt(L / 1.1) ) || ((sqrt(system[j][0] * system[j][0] + system[j][1] * system[j][1]) > sqrt(L / 0.53)) ))) system[j][4] = 0.0;
    }
    system = system1;
  }
  Finder.close();
  int m;
  m = system.size()/system[0].size();

  std::vector<bool> Water;
  Water = FinalCheck( system, Water, n);

  //Report
  for (int i = 0 ; i < n ; i++){
    Report << "Planet " << i << "ends up at" << system[i][0] << " and " << system[i][1] << "has mass " << system[i][2] ;
    if (system[i][3] == 1) Report << ", which is the 'Jupiter' of the system." ;
    if (system[i][4] == 1) Report << ", which can have liquid water on the surface." ;
  }
  Report.close();
  ///////////////////////////
  //Report cleans everything up and gives the results
  //Shows the plot, lists the Planets
  //Reports the Positions and Masses of all Planets
  //Reports which was the Jupiter and which if any were Habitable
  //////////////////////////
  return 0;
}

Любые мысли, которые были бы у гуру, были бы оценены, особенно с тем, чтобы избавиться от этих -пропускных ошибок.

РЕДАКТИРОВАТЬ 1 - Код в том виде, в котором он представлен, теперь будет полностью скомпилирован, но вернет ошибку сегментации во время процедуры Star. После того, как пользователь вводит тип звезды, но до того, как он на самом деле делает звезду, насколько я могу судить.

...