So I am in the process of translating a program I created in C. The goal of this program is to simply read a Matrix from a file, Compress the matrix in sparse row format, then calculate the matrix-vector product.
Here is a snippet of the program in C.
//Read the MatrixMarket file and initialize a CSR formatted matrix.
csr_load_matrix(fileName, &compressedSparseMatrix);
//Set the correct values to the struct and create the memory allocation.
double *x;
double *y;
x = malloc(compressedSparseMatrix.cols * sizeof(double));
y = malloc(compressedSparseMatrix.rows * sizeof(double));
//initialize the vector x
for(int i = 0; i < compressedSparseMatrix.cols; i++){
x[i]= i+1;
}
//Calculate how long it takes to find the Matrix-Vector Product for the CSR Matrix.
//Start the timer.
clock_t begin = clock();
for (int i = 0; i < iterations; i++) {
csrMVP(&compressedSparseMatrix, x, y);
}
clock_t end = clock();
double totalTimeSpent = (double) (end - begin) / CLOCKS_PER_SEC;
This is my Main.c and my csrMVP function is attached below:
int csrMVP(CSR_Matrix *funcMatrix, double *x, double *y){
unsigned int i, j;
unsigned int k = 0;
double *value = funcMatrix->val;
unsigned int *column = funcMatrix->col;
unsigned int *rowPointer = funcMatrix->ptr;
double hold;
for(i = 0; i < funcMatrix->rows; i++){
hold = 0.0;
j = k;
k = rowPointer[i+1];
for(j; j < k; j++){
y[i] = y[i] + value[j] * x[i];
}
}
}
My program runs perfectly in C. The idea here is that I want to calculate the MVP 1000 times and see how fast/slow my compiler can do it.
So now My next goal is to use concurrency in GoLang to compare how fast Golang can execute the MVP process 1000 times.
Here is the start of my Golang program: (for the sake of space pretend []float64{...}
is a big matrix.)
func main(){
var interation int
m := mat64.NewDense(32, 32, []float64{...})
//csr_print_matrix(m)
//m.CSRPrint()
//var y []float64
y := make([]float64, 32)
x := make([]int, 32)
for i := range x {
x[i] = i + 1
}
interation = 2
start := time.Now()
for i := 0; i < interation; i ++ {
m.CSRMVP(x, y)
}
elapsed := time.Since(start)
log.Printf("Matrix took %s", elapsed)
}
And my m.CSRMVP() func is:
func (m *Dense) CSRMVP(x []int, y []float64){
fmt.Println("Value of Y:")
var j,end, newY int
var values []float64
var col_indices, row_ptr []int
values = m.mat.Data
end = 0
for i := 0; i < m.capCols; i++{
y[i] = 0.0
newY = int(y[i])
j = end
end = row_ptr[i+1]
for ; j < end; j++ {
newY = newY + int(values[j]) * x[col_indices[j]]
fmt.Print(newY)
y[i] = float64(newY)
}
}
}
The issue appears to be a memory allocation problem with passing variables x and y.
This is the output of my program running MVP just once.
panic: runtime error: index out of range
goroutine 1 [running]:
github.com/gonum/matrix/mat64.(*Dense).CSRMVP(0xc42001e100, 0xc420055d50, 0x20, 0x20, 0xc420055e50, 0x20, 0x20)
/Users/jeanmac/go/src/github.com/gonum/matrix/mat64/dense.go:573 +0x215
main.main()
/Users/jeanmac/go/src/matrices/main.go:75 +0x16c
I am still learning Go as I go along. My goal was just to see what's faster. I believe my error is due to incorrect memory allocation for x and y. in C I call Malloc to create the memory I need for these variables and im not sure what the alternative is for Go.
Line 573 in dense.go corresponding:
end = row_ptr[i+1]
Line 75 in main.go corresponding:
m.CSRMVP(x, y)