|
@ -1,12 +1,13 @@ |
|
|
/* ===== INCLUDES ===== */ |
|
|
/* ===== INCLUDES ===== */ |
|
|
|
|
|
|
|
|
#include "serial_gs_pagerank_functions.h" |
|
|
#include "openmp_gs_pagerank_functions.h" |
|
|
#include <omp.h> |
|
|
|
|
|
/* ===== CONSTANTS ===== */ |
|
|
/* ===== CONSTANTS ===== */ |
|
|
|
|
|
|
|
|
const char *ARGUMENT_CONVERGENCE_TOLERANCE = "-c"; |
|
|
const char *ARGUMENT_CONVERGENCE_TOLERANCE = "-c"; |
|
|
const char *ARGUMENT_MAX_ITERATIONS = "-m"; |
|
|
const char *ARGUMENT_MAX_ITERATIONS = "-m"; |
|
|
const char *ARGUMENT_DAMPING_FACTOR = "-a"; |
|
|
const char *ARGUMENT_DAMPING_FACTOR = "-a"; |
|
|
|
|
|
const char *ARGUMENT_THREADS_NUMBER = "-t"; |
|
|
const char *ARGUMENT_VERBAL_OUTPUT = "-v"; |
|
|
const char *ARGUMENT_VERBAL_OUTPUT = "-v"; |
|
|
const char *ARGUMENT_OUTPUT_HISTORY = "-h"; |
|
|
const char *ARGUMENT_OUTPUT_HISTORY = "-h"; |
|
|
const char *ARGUMENT_OUTPUT_FILENAME = "-o"; |
|
|
const char *ARGUMENT_OUTPUT_FILENAME = "-o"; |
|
@ -15,26 +16,31 @@ const int NUMERICAL_BASE = 10; |
|
|
char *DEFAULT_OUTPUT_FILENAME = "pagerank_output"; |
|
|
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 = 2; |
|
|
const int SPARSITY_INCREASE_ITERATION_PERIOD = 3; |
|
|
const int SPARSITY_INCREASE_ITERATION_PERIOD = 10; |
|
|
|
|
|
|
|
|
|
|
|
/* ===== GLOBAL VARIABLES ====== */ |
|
|
|
|
|
|
|
|
|
|
|
int numberOfThreads; |
|
|
|
|
|
|
|
|
/* ===== FUNCTIONS ===== */ |
|
|
/* ===== FUNCTIONS ===== */ |
|
|
|
|
|
|
|
|
int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
int* pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
bool *convergenceStatus, Parameters parameters) { |
|
|
bool *convergenceStatus, Parameters parameters, int* maxIterationsForConvergence) { |
|
|
// Variables declaration
|
|
|
// Variables declaration
|
|
|
int iterations = 0, numberOfPages = parameters.numberOfPages; |
|
|
int numberOfPages = parameters.numberOfPages; |
|
|
|
|
|
int *iterations; |
|
|
double delta, *pagerankDifference, *previousPagerankVector, |
|
|
double delta, *pagerankDifference, *previousPagerankVector, |
|
|
*convergedPagerankVector, *linksFromConvergedPagesPagerankVector; |
|
|
*convergedPagerankVector, *linksFromConvergedPagesPagerankVector; |
|
|
|
|
|
CsrSparseMatrix originalTransitionMatrix = initCsrSparseMatrix(); |
|
|
CooSparseMatrix linksFromConvergedPages = initCooSparseMatrix(); |
|
|
CooSparseMatrix linksFromConvergedPages = initCooSparseMatrix(); |
|
|
bool *convergenceMatrix; |
|
|
bool *convergenceMatrix; |
|
|
|
|
|
|
|
|
int P = omp_get_max_threads(); |
|
|
|
|
|
omp_set_num_threads(P); |
|
|
|
|
|
|
|
|
|
|
|
// Space allocation
|
|
|
// Space allocation
|
|
|
{ |
|
|
{ |
|
|
size_t sizeofDouble = sizeof(double); |
|
|
size_t sizeofDouble = sizeof(double); |
|
|
|
|
|
// iterations until each page converged
|
|
|
|
|
|
iterations = (int *) malloc(numberOfPages * sizeof(int)); |
|
|
// pagerankDifference used to calculate delta
|
|
|
// pagerankDifference used to calculate delta
|
|
|
pagerankDifference = (double *) malloc(numberOfPages * sizeofDouble); |
|
|
pagerankDifference = (double *) malloc(numberOfPages * sizeofDouble); |
|
|
// previousPagerankVector holds last iteration's pagerank vector
|
|
|
// previousPagerankVector holds last iteration's pagerank vector
|
|
@ -50,12 +56,22 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
*convergenceStatus = false; |
|
|
*convergenceStatus = false; |
|
|
|
|
|
|
|
|
// Initialization
|
|
|
// Initialization
|
|
|
allocMemoryForCoo(&linksFromConvergedPages, transitionMatrix->numberOfNonZeroElements); |
|
|
// originalTransitionMatrix used to run pagerank in phases
|
|
|
#pragma omp parallel for num_threads(P) |
|
|
allocMemoryForCsr(&originalTransitionMatrix, transitionMatrix->size, transitionMatrix->numberOfElements); |
|
|
|
|
|
memcpy(originalTransitionMatrix.rowCumulativeIndexes, transitionMatrix->rowCumulativeIndexes, |
|
|
|
|
|
(transitionMatrix->size+1) * sizeof(int)); |
|
|
|
|
|
memcpy(originalTransitionMatrix.columnIndexes, transitionMatrix->columnIndexes, |
|
|
|
|
|
transitionMatrix->numberOfElements * sizeof(int)); |
|
|
|
|
|
memcpy(originalTransitionMatrix.values, transitionMatrix->values, |
|
|
|
|
|
transitionMatrix->numberOfElements * sizeof(double)); |
|
|
|
|
|
|
|
|
|
|
|
allocMemoryForCoo(&linksFromConvergedPages, transitionMatrix->numberOfElements); |
|
|
|
|
|
#pragma omp parallel for num_threads(numberOfThreads) |
|
|
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; |
|
|
linksFromConvergedPagesPagerankVector[i] = 0; |
|
|
linksFromConvergedPagesPagerankVector[i] = 0; |
|
|
|
|
|
iterations[i] = 0; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -66,7 +82,7 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
do { |
|
|
do { |
|
|
// Stores previous pagerank vector
|
|
|
// Stores previous pagerank vector
|
|
|
memcpy(previousPagerankVector, *pagerankVector, numberOfPages * sizeof(double)); |
|
|
memcpy(previousPagerankVector, *pagerankVector, numberOfPages * sizeof(double)); |
|
|
|
|
|
|
|
|
// Calculates new pagerank vector
|
|
|
// Calculates new pagerank vector
|
|
|
calculateNextPagerank(transitionMatrix, previousPagerankVector, |
|
|
calculateNextPagerank(transitionMatrix, previousPagerankVector, |
|
|
pagerankVector, linksFromConvergedPagesPagerankVector, |
|
|
pagerankVector, linksFromConvergedPagesPagerankVector, |
|
@ -75,14 +91,14 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
|
|
|
|
|
|
if (parameters.history) { |
|
|
if (parameters.history) { |
|
|
// Outputs pagerank vector to file
|
|
|
// Outputs pagerank vector to file
|
|
|
savePagerankToFile(parameters.outputFilename, iterations != 0, |
|
|
savePagerankToFile(parameters.outputFilename, NULL, *pagerankVector, |
|
|
*pagerankVector, numberOfPages, parameters.realIterations); |
|
|
numberOfPages, *maxIterationsForConvergence); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Periodically checks for convergence
|
|
|
// Periodically checks for convergence
|
|
|
if (!(iterations % CONVERGENCE_CHECK_ITERATION_PERIOD)) { |
|
|
if (!((*maxIterationsForConvergence) % CONVERGENCE_CHECK_ITERATION_PERIOD)) { |
|
|
// Builds pagerank vectors difference
|
|
|
// Builds pagerank vectors difference
|
|
|
#pragma omp parallel for num_threads(P) |
|
|
#pragma omp parallel for num_threads(numberOfThreads) |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
pagerankDifference[i] = (*pagerankVector)[i] - previousPagerankVector[i]; |
|
|
pagerankDifference[i] = (*pagerankVector)[i] - previousPagerankVector[i]; |
|
|
} |
|
|
} |
|
@ -95,11 +111,13 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
++(*maxIterationsForConvergence); |
|
|
|
|
|
|
|
|
// Periodically increases sparsity
|
|
|
// Periodically increases sparsity
|
|
|
if (iterations && !(iterations % SPARSITY_INCREASE_ITERATION_PERIOD)) { |
|
|
if ((*maxIterationsForConvergence) && !(*maxIterationsForConvergence % SPARSITY_INCREASE_ITERATION_PERIOD)) { |
|
|
bool *newlyConvergedPages = (bool *) malloc(numberOfPages * sizeof(bool)); |
|
|
bool *newlyConvergedPages = (bool *) malloc(numberOfPages * sizeof(bool)); |
|
|
// Checks each individual page for convergence
|
|
|
// Checks each individual page for convergence
|
|
|
#pragma omp parallel for num_threads(P) |
|
|
#pragma omp parallel for num_threads(numberOfThreads) |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
double difference = fabs((*pagerankVector)[i] - |
|
|
double difference = fabs((*pagerankVector)[i] - |
|
|
previousPagerankVector[i]) / fabs(previousPagerankVector[i]); |
|
|
previousPagerankVector[i]) / fabs(previousPagerankVector[i]); |
|
@ -110,9 +128,11 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
newlyConvergedPages[i] = true; |
|
|
newlyConvergedPages[i] = true; |
|
|
convergenceMatrix[i] = true; |
|
|
convergenceMatrix[i] = true; |
|
|
convergedPagerankVector[i] = (*pagerankVector)[i]; |
|
|
convergedPagerankVector[i] = (*pagerankVector)[i]; |
|
|
|
|
|
iterations[i] = *maxIterationsForConvergence; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
#pragma omp parallel for num_threads(P) |
|
|
|
|
|
|
|
|
#pragma omp parallel for num_threads(numberOfThreads) |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
// Filters newly converged pages
|
|
|
// Filters newly converged pages
|
|
|
if (newlyConvergedPages[i] == true) { |
|
|
if (newlyConvergedPages[i] == true) { |
|
@ -132,10 +152,10 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Increases sparsity of the transition matrix by
|
|
|
// Increases sparsity of the transition matrix by zeroing
|
|
|
// deleting elements that correspond to converged pages
|
|
|
// out elements that correspond to converged pages
|
|
|
zeroOutRow(transitionMatrix, i); |
|
|
zeroOutRow(transitionMatrix, i); |
|
|
zeroOutColumn(transitionMatrix, i); |
|
|
//zeroOutColumn(transitionMatrix, i);
|
|
|
|
|
|
|
|
|
// Builds the new linksFromConvergedPagesPagerankVector
|
|
|
// Builds the new linksFromConvergedPagesPagerankVector
|
|
|
cooSparseMatrixVectorMultiplication(linksFromConvergedPages, |
|
|
cooSparseMatrixVectorMultiplication(linksFromConvergedPages, |
|
@ -146,21 +166,29 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
free(newlyConvergedPages); |
|
|
free(newlyConvergedPages); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
++iterations; |
|
|
// Prunes the transition matrix every 8 iterations
|
|
|
|
|
|
if (*maxIterationsForConvergence != 0 && (*maxIterationsForConvergence%8 == 0)) { |
|
|
|
|
|
memcpy(transitionMatrix->values, originalTransitionMatrix.values, |
|
|
|
|
|
transitionMatrix->numberOfElements * sizeof(double)); |
|
|
|
|
|
#pragma omp parallel for num_threads(numberOfThreads) |
|
|
|
|
|
for (int i=0; i<numberOfPages; ++i) { |
|
|
|
|
|
convergedPagerankVector[i] = 0; |
|
|
|
|
|
convergenceMatrix[i] = false; |
|
|
|
|
|
linksFromConvergedPagesPagerankVector[i] = 0; |
|
|
|
|
|
} |
|
|
|
|
|
linksFromConvergedPages.numberOfNonZeroElements = 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// Outputs information about this iteration
|
|
|
// Outputs information about this iteration
|
|
|
if (iterations%2) { |
|
|
if (parameters.verbose){ |
|
|
printf(ANSI_COLOR_BLUE "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, iterations, delta); |
|
|
if ((*maxIterationsForConvergence)%2) { |
|
|
} else { |
|
|
printf(ANSI_COLOR_BLUE "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, *maxIterationsForConvergence, delta); |
|
|
printf(ANSI_COLOR_CYAN "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, iterations, delta); |
|
|
} else { |
|
|
|
|
|
printf(ANSI_COLOR_CYAN "Iteration %d: delta = %f\n" ANSI_COLOR_RESET, *maxIterationsForConvergence, delta); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} while (!*convergenceStatus && (parameters.maxIterations == 0 || |
|
|
} while (!*convergenceStatus && (parameters.maxIterations == 0 || |
|
|
iterations < parameters.maxIterations)); |
|
|
*maxIterationsForConvergence < parameters.maxIterations)); |
|
|
parameters.realIterations = iterations; |
|
|
|
|
|
if (!parameters.history) { |
|
|
|
|
|
// Outputs last pagerank vector to file
|
|
|
|
|
|
savePagerankToFile(parameters.outputFilename, false, *pagerankVector, |
|
|
|
|
|
numberOfPages, parameters.realIterations); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Frees memory
|
|
|
// Frees memory
|
|
|
free(pagerankDifference); |
|
|
free(pagerankDifference); |
|
@ -169,7 +197,7 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
free(linksFromConvergedPagesPagerankVector); |
|
|
free(linksFromConvergedPagesPagerankVector); |
|
|
free(convergenceMatrix); |
|
|
free(convergenceMatrix); |
|
|
destroyCooSparseMatrix(&linksFromConvergedPages); |
|
|
destroyCooSparseMatrix(&linksFromConvergedPages); |
|
|
|
|
|
|
|
|
return iterations; |
|
|
return iterations; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -181,6 +209,9 @@ int pagerank(CsrSparseMatrix *transitionMatrix, double **pagerankVector, |
|
|
void initialize(CsrSparseMatrix *transitionMatrix, |
|
|
void initialize(CsrSparseMatrix *transitionMatrix, |
|
|
double **pagerankVector, Parameters *parameters) { |
|
|
double **pagerankVector, Parameters *parameters) { |
|
|
|
|
|
|
|
|
|
|
|
// Sets the number of threads to be used
|
|
|
|
|
|
omp_set_num_threads(numberOfThreads); |
|
|
|
|
|
|
|
|
// Reads web graph from file
|
|
|
// Reads web graph from file
|
|
|
if ((*parameters).verbose) { |
|
|
if ((*parameters).verbose) { |
|
|
printf(ANSI_COLOR_YELLOW "----- Reading graph from file -----\n" ANSI_COLOR_RESET); |
|
|
printf(ANSI_COLOR_YELLOW "----- Reading graph from file -----\n" ANSI_COLOR_RESET); |
|
@ -190,7 +221,8 @@ void initialize(CsrSparseMatrix *transitionMatrix, |
|
|
// Outputs the algorithm parameters to the console
|
|
|
// Outputs the algorithm parameters to the console
|
|
|
if ((*parameters).verbose) { |
|
|
if ((*parameters).verbose) { |
|
|
printf(ANSI_COLOR_YELLOW "\n----- Running with parameters -----\n" ANSI_COLOR_RESET\ |
|
|
printf(ANSI_COLOR_YELLOW "\n----- Running with parameters -----\n" ANSI_COLOR_RESET\ |
|
|
"Number of pages: %d", (*parameters).numberOfPages); |
|
|
"Number of pages: %d"\ |
|
|
|
|
|
"\nNumber of threads: %d", (*parameters).numberOfPages, numberOfThreads); |
|
|
if (!(*parameters).maxIterations) { |
|
|
if (!(*parameters).maxIterations) { |
|
|
printf("\nMaximum number of iterations: inf"); |
|
|
printf("\nMaximum number of iterations: inf"); |
|
|
} else { |
|
|
} else { |
|
@ -201,7 +233,7 @@ void initialize(CsrSparseMatrix *transitionMatrix, |
|
|
"\nGraph filename: %s\n", (*parameters).convergenceCriterion, |
|
|
"\nGraph filename: %s\n", (*parameters).convergenceCriterion, |
|
|
(*parameters).dampingFactor, (*parameters).graphFilename); |
|
|
(*parameters).dampingFactor, (*parameters).graphFilename); |
|
|
} |
|
|
} |
|
|
(*parameters).realIterations = 0; |
|
|
|
|
|
// Allocates memory for the pagerank vector
|
|
|
// Allocates memory for the pagerank vector
|
|
|
(*pagerankVector) = (double *) malloc((*parameters).numberOfPages * sizeof(double)); |
|
|
(*pagerankVector) = (double *) malloc((*parameters).numberOfPages * sizeof(double)); |
|
|
double webUniformProbability = 1. / (*parameters).numberOfPages; |
|
|
double webUniformProbability = 1. / (*parameters).numberOfPages; |
|
@ -221,24 +253,22 @@ void calculateNextPagerank(CsrSparseMatrix *transitionMatrix, |
|
|
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; |
|
|
|
|
|
|
|
|
csrSparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector, |
|
|
csrSparseMatrixVectorMultiplication(*transitionMatrix, previousPagerankVector, |
|
|
pagerankVector, vectorSize); |
|
|
pagerankVector, vectorSize); |
|
|
#pragma omp parallel for |
|
|
|
|
|
|
|
|
#pragma omp parallel for num_threads(4) |
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
(*pagerankVector)[i] = dampingFactor * (*pagerankVector)[i]; |
|
|
(*pagerankVector)[i] = dampingFactor * (*pagerankVector)[i]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
double normDifference = vectorNorm(previousPagerankVector, vectorSize) - |
|
|
double normDifference = vectorNorm(previousPagerankVector, vectorSize) - |
|
|
vectorNorm(*pagerankVector, vectorSize); |
|
|
vectorNorm(*pagerankVector, vectorSize); |
|
|
#pragma omp parallel for |
|
|
|
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
//(*pagerankVector)[i] += normDifference * webUniformProbability +
|
|
|
(*pagerankVector)[i] += normDifference * webUniformProbability + |
|
|
//linksFromConvergedPagesPagerankVector[i] + convergedPagerankVector[i];
|
|
|
linksFromConvergedPagesPagerankVector[i] + convergedPagerankVector[i]; |
|
|
(*pagerankVector)[i] += 0.5*normDifference* webUniformProbability +linksFromConvergedPagesPagerankVector[i] + convergedPagerankVector[i]; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -261,13 +291,15 @@ double vectorNorm(double *vector, int vectorSize) { |
|
|
* parseArguments parses the command line arguments given by the user. |
|
|
* parseArguments parses the command line arguments given by the user. |
|
|
*/ |
|
|
*/ |
|
|
void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters) { |
|
|
void parseArguments(int argumentCount, char **argumentVector, Parameters *parameters) { |
|
|
if (argumentCount < 2 || argumentCount > 10) { |
|
|
if (argumentCount < 2 || argumentCount > 16) { |
|
|
validUsage(argumentVector[0]); |
|
|
validUsage(argumentVector[0]); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
numberOfThreads = omp_get_max_threads(); |
|
|
|
|
|
|
|
|
(*parameters).numberOfPages = 0; |
|
|
(*parameters).numberOfPages = 0; |
|
|
(*parameters).maxIterations = 0; |
|
|
(*parameters).maxIterations = 0; |
|
|
(*parameters).convergenceCriterion = 1; |
|
|
(*parameters).convergenceCriterion = 0.001; |
|
|
(*parameters).dampingFactor = 0.85; |
|
|
(*parameters).dampingFactor = 0.85; |
|
|
(*parameters).verbose = false; |
|
|
(*parameters).verbose = false; |
|
|
(*parameters).history = false; |
|
|
(*parameters).history = false; |
|
@ -304,6 +336,15 @@ void parseArguments(int argumentCount, char **argumentVector, Parameters *parame |
|
|
exit(EXIT_FAILURE); |
|
|
exit(EXIT_FAILURE); |
|
|
} |
|
|
} |
|
|
(*parameters).dampingFactor = alphaInput; |
|
|
(*parameters).dampingFactor = alphaInput; |
|
|
|
|
|
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_THREADS_NUMBER)) { |
|
|
|
|
|
argumentIndex = checkIncrement(argumentIndex, argumentCount, argumentVector[0]); |
|
|
|
|
|
|
|
|
|
|
|
size_t threadsInput = strtol(argumentVector[argumentIndex], &endPointer, NUMERICAL_BASE); |
|
|
|
|
|
if (threadsInput == 0 && endPointer) { |
|
|
|
|
|
printf("Invalid iterations argument\n"); |
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
} |
|
|
|
|
|
numberOfThreads = threadsInput; |
|
|
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_VERBAL_OUTPUT)) { |
|
|
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_VERBAL_OUTPUT)) { |
|
|
(*parameters).verbose = true; |
|
|
(*parameters).verbose = true; |
|
|
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_OUTPUT_HISTORY)) { |
|
|
} else if (!strcmp(argumentVector[argumentIndex], ARGUMENT_OUTPUT_HISTORY)) { |
|
@ -423,33 +464,27 @@ void generateNormalizedTransitionMatrixFromFile(CsrSparseMatrix *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* pageOutdegree = malloc((*parameters).numberOfPages*sizeof(int)); |
|
|
int* pageOutdegree = malloc((*parameters).numberOfPages*sizeof(int)); |
|
|
for (int i=0; i<(*parameters).numberOfPages; ++i){ |
|
|
for (int i=0; i<(*parameters).numberOfPages; ++i){ |
|
|
pageOutdegree[i] = 0; |
|
|
pageOutdegree[i] = 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<numberOfEdges; ++i) { |
|
|
for (int i=0; i<numberOfEdges; ++i) { |
|
|
int currentRow = tempMatrix.elements[i]->rowIndex; |
|
|
int currentRow = tempMatrix.elements[i]->rowIndex; |
|
|
|
|
|
++pageOutdegree[currentRow]; |
|
|
if (currentRow == tempMatrix.elements[i]->rowIndex) { |
|
|
|
|
|
++pageOutdegree[currentRow]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (int i=0; i<tempMatrix.size; ++i) { |
|
|
for (int i=0; i<tempMatrix.size; ++i) { |
|
|
tempMatrix.elements[i]->value = 1./pageOutdegree[tempMatrix.elements[i]->rowIndex]; |
|
|
tempMatrix.elements[i]->value = 1./pageOutdegree[tempMatrix.elements[i]->rowIndex]; |
|
|
} |
|
|
} |
|
|
|
|
|
free(pageOutdegree); |
|
|
|
|
|
|
|
|
// Transposes the temporary transition matrix (P^T).
|
|
|
// Transposes the temporary transition matrix (P^T).
|
|
|
transposeSparseMatrix(&tempMatrix); |
|
|
transposeSparseMatrix(&tempMatrix); |
|
|
allocMemoryForCsr(transitionMatrix, numberOfEdges); |
|
|
|
|
|
|
|
|
allocMemoryForCsr(transitionMatrix, (*parameters).numberOfPages, numberOfEdges); |
|
|
// Transforms the temporary COO matrix to the desired CSR format
|
|
|
// Transforms the temporary COO matrix to the desired CSR format
|
|
|
transformToCSR(tempMatrix, transitionMatrix); |
|
|
transformToCSR(tempMatrix, transitionMatrix); |
|
|
//printCsrSparseMatrix(*transitionMatrix);
|
|
|
|
|
|
destroyCooSparseMatrix(&tempMatrix); |
|
|
destroyCooSparseMatrix(&tempMatrix); |
|
|
|
|
|
|
|
|
fclose(graphFile); |
|
|
fclose(graphFile); |
|
@ -486,27 +521,34 @@ int checkIncrement(int previousIndex, int maxIndex, char *programName) { |
|
|
return ++previousIndex; |
|
|
return ++previousIndex; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void savePagerankToFile(char *filename, bool append, double *pagerankVector, |
|
|
void savePagerankToFile(char *filename, int *iterationsUntilConvergence, |
|
|
int vectorSize, int realIterations) { |
|
|
double *pagerankVector, int vectorSize, int iteration) { |
|
|
FILE *outputFile; |
|
|
FILE *outputFile; |
|
|
|
|
|
|
|
|
if (append) { |
|
|
outputFile = fopen(filename, "a"); |
|
|
outputFile = fopen(filename, "a"); |
|
|
|
|
|
} else { |
|
|
|
|
|
outputFile = fopen(filename, "w"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (outputFile == NULL) { |
|
|
if (outputFile == NULL) { |
|
|
printf("Error while opening the output file.\n"); |
|
|
printf("Error while opening the output file.\n"); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
//Save numberofPages and convergence time
|
|
|
|
|
|
|
|
|
fprintf(outputFile, "\n----- Iteration %d -----\n", iteration); |
|
|
|
|
|
|
|
|
|
|
|
// Saves the pagerank vector
|
|
|
|
|
|
double sum = 0; |
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
fprintf(outputFile, "%f ", pagerankVector[i]); |
|
|
sum += pagerankVector[i]; |
|
|
} |
|
|
} |
|
|
fprintf(outputFile, "\n"); |
|
|
if (iterationsUntilConvergence == NULL){ |
|
|
//fprintf(outputFile, "%d\t", vectorSize);
|
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
//fprintf(outputFile, "%d\t", realIterations);
|
|
|
fprintf(outputFile, "%d = %.10g\n", i, pagerankVector[i]/sum); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
for (int i=0; i<vectorSize; ++i) { |
|
|
|
|
|
fprintf(outputFile, "%d\t%d\t%.10g\n", i, iterationsUntilConvergence[i], |
|
|
|
|
|
pagerankVector[i]/sum); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
fclose(outputFile); |
|
|
fclose(outputFile); |
|
|
} |
|
|
} |