17 Commits
24 changed files with 963 additions and 1062 deletions
+2 -5
View File
@@ -1,6 +1,3 @@
.swp .swp
test .vscode
test2 *.txt
test_loader
time
.vscode
+4 -2
View File
@@ -1,2 +1,4 @@
# Lina # Lina, the nice-to-read linear algebra toolkit!
Lina (***Lin**ear **A**lgebra*) is a C library that implements common linear algebra operations. 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.
+181
View File
@@ -0,0 +1,181 @@
#include <time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../src/lina.h"
#define A_ROWS 960llu
#define A_COLS 960llu
#define B_ROWS 960llu
#define B_COLS 960llu
int saveMatrixToStream(FILE *fp, double *A, int width, int height, char **error);
static uint64_t nanos();
int main()
{
uint64_t ops = A_ROWS*B_COLS*2*A_COLS;
uint64_t start,stop,lina_dot_time, lina_dot1_time, lina_dot2_time, lina_dot3_time, lina_dot4_time;
double *A = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*A_COLS);
double *B = (double *)aligned_alloc(32,sizeof(double)*B_ROWS*B_COLS);
double *C1 = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*B_COLS);
double *C2 = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*B_COLS);
double *C3 = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*B_COLS);
double *C4 = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*B_COLS);
double *C5 = (double *)aligned_alloc(32,sizeof(double)*A_ROWS*B_COLS);
for (int i = 0; i < A_ROWS*A_COLS; i++)
A[i] = (double)(rand()%2);
for (int i = 0; i < B_ROWS*B_COLS; i++)
B[i] = (double)(rand()%2);
for (int i = 0; i < A_ROWS*B_COLS; i++)
{
C1[i] = (double)(rand()%2);
C2[i] = (double)(rand()%2);
C3[i] = (double)(rand()%2);
C4[i] = (double)(rand()%2);
C5[i] = (double)(rand()%2);
}
start = nanos();
lina_dot(A,B,C1,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot_time = stop-start;
start = nanos();
lina_dot1(A,B,C2,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot1_time = stop-start;
start = nanos();
lina_dot2(A,B,C3,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot2_time = stop-start;
start = nanos();
lina_dot3(A,B,C4,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot3_time = stop-start;
start = nanos();
lina_dot4(A,B,C5,A_ROWS,A_COLS,B_COLS);
stop = nanos();
lina_dot4_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)
&& !memcmp(C4,C5,sizeof(double)*A_ROWS*B_COLS))
{
printf( "lina_dot : %f GFLOPS\n"
"lina_dot1: %f GFLOPS\n"
"lina_dot2: %f GFLOPS\n"
"lina_dot3: %f GFLOPS\n"
"lina_dot4: %f GFLOPS\n", (double)ops/lina_dot_time,
(double)ops/lina_dot1_time,
(double)ops/lina_dot2_time,
(double)ops/lina_dot3_time,
(double)ops/lina_dot4_time);
FILE *fp = fopen("lina_dots_success.txt", "w");
if (!fp)
return -1;
saveMatrixToStream(fp,C1,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C2,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C3,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C4,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C5,A_ROWS,A_COLS,NULL);
fclose(fp);
}
else
{
printf("ERRORE: i prodotti matriciali sono diversi!\n");
FILE *fp = fopen("lina_dots_error.txt", "w");
if (!fp)
return -1;
saveMatrixToStream(fp,C1,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C2,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C3,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C4,A_ROWS,A_COLS,NULL);
fprintf(fp,"\nFINE\n");
saveMatrixToStream(fp,C5,A_ROWS,A_COLS,NULL);
fclose(fp);
}
free(A);
free(B);
free(C1);
free(C2);
free(C3);
free(C4);
free(C5);
}
static uint64_t nanos()
{
struct timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return (uint64_t)time.tv_sec*1000000000 + (uint64_t)time.tv_nsec;
}
int saveMatrixToStream(FILE *fp, double *A, int width, int height, char **error)
{
assert(A != NULL);
char *dummy;
if (error == NULL)
error = &dummy;
else
*error = NULL;
if (width < 1) {
*error = "The provided width is less than one";
return -1;
}
if (height < 1) {
*error = "The provided height is less than one";
return -1;
}
if (fp == NULL)
fp = stdout;
putc('[',fp);
for (int i = 0; i < height-1; i++) {
for (int j = 0; j < width-1; j++)
fprintf(fp, "%.1f ", A[i*width + j]);
fprintf(fp, "%.1f,\n", A[i*width + width-1]);
}
for (int j = 0; j < width-1; j++)
fprintf(fp, "%.1f ", A[(height-1)*width + j]);
fprintf(fp, "%.1f", A[(height-1)*width + width-1]);
putc(']',fp);
return 0;
}
+3
View File
@@ -0,0 +1,3 @@
gcc bench_dot.c ../src/lina.c -O3 -march=native -ffast-math -funroll-loops -o bench_dot
./bench_dot
python3 py_dot.py
+22
View File
@@ -0,0 +1,22 @@
import os
os.environ['OMP_NUM_THREADS'] = '1'
import numpy as np
import time
N = 1024
if __name__ == "__main__":
A = np.random.randn(N,N).astype(np.float64)
B = np.random.randn(N,N).astype(np.float64)
start = time.monotonic()
C = A @ B
stop = time.monotonic()
s = stop-start
ops = 2*N*N*N
print(f"NUMPY: {ops/s * 1e-9} GFLOPS\n")
-87
View File
@@ -1,87 +0,0 @@
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#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;
}
-2
View File
@@ -1,2 +0,0 @@
gcc tests/test.c src/lina.c -o test -Wall -Wextra -g -Isrc/
gcc tests/test_loader.c src/lina.c -o test_loader -Wall -Wextra -g -Isrc/
+737 -294
View File
File diff suppressed because it is too large Load Diff
+14 -5
View File
@@ -1,6 +1,15 @@
#include <stdbool.h>
#include <stdio.h>
void lina_dot(double *A, double *B, double *C, int m, int n, int l); void lina_dot(double *A, double *B, double *C, int m, int n, int l);
void lina_add(double *A, double *B, double *C, int m, int n); void lina_dot1(double *A, double *B, double *C, int m, int n, int l);
void lina_scale(double *A, double *B, double k, int m, int n); void lina_dot2(double *A, double *B, double *C, int m, int n, int l);
void lina_transpose(double *A, double *B, int m, int n); void lina_dot3(double *A, double *B, double *C, int m, int n, int l);
double *lina_loadMatrixFromStream(FILE *fp, int *width, int *height, char **error); void lina_dot4(double *A, double *B, double *C, int m, int n, int l);
void lina_add(double *A, double *B, double *C, int m, int n);
void lina_scale(double *A, double *B, double k, int m, int n);
void lina_conv(double *A, double *B, double *C, int Aw, int Ah, int Bw, int Bh);
void lina_transpose(double *A, double *B, int m, int n);
bool lina_inverse(double *M, double *D, int n);
double *lina_loadMatrixFromStream(FILE *fp, int *width, int *height, char **error);
int lina_saveMatrixToStream(FILE *fp, double *A, int width, int height, char **error);
-16
View File
@@ -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.
-11
View File
@@ -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]
-9
View File
@@ -1,9 +0,0 @@
[1 1 1,
1 1 1,
1 1 1]
[2 2 2,
2 2 2,
2 2 2]
[2]
-553
View File
@@ -1,553 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <dirent.h>
#include <sys/types.h>
#include <errno.h>
#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<n_add_tests;i++){
double *C = (double*) malloc(sizeof(*C)*add_tests[i].m * add_tests[i].n);
check(C != NULL);
lina_add(add_tests[i].A, add_tests[i].B, C,add_tests[i].m,add_tests[i].n);
if( !memcmp(add_tests[i].C, C, sizeof(*C)*add_tests[i].m * add_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_add() failed on the following matrices:\n");
pmatrix(stderr,add_tests[i].A, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"+\n");
pmatrix(stderr,add_tests[i].B, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"lina_add() gives following output:\n");
pmatrix(stderr,C, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,add_tests[i].C, add_tests[i].m, add_tests[i].n);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_add_tests != 0)
fprintf(stdout, "Test on lina_add() finished: %d out of %d tests were succesfull\n",passed_tests,n_add_tests);
else
fprintf(stdout, "There are no tests for lina_add() function.\n");
}
//Starting the lina_dot tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_dot():\n");
for(int i=0;i<n_dot_tests;i++){
double *C = (double*) malloc(sizeof(*C)*dot_tests[i].m * dot_tests[i].l);
check(C != NULL);
lina_dot(dot_tests[i].A, dot_tests[i].B, C, dot_tests[i].m, dot_tests[i].n, dot_tests[i].l);
if( !memcmp(dot_tests[i].C, C, sizeof(*C)*dot_tests[i].m * dot_tests[i].l) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_dot() failed on the following matrices:\n");
pmatrix(stderr,dot_tests[i].A, dot_tests[i].m, dot_tests[i].n);
fprintf(stderr,"*\n");
pmatrix(stderr,dot_tests[i].B, dot_tests[i].n, dot_tests[i].l);
fprintf(stderr,"lina_dot() gives following output:\n");
pmatrix(stderr,C, dot_tests[i].m, dot_tests[i].l);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,dot_tests[i].C, dot_tests[i].m, dot_tests[i].l);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_dot_tests != 0)
fprintf(stdout, "Test on lina_dot() finished: %d out of %d tests were succesfull\n",passed_tests,n_dot_tests);
else
fprintf(stdout, "There are no tests for lina_dot() function.\n");
}
//Starting the lina_transpose tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_transpose():\n");
for(int i=0;i<n_transpose_tests;i++){
double *C = (double*) malloc(sizeof(*C)*transpose_tests[i].m * transpose_tests[i].n);
check(C != NULL);
lina_transpose(transpose_tests[i].A, C, transpose_tests[i].m, transpose_tests[i].n);
if( !memcmp(transpose_tests[i].B, C, sizeof(*C)*transpose_tests[i].m * transpose_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_transpose() failed on the following matrices:\n");
pmatrix(stderr,transpose_tests[i].A, transpose_tests[i].m, transpose_tests[i].n);
fprintf(stderr,"lina_transpose() gives following output:\n");
pmatrix(stderr,C, transpose_tests[i].n, transpose_tests[i].m);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,transpose_tests[i].B, transpose_tests[i].n, transpose_tests[i].m);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_transpose_tests != 0)
fprintf(stdout, "Test on lina_transpose() finished: %d out of %d tests were succesfull\n",passed_tests,n_transpose_tests);
else
fprintf(stdout, "There are no tests for lina_transpose() function.\n");
}
//Starting the lina_scale tests
{
int passed_tests = 0;
fprintf(stdout,"\nStarting tests on lina_scale():\n");
for(int i=0;i<n_scale_tests;i++){
double *C = (double*) malloc(sizeof(*C)*scale_tests[i].m * scale_tests[i].n);
check(C != NULL);
lina_scale(scale_tests[i].A, C, scale_tests[i].s, scale_tests[i].m, scale_tests[i].n);
if( !memcmp(scale_tests[i].B, C, sizeof(*C)*scale_tests[i].m * scale_tests[i].n) )
passed_tests += 1;
else{
fprintf(stderr,"----------------------------------------------------\n");
fprintf(stderr,"Test on lina_scale() failed on the following matrices:\n");
pmatrix(stderr,scale_tests[i].A, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"lina_scale() gives following output:\n");
pmatrix(stderr, C, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"instead of:\n");
pmatrix(stderr,scale_tests[i].B, scale_tests[i].m, scale_tests[i].n);
fprintf(stderr,"----------------------------------------------------\n");
}
free(C);
}
if(n_scale_tests != 0)
fprintf(stdout, "Test on lina_scale() finished: %d out of %d tests were succesfull\n",passed_tests,n_scale_tests);
else
fprintf(stdout, "There are no tests for lina_scale() function.\n");
}
//Freeing the memory of all the heap variables
{
//Freeing add_tests memory
for(int i=0;i< n_add_tests;i++)
{
free(add_tests[i].A);
free(add_tests[i].B);
free(add_tests[i].C);
}
//Freeing dot_tests memory
for(int i=0;i< n_dot_tests;i++)
{
free(dot_tests[i].A);
free(dot_tests[i].B);
free(dot_tests[i].C);
}
//Freeing scale_tests memory
for(int i=0;i< n_scale_tests;i++)
{
free(scale_tests[i].A);
free(scale_tests[i].B);
}
//Freeing transpose_tests memory
for(int i=0;i< n_transpose_tests;i++)
{
free(transpose_tests[i].A);
free(transpose_tests[i].B);
}
}
return 0;
}
static void pmatrix(FILE *fp, double *A,int m,int n){
for(int i = 0; i<m; i++){
fprintf(fp, " | ");
for(int j = 0; j< n; j++)
fprintf(fp, "%g ",A[i*n + j]);
fprintf(fp, "|\n");
}
fprintf(fp, "\n");
}
-9
View File
@@ -1,9 +0,0 @@
[1 0 0 0,
0 2 0 0,
0 0 3 0,
0 0 0 4]
[1 0 0 0,
0 2 0 0,
0 0 3 0,
0 0 0 4]
-6
View File
@@ -1,6 +0,0 @@
[1 2,
3 4,
5 6]
[1 3 5,
2 4 6]
-9
View File
@@ -1,9 +0,0 @@
[1 2 3 4,
0 0 0 0,
0 0 0 0,
0 0 0 0]
[1 0 0 0,
2 0 0 0,
3 0 0 0,
4 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 1 0 0,
0 2 0 0,
0 3 0 0,
0 4 0 0]
[0 0 0 0,
1 2 3 4,
0 0 0 0,
0 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 0 1 0,
0 0 2 0,
0 0 3 0,
0 0 4 0]
[0 0 0 0,
0 0 0 0,
1 2 3 4,
0 0 0 0]
-9
View File
@@ -1,9 +0,0 @@
[0 0 0 0,
0 0 0 0,
0 0 0 0,
1 2 3 4]
[0 0 0 1,
0 0 0 2,
0 0 0 3,
0 0 0 4]
-7
View File
@@ -1,7 +0,0 @@
[1 0 0,
0 2 0,
0 0 3]
[1 0 0,
0 2 0,
0 0 3]
-7
View File
@@ -1,7 +0,0 @@
[1 2 3,
0 0 0,
0 0 0]
[1 0 0,
2 0 0,
3 0 0]
-7
View File
@@ -1,7 +0,0 @@
[0 0 1,
0 0 2,
0 0 3]
[0 0 0,
0 0 0,
1 2 3]
-6
View File
@@ -1,6 +0,0 @@
[1 2 3,
4 5 6]
[1 4,
2 5,
3 6]