Browse Source

Squash commit

master
Apostolos Fanakis 6 years ago
commit
f3ef16d3eb
  1. 21
      Blocking/spaceOptimized/Makefile
  2. 151
      Blocking/spaceOptimized/knnMPIBlocking.c
  3. 242
      Blocking/spaceOptimized/knnMPIBlockingDeclarations.c
  4. 89
      Blocking/spaceOptimized/knnMPIBlockingDeclarations.h
  5. BIN
      Blocking/timeOptimized/KnnMPIBlockingTimeOptimized
  6. 21
      Blocking/timeOptimized/Makefile
  7. 162
      Blocking/timeOptimized/knnMPIBlocking.c
  8. 237
      Blocking/timeOptimized/knnMPIBlockingDeclarations.c
  9. 93
      Blocking/timeOptimized/knnMPIBlockingDeclarations.h
  10. 21
      NonBlocking/spaceOptimized/Makefile
  11. 138
      NonBlocking/spaceOptimized/knnMPINonBlocking.c
  12. 256
      NonBlocking/spaceOptimized/knnMPINonBlockingDeclarations.c
  13. 91
      NonBlocking/spaceOptimized/knnMPINonBlockingDeclarations.h
  14. BIN
      NonBlocking/timeOptimized/KnnMPINonBlockingTimeOptimized
  15. 21
      NonBlocking/timeOptimized/Makefile
  16. 149
      NonBlocking/timeOptimized/knnMPINonBlocking.c
  17. BIN
      NonBlocking/timeOptimized/knnMPINonBlocking.o
  18. 237
      NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.c
  19. 95
      NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.h
  20. BIN
      NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.o
  21. 22
      README.md
  22. 21
      Serial/spaceOptimized/Makefile
  23. 48
      Serial/spaceOptimized/knnSerial.c
  24. 192
      Serial/spaceOptimized/knnSerialDeclarations.c
  25. 65
      Serial/spaceOptimized/knnSerialDeclarations.h
  26. 21
      Serial/timeOptimized/Makefile
  27. 53
      Serial/timeOptimized/knnSerial.c
  28. 188
      Serial/timeOptimized/knnSerialDeclarations.c
  29. 68
      Serial/timeOptimized/knnSerialDeclarations.h
  30. 85
      dev/bin_to_txt.c
  31. 40
      dev/generate_set.c
  32. 198
      dev/knnSerial (copy).c
  33. 65
      dev/points_read_malloc.c
  34. 60
      dev/points_read_try.c
  35. 14
      stats/1/B_1000.txt
  36. 14
      stats/1/B_13000.txt
  37. 14
      stats/1/B_17000.txt
  38. 14
      stats/1/B_21000.txt
  39. 14
      stats/1/B_5000.txt
  40. 14
      stats/1/B_9000.txt
  41. 10
      stats/1/NB_1000.txt
  42. 10
      stats/1/NB_13000.txt
  43. 10
      stats/1/NB_17000.txt
  44. 10
      stats/1/NB_21000.txt
  45. 10
      stats/1/NB_5000.txt
  46. 10
      stats/1/NB_9000.txt
  47. 14
      stats/2/SO_B_1000.txt
  48. 14
      stats/2/SO_B_13000.txt
  49. 14
      stats/2/SO_B_17000.txt
  50. 14
      stats/2/SO_B_21000.txt
  51. 14
      stats/2/SO_B_5000.txt
  52. 14
      stats/2/SO_B_9000.txt
  53. 10
      stats/2/SO_NB_1000.txt
  54. 10
      stats/2/SO_NB_13000.txt
  55. 10
      stats/2/SO_NB_17000.txt
  56. 10
      stats/2/SO_NB_21000.txt
  57. 10
      stats/2/SO_NB_5000.txt
  58. 10
      stats/2/SO_NB_9000.txt
  59. 14
      stats/2/TO_B_1000.txt
  60. 14
      stats/2/TO_B_13000.txt
  61. 14
      stats/2/TO_B_17000.txt
  62. 14
      stats/2/TO_B_21000.txt
  63. 14
      stats/2/TO_B_5000.txt
  64. 14
      stats/2/TO_B_9000.txt
  65. 10
      stats/2/TO_NB_1000.txt
  66. 10
      stats/2/TO_NB_13000.txt
  67. 10
      stats/2/TO_NB_17000.txt
  68. 10
      stats/2/TO_NB_21000.txt
  69. 10
      stats/2/TO_NB_5000.txt
  70. 10
      stats/2/TO_NB_9000.txt
  71. 14
      stats/2/low_k/SO_B_1000.txt
  72. 14
      stats/2/low_k/SO_B_13000.txt
  73. 14
      stats/2/low_k/SO_B_17000.txt
  74. 14
      stats/2/low_k/SO_B_21000.txt
  75. 14
      stats/2/low_k/SO_B_5000.txt
  76. 14
      stats/2/low_k/SO_B_9000.txt
  77. 10
      stats/2/low_k/SO_NB_1000.txt
  78. 10
      stats/2/low_k/SO_NB_13000.txt
  79. 10
      stats/2/low_k/SO_NB_17000.txt
  80. 10
      stats/2/low_k/SO_NB_21000.txt
  81. 10
      stats/2/low_k/SO_NB_5000.txt
  82. 10
      stats/2/low_k/SO_NB_9000.txt
  83. 14
      stats/2/low_k/TO_B_1000.txt
  84. 14
      stats/2/low_k/TO_B_13000.txt
  85. 14
      stats/2/low_k/TO_B_17000.txt
  86. 14
      stats/2/low_k/TO_B_21000.txt
  87. 14
      stats/2/low_k/TO_B_5000.txt
  88. 14
      stats/2/low_k/TO_B_9000.txt
  89. 10
      stats/2/low_k/TO_NB_1000.txt
  90. 10
      stats/2/low_k/TO_NB_13000.txt
  91. 10
      stats/2/low_k/TO_NB_17000.txt
  92. 10
      stats/2/low_k/TO_NB_21000.txt
  93. 10
      stats/2/low_k/TO_NB_5000.txt
  94. 10
      stats/2/low_k/TO_NB_9000.txt
  95. 14
      stats/2/square_array/SO_B_1000.txt
  96. 14
      stats/2/square_array/SO_B_13000.txt
  97. 14
      stats/2/square_array/SO_B_17000.txt
  98. 0
      stats/2/square_array/SO_B_21000.txt
  99. 14
      stats/2/square_array/SO_B_5000.txt
  100. 14
      stats/2/square_array/SO_B_9000.txt

21
Blocking/spaceOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnMPIBlockingSpaceOptimized
CC=mpicc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnMPIBlocking.o knnMPIBlockingDeclarations.o
DEPS=knnMPIBlockingDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

151
Blocking/spaceOptimized/knnMPIBlocking.c

@ -0,0 +1,151 @@
#include <stdio.h>
#include <sys/time.h>
#include "knnMPIBlockingDeclarations.h"
#include "mpi.h"
/* Structs */
struct timeval startwtime, endwtime
, commStartWTime, commEndWTime
, calcStartWTime, calcEndWTime;
/* Global variables */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0;
char *pointsFilename = NULL, *testFilename = NULL;
double seq_time = 0;
/* Main */
int main(int argc, char **argv){
int numberOfTasks = 0, taskId = 0, chunksize = 0, myOffset = 0, destination = 0, source = 0;
double **myPoints, **inBuffer, **outBuffer, commTimeSum = 0, calcTimeSum = 0;
neighbor **sortedNeighborsArray;
MPI_Status status;
getArguments(argc, argv);
//Initializes mpi and necessary variables
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numberOfTasks);
if (numberOfPoints % numberOfTasks != 0){
printf("Quitting. Number of points must be divisible by number of MPI tasks.\n");
abExit(0);
}
MPI_Comm_rank(MPI_COMM_WORLD, &taskId);
chunksize = numberOfPoints / numberOfTasks; //number of points each task has
myOffset = taskId * chunksize; //this task's offset from (complete) point's array start
destination = taskId + 1; //this task's destination task id for sending messages
if (destination >= numberOfTasks){
destination = 0;
}
source= taskId - 1; //this task's source task id for receiving messages
if (source < 0){
source = numberOfTasks - 1;
}
init(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize
, myOffset * numberOfDimensions);
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&startwtime, NULL);
}
gettimeofday(&calcStartWTime, NULL);
//Calculates distances between task's own points
calculateDistances(&myPoints, &myPoints, &sortedNeighborsArray, chunksize, myOffset
, taskId * chunksize);
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
for (int chunk=0; chunk<numberOfTasks-1; ++chunk){
gettimeofday(&commStartWTime, NULL);
//sends-receives points array blocks
if (taskId == MASTER){
//master task sends first to avoid deadlocks
MPI_Send((chunk == 0) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD);
MPI_Recv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &status);
} else {
//other tasks receive first
MPI_Recv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &status);
MPI_Send((chunk == 0) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD);
}
gettimeofday(&commEndWTime, NULL);
commTimeSum += (double)((commEndWTime.tv_usec - commStartWTime.tv_usec)/1.0e6
+ commEndWTime.tv_sec - commStartWTime.tv_sec);
//offset, the task that sent new points block has from (complete) point's array start
//used for storing the correct neighbor id's in neighbors array
int offset = source - chunk;
if (offset < 0){
offset += numberOfTasks;
}
offset *= chunksize;
gettimeofday(&calcStartWTime, NULL);
//calculates distances between task's points and new points received
calculateDistances(&myPoints, &inBuffer, &sortedNeighborsArray, chunksize, myOffset
, offset);
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
swapPointers(&inBuffer, &outBuffer);
}
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
}
if (test(&sortedNeighborsArray, chunksize, myOffset, testFilename)){
printf("Validity check failed for task %d!\n", taskId);
} else {
printf("Validity check success for task %d!\n", taskId);
}
if (taskId == MASTER){
printf("Number of points = %d\n", numberOfPoints);
printf("Number of dimensions = %d\n", numberOfDimensions);
printf("Number of neighbors = %d\n", numberOfNeighbors);
printf("Number of tasks = %d\n", numberOfTasks);
}
for(int i=0; i<numberOfTasks; ++i) {
MPI_Barrier(MPI_COMM_WORLD);
if (i == taskId) {
printf("Task %d communications time sum = %f\n", taskId, commTimeSum);
printf("Task %d calculations time sum = %f\n", taskId, calcTimeSum);
/*
Uncomment to print the results
*/
/*for (int x=0; x<chunksize; ++x){
for (int y=0; y<numberOfNeighbors; ++y){
printf("%d to %d = %f\n", x + taskId * chunksize
, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
}
}
cleanUp(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize);
MPI_Finalize();
}

242
Blocking/spaceOptimized/knnMPIBlockingDeclarations.c

@ -0,0 +1,242 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "knnMPIBlockingDeclarations.h"
#include "mpi.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tdf is the filename of the dataset file\n");
printf("\ttf is the filename of the dataset file\n");
abExit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = atoi(argv[3]);
if (numberOfNeighbors >= numberOfPoints) {
numberOfNeighbors = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize, int offset){
//Allocates memory for points array
*pointsArray = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points coming from another process
*inBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points going out to another process
*outBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * chunksize))) != NULL ){
for (int row = 0; row < chunksize; ++row){
if ( ( (*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL ){
printf("Error allocating memory\n");
abExit(1);
}
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray, chunksize, offset)){
abExit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<chunksize; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = -1;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double **array;
//allocates a continuous block of memory
double *tempArray = (double *)calloc(rows * columns, sizeof(double));
if (tempArray == NULL){
printf("Error allocating memory\n");
abExit(1);
}
//creates pointers to each row and column for easy indexing
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array, int chunksize, int offset){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
if (offset && fseek(pointsBinaryFile, offset * sizeof(double), SEEK_SET)){
printf("Error reading the file. Quitting.\n");
abExit(0);
}
for (int point=0; point<chunksize; ++point){
if ( fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions ){
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray, int chunksize, int myOffset, int indexOffset){
for (int firstPoint=0; firstPoint<chunksize; ++firstPoint){
for (int secondPoint=0; secondPoint<chunksize; ++secondPoint){
if (myOffset + firstPoint == indexOffset + secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
double tmpDiff = (*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex];
distance += tmpDiff * tmpDiff;
}
addDistanceAndShift(sortedNeighborsArray, firstPoint, indexOffset + secondPoint
, distance);
}
}
}
void addDistanceAndShift(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId
, double pointsDistance){
for (int arrayIndex=0; arrayIndex<numberOfNeighbors; ++arrayIndex){
//Gets distance stored in the array for this index
double thisNeighborDistance = (*sortedNeighborsArray)[firstPointId][arrayIndex].distance;
if (thisNeighborDistance == -1){ //Loop reached the end of the array
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
} else if (thisNeighborDistance > pointsDistance){
//Distance at the this index is greater than the distance being inserted
//Shifts right all non empty columns holding distances lower than pointsDistance
for (int moveColumn=numberOfNeighbors-2; moveColumn>=arrayIndex; --moveColumn){
double tempDistance = (*sortedNeighborsArray)[firstPointId][moveColumn].distance;
if (tempDistance == -1){ //Skips empty columns
continue;
}
(*sortedNeighborsArray)[firstPointId][moveColumn+1].distance = tempDistance;
(*sortedNeighborsArray)[firstPointId][moveColumn+1].neighborId
= (*sortedNeighborsArray)[firstPointId][moveColumn].neighborId;
}
//Inserts pointsDistance in the space created after shifting
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
}
}
}
void swapPointers(double ***firstArray, double ***secondArray){
double **tempPtr = *firstArray;
*firstArray = *secondArray;
*secondArray = tempPtr;
}
int test(neighbor ***sortedNeighborsArray, int chunksize, int offset, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
char *discarded = NULL;
size_t n = 0;
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
if (offset){
for (int line=0; line<offset; ++line){
if (getline(&discarded, &n, testFile) == -1){
perror("Error reading test file");
return 1;
}
n = 0;
}
free(discarded);
}
for (int point=0; point<chunksize; ++point){
for (int i=0; i<numberOfNeighbors; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){ //-1 because f@ck matlab
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize){
free((*pointsArray)[0]);
free(*pointsArray);
free((*inBuffer)[0]);
free(*inBuffer);
free((*outBuffer)[0]);
free(*outBuffer);
for (int row=0; row<chunksize; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}
void abExit(int exitCode){
int initialized = 0;
MPI_Initialized(&initialized);
if (initialized){
MPI_Abort(MPI_COMM_WORLD, -1);
}
exit(0);
}

89
Blocking/spaceOptimized/knnMPIBlockingDeclarations.h

@ -0,0 +1,89 @@
#ifndef KNNMPIBLOCKINGFUNCTIONDECLARATION_H_ /* Include guard */
#define KNNMPIBLOCKINGFUNCTIONDECLARATION_H_
/* Constants definitions */
#define MASTER 0 //task id of the master process
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors knn should find for each point
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, double ***inBuffer //pointer to the array used as input buffer for mpi
, double ***outBuffer //pointer to the array used as output buffer for mpi
, neighbor ***sortedNeighborsArray //pointer to the array holding the distances and ID's
, int chunksize //number of rows (points) to be allocated
, int offset); //process offset used when reading points from the file
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array //array that will hold the coordinates of the points
, int chunksize //number of rows (points) to be read
, int offset); //offset from which reading will start
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray //array that holds the distances
, int chunksize //number of points
, int myOffset //offset used for ID's of first pool's points
, int indexOffset); //offset used for ID's of seconds pool's points
//Function addDistanceAndShift searches an array of neighbors (struct) for an index holding either
//an empty distance or a distance that is greater than the one that came in the arguments
//(pointsDistance), shifts "right" one time all values of the array after this index and fills the
//empty position created after shifting with the one that came in the arguments (pointsDistance)
void addDistanceAndShift(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function swapPointers swaps the memory blocks pointed to by two pointers
void swapPointers(double ***firstArray //first memory block
, double ***secondArray); //second memory block
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, int chunksize //number of points
, int offset //process offset
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, double ***inBuffer //input buffer pointer
, double ***outBuffer //output buffer pointer
, neighbor ***sortedNeighborsArray //distances array pointer
, int chunksize); //number of rows (points)
//Function abExit exits the program after checking for mpi initialization
void abExit(int exitCode); //exit code to exit with
#endif // KNNMPIBLOCKINGFUNCTIONDECLARATION_H_

