From 6e68ec53b49d620260bee08d33d2e3135cd0a3af Mon Sep 17 00:00:00 2001
From: Chris Maffeo <cmaffeo2@illinois.edu>
Date: Tue, 16 Jan 2024 17:50:44 -0600
Subject: [PATCH] Fix issue with templated callSync function so that it can be
 used easily on functions taking rvalue arguments

---
 src/ParticlePatch.cpp | 28 +++++++++-------------------
 src/ParticlePatch.h   |  4 ++--
 src/Proxy.h           |  9 +++++----
 src/SimSystem.cpp     |  3 +--
 4 files changed, 17 insertions(+), 27 deletions(-)

diff --git a/src/ParticlePatch.cpp b/src/ParticlePatch.cpp
index 4bf45d8..3611eac 100644
--- a/src/ParticlePatch.cpp
+++ b/src/ParticlePatch.cpp
@@ -98,7 +98,7 @@ void Patch::compute() {
 
 // template<typename T>
 // size_t Patch::send_particles_filtered( Proxy<Patch>& destination, T filter ) {
-size_t Patch::send_particles_filtered( Proxy<Patch>* destination, std::function<bool(size_t,Patch::Data)> filter ) {
+size_t Patch::send_particles_filtered( Proxy<Patch>& destination, std::function<bool(size_t,Patch::Data)> filter ) {
 // TODO determine who allocates and cleans up temporary data
     // TODO determine if there is a good way to avoid having temporary data (this can be done later if delegated to a reasonable object)
 
@@ -108,28 +108,18 @@ size_t Patch::send_particles_filtered( Proxy<Patch>* destination, std::function<
     // TODO currently everything is sychronous, but that will change; how do we avoid race conditions?
     // E.g. have a single array allocated with known start and end for each PE/Patch?
     
-    Data buffer;		// not sure which object should allocate
-    { 
-    using _filter_t = decltype(filter);
-    // using A = decltype(destination->metadata.data);
-    using A = Proxy<Patch::Data>&;
-    // size_t num_sent = metadata.data.callSync<size_t,A>( &Patch::Data::send_particles_filtered, destination->metadata.data, filter );
-    // size_t num_sent = metadata.data.callSync<size_t,A>( static_cast<size_t (Patch::Data::*)(Proxy<Patch::Data>&, _filter_t)>(&Patch::Data::send_particles_filtered), destination->metadata.data, filter );
-
-    // size_t num_sent = metadata.data.callSync<size_t,A>( &Patch::Data::send_particles_filtered, destination->metadata.data, filter );
-    size_t num_sent = metadata.data.callSync( &Patch::Data::send_particles_filtered, &((*destination)->metadata.data), filter );
-
-    }
-    // size_t num_sent = metadata.data.callSync<size_t,Proxy<Patch::Data>&,_filter_t>( &Patch::Data::send_particles_filtered<_filter_t>, destination->metadata.data, filter );
-    return 0;
+    // Data buffer;		// not sure which object should allocate
+    size_t num_sent = metadata.data.callSync( &Patch::Data::send_particles_filtered,
+					      destination->metadata.data, filter );
+    return num_sent;
 };
 
 // template<typename T>
 // size_t Patch::Data::send_particles_filtered( Proxy<Patch::Data>& destination, T filter ) { }
-size_t Patch::Data::send_particles_filtered( Proxy<Patch::Data>* destination, std::function<bool(size_t,Patch::Data)> filter ) { 
-    Data buffer;		// not sure which object should allocate
-    // metadata.data.callSync( &Patch::Data::send_particles_filtered, destination, filter );
-    // x
+size_t Patch::Data::send_particles_filtered( Proxy<Patch::Data>& destination, std::function<bool(size_t,Patch::Data)> filter ) { 
+    // Data buffer;		// not sure which object should allocate
+    WARN("Patch::Data::send_particles_filtered() was called but is not implemented");
+    // metadata->data.callSync( &Patch::Data::send_particles_filtered, destination, filter );
     return 0;
 };
 
diff --git a/src/ParticlePatch.h b/src/ParticlePatch.h
index 2423565..fa03ef8 100644
--- a/src/ParticlePatch.h
+++ b/src/ParticlePatch.h
@@ -146,7 +146,7 @@ public:
 	// Replace with auto? Return number of particles sent?
 	// template<typename T>
 	// size_t send_particles_filtered( Proxy<Data>& destination, T filter ); // = [](size_t idx, Patch::Data d)->bool { return true; } );
-	size_t send_particles_filtered( Proxy<Data>* destination, std::function<bool(size_t,Data)> filter ); // = [](size_t idx, Patch::Data d)->bool { return true; } );
+	size_t send_particles_filtered( Proxy<Data>& destination, std::function<bool(size_t,Data)> filter ); // = [](size_t idx, Patch::Data d)->bool { return true; } );
 
     };
 
@@ -191,7 +191,7 @@ public:
     // template<typename T>
     // size_t send_particles_filtered( Proxy<Patch>& destination, T filter );
     // // [](size_t idx, Patch::Data d)->bool { return true; } );
-    size_t send_particles_filtered( Proxy<Patch>* destination, std::function<bool(size_t,Data)> filter );
+    size_t send_particles_filtered( Proxy<Patch>& destination, std::function<bool(size_t,Data)> filter );
     // [](size_t idx, Patch::Data d)->bool { return true; } );
 
     void clear() {
diff --git a/src/Proxy.h b/src/Proxy.h
index eeac2c1..f4b4c24 100644
--- a/src/Proxy.h
+++ b/src/Proxy.h
@@ -89,15 +89,16 @@ public:
 				//
 				// A: depends on how Proxy<Proxy<T>>
 				// objects are used
-    
-    template <typename RetType, typename... Args>
-    RetType callSync(RetType (T::*memberFunc)(Args...), Args&&... args) {
+
+    // Use two template parameter packs as suggested here: https://stackoverflow.com/questions/26994969/inconsistent-parameter-pack-deduction-with-variadic-templates
+    template <typename RetType, typename... Args1, typename... Args2>
+    RetType callSync(RetType (T::*memberFunc)(Args1...), Args2&&... args) {
         switch (location.type) {
             case Resource::CPU:
 	    // 	return ([&](auto&&... capturedArgs) {
             //     return (addr->*memberFunc)(std::forward<decltype(capturedArgs)>(capturedArgs)...);
             // })(std::forward<Args>(args)...);
-		return (addr->*memberFunc)(std::forward<Args>(args)...);
+		return (addr->*memberFunc)(std::forward<Args2>(args)...);
             case Resource::GPU:
                 // Handle GPU-specific logic
                 std::cerr << "Error: GPU not implemented in synchronous call." << std::endl;
diff --git a/src/SimSystem.cpp b/src/SimSystem.cpp
index bd5c13d..4fe9c39 100644
--- a/src/SimSystem.cpp
+++ b/src/SimSystem.cpp
@@ -52,9 +52,8 @@ void CellDecomposer::decompose(SimSystem& sys, ResourceCollection& resources) {
 	    using _filter_t = decltype(filter);
 	    // p.callSync<void,Proxy<Patch>,_filter_t>( &Patch::send_particles_filtered<_filter_t>, p2_p, filter );
 	    // p.callSync<size_t, Proxy<Patch>&, _filter_t>(static_cast<size_t (Patch::*)(Proxy<Patch>&, _filter_t)>(&Patch::send_particles_filtered<_filter_t>), p2_p, filter);
-	    p.callSync( &Patch::test ); // DEBUG
 	    // p.callSync<size_t, Proxy<Patch>&>( &Patch::send_particles_filtered, p2_p, filter);
-	    p.callSync( &Patch::send_particles_filtered, &p2_p, filter);
+	    p.callSync( &Patch::send_particles_filtered, p2_p, filter);
 	    
 	    num_particles += p.metadata->num;
 	}
-- 
GitLab