commit f3ef16d3ebc1fcba196cf185cd1722e147cb2831 Author: Apostolof Date: Fri Jan 18 13:12:58 2019 +0200 Squash commit diff --git a/Blocking/spaceOptimized/Makefile b/Blocking/spaceOptimized/Makefile new file mode 100644 index 0000000..d6d9ad5 --- /dev/null +++ b/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 *~ \ No newline at end of file diff --git a/Blocking/spaceOptimized/knnMPIBlocking.c b/Blocking/spaceOptimized/knnMPIBlocking.c new file mode 100644 index 0000000..2e179c0 --- /dev/null +++ b/Blocking/spaceOptimized/knnMPIBlocking.c @@ -0,0 +1,151 @@ +#include +#include + +#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 +#include +#include + +#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 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 +#include +#include + +#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 +#include +#include + +#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 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 +#include + +#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 +#include +#include + +#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 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 +#include +#include + +#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 +#include +#include + +#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 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 +#include + +#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 +#include +#include + +#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 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 +#include +#include + +#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 +#include +#include + +#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 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 +#include +#include + +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(); +} \ No newline at end of file diff --git a/dev/generate_set.c b/dev/generate_set.c new file mode 100644 index 0000000..c5675d8 --- /dev/null +++ b/dev/generate_set.c @@ -0,0 +1,40 @@ +#include +#include + +#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 +#include +#include + +#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) { + 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 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 +#include +#include + +#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 +#include +#include + +#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