BIN
Blocking/timeOptimized/KnnMPIBlockingTimeOptimized

Binary file not shown.

21
Blocking/timeOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnMPIBlockingTimeOptimized
CC=mpicc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnMPIBlocking.o knnMPIBlockingDeclarations.o
DEPS=knnMPIBlockingDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

162
Blocking/timeOptimized/knnMPIBlocking.c

@ -0,0 +1,162 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "knnMPIBlockingDeclarations.h"
#include "mpi.h"
/* Structs */
struct timeval startwtime, endwtime
, commStartWTime, commEndWTime
, calcStartWTime, calcEndWTime;
/* Global variables */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0, k = 0;
char *pointsFilename = NULL, *testFilename = NULL;
double seq_time = 0;
/* Main */
int main(int argc, char **argv){
int numberOfTasks = 0, taskId = 0, chunksize = 0, myOffset = 0, destination = 0, source = 0;
double **myPoints, **inBuffer, **outBuffer, commTimeSum = 0, calcTimeSum = 0;
neighbor **sortedNeighborsArray;
MPI_Status status;
getArguments(argc, argv);
//Initializes mpi and necessary variables
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numberOfTasks);
if (numberOfPoints % numberOfTasks != 0){
printf("Quitting. Number of points must be divisible by number of MPI tasks.\n");
abExit(0);
}
MPI_Comm_rank(MPI_COMM_WORLD, &taskId);
chunksize = numberOfPoints / numberOfTasks; //number of points each task has
myOffset = taskId * chunksize; //this task's offset from (complete) point's array start
destination = taskId + 1; //this task's destination task id for sending messages
if (destination >= numberOfTasks){
destination = 0;
}
source= taskId - 1; //this task's source task id for receiving messages
if (source < 0){
source = numberOfTasks - 1;
}
init(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize
, myOffset * numberOfDimensions);
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&startwtime, NULL);
}
gettimeofday(&calcStartWTime, NULL);
//Calculates distances between task's own points
calculateDistances(&myPoints, &myPoints, &sortedNeighborsArray, chunksize, myOffset
, taskId * chunksize);
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
for (int chunk=0; chunk<numberOfTasks-1; ++chunk){
gettimeofday(&commStartWTime, NULL);
//sends-receives points array blocks
if (taskId == MASTER){
//master task sends first to avoid deadlocks
MPI_Send((chunk == 0) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD);
MPI_Recv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &status);
} else {
//other tasks receive first
MPI_Recv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &status);
MPI_Send((chunk == 0) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD);
}
gettimeofday(&commEndWTime, NULL);
commTimeSum += (double)((commEndWTime.tv_usec - commStartWTime.tv_usec)/1.0e6
+ commEndWTime.tv_sec - commStartWTime.tv_sec);
//offset, the task that sent new points block has from (complete) point's array start
//used for storing the correct neighbor id's in neighbors array
int offset = source - chunk;
if (offset < 0){
offset += numberOfTasks;
}
offset *= chunksize;
gettimeofday(&calcStartWTime, NULL);
//calculates distances between task's points and new points received
calculateDistances(&myPoints, &inBuffer, &sortedNeighborsArray, chunksize, myOffset
, offset);
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
swapPointers(&inBuffer, &outBuffer);
}
gettimeofday(&calcStartWTime, NULL);
for (int point=0; point<chunksize; ++point){
qsort (sortedNeighborsArray[point], numberOfNeighbors, sizeof(neighbor), compare);
}
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
if (test(&sortedNeighborsArray, chunksize, myOffset, testFilename)){
printf("Validity check failed for task %d!\n", taskId);
} else {
printf("Validity check success for task %d!\n", taskId);
}
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
}
if (taskId == MASTER){
printf("Number of points = %d\n", numberOfPoints);
printf("Number of dimensions = %d\n", numberOfDimensions);
printf("Number of neighbors = %d\n", numberOfNeighbors);
printf("Number of tasks = %d\n", numberOfTasks);
}
for(int i=0; i<numberOfTasks; ++i) {
MPI_Barrier(MPI_COMM_WORLD);
if (i == taskId) {
printf("Task %d communications time sum = %f\n", taskId, commTimeSum);
printf("Task %d calculations time sum = %f\n", taskId, calcTimeSum);
/*
Uncomment to print the results
*/
/*for (int x=0; x<chunksize; ++x){
for (int y=0; y<numberOfNeighbors; ++y){
printf("%d to %d = %f\n", x + taskId * chunksize
, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
}
}
cleanUp(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize);
MPI_Finalize();
}

237
Blocking/timeOptimized/knnMPIBlockingDeclarations.c

@ -0,0 +1,237 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "knnMPIBlockingDeclarations.h"
#include "mpi.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tdf is the filename of the dataset file\n");
printf("\ttf is the filename of the dataset file\n");
abExit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = numberOfPoints - 1;
k = atoi(argv[3]);
if (k >= numberOfPoints){
k = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize, int offset){
//Allocates memory for points array
*pointsArray = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points coming from another process
*inBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points going out to another process
*outBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * chunksize))) != NULL ){
for (int row = 0; row < chunksize; ++row){
if ( ( (*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL ){
printf("Error allocating memory\n");
abExit(1);
}
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray, chunksize, offset)){
abExit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<chunksize; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = -1;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double **array;
//allocates a continuous block of memory
double *tempArray = (double *)calloc(rows * columns, sizeof(double));
if (tempArray == NULL){
printf("Error allocating memory\n");
abExit(1);
}
//creates pointers to each row and column for easy indexing
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array, int chunksize, int offset){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
if (fseek(pointsBinaryFile, offset * sizeof(double), SEEK_SET)){
printf("Error reading the file. Quitting.\n");
abExit(0);
}
for (int point=0; point<chunksize; ++point){
if ( fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions ){
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray, int chunksize, int myOffset, int indexOffset){
for (int firstPoint=0; firstPoint<chunksize; ++firstPoint){
for (int secondPoint=0; secondPoint<chunksize; ++secondPoint){
if (myOffset + firstPoint == indexOffset + secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
double tmpDiff = (*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex];
distance += tmpDiff * tmpDiff;
}
addDistance(sortedNeighborsArray, firstPoint, myOffset + firstPoint
, indexOffset + secondPoint, distance);
}
}
}
void addDistance(neighbor ***sortedNeighborsArray, int firstPointIndex, int firstPointId
, int secondPointId, double pointsDistance){
//Determines actual index in which the distance will be added
int insertIndex = secondPointId;
if (secondPointId > firstPointId){
--insertIndex;
}
(*sortedNeighborsArray)[firstPointIndex][insertIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointIndex][insertIndex].neighborId = secondPointId;
}
int compare (const void *a, const void *b){
//Casts arguments to pointers to neighbors
const neighbor *neighborA = (neighbor*) a;
const neighbor *neighborB = (neighbor*) b;
if (neighborA->distance == neighborB->distance){
return 0;
} else{
return neighborA->distance > neighborB->distance ? 1 : -1;
}
}
void swapPointers(double ***firstArray, double ***secondArray){
double **tempPtr = *firstArray;
*firstArray = *secondArray;
*secondArray = tempPtr;
}
int test(neighbor ***sortedNeighborsArray, int chunksize, int offset, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
char *discarded = NULL;
size_t n = 0;
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
if (offset){
for (int line=0; line<offset; ++line){
if (getline(&discarded, &n, testFile) == -1){
perror("Error reading test file");
return 1;
}
n = 0;
}
free(discarded);
}
for (int point=0; point<chunksize; ++point){
for (int i=0; i<k; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){ //-1 because f@ck matlab
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize){
free((*pointsArray)[0]);
free(*pointsArray);
free((*inBuffer)[0]);
free(*inBuffer);
free((*outBuffer)[0]);
free(*outBuffer);
for (int row=0; row<chunksize; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}
void abExit(int exitCode){
int initialized = 0;
MPI_Initialized(&initialized);
if (initialized){
MPI_Abort(MPI_COMM_WORLD, -1);
}
exit(0);
}

93
Blocking/timeOptimized/knnMPIBlockingDeclarations.h

@ -0,0 +1,93 @@
#ifndef KNNMPIBLOCKINGFUNCTIONDECLARATION_H_ /* Include guard */
#define KNNMPIBLOCKINGFUNCTIONDECLARATION_H_
/* Constants definitions */
#define MASTER 0 //task id of the master process
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors knn should find for each point
extern int k; //number of nearest neighbors requested by the user
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, double ***inBuffer //pointer to the array used as input buffer for mpi
, double ***outBuffer //pointer to the array used as output buffer for mpi
, neighbor ***sortedNeighborsArray //pointer to the array holding the distances and ID's
, int chunksize //number of rows (points) to be allocated
, int offset); //process offset used when reading points from the file
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array //array that will hold the coordinates of the points
, int chunksize //number of rows (points) to be read
, int offset); //offset from which reading will start
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray //array that holds the distances
, int chunksize //number of points
, int myOffset //offset used for ID's of first pool's points
, int indexOffset); //offset used for ID's of seconds pool's points
//Function addDistance adds distances to sorted neighbors array sorted by the ID of the neighbor
void addDistance(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointIndex //Index of the first point in task's array
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function compare compares two neighbors using their distance fields, returns 0 if distances are
//equal, 1 if distance of first argument is greater and -1 otherwise
int compare (const void *a //first neighbor
, const void *b); //second neighbor
//Function swapPointers swaps the memory blocks pointed to by two pointers
void swapPointers(double ***firstArray //first memory block
, double ***secondArray); //second memory block
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, int chunksize //number of points
, int offset //process offset
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, double ***inBuffer //input buffer pointer
, double ***outBuffer //output buffer pointer
, neighbor ***sortedNeighborsArray //distances array pointer
, int chunksize); //number of rows (points)
//Function abExit exits the program after checking for mpi initialization
void abExit(int exitCode); //exit code to exit with
#endif // KNNMPIBLOCKINGFUNCTIONDECLARATION_H_

