#pragma TASS input { SIZE == 15 }
int SIZE;
#pragma TASS input 
float v_input[SIZE][SIZE*SIZE];
#pragma TASS input 
float t_input[SIZE*SIZE];
#pragma TASS input 
int vi_input[SIZE];
#pragma TASS input 
float s_input[SIZE];
#pragma TASS output 
float s_output[SIZE];

/* bs: read only
 * s: read and written
 * v: read only
 * t: read only
 * vi : read only
 */
void dgemv(int bs, float *s, float **v, float *t, int  *vi ) {
	float *x[SIZE];
	int k;
	int j;
	int cntr;
	
	for (cntr = 0; cntr < SIZE; cntr++) {
		x[cntr] = t + bs * (*vi);
		vi = vi + 1;	
		for (j=0; j<bs; j++){
			for (k=0; k<bs; k++){
				s[k] -= v[cntr][bs* j+k] * x[cntr][j];
			}
		}
	}	
}

void main() {
	float* v[SIZE];
	float s[SIZE];
	int i;
    
	for (i = 0; i < SIZE; i++) {
		v[i] = &v_input[i][0];
		s[i] = s_input[i];
#pragma TASS assume vi_input[i] >= 0 && vi_input[i] < SIZE;
	}  
	dgemv(SIZE, &s[0], &v[0], &t_input[0], &vi_input[0]);
	for (i = 0; i < SIZE; i++) s_output[i] = s[i];
}