Browse Source

Change transition matrix to CSR, Remove LIL

master
Apostolos Fanakis 6 years ago
parent
commit
a142a02a04
No known key found for this signature in database GPG Key ID: 56CE2DEDE9F1FB78
  1. 4
      serial/Makefile
  2. 96
      serial/coo_sparse_matrix.c
  3. 18
      serial/coo_sparse_matrix.h
  4. 93
      serial/csr_sparse_matrix.c
  5. 24
      serial/csr_sparse_matrix.h
  6. 76
      serial/lil_sparse_matrix.c
  7. 29
      serial/lil_sparse_matrix.h
  8. 4
      serial/serial_gs_pagerank.c
  9. 79
      serial/serial_gs_pagerank_functions.c
  10. 9
      serial/serial_gs_pagerank_functions.h

4
serial/Makefile

@ -7,8 +7,8 @@ CC = gcc
RM = rm -f RM = rm -f
CFLAGS_DEBUG=-O0 -ggdb3 -Wall -I. CFLAGS_DEBUG=-O0 -ggdb3 -Wall -I.
CFLAGS=-O3 -Wall -I. CFLAGS=-O3 -Wall -I.
OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o coo_sparse_matrix.o lil_sparse_matrix.o OBJ=serial_gs_pagerank.o serial_gs_pagerank_functions.o coo_sparse_matrix.o csr_sparse_matrix.o
DEPS=serial_gs_pagerank_functions.h coo_sparse_matrix.h lil_sparse_matrix.h DEPS=serial_gs_pagerank_functions.h coo_sparse_matrix.h csr_sparse_matrix.h
# ========================================== # ==========================================
# TARGETS # TARGETS

96
serial/coo_sparse_matrix.c

