 	block = (h_network->_layers[h_network->_nb_layers-1]._X_size < MAX_NB_THREADS ? h_network->_layers[h_network->_nb_layers-1]._X_size : MAX_NB_THREADS);
 	grid = h_network->_layers[h_network->_nb_layers-1]._X_size / MAX_NB_THREADS + (h_network->_layers[h_network->_nb_layers-1]._X_size%MAX_NB_THREADS ? 1 : 0);
 	gpu_propagateFront_setOutput<<<grid, block>>>(d_network, out_computed);
-	cudaDeviceSynchronize();
 }
 
 __global__ void gpu_propagateBackFirstDerivate_setXError(struct neural_network *network, pop::F32* desired_output, unsigned int in_elt_size, unsigned int idx, int l) {

	struct layer* _layers;
};

const int EPOCH=13;

static std::string getCurrentTime() {
	time_t rawtime;

		block = (nb_weights < MAX_NB_THREADS ? nb_weights : MAX_NB_THREADS);
		grid = nb_weights / MAX_NB_THREADS + (nb_weights%MAX_NB_THREADS ? 1 : 0);
		gpu_propagateBackFirstDerivate_setWeight<<<grid, block>>>(d_network, l);

#if 0
		// quite slow: 5m30 per epoch...
		int Y_max = h_network->_layers[l]._Y_size;
		block = (Y_max < MAX_NB_THREADS ? Y_max : MAX_NB_THREADS);
		grid = Y_max / MAX_NB_THREADS + (Y_max%MAX_NB_THREADS ? 1 : 0);
		gpu_propagateBackFirstDerivate_setWeight_v2<<<grid, block, Y_max * sizeof(pop::F32)>>>(d_network, l, Y_max);
#endif

		// _d_E_X[l-1][j] = sum_{i=0}^{_W[l-1].sizeI()}{_W[l](i, j) * _d_E_Y[l](i)}, j=0 to _X[l].size()
		block = (h_network->_layers[l-1]._X_size < MAX_NB_THREADS ? h_network->_layers[l-1]._X_size : MAX_NB_THREADS);
		grid = h_network->_layers[l-1]._X_size / MAX_NB_THREADS + (h_network->_layers[l-1]._X_size%MAX_NB_THREADS ? 1 : 0);
		gpu_propagateBackFirstDerivate_setPreviousXError<<<grid, block>>>(d_network, l);
	}
}

