How to parallelize this code snippet using Openmp

Asked

Viewed 785 times

0

I’m trying to parallelize an activity using OpenMp. I having problems because after the first is the code below the result shows wrong.

#include <stdio.h>
#include <fstream>
#include <sstream>
#include <omp.h>
#include <cstdlib>
#include <iostream>

using namespace std;

int countLines(ifstream &file) {

    int count = 0;

    for (string line; getline(file, line); ) {
        count++;
    }

    return count;
}

float maxErrorCriteria(float *array, int arraySize) {

    float max = 0;

    #pragma omp parallel for
    for (int i = 0; i < arraySize; i++) {
        #pragma omp critical
        if (array[i] > max) {
            max = array[i];
        }
    }

    return max;
}

void invertSignal(float *array) {
    *array == 0 ? 0 : *array *= -1;
}

int arrayPosition(int line, int column, int columnCount) {
    return (((line) * (columnCount)) + column);
}

void alocateArray(float **array, int size) {
    *array = new float[size];
}

void cleanArray(float *array, int size) {
    int i;

    #pragma omp parallel for private(i)
    for (i = 0; i < size; i++) {
        array[i] = 0;
    }
}

int main() {

    ifstream file;
    int matrixSize = 0;
    int row = 0;
    int column = 0;
    int i = 0;
    int j = 0;
    int pos = 0;
    float *variableArray;
    float *constantArray;
    float *errorArray;
    float *errorArrayAux;
    float const STOP_CRITERIA = 0.001;
    string filename = "matriz.txt";

    // abrindo o arquivo
    file.open(filename.c_str());

    // buscando o numero de linhas
    row = countLines(file);

    // criando vetor dos valores das constantes 1 / diagonal principal
    alocateArray(&constantArray, row);
    cleanArray(constantArray, row);

    // calculando o tamanho da matriz
    column = row + 1;
    matrixSize = row * column;

    // criando vetor valores da matriz
    alocateArray(&variableArray, matrixSize);
    cleanArray(variableArray, matrixSize);

    // reposicionando o arquivo no inicio
    file.clear();
    file.seekg(0, file.beg);

    // populando o vetor de variveis
    #pragma omp parallel shared(i, j, pos, variableArray)
    #pragma omp parallel for 
    for(i = 0; i < row; i++) {
        for (j = 0; j < column; j++) {
            pos = arrayPosition(i, j, column);
            file >> variableArray[pos];         
        }
    }

    pos = 0;
    // populando o vetor de constantes
    #pragma omp parallel for private(i, pos) shared(constantArray, variableArray)
    for(i = 0; i < row; i++) {
        pos = arrayPosition(i, i, column);
        constantArray[i] = (1 / variableArray[pos]);
        variableArray[pos] = 0;
    }

    // invertendo o sinal
    #pragma omp parallel for private (i, j, pos) shared(variableArray)
    for(i = 0; i < row; i++) {
        for (j = 0; j < (column - 1); j++) {
            pos = arrayPosition(i, j, column);
            invertSignal(&variableArray[pos]);
        }
    }

    // fechado o arquivo
    file.close();

    // criando vetor da margem de erro valores da matriz
    alocateArray(&errorArray, row);
    cleanArray(errorArray, row);

    // criando vetor auxiliar da margem de erro valores da matriz
    alocateArray(&errorArrayAux, row);
    cleanArray(errorArrayAux, row);

    float higherCriteria = 0;

    do {

        for(i = 0; i < row; i++) {

            for (j = 0; j < (column - 1); j++) {
                pos = arrayPosition(i, j, column);
                errorArrayAux[i] += variableArray[pos] * errorArray[j];
            }

            pos = arrayPosition(i, j, column);
            errorArrayAux[i] += variableArray[pos];
            errorArrayAux[i] *= constantArray[i];

        }

        // copiando os valores
        memcpy(errorArray, errorArrayAux, row * sizeof(float));

        // localizando o maior
        higherCriteria = maxErrorCriteria(errorArray, row);

        for(int cu = 0; cu < row; cu++) {
            cout << "x"<< (cu+1) << " " << errorArrayAux[cu] << "\n";
        }
        cout << "\n";

        // limpando o vetor
        cleanArray(errorArrayAux, row);

    } while(STOP_CRITERIA > (1 - higherCriteria));


    for(int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            pos = arrayPosition(i, j, column);
            cout << variableArray[pos] << " ";
        }
        cout << "\n";
    }

    system("PAUSE");
}

The process is as follows, in the first for I populate the array with contents of a file, it works correctly, in the second for would be to separate the values from the main diagonal to a second array and reset the values. And in the third will reverse the values that are in the last column of this vector.

The function arrayPosition returns the value of the array position as a function of the 2 for that simulate it as a matrix.

