 	}
 }
 
-__global__ void kernel(float * A_GPU, float * B_GPU, float * C_GPU) {
+__global__ void kernel(float * A_GPU, float * B_GPU, float * C_GPU, ArrayMetaData2D A_gpu_md, ArrayMetaData2D B_gpu_md) {
+	////////////////////////////////////
+	// Marcus's idea of how it should work
+	const int blockY = blockIdx.y; // the global block indexes
+	const int blockX = blockIdx.x;	
+	
+	// Get the reference to C starting at the row and column
+	// Essentially this is the whole block
+	// I've probably f'ed up the index
+	float * C_block = &C_GPU[A_gpu_md.dimension2 * blockY * BLOCK_SIZE + blockX * BLOCK_SIZE]
+	
+	const int sub_row = threadIdx.y; // valued from 0:blocksize-1
+	const int sub_col = threadIdx.x; // valued from 0:blocksize-1
+	
+	// Th value we're going to shove into the final array
+	volatile float my_final_value = 0.0f;
+	
+	// Let's loop over each block!
+	for (int i = 0; i < A_gpu_md.dimension2 / BLOCK_SIZE; m++) {
+		// Get the sub block
+		float * A_block = A_GPU[];
+		float * B_block = B_GPU[];
+	
+		// Here's all the shared memory we'll need
+		__shared__ float sharedA[BLOCK_SIZE][BLOCK_SIZE];
+		__shared__ float sharedB[BLOCK_SIZE][BLOCK_SIZE];
+
+		// Fill in that shared array with my column
+		sharedA[sub_row][sub_col] = A_block[];
+		sharedB[sub_row][sub_col] = B_block[];
+
+		// Sum up all the elements that go from 0:BLOCKSIZE
+		// So the row of A and the column of B for 0 to BLOCKSIZE
+		for (int j = 0; j < BLOCK_SIZE; e++) my_final_value += sharedA[sub_row][j] * sharedB[j][sub_col]
+	}
+	
+	C_block[sub_row * B_gpu_md.dimension1 + sub_col] = my_final_value;
+	//
+	////////////////////////////////////////////////	
 	int srow = 0;
 	int scol = 0;
 	int threadId = blockDim.x * blockIdx.x + threadIdx.x;

        double elapsed = (end - start) / (double) CLOCKS_PER_SEC;
        printf("Computation time in the CPU: %f seconds\n", elapsed);
	
	copyMatricesToGPU();
	kernel <<< 32, 32 >>>  (A_GPU, B_GPU, C_GPU);

	return 0;
}

//----------------------------------- host function definitions -----------------------------------------

void allocateAndInitializeAB();
void computeCpuMMM();/
void copyMatricesToGPU();
void copyResultFromGPU();
void compareHostAndGpuOutput();
void die(const char *error); 
void check_error(cudaError e);
__global__ void kernel(float * A_GPU, float * B_GPU, float * C_GPU, ArrayMetaData2D A_gpu_md, ArrayMetaData2D B_gpu_md);
//----------------------------------- CUDA function definitions -----------------------------------------

#define BLOCK_SIZE 10

//-------------------------------------------------------------------------------------------------------
int main(int argc, char **argv) {
