From f7eefa416ec1fe5f0777f7c1ab7302af0ad27eab Mon Sep 17 00:00:00 2001
From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa>
Date: Fri, 20 May 2011 22:29:46 +0000
Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@6194
 f3b2605a-c512-4ea7-a41b-209d697bcdaa

---
 src/neighbor.cpp | 12 +++++++++---
 src/neighbor.h   | 21 ++++++++++++---------
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/src/neighbor.cpp b/src/neighbor.cpp
index fc4f1125e5..e8ecccc9a0 100644
--- a/src/neighbor.cpp
+++ b/src/neighbor.cpp
@@ -480,11 +480,11 @@ void Neighbor::init()
     // fix/compute requests:
     //   kind of request = half or full, occasional or not doesn't matter
     //   if request = half and non-skip pair half/respaouter exists,
-    //     become copy of that list
+    //     become copy of that list if cudable flag matches
     //   if request = full and non-skip pair full exists,
-    //     become copy of that list
+    //     become copy of that list if cudable flag matches
     //   if request = half and non-skip pair full exists,
-    //     become half_from_full of that list
+    //     become half_from_full of that list if cudable flag matches
     //   if no matches, do nothing, fix/compute list will be built directly
     //   ok if parent is copy list
 
@@ -534,6 +534,8 @@ void Neighbor::init()
 	  if (requests[i]->half && requests[j]->pair &&
 	      requests[j]->skip == 0 && requests[j]->respaouter) break;
 	}
+	if (j < nlist && requests[j]->cudable != requests[i]->cudable)
+	  j = nlist;
 	if (j < nlist) {
 	  requests[i]->copy = 1;
 	  lists[i]->listcopy = lists[j];
@@ -542,6 +544,8 @@ void Neighbor::init()
 	    if (requests[i]->half && requests[j]->pair &&
 		requests[j]->skip == 0 && requests[j]->full) break;
 	  }
+	  if (j < nlist && requests[j]->cudable != requests[i]->cudable)
+	    j = nlist;
 	  if (j < nlist) {
 	    requests[i]->half = 0;
 	    requests[i]->half_from_full = 1;
@@ -553,11 +557,13 @@ void Neighbor::init()
 
     // set ptrs to pair_build and stencil_create functions for each list
     // ptrs set to NULL if not set explicitly
+    // also set cudable to 0 if any neigh list request is not cudable
 
     for (i = 0; i < nlist; i++) {
       choose_build(i,requests[i]);
       if (style != NSQ) choose_stencil(i,requests[i]);
       else stencil_create[i] = NULL;
+      if (!requests[i]->cudable) cudable = 0;
     }
 
     // set each list's build/grow/stencil/ghost flags based on neigh request
diff --git a/src/neighbor.h b/src/neighbor.h
index 607a145a73..c2fa635d63 100644
--- a/src/neighbor.h
+++ b/src/neighbor.h
@@ -19,6 +19,8 @@
 namespace LAMMPS_NS {
 
 class Neighbor : protected Pointers {
+  friend class Cuda;
+
  public:
   int style;                       // 0,1,2 = nsq, bin, multi
   int every;                       // build every this many steps
@@ -29,6 +31,7 @@ class Neighbor : protected Pointers {
   int oneatom;                     // max # of neighbors for one atom
   int includegroup;                // only build pairwise lists for this group
   int build_once;                  // 1 if only build lists once per run
+  int cudable;                     // GPU <-> CPU communication flag for CUDA
 
   double skin;                     // skin distance
   double cutneighmin;              // min neighbor cutoff for all type pairs
@@ -61,15 +64,15 @@ class Neighbor : protected Pointers {
 
   Neighbor(class LAMMPS *);
   virtual ~Neighbor();
-  void init();
-  int request(void *);         // another class requests a neighbor list
-  void print_lists_of_lists(); // debug print out
-  int decide();                // decide whether to build or not
-  int check_distance();        // check max distance moved since last build
-  void setup_bins();           // setup bins based on box and cutoff
-  void build();                // create all neighbor lists (pair,bond)
-  void build_one(int);         // create a single neighbor list
-  void set(int, char **);      // set neighbor style and skin distance
+  virtual void init();
+  int request(void *);              // another class requests a neighbor list
+  void print_lists_of_lists();      // debug print out
+  int decide();                     // decide whether to build or not
+  virtual int check_distance();     // check max distance moved since last build
+  void setup_bins();                // setup bins based on box and cutoff
+  virtual void build();             // create all neighbor lists (pair,bond)
+  void build_one(int);              // create a single neighbor list
+  void set(int, char **);           // set neighbor style and skin distance
   void modify_params(int, char**);  // modify parameters that control builds
   bigint memory_usage();