21
NonBlocking/spaceOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnMPINonBlockingSpaceOptimized
CC=mpicc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnMPINonBlocking.o knnMPINonBlockingDeclarations.o
DEPS=knnMPINonBlockingDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

138
NonBlocking/spaceOptimized/knnMPINonBlocking.c

@ -0,0 +1,138 @@
#include <stdio.h>
#include <sys/time.h>
#include "knnMPINonBlockingDeclarations.h"
#include "mpi.h"
/* Structs */
struct timeval startwtime, endwtime
, calcStartWTime, calcEndWTime;
/* Global variables */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0;
char *pointsFilename = NULL, *testFilename = NULL;
double seq_time = 0;
/* Main */
int main(int argc, char **argv){
int numberOfTasks = 0, taskId = 0, chunksize = 0, myOffset = 0, destination = 0, source = 0;
double **myPoints, **inBuffer, **outBuffer, calcTimeSum = 0;
neighbor **sortedNeighborsArray;
MPI_Status statuses[2];
MPI_Request requests[2];
getArguments(argc, argv);
//Initializes mpi and necessary variables
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numberOfTasks);
if (numberOfPoints % numberOfTasks != 0){
printf("Quitting. Number of points must be divisible by number of MPI tasks.\n");
abExit(0);
}
MPI_Comm_rank(MPI_COMM_WORLD, &taskId);
chunksize = numberOfPoints / numberOfTasks; //number of points each task has
myOffset = taskId * chunksize; //this task's offset from (complete) point's array start
destination = taskId + 1; //this task's destination task id for sending messages
if (destination >= numberOfTasks){
destination = 0;
}
source= taskId - 1; //this task's source task id for receiving messages
if (source < 0){
source = numberOfTasks - 1;
}
init(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray
,chunksize, myOffset * numberOfDimensions);
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&startwtime, NULL);
}
for (int chunk=-1; chunk<numberOfTasks-1; ++chunk){
int lastLoop = (chunk == numberOfTasks-1-1) ? 1 : 0;
if (!lastLoop){ //last loop doesn't send nor receive
//sends-receives points array blocks
MPI_Isend((chunk == -1) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD
, &requests[BLOCK_SENT]);
MPI_Irecv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &requests[BLOCK_RECEIVED]);
}
//offset of the task that sent new points block from (complete) point's array start
//used for storing the correct neighbor id's in neighbors array
int offset = source - chunk;
if (offset < 0){
offset += numberOfTasks;
}
offset *= chunksize;
gettimeofday(&calcStartWTime, NULL);
if (chunk == -1){
//calculates distances between task's own points
calculateDistances(&myPoints, &myPoints, &sortedNeighborsArray
, chunksize, myOffset, taskId * chunksize);
} else {
//calculates distances between task's points and new points received
calculateDistances(&myPoints, &outBuffer, &sortedNeighborsArray
, chunksize, myOffset, offset);
}
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
if (!lastLoop){ //last loop doesn't send nor receive
//continues with next loop (and calculations) only after sending and receiving is done
MPI_Waitall(2, requests, statuses);
}
swapPointers(&inBuffer, &outBuffer);
}
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
}
if (test(&sortedNeighborsArray, chunksize, myOffset, testFilename)){
printf("Validity check failed for task %d!\n", taskId);
} else {
printf("Validity check success for task %d!\n", taskId);
}
if (taskId == MASTER){
printf("Number of points = %d\n", numberOfPoints);
printf("Number of dimensions = %d\n", numberOfDimensions);
printf("Number of neighbors = %d\n", numberOfNeighbors);
printf("Number of tasks = %d\n", numberOfTasks);
}
for(int i=0; i<numberOfTasks; ++i) {
MPI_Barrier(MPI_COMM_WORLD);
if (i == taskId) {
printf("Task %d calculations time sum = %f\n", taskId, calcTimeSum);
/*
Uncomment to print the results
*/
/*for (int x=0; x<chunksize; ++x){
for (int y=0; y<numberOfNeighbors; ++y){
printf("%d to %d = %f\n", x + taskId * chunksize
, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
}
}
cleanUp(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize);
MPI_Finalize();
}

256
NonBlocking/spaceOptimized/knnMPINonBlockingDeclarations.c

@ -0,0 +1,256 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "knnMPINonBlockingDeclarations.h"
#include "mpi.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tdf is the filename of the dataset file\n");
printf("\ttf is the filename of the dataset file\n");
abExit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = atoi(argv[3]);
if (numberOfNeighbors >= numberOfPoints) {
numberOfNeighbors = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize, int offset){
//Allocates memory for points array
*pointsArray = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points coming from another process
*inBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points going out to another process
*outBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * chunksize))) != NULL ){
for (int row = 0; row < chunksize; ++row){
if ( ( (*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL ){
printf("Error allocating memory\n");
abExit(1);
}
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray, chunksize, offset)){
abExit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<chunksize; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = -1;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double **array;
//allocates a continuous block of memory
double *tempArray = (double *)calloc(rows * columns, sizeof(double));
if (tempArray == NULL){
printf("Error allocating memory\n");
abExit(1);
}
//creates pointers to each row and column for easy indexing
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array, int chunksize, int offset){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
if (fseek(pointsBinaryFile, offset * sizeof(double), SEEK_SET)){
printf("Error reading the file. Quitting.\n");
abExit(0);
}
for (int point=0; point<chunksize; ++point){
if ( fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions ){
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray, int chunksize, int myOffset, int indexOffset){
for (int firstPoint=0; firstPoint<chunksize; ++firstPoint){
for (int secondPoint=0; secondPoint<chunksize; ++secondPoint){
if (myOffset + firstPoint == indexOffset + secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
double tmpDiff = (*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex];
distance += tmpDiff * tmpDiff;
}
addDistanceAndShift(sortedNeighborsArray, firstPoint, indexOffset + secondPoint
, distance);
}
}
}
void addDistanceAndShift(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId
, double pointsDistance){
for (int arrayIndex=0; arrayIndex<numberOfNeighbors; ++arrayIndex){
//Gets distance stored in the array for this index
double thisNeighborDistance = (*sortedNeighborsArray)[firstPointId][arrayIndex].distance;
if (thisNeighborDistance == -1){ //Loop reached the end of the array
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
} else if (thisNeighborDistance > pointsDistance){
//Distance at the this index is greater than the distance being inserted
//Shifts right all non empty columns holding distances lower than pointsDistance
for (int moveColumn=numberOfNeighbors-2; moveColumn>=arrayIndex; --moveColumn){
double tempDistance = (*sortedNeighborsArray)[firstPointId][moveColumn].distance;
if (tempDistance == -1){ //Skips empty columns
continue;
}
(*sortedNeighborsArray)[firstPointId][moveColumn+1].distance = tempDistance;
(*sortedNeighborsArray)[firstPointId][moveColumn+1].neighborId
= (*sortedNeighborsArray)[firstPointId][moveColumn].neighborId;
}
/*
Forward iteration is slower than reverse!
*/
/*for (int moveColumn=arrayIndex; moveColumn<numberOfNeighbors-1; ++moveColumn){
double tempDistance = (*sortedNeighborsArray)[firstPointId][moveColumn].distance;
if (tempDistance == -1){ //Skips empty columns
break;
}
(*sortedNeighborsArray)[firstPointId][moveColumn+1].distance = tempDistance;
(*sortedNeighborsArray)[firstPointId][moveColumn+1].neighborId
= (*sortedNeighborsArray)[firstPointId][moveColumn].neighborId;
}*/
//Inserts pointsDistance in the space created after shifting
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
}
}
}
void swapPointers(double ***firstArray, double ***secondArray){
double **tempPtr = *firstArray;
*firstArray = *secondArray;
*secondArray = tempPtr;
}
int test(neighbor ***sortedNeighborsArray, int chunksize, int offset, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
char *discarded = NULL;
size_t n = 0;
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
if (offset){
for (int line=0; line<offset; ++line){
if (getline(&discarded, &n, testFile) == -1){
perror("Error reading test file");
return 1;
}
n = 0;
}
free(discarded);
}
for (int point=0; point<chunksize; ++point){
for (int i=0; i<numberOfNeighbors; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){ //-1 because f@ck matlab
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize){
free((*pointsArray)[0]);
free(*pointsArray);
free((*inBuffer)[0]);
free(*inBuffer);
free((*outBuffer)[0]);
free(*outBuffer);
for (int row=0; row<chunksize; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}
void abExit(int exitCode){
int initialized = 0;
MPI_Initialized(&initialized);
if (initialized){
MPI_Abort(MPI_COMM_WORLD, -1);
}
exit(0);
}

91
NonBlocking/spaceOptimized/knnMPINonBlockingDeclarations.h

@ -0,0 +1,91 @@
#ifndef KNNMPINONBLOCKINGFUNCTIONDECLARATIONS_H_ /* Include guard */
#define KNNMPINONBLOCKINGFUNCTIONDECLARATIONS_H_
/* Constants definitions */
#define MASTER 0 //task id of the master process
#define BLOCK_SENT 0 //index of request used for sending blocks in the requests array
#define BLOCK_RECEIVED 1 //index of request used for receiving blocks in the requests array
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors knn should find for each point
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, double ***inBuffer //pointer to the array used as input buffer for mpi
, double ***outBuffer //pointer to the array used as output buffer for mpi
, neighbor ***sortedNeighborsArray //pointer to the array holding the distances and ID's
, int chunksize //number of rows (points) to be allocated
, int offset); //process offset used when reading points from the file
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array //array that will hold the coordinates of the points
, int chunksize //number of rows (points) to be read
, int offset); //offset from which reading will start
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray //array that holds the distances
, int chunksize //number of points
, int myOffset //offset used for ID's of first pool's points
, int indexOffset); //offset used for ID's of seconds pool's points
//Function addDistanceAndShift searches an array of neighbors (struct) for an index holding either
//an empty distance or a distance that is greater than the one that came in the arguments
//(pointsDistance), shifts "right" one time all values of the array after this index and fills the
//empty position created after shifting with the one that came in the arguments (pointsDistance)
void addDistanceAndShift(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function swapPointers swaps the memory blocks pointed to by two pointers
void swapPointers(double ***firstArray //first memory block
, double ***secondArray); //second memory block
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, int chunksize //number of points
, int offset //process offset
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, double ***inBuffer //input buffer pointer
, double ***outBuffer //output buffer pointer
, neighbor ***sortedNeighborsArray //distances array pointer
, int chunksize); //number of rows (points)
//Function abExit exits the program after checking for mpi initialization
void abExit(int exitCode); //exit code to exit with
#endif // KNNMPINONBLOCKINGFUNCTIONDECLARATIONS_H_

BIN
NonBlocking/timeOptimized/KnnMPINonBlockingTimeOptimized

Binary file not shown.

21
NonBlocking/timeOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnMPINonBlockingTimeOptimized
CC=mpicc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnMPINonBlocking.o knnMPINonBlockingDeclarations.o
DEPS=knnMPINonBlockingDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

149
NonBlocking/timeOptimized/knnMPINonBlocking.c

