split into CUDA and OpenMP implementations