diff --git a/src/ParticlePatch.h b/src/ParticlePatch.h index 62ca1c9c6b7dd2870d5c83a7a1a0d10bf1188937..52e6266b118f0177df31205467081cfb9210dfbf 100644 --- a/src/ParticlePatch.h +++ b/src/ParticlePatch.h @@ -161,7 +161,6 @@ private: std::vector<std::unique_ptr<PatchOp>> nonlocal_computes; // Operations that will be performed on this patch each timestep // CPU particle arrays - struct Data { VectorArr* pos_force; VectorArr* momentum; diff --git a/src/Proxy.h b/src/Proxy.h index 654c852a114cab4044dfa439b017d20dd2e7e5db..bec32e21995bbd15ef6c49725188294c1c45636c 100644 --- a/src/Proxy.h +++ b/src/Proxy.h @@ -3,16 +3,24 @@ #include <iostream> #include "ARBDException.h" +/** + * @brief Represents a resource that can store data and perform computations. + */ struct Resource { - // Represents something that can store data and compute things + /** + * @brief Enum to specify the type of the resource (e.g., CPU or GPU). + */ enum ResourceType {CPU, GPU}; - ResourceType type; - size_t id; // maybe something else + ResourceType type; ///< Type of the resource. + size_t id; ///< ID or any other identifier associated with the resource. // HOST DEVICE static bool is_local() { // check if thread/gpu idx matches some global idx }; }; // START traits // https://stackoverflow.com/questions/55191505/c-compile-time-check-if-method-exists-in-template-type +/** + * @brief Template trait to check if a method 'send_children' exists in a type. + */ #include <type_traits> template <typename T, typename = void> struct has_send_children : std::false_type {}; @@ -22,20 +30,42 @@ struct has_send_children<T, decltype(std::declval<T>().send_children(Resource{Re // END traits -// Template argument is concrete class with data to be proxied -// 'Proxy' is probably a bad name because this is not quite the GoF Proxy Pattern +/** + * @brief Template class representing a proxy for the underlying data. + * @tparam T The type of the underlying data. + */ template<typename T> class Proxy { public: + + /** + * @brief Default constructor initializes the location to a default CPU resource and the address to nullptr. + */ Proxy<T>() : location(Resource{Resource::CPU,0}), addr(nullptr) {}; Proxy<T>(const Resource& r, T* obj) : location(r), addr(obj) {}; + + /** + * @brief Overloaded operator-> returns the address of the underlying object. + * @return The address of the underlying object. + */ auto operator->() { return addr; } auto operator->() const { return addr; } - Resource location; - T* addr; -}; + /** + * @brief The resource associated with the data represented by the proxy. + */ + Resource location; ///< The device (thread/gpu) holding the data represented by the proxy. + T* addr; ///< The address of the underlying object. +}; +/** + * @brief Template function to send data ignoring children to a specified location. + * @tparam T The type of the data to be sent. + * @param location The destination resource for the data. + * @param obj The data to be sent. + * @param dest Optional parameter to provide a pre-allocated destination. If not provided, memory is allocated. + * @return A Proxy representing the data at the destination location. + */ template <typename T> HOST inline Proxy<T> _send_ignoring_children(const Resource& location, T& obj, T* dest = nullptr) { switch (location.type) { @@ -58,7 +88,15 @@ HOST inline Proxy<T> _send_ignoring_children(const Resource& location, T& obj, T return Proxy<T>(location, dest); } -// This ugly template allows overloading copy_to_cuda, depending on whether T.copy_to_cuda exists using C++14-compatible SFINAE +/** + * @brief Template function to send simple objects to a specified location without considering child objects. + * This version will be selected upon send(location, obj) if obj.send_children does not exist (C++14-compatible SFINAE) + * @tparam T The type of the data to be sent. + * @param location The destination resource for the data. + * @param obj The data to be sent. + * @param dest Optional parameter to provide a pre-allocated destination. If not provided, memory is allocated. + * @return A Proxy representing the data at the destination location. + */ template <typename T, typename Dummy = void, typename std::enable_if_t<!has_send_children<T>::value, Dummy>* = nullptr> HOST inline Proxy<T> send(const Resource& location, T& obj, T* dest = nullptr) { printf("Sending object %s @%x to device at %x\n", type_name<T>().c_str(), &obj, dest); @@ -69,6 +107,15 @@ HOST inline Proxy<T> send(const Resource& location, T& obj, T* dest = nullptr) { return ret; } +/** + * @brief Template function to send more complex objects to a specified location. + * This version will be selected upon send(location, obj) if obj.send_children exists (C++14-compatible SFINAE) + * @tparam T The type of the data to be sent. + * @param location The destination resource for the data. + * @param obj The data to be sent. + * @param dest Optional parameter to provide a pre-allocated destination. If not provided, memory is allocated on the GPU. + * @return A Proxy representing the data at the destination location. + */ template <typename T, typename Dummy = void, typename std::enable_if_t<has_send_children<T>::value, Dummy>* = nullptr> HOST inline Proxy<T> send(const Resource& location, T& obj, T* dest = nullptr) { printf("Sending object %s @%x to device at %x\n", type_name<T>().c_str(), &obj, dest);