@ -0,0 +1,149 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "knnMPINonBlockingDeclarations.h"
#include "mpi.h"
/* Structs */
struct timeval startwtime, endwtime
, calcStartWTime, calcEndWTime;
/* Global variables */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0, k = 0;
char *pointsFilename = NULL, *testFilename = NULL;
double seq_time = 0;
/* Main */
int main(int argc, char **argv){
int numberOfTasks = 0, taskId = 0, chunksize = 0, myOffset = 0, destination = 0, source = 0;
double **myPoints, **inBuffer, **outBuffer, calcTimeSum = 0;
neighbor **sortedNeighborsArray;
MPI_Status statuses[2];
MPI_Request requests[2];
getArguments(argc, argv);
//Initializes mpi and necessary variables
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numberOfTasks);
if (numberOfPoints % numberOfTasks != 0){
printf("Quitting. Number of points must be divisible by number of MPI tasks.\n");
abExit(0);
}
MPI_Comm_rank(MPI_COMM_WORLD, &taskId);
chunksize = numberOfPoints / numberOfTasks; //number of points each task has
myOffset = taskId * chunksize; //this task's offset from (complete) point's array start
destination = taskId + 1; //this task's destination task id for sending messages
if (destination >= numberOfTasks){
destination = 0;
}
source= taskId - 1; //this task's source task id for receiving messages
if (source < 0){
source = numberOfTasks - 1;
}
init(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray
,chunksize, myOffset * numberOfDimensions);
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&startwtime, NULL);
}
for (int chunk=-1; chunk<numberOfTasks-1; ++chunk){
int lastLoop = (chunk == numberOfTasks-1-1) ? 1 : 0;
if (!lastLoop){ //last loop doesn't send nor receive
//sends-receives points array blocks
MPI_Isend((chunk == -1) //if this is the first loop
? &(myPoints[0][0]) //send this task's points
: &(outBuffer[0][0]) //else send the points received from previous loop
, chunksize * numberOfDimensions, MPI_DOUBLE, destination, taskId, MPI_COMM_WORLD
, &requests[BLOCK_SENT]);
MPI_Irecv(&(inBuffer[0][0]), chunksize * numberOfDimensions, MPI_DOUBLE, source, source
, MPI_COMM_WORLD, &requests[BLOCK_RECEIVED]);
}
//offset of the task that sent new points block from (complete) point's array start
//used for storing the correct neighbor id's in neighbors array
int offset = source - chunk;
if (offset < 0){
offset += numberOfTasks;
}
offset *= chunksize;
gettimeofday(&calcStartWTime, NULL);
if (chunk == -1){
//calculates distances between task's own points
calculateDistances(&myPoints, &myPoints, &sortedNeighborsArray
, chunksize, myOffset, taskId * chunksize);
} else {
//calculates distances between task's points and new points received
calculateDistances(&myPoints, &outBuffer, &sortedNeighborsArray
, chunksize, myOffset, offset);
}
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
if (!lastLoop){ //last loop doesn't send nor receive
//continues with next loop (and calculations) only after sending and receiving is done
MPI_Waitall(2, requests, statuses);
}
swapPointers(&inBuffer, &outBuffer);
}
gettimeofday(&calcStartWTime, NULL);
for (int point=0; point<chunksize; ++point){
qsort (sortedNeighborsArray[point], numberOfNeighbors, sizeof(neighbor), compare);
}
gettimeofday(&calcEndWTime, NULL);
calcTimeSum += (double)((calcEndWTime.tv_usec - calcStartWTime.tv_usec)/1.0e6
+ calcEndWTime.tv_sec - calcStartWTime.tv_sec);
MPI_Barrier(MPI_COMM_WORLD);
if (taskId == MASTER){
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
}
if (test(&sortedNeighborsArray, chunksize, myOffset, testFilename)){
printf("Validity check failed for task %d!\n", taskId);
} else {
printf("Validity check success for task %d!\n", taskId);
}
if (taskId == MASTER){
printf("Number of points = %d\n", numberOfPoints);
printf("Number of dimensions = %d\n", numberOfDimensions);
printf("Number of neighbors = %d\n", numberOfNeighbors);
printf("Number of tasks = %d\n", numberOfTasks);
}
for(int i=0; i<numberOfTasks; ++i) {
MPI_Barrier(MPI_COMM_WORLD);
if (i == taskId) {
printf("Task %d calculations time sum = %f\n", taskId, calcTimeSum);
/*
Uncomment to print the results
*/
/*for (int x=0; x<chunksize; ++x){
for (int y=0; y<k; ++y){
printf("%d to %d = %f\n", x + taskId * chunksize
, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
}
}
cleanUp(&myPoints, &inBuffer, &outBuffer, &sortedNeighborsArray, chunksize);
MPI_Finalize();
}

BIN
NonBlocking/timeOptimized/knnMPINonBlocking.o

Binary file not shown.

237
NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.c

@ -0,0 +1,237 @@
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include "knnMPINonBlockingDeclarations.h"
#include "mpi.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tdf is the filename of the dataset file\n");
printf("\ttf is the filename of the dataset file\n");
abExit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = numberOfPoints - 1;
k = atoi(argv[3]);
if (k >= numberOfPoints){
k = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize, int offset){
//Allocates memory for points array
*pointsArray = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points coming from another process
*inBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for the buffer storing points going out to another process
*outBuffer = cMalloc(chunksize, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * chunksize))) != NULL ){
for (int row = 0; row < chunksize; ++row){
if ( ( (*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL ){
printf("Error allocating memory\n");
abExit(1);
}
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray, chunksize, offset)){
abExit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<chunksize; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = DBL_MAX;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double **array;
//allocates a continuous block of memory
double *tempArray = (double *)calloc(rows * columns, sizeof(double));
if (tempArray == NULL){
printf("Error allocating memory\n");
abExit(1);
}
//creates pointers to each row and column for easy indexing
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
abExit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array, int chunksize, int offset){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
if (fseek(pointsBinaryFile, offset * sizeof(double), SEEK_SET)){
printf("Error reading the file. Quitting.\n");
abExit(0);
}
for (int point=0; point<chunksize; ++point){
if ( fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions ){
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray, int chunksize, int myOffset, int indexOffset){
for (int firstPoint=0; firstPoint<chunksize; ++firstPoint){
for (int secondPoint=0; secondPoint<chunksize; ++secondPoint){
if (myOffset + firstPoint == indexOffset + secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
double tmpDiff = (*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex];
distance += tmpDiff * tmpDiff;
}
addDistance(sortedNeighborsArray, firstPoint, myOffset + firstPoint
, indexOffset + secondPoint, distance);
}
}
}
void addDistance(neighbor ***sortedNeighborsArray, int firstPointIndex, int firstPointId
, int secondPointId, double pointsDistance){
//Determines actual index in which the distance will be added
int insertIndex = secondPointId;
if (secondPointId > firstPointId){
--insertIndex;
}
(*sortedNeighborsArray)[firstPointIndex][insertIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointIndex][insertIndex].neighborId = secondPointId;
}
int compare (const void *a, const void *b){
//Casts arguments to pointers to neighbors
const neighbor *neighborA = (neighbor*) a;
const neighbor *neighborB = (neighbor*) b;
if (neighborA->distance == neighborB->distance){
return 0;
} else{
return neighborA->distance > neighborB->distance ? 1 : -1;
}
}
void swapPointers(double ***firstArray, double ***secondArray){
double **tempPtr = *firstArray;
*firstArray = *secondArray;
*secondArray = tempPtr;
}
int test(neighbor ***sortedNeighborsArray, int chunksize, int offset, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
char *discarded = NULL;
size_t n = 0;
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
if (offset){
for (int line=0; line<offset; ++line){
if (getline(&discarded, &n, testFile) == -1){
perror("Error reading test file");
return 1;
}
n = 0;
}
free(discarded);
}
for (int point=0; point<chunksize; ++point){
for (int i=0; i<k; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){ //-1 because f@ck matlab
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, double ***inBuffer, double ***outBuffer
, neighbor ***sortedNeighborsArray, int chunksize){
free((*pointsArray)[0]);
free(*pointsArray);
free((*inBuffer)[0]);
free(*inBuffer);
free((*outBuffer)[0]);
free(*outBuffer);
for (int row=0; row<chunksize; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}
void abExit(int exitCode){
int initialized = 0;
MPI_Initialized(&initialized);
if (initialized){
MPI_Abort(MPI_COMM_WORLD, -1);
}
exit(0);
}

95
NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.h

@ -0,0 +1,95 @@
#ifndef KNNMPINONBLOCKINGFUNCTIONDECLARATION_H_ /* Include guard */
#define KNNMPINONBLOCKINGFUNCTIONDECLARATION_H_
/* Constants definitions */
#define MASTER 0 //task id of the master process
#define BLOCK_SENT 0 //index of request used for sending blocks in the requests array
#define BLOCK_RECEIVED 1 //index of request used for receiving blocks in the requests array
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors that should be found for each point
extern int k; //number of nearest neighbors requested by the user
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, double ***inBuffer //pointer to the array used as input buffer for mpi
, double ***outBuffer //pointer to the array used as output buffer for mpi
, neighbor ***sortedNeighborsArray //pointer to the array holding the distances and ID's
, int chunksize //number of rows (points) to be allocated
, int offset); //process offset used when reading points from the file
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array //array that will hold the coordinates of the points
, int chunksize //number of rows (points) to be read
, int offset); //offset from which reading will start
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray //array that holds the distances
, int chunksize //number of points
, int myOffset //offset used for ID's of first pool's points
, int indexOffset); //offset used for ID's of seconds pool's points
//Function addDistance adds distances to sorted neighbors array sorted by the ID of the neighbor
void addDistance(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointIndex //Index of the first point in task's array
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function compare compares two neighbors using their distance fields, returns 0 if distances are
//equal, 1 if distance of first argument is greater and -1 otherwise
int compare (const void *a //first neighbor
, const void *b); //second neighbor
//Function swapPointers swaps the memory blocks pointed to by two pointers
void swapPointers(double ***firstArray //first memory block
, double ***secondArray); //second memory block
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, int chunksize //number of points
, int offset //process offset
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, double ***inBuffer //input buffer pointer
, double ***outBuffer //output buffer pointer
, neighbor ***sortedNeighborsArray //distanced array pointer
, int chunksize); //number of rows (points)
//Function abExit exits the program after checking for mpi initialization
void abExit(int exitCode); //exit code to exit with
#endif // KNNMPINONBLOCKINGFUNCTIONDECLARATION_H_

BIN
NonBlocking/timeOptimized/knnMPINonBlockingDeclarations.o

Binary file not shown.

22
README.md

@ -0,0 +1,22 @@
Project includes 6 versions of a knn algorithm implementation:
Serial - space optimized
Serial - time optimized
MPI parallel - blocking communications - space optimized
MPI parallel - blocking communications - time optimized
MPI parallel - non blocking communications - space optimized
MPI parallel - non blocking communications - time optimized
Project folder also includes some test files and execution results (stats folder).
In folder testFiles there is a dataset of 60000 points of 30 dimensions each, as
well as three IDX files extracted from Matlab storing correctly sorted IDs.
These files are named according to the convention: numberOfPoints_k
after the number of points and selected k that were used to run the Matlab
script.
To run any version first run make. Then copy testFiles/data.bin and one of the
IDX test files into the folder. Finally run with:
mpiexec -np numTasks ./prog.out numPoints numDimensions k data.bin idxFileName
To extract a new IDX file from Matlab run knn with the dataset and then extract
IDX variable to an ods/excel. Open the generated file and save as csv.

21
Serial/spaceOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnSerialSpaceOptimized
CC=gcc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnSerial.o knnSerialDeclarations.o
DEPS=knnSerialDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

48
Serial/spaceOptimized/knnSerial.c