@ -3,16 +3,25 @@
CooSparseMatrix initCooSparseMatrix() { CooSparseMatrix initCooSparseMatrix() {
CooSparseMatrix sparseMatrix; CooSparseMatrix sparseMatrix;
sparseMatrix.size = 0; sparseMatrix.size = 0;
sparseMatrix.numberOfNonZeroElements = 0;
sparseMatrix.elements = NULL; sparseMatrix.elements = NULL;
return sparseMatrix; return sparseMatrix;
} }
void allocMemoryForElements (CooSparseMatrix *sparseMatrix, int elements) { void allocMemoryForCoo(CooSparseMatrix *sparseMatrix, int numberOfElements) {
sparseMatrix->elements = (CooSparseMatrixElement **) malloc( sparseMatrix->elements = (CooSparseMatrixElement **) malloc(
elements * sizeof(CooSparseMatrixElement *)); numberOfElements * sizeof(CooSparseMatrixElement *));
sparseMatrix->size = numberOfElements;
} }
void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column) { void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column) {
if (sparseMatrix->numberOfNonZeroElements == sparseMatrix->size) {
printf("%d == %d |||| %d, %d\n", sparseMatrix->numberOfNonZeroElements,
sparseMatrix->size, row, column);
printf("Number of non zero elements exceeded size of matrix!\n");
exit(EXIT_FAILURE);
}
// Creates the new element // Creates the new element
CooSparseMatrixElement *newElement = (CooSparseMatrixElement *) malloc( CooSparseMatrixElement *newElement = (CooSparseMatrixElement *) malloc(
sizeof(CooSparseMatrixElement)); sizeof(CooSparseMatrixElement));
@ -20,58 +29,57 @@ void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column
newElement->rowIndex = row; newElement->rowIndex = row;
newElement->columnIndex = column; newElement->columnIndex = column;
sparseMatrix->elements[sparseMatrix->size] = newElement; sparseMatrix->elements[sparseMatrix->numberOfNonZeroElements] = newElement;
sparseMatrix->size = sparseMatrix->size + 1; sparseMatrix->numberOfNonZeroElements = sparseMatrix->numberOfNonZeroElements + 1;
} }
void zeroOutRow(CooSparseMatrix *sparseMatrix, int row) { void transposeSparseMatrix(CooSparseMatrix *sparseMatrix) {
for (int i=0; i<sparseMatrix->size; ++i) { for (int i=0; i<sparseMatrix->numberOfNonZeroElements; ++i) {
CooSparseMatrixElement *element = sparseMatrix->elements[i];
if (element->rowIndex == row) {
element->value = 0;
}
}
}
void zeroOutColumn(CooSparseMatrix *sparseMatrix, int column) {
for (int i=0; i<sparseMatrix->size; ++i) {
CooSparseMatrixElement *element = sparseMatrix->elements[i]; CooSparseMatrixElement *element = sparseMatrix->elements[i];
if (element->columnIndex == column) { int tempRow = element->rowIndex;
element->value = 0; element->rowIndex = element->columnIndex;
} element->columnIndex = tempRow;
} }
} }
int *getRowIndexes(CooSparseMatrix sparseMatrix, int row, int *rowSize) { void transformToCSR(CooSparseMatrix initialSparseMatrix,
*rowSize = 0; CsrSparseMatrix *transformedSparseMatrix) {
for (int i=0; i<sparseMatrix.size; ++i) { // Taken from here: https://github.com/scipy/scipy/blob/3b36a57/scipy/sparse/sparsetools/coo.h#L34
if (sparseMatrix.elements[i]->rowIndex == row) { if (initialSparseMatrix.numberOfNonZeroElements > transformedSparseMatrix->size) {
++(*rowSize); printf("Transformed CSR matrix does not have enough space!\n");
} exit(EXIT_FAILURE);
} }
if (!(*rowSize)) { for (int i=0; i<initialSparseMatrix.numberOfNonZeroElements; ++i){
return NULL; int rowIndex = initialSparseMatrix.elements[i]->rowIndex;
transformedSparseMatrix->rowCumulativeIndexes[rowIndex] =
transformedSparseMatrix->rowCumulativeIndexes[rowIndex] + 1;
} }
int *indexes = (int *) malloc((*rowSize) * sizeof(int)); // Cumulative sums the non zero elements per row
int rowElementIndex = 0; for (int i=0, sum=0; i<transformedSparseMatrix->size+1; ++i){
for (int i=0; i<sparseMatrix.size; ++i) { int temp = transformedSparseMatrix->rowCumulativeIndexes[i];
if (sparseMatrix.elements[i]->rowIndex == row) { transformedSparseMatrix->rowCumulativeIndexes[i] = sum;
indexes[rowElementIndex] = i; sum += temp;
++rowElementIndex;
}
} }
return indexes; for (int i=0; i<initialSparseMatrix.numberOfNonZeroElements; ++i){
} int row = initialSparseMatrix.elements[i]->rowIndex;
int destinationIndex = transformedSparseMatrix->rowCumulativeIndexes[row];
void transposeSparseMatrix(CooSparseMatrix *sparseMatrix) { transformedSparseMatrix->columnIndexes[destinationIndex] = initialSparseMatrix.elements[i]->columnIndex;
for (int i=0; i<sparseMatrix->size; ++i) { transformedSparseMatrix->values[destinationIndex] = initialSparseMatrix.elements[i]->value;
CooSparseMatrixElement *element = sparseMatrix->elements[i];
int tempRow = element->rowIndex; transformedSparseMatrix->rowCumulativeIndexes[row]++;
element->rowIndex = element->columnIndex;
element->columnIndex = tempRow;
} }
for (int i=0, last=0; i<=transformedSparseMatrix->size; i++){
int temp = transformedSparseMatrix->rowCumulativeIndexes[i];
transformedSparseMatrix->rowCumulativeIndexes[i] = last;
last = temp;
}
transformedSparseMatrix->numberOfNonZeroElements = initialSparseMatrix.numberOfNonZeroElements;
} }
void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix, void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix,
@ -82,7 +90,7 @@ void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix,
} }
CooSparseMatrixElement *element; CooSparseMatrixElement *element;
for (int i=0; i<sparseMatrix.size; ++i) { for (int i=0; i<sparseMatrix.numberOfNonZeroElements; ++i) {
element = sparseMatrix.elements[i]; element = sparseMatrix.elements[i];
int row = element->rowIndex, column = element->columnIndex; int row = element->rowIndex, column = element->columnIndex;
@ -97,19 +105,19 @@ void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix,
} }
void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix) { void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix) {
for (int i=0; i<sparseMatrix->size; ++i) { for (int i=0; i<sparseMatrix->numberOfNonZeroElements; ++i) {
free(sparseMatrix->elements[i]); free(sparseMatrix->elements[i]);
} }
free(sparseMatrix->elements); free(sparseMatrix->elements);
} }
void printCooSparseMatrix(CooSparseMatrix sparseMatrix) { void printCooSparseMatrix(CooSparseMatrix sparseMatrix) {
if (sparseMatrix.size == 0) { if (sparseMatrix.numberOfNonZeroElements == 0) {
return; return;
} }
CooSparseMatrixElement *element; CooSparseMatrixElement *element;
for (int i=0; i<sparseMatrix.size; ++i) { for (int i=0; i<sparseMatrix.numberOfNonZeroElements; ++i) {
element = sparseMatrix.elements[i]; element = sparseMatrix.elements[i];
printf("[%d,%d] = %f\n", element->rowIndex, element->columnIndex, printf("[%d,%d] = %f\n", element->rowIndex, element->columnIndex,
element->value); element->value);

18
serial/coo_sparse_matrix.h

@ -6,25 +6,27 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "csr_sparse_matrix.h"
typedef struct cooSparseMatrixElement { typedef struct cooSparseMatrixElement {
double value; double value;
int rowIndex, columnIndex; int rowIndex, columnIndex;
} CooSparseMatrixElement; } CooSparseMatrixElement;
typedef struct cooSparseMatrix { typedef struct cooSparseMatrix {
int size; int size, numberOfNonZeroElements;
CooSparseMatrixElement **elements; CooSparseMatrixElement **elements;
} CooSparseMatrix; } CooSparseMatrix;
CooSparseMatrix initCooSparseMatrix(); CooSparseMatrix initCooSparseMatrix();
void allocMemoryForElements (CooSparseMatrix *sparseMatrix, int elements); void allocMemoryForCoo(CooSparseMatrix *sparseMatrix, int numberOfElements);
void addElement(CooSparseMatrix *sparseMatrix, double value, int row, int column); void addElement(CooSparseMatrix *sparseMatrix, double value, int row,
void zeroOutRow(CooSparseMatrix *sparseMatrix, int row); int column);
void zeroOutColumn(CooSparseMatrix *sparseMatrix, int column);
int *getRowIndexes(CooSparseMatrix sparseMatrix, int row, int *rowSize);
void transposeSparseMatrix(CooSparseMatrix *sparseMatrix); void transposeSparseMatrix(CooSparseMatrix *sparseMatrix);
void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix, double *vector, void transformToCSR(CooSparseMatrix initialSparseMatrix,
double **product, int vectorSize); CsrSparseMatrix *transformedSparseMatrix);
void cooSparseMatrixVectorMultiplication(CooSparseMatrix sparseMatrix,
double *vector, double **product, int vectorSize);
void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix); void destroyCooSparseMatrix(CooSparseMatrix *sparseMatrix);
void printCooSparseMatrix(CooSparseMatrix sparseMatrix); void printCooSparseMatrix(CooSparseMatrix sparseMatrix);

93
serial/csr_sparse_matrix.c

@ -0,0 +1,93 @@
#include "csr_sparse_matrix.h"
CsrSparseMatrix initCsrSparseMatrix() {
CsrSparseMatrix sparseMatrix;
sparseMatrix.size = 0;
sparseMatrix.numberOfNonZeroElements = 0;
sparseMatrix.values = NULL;
sparseMatrix.columnIndexes = NULL;
sparseMatrix.rowCumulativeIndexes = NULL;
return sparseMatrix;
}
void allocMemoryForCsr(CsrSparseMatrix *sparseMatrix, int numberOfElements) {
sparseMatrix->values = (double *) malloc(numberOfElements * sizeof(double));
sparseMatrix->columnIndexes = (int *) malloc(
numberOfElements * sizeof(int));
sparseMatrix->rowCumulativeIndexes = (int *) malloc(
(numberOfElements + 1) * sizeof(int));
for (int i=0; i<numberOfElements+1; ++i) {
sparseMatrix->rowCumulativeIndexes[i] = 0;
}
sparseMatrix->size = numberOfElements;
}
// Row indexes start from 0!
void zeroOutRow(CsrSparseMatrix *sparseMatrix, int row) {
int startIndex = sparseMatrix->rowCumulativeIndexes[row],
endIndex = sparseMatrix->rowCumulativeIndexes[row+1];
for (int i=startIndex; i<endIndex; ++i) {
sparseMatrix->values[i] = 0;
}
}
void zeroOutColumn(CsrSparseMatrix *sparseMatrix, int column) {
for (int i=0; i<sparseMatrix->numberOfNonZeroElements; ++i){
if(sparseMatrix->columnIndexes[i] == column){
// Zeros out this element
sparseMatrix->values[i] = 0;
}
}
}
void csrSparseMatrixVectorMultiplication(CsrSparseMatrix sparseMatrix,
double *vector, double **product, int vectorSize) {
// Initializes the elements of the product vector to zero
for (int i=0; i<vectorSize; ++i) {
(*product)[i] = 0;
}
for (int i=0; i<sparseMatrix.size; ++i) {
// Gets start and end indexes of this row's elements
int startIndex = sparseMatrix.rowCumulativeIndexes[i],
endIndex = sparseMatrix.rowCumulativeIndexes[i+1];
if (startIndex == endIndex) {
// This row has no elements
continue;
}
double sum = 0;
for(int j=startIndex; j<endIndex; ++j){
int elementColumn = sparseMatrix.columnIndexes[j];
sum += sparseMatrix.values[j] * vector[elementColumn];
}
(*product)[i] = sum;
}
}
void destroyCsrSparseMatrix(CsrSparseMatrix *sparseMatrix) {
free(sparseMatrix->values);
free(sparseMatrix->rowCumulativeIndexes);
free(sparseMatrix->columnIndexes);
}
void printCsrSparseMatrix(CsrSparseMatrix sparseMatrix) {
if (sparseMatrix.size == 0) {
return;
}
for (int i=0; i<sparseMatrix.size; ++i){
int startIndex = sparseMatrix.rowCumulativeIndexes[i],
endIndex = sparseMatrix.rowCumulativeIndexes[i+1];
for(int j=startIndex; j<endIndex; ++j){
printf("Row [%d] has [%d] nz elements: \n at column[%d] is value = %f \n",
i, endIndex-startIndex,
sparseMatrix.columnIndexes[j],
sparseMatrix.values[j]);
}
}
}

24
serial/csr_sparse_matrix.h

@ -0,0 +1,24 @@
#ifndef CSR_SPARSE_MATRIX_H /* Include guard */
#define CSR_SPARSE_MATRIX_H
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct csrSparseMatrix {
int size, numberOfNonZeroElements;
int *rowCumulativeIndexes, *columnIndexes;
double *values;
} CsrSparseMatrix;
CsrSparseMatrix initCsrSparseMatrix();
void allocMemoryForCsr(CsrSparseMatrix *sparseMatrix, int numberOfElements);
void zeroOutRow(CsrSparseMatrix *sparseMatrix, int row);
void zeroOutColumn(CsrSparseMatrix *sparseMatrix, int column);
void csrSparseMatrixVectorMultiplication(CsrSparseMatrix sparseMatrix,
double *vector, double **product, int vectorSize);
void destroyCsrSparseMatrix(CsrSparseMatrix *sparseMatrix);
void printCsrSparseMatrix(CsrSparseMatrix sparseMatrix);
#endif // CSR_SPARSE_MATRIX_H

76
serial/lil_sparse_matrix.c

@ -1,76 +0,0 @@
#include "lil_sparse_matrix.h"
LilSparseMatrix createLilSparseMatrix() {
LilSparseMatrix sparseMatrix;
sparseMatrix.elements = 0;
sparseMatrix.firstElement = NULL;
sparseMatrix.lastElement = NULL;
return sparseMatrix;
}
void apendElement(LilSparseMatrix *sparseMatrix, double value, int row, int column) {
// Creates the new element
LilSparseMatrixElement *newElement = (LilSparseMatrixElement *) malloc(sizeof(LilSparseMatrixElement));
newElement->value = value;
newElement->rowIndex = row;
newElement->columnIndex = column;
newElement->nextElement = NULL;
if (sparseMatrix->firstElement == NULL) {
// Sparse matrix is empty, this is the first element
sparseMatrix->firstElement = newElement;
sparseMatrix->lastElement = newElement;
} else {
//Gets last element of the matrix
LilSparseMatrixElement *lastElement = sparseMatrix->lastElement;
lastElement->nextElement = newElement;
sparseMatrix->lastElement = newElement;
}
sparseMatrix->elements = sparseMatrix->elements + 1;
}
void lilSparseMatrixVectorMultiplication(LilSparseMatrix sparseMatrix,
double *vector, double **product, int vectorSize) {
// Initializes the elements of the product vector to zero
for (int i=0; i<vectorSize; ++i) {
(*product)[i] = 0;
}
LilSparseMatrixElement *element = sparseMatrix.firstElement;
for (int i=0; i<sparseMatrix.elements; ++i) {
int row = element->rowIndex, column = element->columnIndex;
if (row >= vectorSize) {
printf("Error at sparseMatrixVectorMultiplication. Matrix has more rows than vector!\n");
printf("row = %d\n", row);
exit(EXIT_FAILURE);
}
(*product)[row] = (*product)[row] + element->value * vector[column];
element = element->nextElement;
}
}
void destroyLilSparseMatrix(LilSparseMatrix *sparseMatrix) {
LilSparseMatrixElement *currentElement = sparseMatrix->firstElement;
while (currentElement != NULL) {
LilSparseMatrixElement *toDelete = currentElement;
currentElement = currentElement->nextElement;
free(toDelete);
}
}
void printLilSparseMatrix(LilSparseMatrix sparseMatrix) {
if (sparseMatrix.elements == 0) {
return;
}
LilSparseMatrixElement *currentElement = sparseMatrix.firstElement;
for (int i=0; i<sparseMatrix.elements; ++i) {
printf("[%d,%d] = %f\n", currentElement->rowIndex,
currentElement->columnIndex, currentElement->value);
currentElement = currentElement->nextElement;
}
}

29
serial/lil_sparse_matrix.h

@ -1,29 +0,0 @@
#ifndef LIL_SPARSE_MATRIX_H /* Include guard */
#define LIL_SPARSE_MATRIX_H
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct lilSparseMatrixElement {
double value;
int rowIndex, columnIndex;
struct lilSparseMatrixElement *nextElement;
} LilSparseMatrixElement;
typedef struct lilSparseMatrix {
int elements;
LilSparseMatrixElement *firstElement;
LilSparseMatrixElement *lastElement;
} LilSparseMatrix;
LilSparseMatrix createLilSparseMatrix();
void apendElement(LilSparseMatrix *sparseMatrix, double value, int row,
int column);
void lilSparseMatrixVectorMultiplication(LilSparseMatrix sparseMatrix,
double *vector, double **product, int vectorSize);
void destroyLilSparseMatrix(LilSparseMatrix *sparseMatrix);
void printLilSparseMatrix(LilSparseMatrix sparseMatrix);
#endif // LIL_SPARSE_MATRIX_H

4
serial/serial_gs_pagerank.c

@ -7,7 +7,7 @@ struct timeval startwtime, endwtime;
double seq_time; double seq_time;
int main(int argc, char **argv) { int main(int argc, char **argv) {
CooSparseMatrix transitionMatrix = initCooSparseMatrix(); CsrSparseMatrix transitionMatrix = initCsrSparseMatrix();
double *pagerankVector; double *pagerankVector;
bool convergenceStatus; bool convergenceStatus;
Parameters parameters; Parameters parameters;
@ -40,5 +40,5 @@ int main(int argc, char **argv) {
seq_time); seq_time);
free(pagerankVector); free(pagerankVector);
destroyCooSparseMatrix(&transitionMatrix); destroyCsrSparseMatrix(&transitionMatrix);
} }

79
serial/serial_gs_pagerank_functions.c

@ -16,17 +16,17 @@ char *DEFAULT_OUTPUT_FILENAME = "pagerank_output";
const int FILE_READ_BUFFER_SIZE = 4096; const int FILE_READ_BUFFER_SIZE = 4096;
const int CONVERGENCE_CHECK_ITERATION_PERIOD = 3; const int CONVERGENCE_CHECK_ITERATION_PERIOD = 3;
const int SPARSITY_INCREASE_ITERATION_PERIOD = 9; const int SPARSITY_INCREASE_ITERATION_PERIOD = 3;
/* ===== FUNCTIONS ===== */ /* ===== FUNCTIONS ===== */
int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector, int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector,
bool *convergenceStatus, Parameters parameters) { bool *convergenceStatus, Parameters parameters) {
// Variables declaration // Variables declaration
int iterations = 0, numberOfPages = parameters.numberOfPages; int iterations = 0, numberOfPages = parameters.numberOfPages;
double delta, *pagerankDifference, *previousPagerankVector, double delta, *pagerankDifference, *previousPagerankVector,
*convergedPagerankVector, *linksFromConvergedPagesPagerankVector; *convergedPagerankVector, *linksFromConvergedPagesPagerankVector;
LilSparseMatrix linksFromConvergedPages = createLilSparseMatrix(); CooSparseMatrix linksFromConvergedPages = initCooSparseMatrix();
bool *convergenceMatrix; bool *convergenceMatrix;
// Space allocation // Space allocation
@ -47,6 +47,7 @@ int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector,
*convergenceStatus = false; *convergenceStatus = false;
// Initialization // Initialization
allocMemoryForCoo(&linksFromConvergedPages, transitionMatrix->numberOfNonZeroElements);
for (int i=0; i<numberOfPages; ++i) { for (int i=0; i<numberOfPages; ++i) {
convergedPagerankVector[i] = 0; convergedPagerankVector[i] = 0;
convergenceMatrix[i] = false; convergenceMatrix[i] = false;
@ -107,17 +108,21 @@ int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector,
} }
for (int i=0; i<numberOfPages; ++i) { for (int i=0; i<numberOfPages; ++i) {
// Filters newly converged pages
if (newlyConvergedPages[i] == true) { if (newlyConvergedPages[i] == true) {
int rowSize; // Checks if this converged page has an out-link to a non converged one
int *rowIndexes = getRowIndexes(*transitionMatrix, i, &rowSize); int rowStartIndex = transitionMatrix->rowCumulativeIndexes[i],
for (int j=0; j<rowSize; ++j){ rowEndIndex = transitionMatrix->rowCumulativeIndexes[i+1];
CooSparseMatrixElement *element = transitionMatrix->elements[rowIndexes[j]]; if (rowEndIndex > rowStartIndex) {
// Checks for links from converged pages to non converged // This row (page) has non zero elements (out-links)
int pageLinksTo = element->columnIndex; for (int j=rowStartIndex; j<rowEndIndex; ++j) {
if (convergenceMatrix[pageLinksTo] == false){ // Checks for links from converged pages to non converged
// Link exists, adds element to the vector int pageLinksTo = transitionMatrix->columnIndexes[j];
apendElement(&linksFromConvergedPages, if (convergenceMatrix[pageLinksTo] == false){
element->value, i, pageLinksTo); // Link exists, adds element to the vector
addElement(&linksFromConvergedPages,
transitionMatrix->values[j], i, pageLinksTo);
}
} }
} }
@ -127,7 +132,7 @@ int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector,
zeroOutColumn(transitionMatrix, i); zeroOutColumn(transitionMatrix, i);
// Builds the new linksFromConvergedPagesPagerankVector // Builds the new linksFromConvergedPagesPagerankVector
lilSparseMatrixVectorMultiplication(linksFromConvergedPages, cooSparseMatrixVectorMultiplication(linksFromConvergedPages,
*pagerankVector, &linksFromConvergedPagesPagerankVector, *pagerankVector, &linksFromConvergedPagesPagerankVector,
numberOfPages); numberOfPages);
} }
@ -157,7 +162,7 @@ int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector,
free(convergedPagerankVector); free(convergedPagerankVector);
free(linksFromConvergedPagesPagerankVector); free(linksFromConvergedPagesPagerankVector);
free(convergenceMatrix); free(convergenceMatrix);
destroyLilSparseMatrix(&linksFromConvergedPages); destroyCooSparseMatrix(&linksFromConvergedPages);
return iterations; return iterations;
} }
@ -167,7 +172,7 @@ int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector,
* from the file and creates the initial transition probability distribution * from the file and creates the initial transition probability distribution
* matrix. * matrix.
*/ */
void initialize(CooSparseMatrix *transitionMatrix, void initialize(CsrSparseMatrix *transitionMatrix,
double **pagerankVector, Parameters *parameters) { double **pagerankVector, Parameters *parameters) {
// Reads web graph from file // Reads web graph from file
@ -197,9 +202,6 @@ void initialize(CooSparseMatrix *transitionMatrix,
for (int i=0; i<(*parameters).numberOfPages; ++i) { for (int i=0; i<(*parameters).numberOfPages; ++i) {
(*pagerankVector)[i] = webUniformProbability; (*pagerankVector)[i] = webUniformProbability;
} }
// Transposes the transition matrix (P^T).
transposeSparseMatrix(transitionMatrix);
} }
// ==================== MATH UTILS ==================== // ==================== MATH UTILS ====================
@ -208,14 +210,14 @@ void initialize(CooSparseMatrix *transitionMatrix,
* calculateNextPagerank calculates the product of the multiplication * calculateNextPagerank calculates the product of the multiplication
* between a matrix and the a vector in a cheap way. * between a matrix and the a vector in a cheap way.
*/ */
void calculateNextPagerank(CooSparseMatrix *transitionMatrix, void calculateNextPagerank(CsrSparseMatrix *transitionMatrix,
double *previousPagerankVector, double **pagerankVector, double *previousPagerankVector, double **pagerankVector,
double *linksFromConvergedPagesPagerankVector, double *linksFromConvergedPagesPagerankVector,
double *convergedPagerankVector, int vectorSize, double dampingFactor) { double *convergedPagerankVector, int vectorSize, double dampingFactor) {
// Calculates the web uniform probability once. // Calculates the web uniform probability once.
double webUniformProbability = 1. / vectorSize; double webUniformProbability = 1. / vectorSize;
cooSparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector, csrSparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector,
pagerankVector, vectorSize); pagerankVector, vectorSize);
for (int i=0; i<vectorSize; ++i) { for (int i=0; i<vectorSize; ++i) {
@ -319,7 +321,7 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame
* readGraphFromFile loads the file supplied in the command line arguments to an * readGraphFromFile loads the file supplied in the command line arguments to an
* array (directedWebGraph) that represents the graph. * array (directedWebGraph) that represents the graph.
*/ */
void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatrix, void generateNormalizedTransitionMatrixFromFile(CsrSparseMatrix *transitionMatrix,
Parameters *parameters){ Parameters *parameters){
FILE *graphFile; FILE *graphFile;
@ -385,16 +387,12 @@ void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatri
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
int tenPercentIncrements = (int) numberOfEdges/10;
int maxPageIndex = 0; int maxPageIndex = 0;
allocMemoryForElements(transitionMatrix, numberOfEdges); CooSparseMatrix tempMatrix = initCooSparseMatrix();
allocMemoryForCoo(&tempMatrix, numberOfEdges);
for (int i=0; i<numberOfEdges; i++) { for (int i=0; i<numberOfEdges; i++) {
if (((*parameters).verbose) && (tenPercentIncrements != 0) && ((i % tenPercentIncrements) == 0)) {
int percentage = (i/tenPercentIncrements)*10;
printf("%d%% • ", percentage);
}
int fileFrom = 0, fileTo = 0; int fileFrom = 0, fileTo = 0;
if (!fscanf(graphFile, "%d %d", &fileFrom, &fileTo)) { if (!fscanf(graphFile, "%d %d", &fileFrom, &fileTo)) {
break; break;
@ -406,9 +404,8 @@ void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatri
if (fileTo > maxPageIndex) { if (fileTo > maxPageIndex) {
maxPageIndex = fileTo; maxPageIndex = fileTo;
} }
addElement(transitionMatrix, 1, fileFrom, fileTo); addElement(&tempMatrix, 1, fileFrom, fileTo);
} }
printf("\n");
if ((*parameters).verbose) { if ((*parameters).verbose) {
printf("Max page index found is: %d\n", maxPageIndex); printf("Max page index found is: %d\n", maxPageIndex);
@ -417,15 +414,15 @@ void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatri
// Calculates the outdegree of each page and assigns the uniform probability // Calculates the outdegree of each page and assigns the uniform probability
// of transition to the elements of the corresponding row // of transition to the elements of the corresponding row
int currentRow = transitionMatrix->elements[0]->rowIndex, pageOutdegree = 1; int currentRow = tempMatrix.elements[0]->rowIndex, pageOutdegree = 1;
for (int i=1; i<transitionMatrix->size; ++i) { for (int i=1; i<tempMatrix.size; ++i) {
CooSparseMatrixElement *currentElement = transitionMatrix->elements[i]; CooSparseMatrixElement *currentElement = tempMatrix.elements[i];
if (currentElement->rowIndex == currentRow) { if (currentElement->rowIndex == currentRow) {
++pageOutdegree; ++pageOutdegree;
} else { } else {
double pageUniformProbability = 1. / pageOutdegree; double pageUniformProbability = 1. / pageOutdegree;
for (int j=i-pageOutdegree; j<i; ++j) { for (int j=i-pageOutdegree; j<i; ++j) {
transitionMatrix->elements[j]->value = pageUniformProbability; tempMatrix.elements[j]->value = pageUniformProbability;
} }
currentRow = currentElement->rowIndex; currentRow = currentElement->rowIndex;
@ -435,10 +432,18 @@ void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatri
// Does the last row // Does the last row
double pageUniformProbability = 1. / pageOutdegree; double pageUniformProbability = 1. / pageOutdegree;
for (int j=transitionMatrix->size-pageOutdegree; j<transitionMatrix->size; ++j) { for (int j=tempMatrix.size-pageOutdegree; j<tempMatrix.size; ++j) {
transitionMatrix->elements[j]->value = pageUniformProbability; tempMatrix.elements[j]->value = pageUniformProbability;
} }
// Transposes the temporary transition matrix (P^T).
transposeSparseMatrix(&tempMatrix);
allocMemoryForCsr(transitionMatrix, numberOfEdges);
// Transforms the temporary COO matrix to the desired CSR format
transformToCSR(tempMatrix, transitionMatrix);
destroyCooSparseMatrix(&tempMatrix);
fclose(graphFile); fclose(graphFile);
} }

9
serial/serial_gs_pagerank_functions.h

@ -10,7 +10,6 @@
#include <math.h> #include <math.h>
#include "coo_sparse_matrix.h" #include "coo_sparse_matrix.h"
#include "lil_sparse_matrix.h"
/* ===== DEFINITIONS ===== */ /* ===== DEFINITIONS ===== */
@ -67,7 +66,7 @@ void parseArguments(int argumentCount, char **argumentVector,
// them to populate the sparse array (transitionMatrix). The entries of the file // them to populate the sparse array (transitionMatrix). The entries of the file
// represent the edges of the web transition graph. The entries are then // represent the edges of the web transition graph. The entries are then
// modified to become the rows of the transition matrix. // modified to become the rows of the transition matrix.
void generateNormalizedTransitionMatrixFromFile(CooSparseMatrix *transitionMatrix, void generateNormalizedTransitionMatrixFromFile(CsrSparseMatrix *transitionMatrix,
Parameters *parameters); Parameters *parameters);
// Function savePagerankToFile appends or overwrites the pagerank vector // Function savePagerankToFile appends or overwrites the pagerank vector
@ -78,14 +77,14 @@ void savePagerankToFile(char *filename, bool append, double *pagerankVector,
// Function initialize allocates memory for the pagerank vector, reads the // Function initialize allocates memory for the pagerank vector, reads the
// dataset from the file and creates the transition probability distribution // dataset from the file and creates the transition probability distribution
// matrix. // matrix.
void initialize(CooSparseMatrix *transitionMatrix, double **pagerankVector, void initialize(CsrSparseMatrix *transitionMatrix, double **pagerankVector,
Parameters *parameters); Parameters *parameters);
// Function vectorNorm calculates the first norm of a vector. // Function vectorNorm calculates the first norm of a vector.
double vectorNorm(double *vector, int vectorSize); double vectorNorm(double *vector, int vectorSize);
// Function calculateNextPagerank calculates the next pagerank vector. // Function calculateNextPagerank calculates the next pagerank vector.
void calculateNextPagerank(CooSparseMatrix *transitionMatrix, void calculateNextPagerank(CsrSparseMatrix *transitionMatrix,
double *previousPagerankVector, double **pagerankVector, double *previousPagerankVector, double **pagerankVector,
double *linksFromConvergedPagesPagerankVector, double *linksFromConvergedPagesPagerankVector,
double *convergedPagerankVector, int vectorSize, double dampingFactor); double *convergedPagerankVector, int vectorSize, double dampingFactor);
@ -93,7 +92,7 @@ void calculateNextPagerank(CooSparseMatrix *transitionMatrix,
// Function pagerank iteratively calculates the pagerank of each page until // Function pagerank iteratively calculates the pagerank of each page until
// either the convergence criterion is met or the maximum number of iterations // either the convergence criterion is met or the maximum number of iterations
// is reached. // is reached.
int pagerank(CooSparseMatrix *transitionMatrix, double **pagerankVector, int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector,
bool *convergenceStatus, Parameters parameters); bool *convergenceStatus, Parameters parameters);
#endif // SERIAL_GS_PAGERANK_FUNCTIONS_H #endif // SERIAL_GS_PAGERANK_FUNCTIONS_H
Loading…
Cancel
Save