diff --git a/.gitignore b/.gitignore index af5bfca..e480a43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,2 @@ .swp -test -test2 -test_loader -time .vscode \ No newline at end of file diff --git a/README.md b/README.md index 014c2c9..db35a83 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # Lina, the nice-to-read linear algebra toolkit! -Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations with the aim to be nice to read! \ No newline at end of file +Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations with the aim to be nice to read! + +The performance branch focuses only on the core functionalities of lina and aims to produce faster and reliable routines. \ No newline at end of file diff --git a/benchmarks/bench_dot.c b/benchmarks/bench_dot.c new file mode 100644 index 0000000..5219168 --- /dev/null +++ b/benchmarks/bench_dot.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include "../src/lina.h" + +#define A_ROWS 1000llu +#define A_COLS 146llu + +#define B_ROWS 146llu +#define B_COLS 1024llu + +uint64_t nanos(); + +int main() +{ + uint64_t ops = A_ROWS*B_COLS*2*A_COLS; + uint64_t start,stop,lina_dot_time, lina_dot_mod1_time, lina_dot_mod1_1_time, lina_dot_mod2_time; + double *A = (double *)malloc(sizeof(double)*A_ROWS*A_COLS); + double *B = (double *)malloc(sizeof(double)*B_ROWS*B_COLS); + + double *C1 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS); + double *C2 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS); + double *C3 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS); + double *C4 = (double *)malloc(sizeof(double)*A_ROWS*B_COLS); + + for (int i = 0; i < A_ROWS*A_COLS; i++) + A[i] = (double)(rand()%10); + for (int i = 0; i < B_ROWS*B_COLS; i++) + B[i] = (double)(rand()%10); + for (int i = 0; i < A_ROWS*B_COLS; i++) + { + C1[i] = (double)(rand()%10); + C2[i] = (double)(rand()%10); + C3[i] = (double)(rand()%10); + C4[i] = (double)(rand()%10); + } + + start = nanos(); + lina_dot(A,B,C1,A_ROWS,A_COLS,B_COLS); + stop = nanos(); + + lina_dot_time = stop-start; + + start = nanos(); + lina_dot_mod1(A,B,C2,A_ROWS,A_COLS,B_COLS); + stop = nanos(); + + lina_dot_mod1_time = stop-start; + + start = nanos(); + lina_dot_mod2(A,B,C3,A_ROWS,A_COLS,B_COLS); + stop = nanos(); + + lina_dot_mod2_time = stop-start; + + start = nanos(); + lina_dot_mod2_old(A,B,C4,A_ROWS,A_COLS,B_COLS); + stop = nanos(); + + lina_dot_mod1_1_time = stop-start; + + if(!memcmp(C1,C2,sizeof(double)*A_ROWS*B_COLS) && !memcmp(C2,C3,sizeof(double)*A_ROWS*B_COLS) && !memcmp(C3,C4,sizeof(double)*A_ROWS*B_COLS)) + { + printf( "lina_dot : %f GFLOPS\n" + "lina_dot_mod1: %f GFLOPS\n" + "lina_dot_mod2: %f GFLOPS\n" + "lina_dot_mod2_old: %f GFLOPS\n", (double)ops/lina_dot_time, + (double)ops/lina_dot_mod1_time, + (double)ops/lina_dot_mod2_time, + (double)ops/lina_dot_mod1_1_time); + + } + else + printf("ERRORE: i prodotti matriciali sono diversi!\n"); + + free(A); + free(B); + free(C1); + free(C2); + free(C3); + free(C4); +} \ No newline at end of file diff --git a/benchmarks/time.c b/benchmarks/time.c deleted file mode 100644 index e5159aa..0000000 --- a/benchmarks/time.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include -#include -#include "lina.h" - -/* This program compares the lina_transpose -** implementation against the naive implementation. -** Build it with: -** $ gcc time.c lina.c -o time -Wall -Wextra -O3 -*/ - -#define check assert - -static void naive_transpose(double *A, double *B, int m, int n) -{ - assert(m > 0 && n > 0); - assert(A != NULL && B != NULL); - - double *support; - - if(A == B) - { - support = malloc(sizeof(*support) * m * n); - - check(support != NULL); - - memcpy(support, A, sizeof(*support) * m * n); - } - else - { - support = A; - } - - for(int i = 0; i < n; i++) - - for(int j = 0; j < m; j++) - - B[j*n + i] = support[i*m + j]; - - if(support != A) - free(support); -} - -// Wrap transposing functions and return their -// execution time. -static double time_transposition(void (*callback)(double*, double*, int, int), double *A, double *B, int m, int n) -{ - clock_t begin = clock(); - - callback(A, B, m, n); - - clock_t end = clock(); - - return (double) (end - begin) / CLOCKS_PER_SEC; -} - -int main() -{ - int m = 1000; - int n = 100000; - - double *big = malloc(sizeof(double) * m * n); - check(big != NULL); - - memset(big, 0, sizeof(double) * m * n); - - printf("lina_transpose took %gms (in-place)\n", - 1000 * time_transposition(lina_transpose, big, big, m, n)); - - printf("naive_transpose took %gms (in-place)\n", - 1000 * time_transposition(naive_transpose, big, big, m, n)); - - double *big2 = malloc(sizeof(double) * m * n); - check(big2 != NULL); - - printf("lina_transpose took %gms\n", - 1000 * time_transposition(lina_transpose, big, big2, m, n)); - - printf("naive_transpose took %gms\n", - 1000 * time_transposition(naive_transpose, big, big2, m, n)); - - free(big); - free(big2); - return 0; -} \ No newline at end of file diff --git a/build.sh b/build.sh deleted file mode 100755 index de22deb..0000000 --- a/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -gcc tests/test.c src/lina.c src/qr.c -o test -Wall -Wextra -g -Isrc/ -lm -gcc tests/test_loader.c src/lina.c src/qr.c -o test_loader -Wall -Wextra -g -Isrc/ -lm \ No newline at end of file diff --git a/test.c b/test.c deleted file mode 100644 index f3e214b..0000000 --- a/test.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include "src/lina.h" - -void print_square_matrix(double *M, int n, FILE *stream) -{ - for (int i = 0; i < n; i++) - { - fprintf(stream, "| "); - for (int j = 0; j < n; j++) - { - fprintf(stderr, "%2.2f ", M[i * n + j]); - } - fprintf(stream, "|\n"); - } - fprintf(stream, "\n"); -} - -void print_vector(double complex *V, int n, FILE *stream) -{ - fprintf(stream, "[ "); - for (int i = 0; i < n; i++) - fprintf(stderr, "(%2.2f + i%2.2f) ", creal(V[i]), cimag(V[i])); - fprintf(stream, "]\n"); -} - -int main(void) -{ - - double M[25] = { - 1, 2, 3, 4, 5, - 5, 1, 2, 3, 4, - 4, 5, 1, 2, 3, - 3, 4, 5, 1, 2, - 2, 3, 4, 5, 1, - }; - - fprintf(stderr, "# --- M --- #\n"); - print_square_matrix(M, 5, stderr); - - - /* - double L[25]; - double U[25]; - int P[5]; - double P2[25]; - lina_decompLUP(M, L, U, P, 5); - lina_reallyP(P, P2, 5); - - fprintf(stderr, "# --- L --- #\n"); - print_square_matrix(L, 5, stderr); - - fprintf(stderr, "# --- U --- #\n"); - print_square_matrix(U, 5, stderr); - - fprintf(stderr, "# --- P2 --- #\n"); - print_square_matrix(P2, 5, stderr); - - double PA[25]; - lina_dot(P2, M, PA, 5, 5, 5); - fprintf(stderr, "# --- PA --- #\n"); - print_square_matrix(PA, 5, stderr); - - double LU[25]; - lina_dot(L, U, LU, 5, 5, 5); - fprintf(stderr, "# --- LU --- #\n"); - print_square_matrix(LU, 5, stderr); - - double det; - lina_det(M, 5, &det); - fprintf(stderr, "det=%2.2f\n", det); - - fprintf(stderr, "# --- eig(M) --- #\n"); - double complex E[5]; - lina_eig(M, E, 5); - print_vector(E, 5, stderr); - */ - - - double invM[25]; - lina_inverse(M, invM, 5); - - double expI[25]; - lina_dot(M, invM, expI, 5, 5, 5); - - fprintf(stderr, "# --- inv(M) --- #\n"); - print_square_matrix(invM, 5, stderr); - - fprintf(stderr, "# --- I? --- #\n"); - print_square_matrix(expI, 5, stderr); - - - /* - double M[16] = { - 1, 5, 4, 2, - 2, 1, 5, 3, - 4, 3, 2, 5, - 5, 4, 3, 1, - }; - - fprintf(stderr, "# --- M --- #\n"); - print_square_matrix(M, 4, stderr); - - double L[16]; - double U[16]; - int P[4]; - lina_decompLUP(M, L, U, P, 4); - fprintf(stderr, "# --- L,U,P --- #\n"); - print_square_matrix(L, 4, stderr); - print_square_matrix(U, 4, stderr); - - fprintf(stderr, "[ "); - for(int i = 0; i < 4; i++) - fprintf(stderr, "%d ", P[i]); - fprintf(stderr, "]\n"); - - double RP[16]; - double PM[16]; - lina_reallyP(P, RP, 4); - lina_dot(RP, M, PM, 4, 4, 4); - - double LU[16]; - lina_dot(L, U, LU, 4, 4, 4); - - fprintf(stderr, "# --- P,PM,LU --- #\n"); - print_square_matrix(RP, 4, stderr); - print_square_matrix(PM, 4, stderr); - print_square_matrix(LU, 4, stderr); - - double det; - lina_det(M, 4, &det); - - fprintf(stderr, "det(M) = %2.2f\n", det); - */ - return 0; -} diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 0496915..0000000 --- a/tests/README.md +++ /dev/null @@ -1,16 +0,0 @@ -## Description -Here is developed the testing unit for all the lina functions that need numerical testing. - -## Usage -For each function in the lina library named in the form of _lina_something()_, here is defined a folder named _something_. In each folder there are many tests, each one identified by a ti.txt file, for i=1,...,n. -Each test file is defined as follows: The first matrix/matrices are the inputs of the function (depending on the function, for example: lina_add() has two inputs A,B and one output C=A+B. A and B have to be the first two matrices in the test file), the last matrix/matrices are the output of the function and after there are input scalar values (ordered in the same order of the function under test) of the function represented as a 1x1 matrix. - -For example, a scale test file, that is a test for the lina_scale() function is defined as follows: - -[1 1 1,1 1 1,1 1 1] -[2 2 2,2 2 2,2 2 2] -[2] - -Where the first matrix is the input, the second the output and the last is the scalar value. - -By default, executing the test file will generate all the testing and provide the results on the stdout. diff --git a/tests/dot/t1.txt b/tests/dot/t1.txt deleted file mode 100644 index 89c6d31..0000000 --- a/tests/dot/t1.txt +++ /dev/null @@ -1,11 +0,0 @@ -[1 0 0, - 0 1 0, - 0 0 1] - -[1 0 0, - 0 1 0, - 0 0 1] - -[1 0 0, - 0 1 0, - 0 0 1] diff --git a/tests/scale/t1.txt b/tests/scale/t1.txt deleted file mode 100644 index 125ee65..0000000 --- a/tests/scale/t1.txt +++ /dev/null @@ -1,9 +0,0 @@ -[1 1 1, - 1 1 1, - 1 1 1] - -[2 2 2, - 2 2 2, - 2 2 2] - -[2] \ No newline at end of file diff --git a/tests/test.c b/tests/test.c deleted file mode 100644 index fed5fc0..0000000 --- a/tests/test.c +++ /dev/null @@ -1,553 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "lina.h" - -#define check assert - -//Print the matrix A with size m by n -static void pmatrix(FILE *fp, double *A, int m, int n); - - -typedef struct dot_test{ - - double *A; - double *B; - double *C; - int m; - int n; - int l; - -}dot_test; - -typedef struct add_test{ - - double *A; - double *B; - double *C; - int m; - int n; - -}add_test; - -typedef struct scale_test{ - - double *A; - double *B; - double s; - int m; - int n; - -}scale_test; - -typedef struct transpose_test{ - - double *A; - double *B; - int m; - int n; - -}transpose_test; - -#define PATH "./tests/" - -int main() -{ - //Defining pointers to the test structures - add_test *add_tests; - dot_test *dot_tests; - scale_test *scale_tests; - transpose_test *transpose_tests; - - //Number of tests for each lina functions - int n_dot_tests, n_add_tests, n_scale_tests, n_transpose_tests; - - //Opening dir stream - DIR *dir = opendir(PATH); - struct dirent *ep; - check(dir != NULL); - - //Loading all the tests from files - while (ep = readdir(dir)) - { - if(ep->d_type != DT_DIR || !strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..")) - continue; - - if(!strcmp(ep->d_name,"add")) - { - - //Implement loading lina_add test matrices - char sub_path[256] = PATH; - strcat(sub_path,ep->d_name); - strcat(sub_path,"/"); - - DIR *sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - struct dirent *sub_ep; - - unsigned int count = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - count += 1; - } - - closedir(sub_dir); - - sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - add_tests = malloc(sizeof(add_test)*count); - n_add_tests = count; - int i = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - - char file_pos[256]; - strcat(file_pos,sub_path); - strcat(file_pos,sub_ep->d_name); - - FILE *fp; - fp = fopen(file_pos,"r"); - check(fp != NULL); - - int m,n; - char *error; - - add_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(add_tests[i].A != NULL); - - add_tests[i].B = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(add_tests[i].B != NULL); - - add_tests[i].C = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(add_tests[i].C != NULL); - - add_tests[i].m = m; - add_tests[i].n = n; - - i += 1; - fclose(fp); - - } - - closedir(sub_dir); - - } - else if (!strcmp(ep->d_name,"dot")) - { - //Implement loading lina_dot test matrices - char sub_path[256] = PATH; - strcat(sub_path,ep->d_name); - strcat(sub_path,"/"); - - DIR *sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - struct dirent *sub_ep; - - unsigned int count = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - count += 1; - } - - closedir(sub_dir); - - sub_dir = opendir(sub_path); - check(sub_dir != NULL); - dot_tests = malloc(sizeof(dot_test)*count); - n_dot_tests = count; - - int i = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - - char file_pos[256]; - strcpy(file_pos,sub_path); - strcat(file_pos,sub_ep->d_name); - - FILE *fp; - fp = fopen(file_pos,"r"); - check(fp != NULL); - - int m,n,l; - char *error; - - dot_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(dot_tests[i].A != NULL); - - dot_tests[i].B = lina_loadMatrixFromStream(fp,&l,&n,&error); - check(dot_tests[i].B != NULL); - - dot_tests[i].C = lina_loadMatrixFromStream(fp,&l,&m,&error); - check(dot_tests[i].C != NULL); - - dot_tests[i].m = m; - dot_tests[i].n = n; - dot_tests[i].l = l; - - i += 1; - fclose(fp); - - } - - closedir(sub_dir); - - - } - else if (!strcmp(ep->d_name,"scale")) - { - //Implement loading lina_scale test matrices - char sub_path[256] = PATH; - strcat(sub_path,ep->d_name); - strcat(sub_path,"/"); - - DIR *sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - struct dirent *sub_ep; - - unsigned int count = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - count += 1; - } - - closedir(sub_dir); - - sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - scale_tests = malloc(sizeof(scale_test)*count); - - n_scale_tests = count; - - int i = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - - char file_pos[256]; - strcpy(file_pos,sub_path); - - strcat(file_pos,sub_ep->d_name); - - FILE *fp; - fp = fopen(file_pos,"r"); - check(fp != NULL); - - int m,n; - int useless1,useless2; - double *scale; - char *error; - - scale_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(scale_tests[i].A != NULL); - - scale_tests[i].B = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(scale_tests[i].B != NULL); - - scale = lina_loadMatrixFromStream(fp,&useless1,&useless2,&error); - check(scale != NULL); - - scale_tests[i].m = m; - scale_tests[i].n = n; - scale_tests[i].s = scale[0]; - free(scale); - - - i += 1; - fclose(fp); - - } - - closedir(sub_dir); - - - } - else if (!strcmp(ep->d_name,"transpose")) - { - //Implement loading lina_transpose test matrices - char sub_path[256] = PATH; - strcat(sub_path,ep->d_name); - strcat(sub_path,"/"); - - DIR *sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - struct dirent *sub_ep; - - unsigned int count = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - count += 1; - } - - closedir(sub_dir); - - sub_dir = opendir(sub_path); - check(sub_dir != NULL); - - transpose_tests = malloc(sizeof(transpose_test)*count); - n_transpose_tests = count; - - int i = 0; - - while (sub_ep = readdir(sub_dir)) - { - if(sub_ep->d_type == DT_DIR) - continue; - - char file_pos[256]; - strcpy(file_pos,sub_path); - strcat(file_pos,sub_ep->d_name); - - FILE *fp; - fp = fopen(file_pos,"r"); - check(fp != NULL); - - int m,n; - char *error; - - transpose_tests[i].A = lina_loadMatrixFromStream(fp,&n,&m,&error); - check(transpose_tests[i].A != NULL); - - transpose_tests[i].B = lina_loadMatrixFromStream(fp,&m,&n,&error); - check(transpose_tests[i].B != NULL); - - transpose_tests[i].m = m; - transpose_tests[i].n = n; - - i += 1; - fclose(fp); - - } - - closedir(sub_dir); - - - } - - } - - closedir(dir); - - //Starting the lina_add tests - { - int passed_tests = 0; - fprintf(stdout,"Starting tests on lina_add():\n"); - for(int i=0;i