@ -0,0 +1,48 @@
#include <stdio.h>
#include <sys/time.h>
#include "knnSerialDeclarations.h"
/* Structs */
struct timeval startwtime, endwtime;
double seq_time;
/* Global variable */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0, direction = 0;
char *pointsFilename, *testFilename;
/* Main */
int main(int argc, char **argv){
double **pointsArray;
neighbor **sortedNeighborsArray;
getArguments(argc, argv);
init(&pointsArray, &sortedNeighborsArray);
gettimeofday(&startwtime, NULL);
calculateDistances(&pointsArray, &pointsArray, &sortedNeighborsArray);
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
if (test(&sortedNeighborsArray, testFilename)){
printf("Validity check failed!\n");
} else {
printf("Validity check success!\n");
}
/*
Uncomment to print the results
*/
/*for (int x=0; x<numberOfPoints; ++x){
for (int y=0; y<numberOfNeighbors; ++y){
printf("%d to %d = %f\n", x, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
cleanUp(&pointsArray, &sortedNeighborsArray);
}

192
Serial/spaceOptimized/knnSerialDeclarations.c

@ -0,0 +1,192 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "knnSerialDeclarations.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename tfilename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tfilename is the filename of the dataset file\n");
printf("\tfilename is the filename of the test file\n");
exit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = atoi(argv[3]);
if (numberOfNeighbors >= numberOfPoints) {
numberOfNeighbors = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, neighbor ***sortedNeighborsArray){
//Allocates continuous memory for points array
*pointsArray = cMalloc(numberOfPoints, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * numberOfPoints)) )
!= NULL){
for (int row = 0; row < numberOfPoints; ++row){
if ( ((*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL){
printf("Error allocating memory\n");
exit(1);
}
}
} else {
printf("Error allocating memory\n");
exit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray)){
printf("Press any key to exit.\n");
getchar();
exit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<numberOfPoints; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = -1;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double *tempArray = (double *)malloc(rows * columns * sizeof(double));
double **array;
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
exit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
for (int point=0; point<numberOfPoints; ++point){
if (fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions) {
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray){
for (int firstPoint=0; firstPoint<numberOfPoints; ++firstPoint){
for (int secondPoint=0; secondPoint<numberOfPoints; ++secondPoint){
if (firstPoint == secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
distance += pow((*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex] ,2);
}
addDistanceAndShift(sortedNeighborsArray, firstPoint, secondPoint, distance);
}
}
}
void addDistanceAndShift(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId
, double pointsDistance){
for (int arrayIndex=0; arrayIndex<numberOfNeighbors; ++arrayIndex){
//Gets distance stored in the array for this index
double thisNeighborDistance = (*sortedNeighborsArray)[firstPointId][arrayIndex].distance;
if (thisNeighborDistance == -1){ //Loop reached the end of the array
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
} else if (thisNeighborDistance > pointsDistance){
//Shifts right all non empty columns holding distances lower than pointsDistance
for (int moveColumn=numberOfNeighbors-2; moveColumn>=arrayIndex; --moveColumn){
double tempDistance = (*sortedNeighborsArray)[firstPointId][moveColumn].distance;
if (tempDistance == -1){ //Skips empty columns
continue;
}
(*sortedNeighborsArray)[firstPointId][moveColumn+1].distance = tempDistance;
(*sortedNeighborsArray)[firstPointId][moveColumn+1].neighborId
= (*sortedNeighborsArray)[firstPointId][moveColumn].neighborId;
}
//Inserts pointsDistance in the space created after shifting
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
}
}
}
int test(neighbor ***sortedNeighborsArray, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
for (int point=0; point<numberOfPoints; ++point){
for (int i=0; i<numberOfNeighbors; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, neighbor ***sortedNeighborsArray){
free((*pointsArray)[0]);
free(*pointsArray);
for (int row=0; row<numberOfPoints; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}

65
Serial/spaceOptimized/knnSerialDeclarations.h

@ -0,0 +1,65 @@
#ifndef KNNSERIALDECLARATIONS_H_ /* Include guard */
#define KNNSERIALDECLARATIONS_H_
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors knn should find for each point
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, neighbor ***sortedNeighborsArray); //pointer to the array holding the distances and ID's
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array); //array that will hold the coordinates of the points
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray); //array that holds the distances
//Function addDistanceAndShift searches an array of neighbors (struct) for an index holding either
//an empty distance or a distance that is greater than the one that came in the arguments
//(pointsDistance), shifts "right" one time all values of the array after this index and fills the
//empty position created after shifting with the one that came in the arguments (pointsDistance)
void addDistanceAndShift(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, neighbor ***sortedNeighborsArray); //distances array pointer
#endif // KNNMPINONBLOCKINGFUNCTIONDECLARATIONS_H_

21
Serial/timeOptimized/Makefile

@ -0,0 +1,21 @@
TARGET=KnnSerialTimeOptimized
CC=gcc
CFLAGS=-Wall -O3 -std=gnu99 -I.
OBJ=knnSerial.o knnSerialDeclarations.o
DEPS=knnSerialDeclarations.h
.PHONY: default all clean
default: $(TARGET)
all: default
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
.PRECIOUS: $(TARGET) $(OBJ)
$(TARGET): $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
clean:
$(RM) *.o *~

53
Serial/timeOptimized/knnSerial.c

@ -0,0 +1,53 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "knnSerialDeclarations.h"
/* Structs */
struct timeval startwtime, endwtime;
double seq_time;
/* Global variable */
int numberOfPoints = 0, numberOfDimensions = 0, numberOfNeighbors = 0, direction = 0, k = 0;
char *pointsFilename, *testFilename;
/* Main */
int main(int argc, char **argv){
double **pointsArray;
neighbor **sortedNeighborsArray;
getArguments(argc, argv);
init(&pointsArray, &sortedNeighborsArray);
gettimeofday(&startwtime, NULL);
calculateDistances(&pointsArray, &pointsArray, &sortedNeighborsArray);
for (int point=0; point<numberOfPoints; ++point){
qsort (sortedNeighborsArray[point], numberOfNeighbors, sizeof(neighbor), compare);
}
gettimeofday(&endwtime, NULL);
seq_time = (double)((endwtime.tv_usec - startwtime.tv_usec)/1.0e6
+ endwtime.tv_sec - startwtime.tv_sec);
printf("Wall clock time = %f\n\n", seq_time);
if (test(&sortedNeighborsArray, testFilename)){
printf("Validity check failed!\n");
} else {
printf("Validity check success!\n");
}
/*
Uncomment to print the results
*/
/*for (int x=0; x<numberOfPoints; ++x){
for (int y=0; y<k; ++y){
printf("%d to %d = %f\n", x, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}*/
cleanUp(&pointsArray, &sortedNeighborsArray);
}

188
Serial/timeOptimized/knnSerialDeclarations.c

