 	if (i >= d_m.getHeight() || j >= d_m.getWidth())
 		return;
 	
-	atomicAdd(&block_result[threadIdx.x], d_m[i][j] * d_v[j]);
+	atomicAdd(&block_result[threadIdx.x], d_m.get(i, j) * d_v[j]);
 	__syncthreads();
 	
 	if (threadIdx.y == 0)

			cudaMemset(data_, 0, size_ * sizeof(float));
	}
	
	__device__ __host__ float& operator[](const unsigned int &x) const {
		return data_[x];
	}

		
		public:
			__device__ __host__ MatrixRow(const Matrix &m, const unsigned int &x) : m_(m), x_(x) {}
			
			/*
				WARNING
				Prefer using .get(x, y)
				for performances
			*/
			__device__ __host__ float& operator[](const unsigned int &y) const {
				return m_.data_[x_ * m_.width_ + y];
			}
	};
	
	/*
		Return the ith element of the matrix
		Equivalent to:
			(*this)[row][col]
		With:
			row = i / width_
			col = i % width_
		
		More efficient to retrieve an element
		It avoids having to create an instance of MatrixRow
		
		(*this).get(x * width_ + y) is more efficient than (*this)[x][y]
	*/
	__device__ __host__ float& get(const unsigned int &i) const {
		return data_[i];
	}
	
	/*
		More efficient than [][] to retrieve an element
		(*this).get(x, y) is more efficient than (*this)[x][y]
	*/
	__device__ __host__ float& get(const unsigned int &i, const unsigned int &j) const {
		return data_[i * width_ + j];
	}
		
	__device__ __host__ MatrixRow operator[](const unsigned int &x) const {
		return MatrixRow(*this, x);
	}
