How to perform the parallelization of this code snippet using OpenMp

0

I'm trying to parallelize an activity using OpenMp . I have problems because after the first one of the code below the result is 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 content of a file, it works correctly, in the second it would be to separate the values from the main diagonal to a second array and to zero the values. And the third one will be to invert the values that are in the last column of this vector.

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

I've been using Visual Studio 2012 .

    
asked by anonymous 17.02.2014 / 17:12

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");
}
    
18.02.2014 / 00:21