@ -0,0 +1,188 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "knnSerialDeclarations.h"
void getArguments(int argc, char** argv){
if (argc != 6) {
printf("Usage: %s p d k filename tfilename\nwhere:\n", argv[0]);
printf("\tp is the the number of points\n");
printf("\td is the number of dimensions of each point\n");
printf("\tk is the number of neighbors to search for\n");
printf("\tfilename is the filename of the dataset file\n");
printf("\tfilename is the filename of the test file\n");
exit(1);
}
numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = numberOfPoints - 1;
k = atoi(argv[3]);
if (k >= numberOfPoints){
k = numberOfPoints - 1;
}
pointsFilename = argv[4];
testFilename = argv[5];
}
void init(double ***pointsArray, neighbor ***sortedNeighborsArray){
//Allocates continuous memory for points array
*pointsArray = cMalloc(numberOfPoints, numberOfDimensions);
//Allocates memory for neighbors array
if ( (*sortedNeighborsArray = (neighbor**)(malloc((sizeof(neighbor *)) * numberOfPoints)) )
!= NULL){
for (int row = 0; row < numberOfPoints; ++row){
if ( ((*sortedNeighborsArray)[row]
= (neighbor*)(malloc((sizeof(neighbor)) * numberOfNeighbors)) ) == NULL){
printf("Error allocating memory\n");
exit(1);
}
}
} else {
printf("Error allocating memory\n");
exit(1);
}
//Reads coordinates from the file
if (readPointsArrayFromFile(pointsArray)){
printf("Press any key to exit.\n");
getchar();
exit(1);
}
//Initializes neighbors array distances and ID's to -1
for (int point=0; point<numberOfPoints; ++point){
for(int neighbor=0; neighbor<numberOfNeighbors; ++neighbor){
(*sortedNeighborsArray)[point][neighbor].distance = -1;
(*sortedNeighborsArray)[point][neighbor].neighborId = -1;
}
}
}
double **cMalloc(int rows, int columns){
double *tempArray = (double *)malloc(rows * columns * sizeof(double));
double **array;
if ((array = ((double**)(malloc((sizeof(double *)) * rows)))) != NULL){
for (int row = 0; row < rows; ++row){
array[row] = &(tempArray[columns * row]);
}
} else {
printf("Error allocating memory\n");
exit(1);
}
return array;
}
int readPointsArrayFromFile(double ***array){
FILE *pointsBinaryFile = fopen(pointsFilename, "rb");
if (pointsBinaryFile == NULL){
printf("Couldn't open points file.\n");
return 1;
}
for (int point=0; point<numberOfPoints; ++point){
if (fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile)
!= numberOfDimensions) {
if(feof(pointsBinaryFile)){
printf("Premature end of file reached.\n");
} else{
printf("Error reading points file.");
}
fclose(pointsBinaryFile);
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void calculateDistances(double ***firstPointsSet, double ***secondPointsSet
, neighbor ***sortedNeighborsArray){
for (int firstPoint=0; firstPoint<numberOfPoints; ++firstPoint){
for (int secondPoint=0; secondPoint<numberOfPoints; ++secondPoint){
if (firstPoint == secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
distance += pow((*firstPointsSet)[firstPoint][dimensionIndex]
- (*secondPointsSet)[secondPoint][dimensionIndex] ,2);
}
addDistance(sortedNeighborsArray, firstPoint, secondPoint, distance);
}
}
}
void addDistance(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId
, double pointsDistance){
//Determines actual index in which the distance will be added
int insertIndex = secondPointId;
if (secondPointId > firstPointId){
--insertIndex;
}
(*sortedNeighborsArray)[firstPointId][insertIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][insertIndex].neighborId = secondPointId;
}
int compare (const void *a, const void *b){
//Casts arguments to pointers to neighbors
const neighbor *neighborA = (neighbor*) a;
const neighbor *neighborB = (neighbor*) b;
if (neighborA->distance == neighborB->distance){
return 0;
} else{
return neighborA->distance > neighborB->distance ? 1 : -1;
}
}
int test(neighbor ***sortedNeighborsArray, char *testFilename){
FILE *testFile = fopen(testFilename, "r");
if (testFile == NULL){
printf("Couldn't open test file.\n");
perror("fopen");
return 1;
}
for (int point=0; point<numberOfPoints; ++point){
for (int i=0; i<k; ++i){
int tempID = 0;
if (fscanf(testFile, "%d,", &tempID) == EOF){
printf("Premature end of file reached.\n");
fclose(testFile);
return 1;
}
if ((*sortedNeighborsArray)[point][i].neighborId != tempID - 1){
fclose(testFile);
return 1;
}
}
}
fclose(testFile);
return 0;
}
void cleanUp(double ***pointsArray, neighbor ***sortedNeighborsArray){
free((*pointsArray)[0]);
free(*pointsArray);
for (int row=0; row<numberOfPoints; ++row){
free((*sortedNeighborsArray)[row]);
}
free(*sortedNeighborsArray);
}

68
Serial/timeOptimized/knnSerialDeclarations.h

@ -0,0 +1,68 @@
#ifndef KNNSERIALDECLARATIONS_H_ /* Include guard */
#define KNNSERIALDECLARATIONS_H_
/* Structs */
typedef struct neighbor{ //simple struct defining a point's neighbor
double distance; //distance between the two neighbors (points)
int neighborId; //index of the neighbor in the (complete) array of points
} neighbor;
/* Global variables */
extern int numberOfPoints; //number of the points knn should run for
extern int numberOfDimensions; //number of dimensions of each point
extern int numberOfNeighbors; //number of nearest neighbors knn should find for each point
extern int k; //number of nearest neighbors requested by the user
extern char *pointsFilename; //name of the binary file storing the coordinates of points
extern char *testFilename; //name of binary file storing correct neighbors IDs array
/* Functions declaration */
//Function getArguments is used to parse arguments provided to main
void getArguments(int argc //arguments count
, char** argv); //arguments array
//Function init allocates memory for the arrays used and initializes them
void init(double ***pointsArray //pointer to the array of points
, neighbor ***sortedNeighborsArray); //pointer to the array holding the distances and ID's
//Function cMalloc allocates and returns a single block of continuous memory which can
//be indexed like a regular array, e.g. array[row][column]
double **cMalloc(int rows //number of rows to be allocated
, int columns); //number of columns to be allocated
//Function readPointsArrayFromFile reads the coordinates of the points from a file and stores them
//in an array
int readPointsArrayFromFile(double ***array); //array that will hold the coordinates of the points
//Function printArray iterates the values of an array printing them
void printArray(int rows //number of array's rows
, int columns //number of array's columns
, double ***array); //array to be printed
//Function calculateDistances calculates the distances between all points in two different sets and
//adds the distance to sortedNeighborsArray
void calculateDistances(double ***firstPointsSet //first pool of points coordinates
, double ***secondPointsSet //second pool of points coordinates
, neighbor ***sortedNeighborsArray); //array that holds the distances
//Function addDistance adds distances to sorted neighbors array, sorted by the ID of the neighbor
void addDistance(neighbor ***sortedNeighborsArray //array that holds the distances
, int firstPointId //ID of the first point
, int secondPointId //ID of the second point
, double pointsDistance); //distance between the two points
//Function compare compares two neighbors using their distance fields, returns 0 if distances are
//equal, 1 if distance of first argument is greater and -1 otherwise
int compare (const void *a //first neighbor
, const void *b); //second neighbor
//Function test checks the validity of the solution based on correct results previously generated
//and stored in a text file
int test(neighbor ***sortedNeighborsArray //array that holds the IDs
, char *testFilename); //name of text file storing correct neighbors IDs array
//Function cleanUp frees all memory previously allocated
void cleanUp(double ***pointsArray //points array pointer
, neighbor ***sortedNeighborsArray); //distances array pointer
#endif // KNNMPINONBLOCKINGFUNCTIONDECLARATIONS_H_

85
dev/bin_to_txt.c

@ -0,0 +1,85 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void writeTotxt(int rows, int columns, double array[rows][columns], char *filename,
int commaSeperated, int tabSeperated);
int main(int argc, char const *argv[]){
double **pointsArray;
char binaryFilename[200], textFilename[200];
int commaSeperated = 0, tabSeperated = 0;
int seperationMethod, numberOfRows, numberOfColumns;
printf("Seperate values with:\n\t[0] Space (default)\n\t[1] Comma\n\t[2] Tab\nInput = ");
scanf("%d", &seperationMethod);
switch(seperationMethod){
case 1 :
commaSeperated = 1;
break;
case 2 :
tabSeperated = 1;
break;
}
printf("\nArray rows = ");
scanf("%d", &numberOfRows);
printf("\nArray columns = ");
scanf("%d", &numberOfColumns);
pointsArray = (double **)(malloc(numberOfRows * sizeof(double *)));
for (int i = 0; i < numberOfRows; ++i){
pointsArray[i] = (double *)(malloc(numberOfColumns * sizeof(double)));
}
printf("\nBinary filename = ");
scanf("%s", binaryFilename);
printf("\nText filename = ");
scanf("%s", textFilename);
FILE *pointsBinaryFile;
pointsBinaryFile = fopen(binaryFilename,"rb");
if(fread(&pointsArray, sizeof(double), numberOfRows * numberOfColumns,
pointsBinaryFile) != numberOfRows * numberOfColumns) {
if(feof(pointsBinaryFile))
printf("There were usefull info after the end of file.\n");
else
printf("File read error.\n");
return 1;
}
fclose(pointsBinaryFile);
for (int i = 0; i < numberOfRows; ++i){
for (int j = 0; j < numberOfColumns; ++j){
printf("%f\n", pointsArray[i][j]);
}
}
FILE *file = fopen(textFilename, "w");
if (file == NULL){
printf("Error opening file!\n");
exit(1);
}
for (int i = 0; i < numberOfRows; ++i){
for (int j = 0; j < numberOfColumns; ++j){
fprintf(file, "%f", pointsArray[i][j]);
if (j != numberOfColumns - 1){
if (commaSeperated){
fprintf(file, ", ");
} else if (tabSeperated){
fprintf(file, "\t");
} else {
fprintf(file, " ");
}
}
}
fprintf(file, "\n");
}
fclose(file);
printf("Done! Press any key to exit.\n");
getchar();
}

40
dev/generate_set.c

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_OF_ROWS 3
#define NUMBER_OF_COLUMNS 2
int main(int argc, char const *argv[]){
double pointsArray[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int row, column;
/*for (row=0; row<NUMBER_OF_ROWS; ++row){
for (column=0; column<NUMBER_OF_COLUMNS; ++column){
pointsArray[row][column] = rand() * 12.8;
printf("pointsArray[%d][%d] = %f\n", row, column, pointsArray[row][column]);
}
}*/
pointsArray[0][0] = 0.0;
pointsArray[0][1] = 1.0;
pointsArray[1][0] = 0.0;
pointsArray[1][1] = 2.0;
pointsArray[2][0] = 0.0;
pointsArray[2][1] = 3.0;
for (row=0; row<NUMBER_OF_ROWS; ++row){
for (column=0; column<NUMBER_OF_COLUMNS; ++column){
printf("pointsArray[%d][%d] = %f\n", row, column, pointsArray[row][column]);
}
}
FILE *pointsBinaryFile;
pointsBinaryFile = fopen("points.bin","wb");
fwrite(pointsArray, sizeof(double), NUMBER_OF_ROWS * NUMBER_OF_COLUMNS, pointsBinaryFile);
fclose(pointsBinaryFile);
printf("Done!");
scanf("%d", &row);
}

198
dev/knnSerial (copy).c

@ -0,0 +1,198 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DEBUG 0
typedef struct neighbor{
double distance;
int neighborId;
} neighbor;
void getArgs(int argc, char** argv);
void init(double ***pointsArray, neighbor ***sortedNeighborsArray);
int readPointsArrayFromFile(double ***array);
void printArray(int rows, int columns, double ***array);
void addDistanceAndShift(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId, double pointsDistance);
void cleanUp(double ***pointsArray, neighbor ***sortedNeighborsArray);
int numberOfPoints, numberOfDimensions, numberOfNeighbors;
int main(int argc, char **argv){
double **pointsArray;
neighbor **sortedNeighborsArray;
getArgs(argc, argv);
init(&pointsArray, &sortedNeighborsArray);
//printArray(numberOfPoints, numberOfDimensions, &pointsArray);
//printf("HERE\n");
for (int firstPoint=0; firstPoint<numberOfPoints; ++firstPoint){
for (int secondPoint=0; secondPoint<numberOfPoints; ++secondPoint){
if (firstPoint == secondPoint){
continue;
}
double distance = 0;
for (int dimensionIndex=0; dimensionIndex<numberOfDimensions; ++dimensionIndex){
double diff = pointsArray[firstPoint][dimensionIndex] - pointsArray[secondPoint][dimensionIndex];
distance += pow(diff ,2);
}
addDistanceAndShift(&sortedNeighborsArray, firstPoint, secondPoint, distance);
}
}
printf("HERE\n");
for (int x=0; x<numberOfPoints; ++x){
for (int y=0; y<numberOfNeighbors; ++y){
printf("%d to %d = %f\n", x, sortedNeighborsArray[x][y].neighborId, sortedNeighborsArray[x][y].distance);
}
printf("\n");
}
cleanUp(&pointsArray, &sortedNeighborsArray);
printf("Done! Press any key to exit.\n");
getchar();
}
void getArgs(int argc, char** argv){
/*if (argc != 4) {
printf("Usage: %s p d k\nwhere:\n\tp is the the number of points\n\td is the number of dimensions of each point\n",
argv[0]);
printf("\tk is the number of neighbors to search for\n");
exit(1);
}*/
/*numberOfPoints = atoi(argv[1]);
numberOfDimensions = atoi(argv[2]);
numberOfNeighbors = atoi(argv[3]);
if (numberOfNeighbors >= numberOfPoints) {
numberOfNeighbors = numberOfPoints - 1;
}*/
numberOfPoints = 10;
numberOfDimensions = 10;
numberOfNeighbors = 5;
}
void init(double ***pointsArray, neighbor ***sortedNeighborsArray){
//Allocates memory for points array
if ((*pointsArray = malloc((sizeof(double *)) * numberOfPoints)) != NULL){
for (int row = 0; row < numberOfPoints; ++row){
if (((*pointsArray)[row] = malloc((sizeof(double)) * numberOfDimensions)) == NULL){
if (DEBUG){
printf("Error allocating memory\n");
}
exit(1);
}
}
} else {
if (DEBUG){
printf("Error allocating memory\n");
}
exit(1);
}
//Allocates memory for neighbors array
if ((*sortedNeighborsArray = malloc((sizeof(neighbor *)) * numberOfPoints)) != NULL){
for (int row = 0; row < numberOfPoints; ++row){
if (((*sortedNeighborsArray)[row] = malloc((sizeof(neighbor)) * numberOfNeighbors)) == NULL){
if (DEBUG){
printf("Error allocating memory\n");
}
exit(1);
}
}
} else {
if (DEBUG){
printf("Error allocating memory\n");
}
exit(1);
}
//Reads coordinates for the file
if (readPointsArrayFromFile(pointsArray)){
if (DEBUG){
printf("Press any key to exit.\n");
getchar();
}
exit(1);
}
//Initializes neighbors array distances to -1
for (int row=0; row<numberOfPoints; ++row){
for(int column=0; column<numberOfNeighbors; ++column){
(*sortedNeighborsArray)[row][column].distance = -1;
}
}
}
int readPointsArrayFromFile(double ***array){
FILE *pointsBinaryFile;
pointsBinaryFile = fopen("data.bin","rb");
for (int point=0; point<numberOfPoints; ++point){
if (fread((*array)[point], sizeof(double), numberOfDimensions, pointsBinaryFile) != numberOfDimensions) {
if(feof(pointsBinaryFile)){
printf("There were info after the end of file.\n");
} else{
printf("Error reading points file.");
}
return 1;
}
}
fclose(pointsBinaryFile);
return 0;
}
void printArray(int rows, int columns, double ***array){
for (int row=0; row<rows; ++row){
for (int column=0; column<columns; ++column){
printf("[%d][%d] = %f\n", row, column, (*array)[row][column]);
}
printf("\n");
}
}
void addDistanceAndShift(neighbor ***sortedNeighborsArray, int firstPointId, int secondPointId, double pointsDistance){
if (DEBUG){
printf("Got %d and %d = %f\n", firstPointId, secondPointId, pointsDistance);
}
for (int arrayIndex=0; arrayIndex<numberOfNeighbors; ++arrayIndex){
//Gets distance stored in the array for this index
double thisNeighborDistance = (*sortedNeighborsArray)[firstPointId][arrayIndex].distance;
if (thisNeighborDistance == -1){ //Loop reached the end of the array
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
} else if (thisNeighborDistance > pointsDistance){ //Distance at the this index is greater than the distance being inserted
//Shifts right all non empty columns holding distances lower than pointsDistance
for (int moveColumn=numberOfNeighbors-2; moveColumn>=arrayIndex; --moveColumn){
double tempDistance = (*sortedNeighborsArray)[firstPointId][moveColumn].distance;
if (tempDistance == -1){ //Skips empty columns
continue;
}
(*sortedNeighborsArray)[firstPointId][moveColumn+1].distance = tempDistance;
(*sortedNeighborsArray)[firstPointId][moveColumn+1].neighborId = (*sortedNeighborsArray)[firstPointId][moveColumn].neighborId;
}
//Inserts pointsDistance in the space created after shifting
(*sortedNeighborsArray)[firstPointId][arrayIndex].distance = pointsDistance;
(*sortedNeighborsArray)[firstPointId][arrayIndex].neighborId = secondPointId;
break;
}
}
}
void cleanUp(double ***pointsArray, neighbor ***sortedNeighborsArray){
for (int row=0; row<numberOfPoints; ++row){
free((*pointsArray)[row]);
}
free(*pointsArray);
//Crashes for some reason...
/*for (int row=0; row<numberOfNeighbors; ++row){
printf("%f\n", (*sortedNeighborsArray)[row][0]);
free((*sortedNeighborsArray)[row]);
}*/
//free(*sortedNeighborsArray);
}

65
dev/points_read_malloc.c

@ -0,0 +1,65 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUMBER_OF_ROWS 10
#define NUMBER_OF_COLUMNS 10
int readArrayFromFile(int rows, int columns, double array[rows][columns]);
void printPointsArray(int rows, int columns, double array[rows][columns]);
void init(int pointsArrayRows, int pointsArrayColumns, double pointsArray[pointsArrayRows][pointsArrayColumns]);
int main(int argc, char const *argv[]){
double **pointsArray;
int row;
pointsArray = (double **)(malloc(NUMBER_OF_ROWS * sizeof(double *)));
for (int i = 0; i < NUMBER_OF_ROWS; ++i){
pointsArray[i] = (double *)(malloc(NUMBER_OF_COLUMNS * sizeof(double)));
}
init(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS, &pointsArray);
printPointsArray(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS, &pointsArray);
printf("Done! Press any key to exit.\n");
scanf("%d", &row);
}
int readArrayFromFile(int rows, int columns, double array[rows][columns]){
FILE *pointsBinaryFile;
pointsBinaryFile = fopen("data.bin","rb");
if(fread(array, sizeof(double), rows * columns, pointsBinaryFile) != rows * columns) {
if(feof(pointsBinaryFile))
printf("There were usefull info after the end of file.\n");
else
printf("File read error.\n");
return 1;
}
fclose(pointsBinaryFile);
return 0;
}
void printPointsArray(int rows, int columns, double array[rows][columns]){
int row, column;
for (row=0; row<rows; ++row){
for (column=0; column<columns; ++column){
printf("pointsArray[%d][%d] = %f\n", row, column, array[row][column]);
}
}
}
void init(int pointsArrayRows, int pointsArrayColumns, double pointsArray[pointsArrayRows][pointsArrayColumns]){
int row, column;
if (readArrayFromFile(pointsArrayRows, pointsArrayColumns, pointsArray)){
printf("Failed... Press any key to exit.\n");
scanf("%d", &row);
exit(1);
}
}

60
dev/points_read_try.c

@ -0,0 +1,60 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUMBER_OF_ROWS 10
#define NUMBER_OF_COLUMNS 10
int readArrayFromFile(int rows, int columns, double array[rows][columns]);
void printPointsArray(int rows, int columns, double array[rows][columns]);
void init(int pointsArrayRows, int pointsArrayColumns, double pointsArray[pointsArrayRows][pointsArrayColumns]);
int main(int argc, char const *argv[]){
double pointsArray[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int row;
init(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS, pointsArray);
printPointsArray(NUMBER_OF_ROWS, NUMBER_OF_COLUMNS, pointsArray);
printf("Done! Press any key to exit.\n");
scanf("%d", &row);
}
int readArrayFromFile(int rows, int columns, double array[rows][columns]){
FILE *pointsBinaryFile;
pointsBinaryFile = fopen("data.bin","rb");
if(fread(array, sizeof(double), rows * columns, pointsBinaryFile) != rows * columns) {
if(feof(pointsBinaryFile))
printf("There were usefull info after the end of file.\n");
else
printf("File read error.\n");
return 1;
}
fclose(pointsBinaryFile);
return 0;
}
void printPointsArray(int rows, int columns, double array[rows][columns]){
int row, column;
for (row=0; row<rows; ++row){
for (column=0; column<columns; ++column){
printf("pointsArray[%d][%d] = %f\n", row, column, array[row][column]);
}
}
}
void init(int pointsArrayRows, int pointsArrayColumns, double pointsArray[pointsArrayRows][pointsArrayColumns]){
int row, column;
if (readArrayFromFile(pointsArrayRows, pointsArrayColumns, pointsArray)){
printf("Failed... Press any key to exit.\n");
scanf("%d", &row);
exit(1);
}
}

14
stats/1/B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.034069
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 communications time sum = 0.000285
Task 0 calculations time sum = 0.033611
Task 1 communications time sum = 0.000269
Task 1 calculations time sum = 0.033482
Task 2 communications time sum = 0.000286
Task 2 calculations time sum = 0.033540
Task 3 communications time sum = 0.000304
Task 3 calculations time sum = 0.033434

14
stats/1/B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 7.261491
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 communications time sum = 0.002371
Task 0 calculations time sum = 7.258963
Task 1 communications time sum = 0.003553
Task 1 calculations time sum = 7.226678
Task 2 communications time sum = 0.003680
Task 2 calculations time sum = 7.163300
Task 3 communications time sum = 0.003646
Task 3 calculations time sum = 7.179779

14
stats/1/B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 12.719311
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 communications time sum = 0.009364
Task 0 calculations time sum = 12.709771
Task 1 communications time sum = 0.013145
Task 1 calculations time sum = 12.654160
Task 2 communications time sum = 0.012834
Task 2 calculations time sum = 12.640520
Task 3 communications time sum = 0.007404
Task 3 calculations time sum = 12.674974

14
stats/1/B_21000.txt

@ -0,0 +1,14 @@
Wall clock time = 19.688050
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 communications time sum = 0.006936
Task 0 calculations time sum = 19.658426
Task 1 communications time sum = 0.002660
Task 1 calculations time sum = 19.588951
Task 2 communications time sum = 0.002747
Task 2 calculations time sum = 19.654984
Task 3 communications time sum = 0.005355
Task 3 calculations time sum = 19.682092

14
stats/1/B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.994548
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 communications time sum = 0.002459
Task 0 calculations time sum = 0.990055
Task 1 communications time sum = 0.000776
Task 1 calculations time sum = 0.990929
Task 2 communications time sum = 0.002396
Task 3 communications time sum = 0.002325
Task 3 calculations time sum = 0.991652
Task 2 calculations time sum = 0.991980

14
stats/1/B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 3.369928
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 communications time sum = 0.001696
Task 0 calculations time sum = 3.367163
Task 1 communications time sum = 0.001609
Task 1 calculations time sum = 3.368111
Task 2 communications time sum = 0.001736
Task 2 calculations time sum = 3.358565
Task 3 communications time sum = 0.001776
Task 3 calculations time sum = 3.337365

10
stats/1/NB_1000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.033778
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 calculations time sum = 0.033493
Task 1 calculations time sum = 0.033525
Task 2 calculations time sum = 0.033579
Task 3 calculations time sum = 0.033483

10
stats/1/NB_13000.txt

@ -0,0 +1,10 @@
Wall clock time = 7.247777
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 calculations time sum = 7.246494
Task 1 calculations time sum = 7.226297
Task 2 calculations time sum = 7.165253
Task 3 calculations time sum = 7.173613

10
stats/1/NB_17000.txt

@ -0,0 +1,10 @@
Wall clock time = 12.712657
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 calculations time sum = 12.704461
Task 1 calculations time sum = 12.666481
Task 2 calculations time sum = 12.647987
Task 3 calculations time sum = 12.703289

10
stats/1/NB_21000.txt

@ -0,0 +1,10 @@
Wall clock time = 19.683746
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 calculations time sum = 19.680478
Task 1 calculations time sum = 19.611837
Task 2 calculations time sum = 19.634485
Task 3 calculations time sum = 19.678910

10
stats/1/NB_5000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.990903
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 calculations time sum = 0.989757
Task 1 calculations time sum = 0.990264
Task 2 calculations time sum = 0.989132
Task 3 calculations time sum = 0.988984

10
stats/1/NB_9000.txt

@ -0,0 +1,10 @@
Wall clock time = 3.374232
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 calculations time sum = 3.373230
Task 1 calculations time sum = 3.370266
Task 2 calculations time sum = 3.370403
Task 3 calculations time sum = 3.343280

14
stats/2/SO_B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.254555
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 communications time sum = 0.000763
Task 0 calculations time sum = 0.253721
Task 1 communications time sum = 0.000805
Task 1 calculations time sum = 0.253366
Task 2 communications time sum = 0.000442
Task 3 communications time sum = 0.000690
Task 3 calculations time sum = 0.253492
Task 2 calculations time sum = 0.254101

14
stats/2/SO_B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 554.284972
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 1 communications time sum = 7.297489
Task 1 calculations time sum = 537.851630
Task 2 communications time sum = 0.852826
Task 2 calculations time sum = 541.811203
Task 3 communications time sum = 2.411117
Task 3 calculations time sum = 551.873807
Task 0 communications time sum = 7.380732
Task 0 calculations time sum = 540.423709

14
stats/2/SO_B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 1239.585742
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 communications time sum = 15.438516
Task 1 communications time sum = 8.418541
Task 1 calculations time sum = 1209.574522
Task 2 communications time sum = 1.685984
Task 2 calculations time sum = 1234.917926
Task 0 calculations time sum = 1209.477226
Task 3 communications time sum = 14.000331
Task 3 calculations time sum = 1225.585384

14
stats/2/SO_B_21000.txt

@ -0,0 +1,14 @@
Wall clock time = 2344.181177
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 communications time sum = 14.015189
Task 0 calculations time sum = 2310.925852
Task 1 communications time sum = 9.007098
Task 1 calculations time sum = 2323.463802
Task 2 communications time sum = 8.904938
Task 2 calculations time sum = 2326.644681
Task 3 communications time sum = 22.523027
Task 3 calculations time sum = 2321.658103

14
stats/2/SO_B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 30.992809
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 communications time sum = 0.023125
Task 0 calculations time sum = 30.965178
Task 1 communications time sum = 0.010953
Task 1 calculations time sum = 30.962624
Task 3 communications time sum = 0.031227
Task 3 calculations time sum = 30.945286
Task 2 communications time sum = 0.009442
Task 2 calculations time sum = 30.983349

14
stats/2/SO_B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 183.127251
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 2 communications time sum = 1.622200
Task 2 calculations time sum = 178.743481
Task 0 communications time sum = 2.004348
Task 0 calculations time sum = 179.725121
Task 1 communications time sum = 0.820660
Task 1 calculations time sum = 179.495873
Task 3 communications time sum = 0.025997
Task 3 calculations time sum = 183.101211

10
stats/2/SO_NB_1000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.254016
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 calculations time sum = 0.253394
Task 1 calculations time sum = 0.253109
Task 2 calculations time sum = 0.253625
Task 3 calculations time sum = 0.253049

10
stats/2/SO_NB_13000.txt

@ -0,0 +1,10 @@
Wall clock time = 554.383816
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 calculations time sum = 540.464332
Task 1 calculations time sum = 537.962039
Task 2 calculations time sum = 541.793609
Task 3 calculations time sum = 551.988150

10
stats/2/SO_NB_17000.txt

@ -0,0 +1,10 @@
Wall clock time = 1239.115736
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 calculations time sum = 1208.784077
Task 3 calculations time sum = 1225.380272
Task 1 calculations time sum = 1209.585533
Task 2 calculations time sum = 1234.820747

10
stats/2/SO_NB_21000.txt

@ -0,0 +1,10 @@
Wall clock time = 2344.109723
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 calculations time sum = 2312.102511
Task 3 calculations time sum = 2321.945771
Task 1 calculations time sum = 2323.699373
Task 2 calculations time sum = 2326.662573

10
stats/2/SO_NB_5000.txt

@ -0,0 +1,10 @@
Wall clock time = 30.982453
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 calculations time sum = 30.969539
Task 1 calculations time sum = 30.962273
Task 2 calculations time sum = 30.971577
Task 3 calculations time sum = 30.943259

10
stats/2/SO_NB_9000.txt

@ -0,0 +1,10 @@
Wall clock time = 183.099425
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 1 calculations time sum = 179.513594
Task 2 calculations time sum = 178.732463
Task 3 calculations time sum = 183.089220
Task 0 calculations time sum = 179.690826

14
stats/2/TO_B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.041514
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 1 communications time sum = 0.000242
Task 0 communications time sum = 0.000279
Task 0 calculations time sum = 0.034408
Task 1 calculations time sum = 0.033503
Task 2 communications time sum = 0.000257
Task 2 calculations time sum = 0.033410
Task 3 communications time sum = 0.000291
Task 3 calculations time sum = 0.033405

14
stats/2/TO_B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 7.268335
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 communications time sum = 0.002351
Task 0 calculations time sum = 7.265863
Task 1 communications time sum = 0.004165
Task 1 calculations time sum = 7.224932
Task 2 communications time sum = 0.004251
Task 3 communications time sum = 0.004838
Task 3 calculations time sum = 7.167590
Task 2 calculations time sum = 7.179096

14
stats/2/TO_B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 12.761921
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 1 communications time sum = 0.012452
Task 1 calculations time sum = 12.639010
Task 0 communications time sum = 0.012091
Task 0 calculations time sum = 12.700233
Task 2 communications time sum = 0.002621
Task 2 calculations time sum = 12.628114
Task 3 communications time sum = 0.003257
Task 3 calculations time sum = 12.677528

14
stats/2/TO_B_21000.txt

@ -0,0 +1,14 @@
Wall clock time = 19.775075
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 1 communications time sum = 0.005514
Task 0 communications time sum = 0.004735
Task 0 calculations time sum = 19.683603
Task 1 calculations time sum = 19.580722
Task 2 communications time sum = 0.003601
Task 2 calculations time sum = 19.653215
Task 3 communications time sum = 0.006058
Task 3 calculations time sum = 19.681204

14
stats/2/TO_B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 1.021175
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 communications time sum = 0.001141
Task 0 calculations time sum = 0.989849
Task 1 communications time sum = 0.000935
Task 1 calculations time sum = 0.990729
Task 2 communications time sum = 0.001140
Task 2 calculations time sum = 0.990895
Task 3 communications time sum = 0.001201
Task 3 calculations time sum = 0.989548

14
stats/2/TO_B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 3.417923
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 communications time sum = 0.001669
Task 0 calculations time sum = 3.369588
Task 1 communications time sum = 0.003304
Task 1 calculations time sum = 3.366839
Task 2 communications time sum = 0.003461
Task 2 calculations time sum = 3.383239
Task 3 communications time sum = 0.003489
Task 3 calculations time sum = 3.329598

10
stats/2/TO_NB_1000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.033758
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 calculations time sum = 0.033505
Task 1 calculations time sum = 0.033490
Task 2 calculations time sum = 0.033499
Task 3 calculations time sum = 0.033585

10
stats/2/TO_NB_13000.txt

@ -0,0 +1,10 @@
Wall clock time = 7.252139
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 2 calculations time sum = 7.167104
Task 3 calculations time sum = 7.181140
Task 0 calculations time sum = 7.248803
Task 1 calculations time sum = 7.227046

10
stats/2/TO_NB_17000.txt

@ -0,0 +1,10 @@
Wall clock time = 12.725699
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 calculations time sum = 12.721062
Task 1 calculations time sum = 12.651490
Task 2 calculations time sum = 12.608332
Task 3 calculations time sum = 12.688143

10
stats/2/TO_NB_21000.txt

@ -0,0 +1,10 @@
Wall clock time = 19.680875
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 calculations time sum = 19.672720
Task 2 calculations time sum = 19.675402
Task 3 calculations time sum = 19.676451
Task 1 calculations time sum = 19.610648

10
stats/2/TO_NB_5000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.990137
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 calculations time sum = 0.989447
Task 2 calculations time sum = 0.988779
Task 1 calculations time sum = 0.988890
Task 3 calculations time sum = 0.988694

10
stats/2/TO_NB_9000.txt

@ -0,0 +1,10 @@
Wall clock time = 3.371798
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 calculations time sum = 3.366320
Task 1 calculations time sum = 3.370863
Task 2 calculations time sum = 3.353532
Task 3 calculations time sum = 3.341214

14
stats/2/low_k/SO_B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.010062
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 communications time sum = 0.000249
Task 1 communications time sum = 0.000260
Task 1 calculations time sum = 0.009729
Task 0 calculations time sum = 0.009775
Task 2 communications time sum = 0.000198
Task 2 calculations time sum = 0.009810
Task 3 communications time sum = 0.000267
Task 3 calculations time sum = 0.009795

14
stats/2/low_k/SO_B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 1.632057
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 communications time sum = 0.003166
Task 0 calculations time sum = 1.628881
Task 1 communications time sum = 0.001151
Task 1 calculations time sum = 1.629646
Task 2 communications time sum = 0.004368
Task 2 calculations time sum = 1.626288
Task 3 communications time sum = 0.003222
Task 3 calculations time sum = 1.626732

14
stats/2/low_k/SO_B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 2.793898
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 3 communications time sum = 0.002752
Task 3 calculations time sum = 2.789319
Task 0 communications time sum = 0.008707
Task 0 calculations time sum = 2.783873
Task 1 communications time sum = 0.001881
Task 1 calculations time sum = 2.790198
Task 2 communications time sum = 0.004918
Task 2 calculations time sum = 2.788967

14
stats/2/low_k/SO_B_21000.txt

@ -0,0 +1,14 @@
Wall clock time = 4.295281
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 1 communications time sum = 0.014575
Task 1 calculations time sum = 4.275249
Task 2 communications time sum = 0.008623
Task 2 calculations time sum = 4.286643
Task 3 communications time sum = 0.013051
Task 3 calculations time sum = 4.274712
Task 0 communications time sum = 0.012873
Task 0 calculations time sum = 4.274911

14
stats/2/low_k/SO_B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.241691
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 communications time sum = 0.000871
Task 0 calculations time sum = 0.240815
Task 1 communications time sum = 0.000740
Task 1 calculations time sum = 0.240827
Task 2 communications time sum = 0.000799
Task 2 calculations time sum = 0.240844
Task 3 communications time sum = 0.000831
Task 3 calculations time sum = 0.240832

14
stats/2/low_k/SO_B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.781440
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 communications time sum = 0.002033
Task 0 calculations time sum = 0.779372
Task 1 communications time sum = 0.001762
Task 1 calculations time sum = 0.779503
Task 2 communications time sum = 0.001510
Task 2 calculations time sum = 0.779920
Task 3 communications time sum = 0.002699
Task 3 calculations time sum = 0.778432

10
stats/2/low_k/SO_NB_1000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.009180
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 calculations time sum = 0.009056
Task 1 calculations time sum = 0.009083
Task 2 calculations time sum = 0.009078
Task 3 calculations time sum = 0.009072

10
stats/2/low_k/SO_NB_13000.txt

@ -0,0 +1,10 @@
Wall clock time = 1.514796
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 3 calculations time sum = 1.513576
Task 0 calculations time sum = 1.510294
Task 1 calculations time sum = 1.511106
Task 2 calculations time sum = 1.509252

10
stats/2/low_k/SO_NB_17000.txt

@ -0,0 +1,10 @@
Wall clock time = 2.596288
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 calculations time sum = 2.588859
Task 1 calculations time sum = 2.594717
Task 2 calculations time sum = 2.589177
Task 3 calculations time sum = 2.590838

10
stats/2/low_k/SO_NB_21000.txt

@ -0,0 +1,10 @@
Wall clock time = 3.991685
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 0 calculations time sum = 3.977723
Task 3 calculations time sum = 3.969148
Task 1 calculations time sum = 3.978771
Task 2 calculations time sum = 3.979802

10
stats/2/low_k/SO_NB_5000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.224615
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 1 calculations time sum = 0.223706
Task 2 calculations time sum = 0.224058
Task 3 calculations time sum = 0.224238
Task 0 calculations time sum = 0.223671

10
stats/2/low_k/SO_NB_9000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.727053
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 10
Number of tasks = 4
Task 2 calculations time sum = 0.724410
Task 3 calculations time sum = 0.723391
Task 0 calculations time sum = 0.725784
Task 1 calculations time sum = 0.724022

14
stats/2/low_k/TO_B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.045668
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 communications time sum = 0.000274
Task 0 calculations time sum = 0.036621
Task 1 communications time sum = 0.000273
Task 1 calculations time sum = 0.033439
Task 2 communications time sum = 0.000280
Task 2 calculations time sum = 0.033491
Task 3 communications time sum = 0.000281
Task 3 calculations time sum = 0.033490

14
stats/2/low_k/TO_B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 7.269148
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 communications time sum = 0.002356
Task 0 calculations time sum = 7.266687
Task 1 communications time sum = 0.003331
Task 1 calculations time sum = 7.232499
Task 2 communications time sum = 0.003731
Task 3 communications time sum = 0.004815
Task 3 calculations time sum = 7.168525
Task 2 calculations time sum = 7.207633

14
stats/2/low_k/TO_B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 12.774908
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 communications time sum = 0.007294
Task 1 communications time sum = 0.005029
Task 1 calculations time sum = 12.661872
Task 0 calculations time sum = 12.767496
Task 2 communications time sum = 0.013357
Task 2 calculations time sum = 12.607397
Task 3 communications time sum = 0.002359
Task 3 calculations time sum = 12.691293

14
stats/2/low_k/TO_B_21000.txt

@ -0,0 +1,14 @@
Wall clock time = 19.765704
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 communications time sum = 0.007475
Task 0 calculations time sum = 19.758115
Task 1 communications time sum = 0.006529
Task 1 calculations time sum = 19.593806
Task 2 communications time sum = 0.002654
Task 2 calculations time sum = 19.628838
Task 3 communications time sum = 0.005116
Task 3 calculations time sum = 19.667014

14
stats/2/low_k/TO_B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 1.015355
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 communications time sum = 0.001099
Task 0 calculations time sum = 0.991580
Task 1 communications time sum = 0.001112
Task 1 calculations time sum = 0.988937
Task 2 communications time sum = 0.001104
Task 2 calculations time sum = 0.990494
Task 3 communications time sum = 0.001151
Task 3 calculations time sum = 0.989527

14
stats/2/low_k/TO_B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 3.409903
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 communications time sum = 0.001667
Task 0 calculations time sum = 3.370045
Task 1 communications time sum = 0.003079
Task 1 calculations time sum = 3.392497
Task 2 communications time sum = 0.003777
Task 2 calculations time sum = 3.351902
Task 3 communications time sum = 0.003148
Task 3 calculations time sum = 3.338251

10
stats/2/low_k/TO_NB_1000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.033655
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 calculations time sum = 0.033443
Task 1 calculations time sum = 0.033401
Task 2 calculations time sum = 0.033422
Task 3 calculations time sum = 0.033523

10
stats/2/low_k/TO_NB_13000.txt

@ -0,0 +1,10 @@
Wall clock time = 7.260061
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 0 calculations time sum = 7.258476
Task 1 calculations time sum = 7.228553
Task 2 calculations time sum = 7.168067
Task 3 calculations time sum = 7.180212

10
stats/2/low_k/TO_NB_17000.txt

@ -0,0 +1,10 @@
Wall clock time = 12.724300
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 1 calculations time sum = 12.662180
Task 2 calculations time sum = 12.674517
Task 3 calculations time sum = 12.691427
Task 0 calculations time sum = 12.715927

10
stats/2/low_k/TO_NB_21000.txt

@ -0,0 +1,10 @@
Wall clock time = 19.714659
Number of points = 21000
Number of dimensions = 30
Number of neighbors = 20999
Number of tasks = 4
Task 0 calculations time sum = 19.677347
Task 1 calculations time sum = 19.646248
Task 2 calculations time sum = 19.695513
Task 3 calculations time sum = 19.708906

10
stats/2/low_k/TO_NB_5000.txt

@ -0,0 +1,10 @@
Wall clock time = 0.990623
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 calculations time sum = 0.989279
Task 1 calculations time sum = 0.989294
Task 2 calculations time sum = 0.990020
Task 3 calculations time sum = 0.989884

10
stats/2/low_k/TO_NB_9000.txt

@ -0,0 +1,10 @@
Wall clock time = 3.376398
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 0 calculations time sum = 3.375470
Task 1 calculations time sum = 3.372552
Task 2 calculations time sum = 3.354796
Task 3 calculations time sum = 3.335200

14
stats/2/square_array/SO_B_1000.txt

@ -0,0 +1,14 @@
Wall clock time = 0.254555
Number of points = 1000
Number of dimensions = 30
Number of neighbors = 999
Number of tasks = 4
Task 0 communications time sum = 0.000763
Task 0 calculations time sum = 0.253721
Task 1 communications time sum = 0.000805
Task 1 calculations time sum = 0.253366
Task 2 communications time sum = 0.000442
Task 3 communications time sum = 0.000690
Task 3 calculations time sum = 0.253492
Task 2 calculations time sum = 0.254101

14
stats/2/square_array/SO_B_13000.txt

@ -0,0 +1,14 @@
Wall clock time = 554.284972
Number of points = 13000
Number of dimensions = 30
Number of neighbors = 12999
Number of tasks = 4
Task 1 communications time sum = 7.297489
Task 1 calculations time sum = 537.851630
Task 2 communications time sum = 0.852826
Task 2 calculations time sum = 541.811203
Task 3 communications time sum = 2.411117
Task 3 calculations time sum = 551.873807
Task 0 communications time sum = 7.380732
Task 0 calculations time sum = 540.423709

14
stats/2/square_array/SO_B_17000.txt

@ -0,0 +1,14 @@
Wall clock time = 1239.585742
Number of points = 17000
Number of dimensions = 30
Number of neighbors = 16999
Number of tasks = 4
Task 0 communications time sum = 15.438516
Task 1 communications time sum = 8.418541
Task 1 calculations time sum = 1209.574522
Task 2 communications time sum = 1.685984
Task 2 calculations time sum = 1234.917926
Task 0 calculations time sum = 1209.477226
Task 3 communications time sum = 14.000331
Task 3 calculations time sum = 1225.585384

0
stats/2/square_array/SO_B_21000.txt

14
stats/2/square_array/SO_B_5000.txt

@ -0,0 +1,14 @@
Wall clock time = 30.992809
Number of points = 5000
Number of dimensions = 30
Number of neighbors = 4999
Number of tasks = 4
Task 0 communications time sum = 0.023125
Task 0 calculations time sum = 30.965178
Task 1 communications time sum = 0.010953
Task 1 calculations time sum = 30.962624
Task 3 communications time sum = 0.031227
Task 3 calculations time sum = 30.945286
Task 2 communications time sum = 0.009442
Task 2 calculations time sum = 30.983349

14
stats/2/square_array/SO_B_9000.txt

@ -0,0 +1,14 @@
Wall clock time = 183.127251
Number of points = 9000
Number of dimensions = 30
Number of neighbors = 8999
Number of tasks = 4
Task 2 communications time sum = 1.622200
Task 2 calculations time sum = 178.743481
Task 0 communications time sum = 2.004348
Task 0 calculations time sum = 179.725121
Task 1 communications time sum = 0.820660
Task 1 calculations time sum = 179.495873
Task 3 communications time sum = 0.025997
Task 3 calculations time sum = 183.101211

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save