2022-08-09 18:53:53 +02:00
|
|
|
/*
|
2022-09-05 10:39:42 +02:00
|
|
|
* Copyright (C) 2022 NHR@FAU, University Erlangen-Nuremberg.
|
|
|
|
* All rights reserved. This file is part of MD-Bench.
|
|
|
|
* Use of this source code is governed by a LGPL-3.0
|
|
|
|
* license that can be found in the LICENSE file.
|
2022-08-09 18:53:53 +02:00
|
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
//---
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
|
|
|
#include <allocate.h>
|
|
|
|
#include <atom.h>
|
2022-08-12 18:12:29 +02:00
|
|
|
#include <device.h>
|
2022-08-09 18:53:53 +02:00
|
|
|
#include <pbc.h>
|
|
|
|
#include <util.h>
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-11 16:42:41 +02:00
|
|
|
extern int NmaxGhost;
|
|
|
|
extern int *PBCx, *PBCy, *PBCz;
|
2022-08-12 17:28:06 +02:00
|
|
|
static int c_NmaxGhost = 0;
|
|
|
|
static int *c_PBCx = NULL, *c_PBCy = NULL, *c_PBCz = NULL;
|
2022-08-09 18:53:53 +02:00
|
|
|
|
2022-08-12 17:28:06 +02:00
|
|
|
__global__ void computeAtomsPbcUpdate(DeviceAtom a, int nlocal, MD_FLOAT xprd, MD_FLOAT yprd, MD_FLOAT zprd) {
|
2022-08-09 18:53:53 +02:00
|
|
|
const int i = blockIdx.x * blockDim.x + threadIdx.x;
|
2022-08-12 17:28:06 +02:00
|
|
|
DeviceAtom *atom = &a;
|
|
|
|
if(i >= nlocal) {
|
2022-08-09 18:53:53 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atom_x(i) < 0.0) {
|
|
|
|
atom_x(i) += xprd;
|
|
|
|
} else if (atom_x(i) >= xprd) {
|
|
|
|
atom_x(i) -= xprd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atom_y(i) < 0.0) {
|
|
|
|
atom_y(i) += yprd;
|
|
|
|
} else if (atom_y(i) >= yprd) {
|
|
|
|
atom_y(i) -= yprd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (atom_z(i) < 0.0) {
|
|
|
|
atom_z(i) += zprd;
|
|
|
|
} else if (atom_z(i) >= zprd) {
|
|
|
|
atom_z(i) -= zprd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-12 17:28:06 +02:00
|
|
|
__global__ void computePbcUpdate(DeviceAtom a, int nlocal, int nghost, int* PBCx, int* PBCy, int* PBCz, MD_FLOAT xprd, MD_FLOAT yprd, MD_FLOAT zprd){
|
2022-08-09 18:53:53 +02:00
|
|
|
const int i = blockIdx.x * blockDim.x + threadIdx.x;
|
2022-08-12 17:28:06 +02:00
|
|
|
if(i >= nghost) {
|
2022-08-09 18:53:53 +02:00
|
|
|
return;
|
|
|
|
}
|
2022-08-11 16:42:41 +02:00
|
|
|
|
2022-08-12 17:28:06 +02:00
|
|
|
DeviceAtom* atom = &a;
|
2022-08-09 18:53:53 +02:00
|
|
|
int *border_map = atom->border_map;
|
|
|
|
atom_x(nlocal + i) = atom_x(border_map[i]) + PBCx[i] * xprd;
|
|
|
|
atom_y(nlocal + i) = atom_y(border_map[i]) + PBCy[i] * yprd;
|
|
|
|
atom_z(nlocal + i) = atom_z(border_map[i]) + PBCz[i] * zprd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update coordinates of ghost atoms */
|
|
|
|
/* uses mapping created in setupPbc */
|
2022-08-12 17:28:06 +02:00
|
|
|
void updatePbc_cuda(Atom *atom, Parameter *param, bool reneigh) {
|
2022-08-09 18:53:53 +02:00
|
|
|
const int num_threads_per_block = get_num_threads();
|
|
|
|
|
2022-08-12 17:28:06 +02:00
|
|
|
if(reneigh) {
|
|
|
|
memcpyToGPU(atom->d_atom.x, atom->x, sizeof(MD_FLOAT) * atom->Nmax * 3);
|
|
|
|
memcpyToGPU(atom->d_atom.type, atom->type, sizeof(int) * atom->Nmax);
|
2022-08-12 04:19:38 +02:00
|
|
|
|
|
|
|
if(c_NmaxGhost < NmaxGhost) {
|
2022-08-09 18:53:53 +02:00
|
|
|
c_NmaxGhost = NmaxGhost;
|
2022-08-12 04:19:38 +02:00
|
|
|
c_PBCx = (int *) reallocateGPU(c_PBCx, NmaxGhost * sizeof(int));
|
|
|
|
c_PBCy = (int *) reallocateGPU(c_PBCy, NmaxGhost * sizeof(int));
|
|
|
|
c_PBCz = (int *) reallocateGPU(c_PBCz, NmaxGhost * sizeof(int));
|
2022-08-12 17:28:06 +02:00
|
|
|
atom->d_atom.border_map = (int *) reallocateGPU(atom->d_atom.border_map, NmaxGhost * sizeof(int));
|
2022-08-09 18:53:53 +02:00
|
|
|
}
|
2022-08-12 04:19:38 +02:00
|
|
|
|
|
|
|
memcpyToGPU(c_PBCx, PBCx, NmaxGhost * sizeof(int));
|
|
|
|
memcpyToGPU(c_PBCy, PBCy, NmaxGhost * sizeof(int));
|
|
|
|
memcpyToGPU(c_PBCz, PBCz, NmaxGhost * sizeof(int));
|
2022-08-12 17:28:06 +02:00
|
|
|
memcpyToGPU(atom->d_atom.border_map, atom->border_map, NmaxGhost * sizeof(int));
|
|
|
|
cuda_assert("updatePbc.reneigh", cudaPeekAtLastError());
|
|
|
|
cuda_assert("updatePbc.reneigh", cudaDeviceSynchronize());
|
2022-08-09 18:53:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
MD_FLOAT xprd = param->xprd;
|
|
|
|
MD_FLOAT yprd = param->yprd;
|
|
|
|
MD_FLOAT zprd = param->zprd;
|
|
|
|
|
|
|
|
const int num_blocks = ceil((float)atom->Nghost / (float)num_threads_per_block);
|
2022-08-12 17:28:06 +02:00
|
|
|
computePbcUpdate<<<num_blocks, num_threads_per_block>>>(atom->d_atom, atom->Nlocal, atom->Nghost, c_PBCx, c_PBCy, c_PBCz, xprd, yprd, zprd);
|
|
|
|
cuda_assert("updatePbc", cudaPeekAtLastError());
|
|
|
|
cuda_assert("updatePbc", cudaDeviceSynchronize());
|
2022-08-09 18:53:53 +02:00
|
|
|
}
|
|
|
|
|
2022-08-12 17:28:06 +02:00
|
|
|
void updateAtomsPbc_cuda(Atom* atom, Parameter *param) {
|
2022-08-09 18:53:53 +02:00
|
|
|
const int num_threads_per_block = get_num_threads();
|
|
|
|
MD_FLOAT xprd = param->xprd;
|
|
|
|
MD_FLOAT yprd = param->yprd;
|
|
|
|
MD_FLOAT zprd = param->zprd;
|
|
|
|
|
|
|
|
const int num_blocks = ceil((float)atom->Nlocal / (float)num_threads_per_block);
|
2022-08-12 17:28:06 +02:00
|
|
|
computeAtomsPbcUpdate<<<num_blocks, num_threads_per_block>>>(atom->d_atom, atom->Nlocal, xprd, yprd, zprd);
|
2022-08-12 04:19:38 +02:00
|
|
|
cuda_assert("computeAtomsPbcUpdate", cudaPeekAtLastError());
|
|
|
|
cuda_assert("computeAtomsPbcUpdate", cudaDeviceSynchronize());
|
2022-08-12 17:28:06 +02:00
|
|
|
memcpyFromGPU(atom->x, atom->d_atom.x, sizeof(MD_FLOAT) * atom->Nlocal * 3);
|
2022-08-09 18:53:53 +02:00
|
|
|
}
|