 		}
 		out_fit_train[0] = d / double(NROWS_TRAIN);
 	}
+	*/
 }
 
 extern "C" __global__
 void sem_fitness_test(double *set, double *sem_test, double *ls_a, double *ls_b, double *out_fit_test) {
-	int tig = blockIdx.x * blockDim.x + threadIdx.x;
+	__shared__ double shm[32]; // Warp size shared memory
+	int tig = blockIdx.x * blockDim.x + threadIdx.x;
+	int block_size = (NROWS_TEST + 32 - 1) / 32;
+
+	if (tig < 32) {
+		double a = *ls_a;
+		double b = *ls_b;
+		int start = block_size * tig;
+		int end = block_size * (tig + 1);
+		if (end > NROWS_TEST)
+			end = NROWS_TEST;
+		shm[tig] = 0;
+		for (int i = start; i < end; i++) {
+			double yy = getDataset(NUM_VARIABLE_SYMBOLS, i+NROWS_TRAIN, set);
+			shm[tig] += ERROR_FUNC(yy, a + b * sem_test[i]);
+		}
+	}
+	__syncthreads();
+
+	if (tig == 0) {
+		for (int i = 1; i < 32; i++) {
+			shm[0] += shm[i];
+		}
+		out_fit_test[1] = shm[0] / double(NROWS_TEST);
+	}
+
+	/*
 	if (tig == 0) {
 		double d = 0;
 		double a = *ls_a;

// Runs with only 2 threads, for this unoptimized version
extern "C" __global__
void sem_fitness_train(double *set, double *sem_train, double *out_fit_train, double *out_ls_a, double *out_ls_b) {
	int tig = blockIdx.x * blockDim.x + threadIdx.x;
	if (tig == 0) {
		double sum_out = 0; // Maybe initialize it to first value and start for loop with 1, faster?
		double sum_tar = 0;

		}
		out_fit_test[1] = d / double(NROWS_TEST);
	}
	*/
}

extern "C" __global__
