mercredi 13 novembre 2019

Infinite loop on MPI implementation of opencv image to base64 conversion

Alright, so this is for an assignment and I've invested a huge amount of time in it. What I need to do is convert an image to a base64 string and output it to an output.txt, but I also do that using 5 processors over MPI, where the 0 processor sends quadrants of the image and receives back base64 strings to be appended. But right now when I run with ./mpiexec -np 5 ./opencv I get thrown an infinite loop and no output, I can't even cout anything in my main method to find out the issue, I'm assuming its something with my sending and receiving the string but please enlighten me if you can

This is the library im using to convert: http://www.adp-gmbh.ch/cpp/common/base64.html

and here's how my code is looking right now you can see comments through it.

#include <iostream>
#include "base64.cpp"
#include <opencv2/opencv.hpp>
#include <mpi.h>
#include<string.h>

using namespace std;



void parallel(cv::Mat img){
  int id;
  int ierr;
  int p;

  ierr = MPI_Init ( NULL,NULL );   //  Initialize MPI.

  if ( ierr != 0 )
  {
    cout << "\n";
    cout << "MPI - Fatal error!\n";
    cout << "  MPI_Init returned nonzero ierr.\n";
    exit ( 1 );
  }
  ierr = MPI_Comm_size ( MPI_COMM_WORLD, &p ); //  Get the number of processes.

  ierr = MPI_Comm_rank ( MPI_COMM_WORLD, &id ); //  Get the individual process ID.



  //P0
  if (id == 0){
    //divide image into 4 quadrants
    cv::Mat top_left
   = img(cv::Range(0, img.rows / 2 - 1), cv::Range(0, img.cols / 2 - 1));
    cv::Mat top_right
   = img(cv::Range(0, img.rows / 2 - 1), cv::Range(img.cols / 2, img.cols - 1));
    cv::Mat bottom_left
   = img(cv::Range(img.rows / 2, img.rows - 1), cv::Range(0, img.cols / 2 - 1));
    cv::Mat bottom_right
   = img(cv::Range(img.rows / 2, img.rows - 1), cv::Range(img.cols / 2, img.cols - 1));
   //Send each quadrant to it's appropriate process
   MPI_Send(top_left.data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
   MPI_Send(top_right.data, 1, MPI_INT, 2, 0, MPI_COMM_WORLD);
   MPI_Send(bottom_left.data, 1, MPI_INT, 3, 0, MPI_COMM_WORLD);
   MPI_Send(bottom_right.data, 1, MPI_INT, 4, 0, MPI_COMM_WORLD);

   //Receive each quadrant as a base64 string
   //initializations
   MPI_Status status;
   int count;
   //1
   MPI_Probe(1,0,MPI_COMM_WORLD,&status);
   MPI_Get_count(&status,MPI_CHAR,&count);
   char *buf1 = new char[count];
   MPI_Recv(&buf1,count,MPI_CHAR,1,0,MPI_COMM_WORLD,&status);
   std::string encoded1 = buf1;
   //2
   MPI_Probe(2,0,MPI_COMM_WORLD,&status);
   MPI_Get_count(&status,MPI_CHAR,&count);
   char *buf2 = new char[count];
   MPI_Recv(&buf2,count,MPI_CHAR,2,0,MPI_COMM_WORLD,&status);
   std::string encoded2 = buf2;
   //3
   MPI_Probe(3,0,MPI_COMM_WORLD,&status);
   MPI_Get_count(&status,MPI_CHAR,&count);
   char *buf3 = new char[count];
   MPI_Recv(&buf3,count,MPI_CHAR,3,0,MPI_COMM_WORLD,&status);
   std::string encoded3 = buf3;
   //4
   MPI_Probe(4,0,MPI_COMM_WORLD,&status);
   MPI_Get_count(&status,MPI_CHAR,&count);
   char *buf4 = new char[count];
   MPI_Recv(&buf4,count,MPI_CHAR,4,0,MPI_COMM_WORLD,&status);
   std::string encoded4 = buf4;

   //Combine 4 strings
   std::string base64fullimage = encoded1 + encoded2 + encoded3 + encoded4;
   // cout << base64fullimage;
   //write output to text file
   ofstream file;
   file.open ("output.txt");
   file << base64fullimage;
   file.close();
  }

  //!PO
  if (id != 0){
    //receive image part
    cv::Mat part;
    MPI_Recv(&part, 1, MPI_INT, 0, id, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    //encode image part to base64
    vector<uchar> buf;
    cv::imencode(".jpg", part, buf);
    uchar *enc_msg = new uchar[buf.size()];
    for(int i=0; i < buf.size(); i++) enc_msg[i] = buf[i];
    string encoded = base64_encode(enc_msg, buf.size());
    //send encoded as base64 image part back to p0
    MPI_Send(encoded.c_str(), encoded.length(), MPI_CHAR, 0, id, MPI_COMM_WORLD);

  }
  MPI_Finalize();
}



int main()
{
printf("test");
cout << "test";
cv::Mat img = cv::imread("donkey.jpg");
parallel(img); //parallel
  return 0;
}

//Compile using mpic++  main.cpp -o opencv `pkg-config --cflags --libs opencv mpi`

Aucun commentaire:

Enregistrer un commentaire