I’ve been using the Visual Studio 2012.

  • "works properly". The contents of the array is the same content as the file? You checked this?

  • @Guilhermebernal, yes, it is correct, in the first.

  • Why i and j sane shared in the last cycle?

  • @luiscubal I forgot to pack this part, because she is commented, in fact the 2 are privates. But the mistake already begins in the second for

  • You can post the function arrayPosition and how the array was declared variableArray?

  • @Tomásbadan posted the entire code!

Show 1 more comment

1 answer

1

The corrected code would be this, remembering that I took the initialization of the variables that are in the clauses.

#include <stdio.h>
#include <fstream>
#include <sstream>
#include <omp.h>
#include <cstdlib>
#include <iostream>

using namespace std;

int arrayPosition(int line, int column, int columnCount) {
    return (((line) * (columnCount)) + column);
}

int countLines(ifstream &file) {

    int count = 0;

    for (string line; getline(file, line); ) {
        count++;
    }

    return count;
}

float maxErrorCriteria(float *array, int arraySize) {

    float max = 0;

    #pragma omp parallel for
    for (int i = 0; i < arraySize; i++) {
        #pragma omp critical
        if (array[i] > max) {
            max = array[i];
        }
    }

    return max;
}

void invertSignal(float *array) {
    *array == 0 ? 0 : *array *= -1;
}

void alocateArray(float **array, int size) {
    *array = new float[size];
}

void cleanArray(float *array, int size) {
    int i;

    #pragma omp parallel for private(i)
    for (i = 0; i < size; i++) {
        array[i] = 0;
    }
}

int main() {

    ifstream file;
    int matrixSize;
    int row;
    int column;
    int i;
    int j;
    int pos;
    float *variableArray;
    float *constantArray;
    float *errorArray;
    float *errorArrayAux;
    float const STOP_CRITERIA = 0.001;
    string filename = "matriz.txt";

    // abrindo o arquivo
    file.open(filename.c_str());

    // buscando o numero de linhas
    row = countLines(file);

    // criando vetor dos valores das constantes 1 / diagonal principal
    alocateArray(&constantArray, row);
    cleanArray(constantArray, row);

    // calculando o tamanho da matriz
    column = row + 1;
    matrixSize = row * column;

    // criando vetor valores da matriz
    alocateArray(&variableArray, matrixSize);
    cleanArray(variableArray, matrixSize);

    // reposicionando o arquivo no inicio
    file.clear();
    file.seekg(0, file.beg);

    // populando o vetor de variveis
    #pragma omp parallel for private(i, j) shared(variableArray)
    for(i = 0; i < row; i++) {
        for (j = 0; j < column; j++) {
            pos = arrayPosition(i, j, column);
            file >> variableArray[pos];         
        }
    }

    // populando o vetor de constantes
    #pragma omp parallel for private(i) shared(constantArray, variableArray)
    for(int i = 0; i < row; i++) {
        pos = arrayPosition(i, i, column);
        constantArray[i] = (1 / variableArray[pos]);
        variableArray[pos] = 0;
    }

    // invertendo o sinal
    #pragma omp parallel for private (i, j) shared(variableArray)
    for(i = 0; i < row; i++) {
        for (j = 0; j < (column - 1); j++) {
            pos = arrayPosition(i, j, column);
            invertSignal(&variableArray[pos]);
        }
    }

    // fechado o arquivo
    file.close();

    // criando vetor da margem de erro valores da matriz
    alocateArray(&errorArray, row);
    cleanArray(errorArray, row);

    // criando vetor auxiliar da margem de erro valores da matriz
    alocateArray(&errorArrayAux, row);
    cleanArray(errorArrayAux, row);

    float higherCriteria = 0;

    do {

        for(i = 0; i < row; i++) {

            for (j = 0; j < (column - 1); j++) {
                pos = arrayPosition(i, j, column);
                errorArrayAux[i] += variableArray[pos] * errorArray[j];
            }

            pos = arrayPosition(i, j, column);
            errorArrayAux[i] += variableArray[pos];
            errorArrayAux[i] *= constantArray[i];

        }

        // copiando os valores
        memcpy(errorArray, errorArrayAux, row * sizeof(float));

        // localizando o maior
        higherCriteria = maxErrorCriteria(errorArray, row);

        for(int cu = 0; cu < row; cu++) {
            cout << "x"<< (cu+1) << " " << errorArrayAux[cu] << "\n";
        }
        cout << "\n";

        // limpando o vetor
        cleanArray(errorArrayAux, row);

    } while(STOP_CRITERIA > (1 - higherCriteria));


    for(int i = 0; i < row; i++) {
        for (int j = 0; j < column; j++) {
            pos = arrayPosition(i, j, column);
            cout << variableArray[pos] << " ";
        }
        cout << "\n";
    }

    system("PAUSE");
}
  • It may prove what was causing the problem?

  • Starting the value of the variables in the for. For example i and j.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.