From 7b7fcf427c12445a90adfccc3d34bab222aefaf7 Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 17:58:56 +0300 Subject: [PATCH 1/6] Added fake default constructors + minor Fixed a TODO item --- src/simulation_objects/MapNode.cu | 5 +++++ src/simulation_objects/MapNode.cuh | 11 +++++++++++ src/simulation_objects/Particle.cuh | 14 ++++++++++++++ src/simulation_objects/SimulationMap.cu | 5 +++++ src/simulation_objects/SimulationMap.cuh | 11 +++++++++++ src/simulation_objects/geometric/Face.cu | 5 +++++ src/simulation_objects/geometric/Face.cuh | 11 +++++++++++ src/simulation_objects/geometric/Polyhedron.cu | 5 +++++ src/simulation_objects/geometric/Polyhedron.cuh | 11 +++++++++++ 9 files changed, 78 insertions(+) diff --git a/src/simulation_objects/MapNode.cu b/src/simulation_objects/MapNode.cu index 332b516..cccc37c 100644 --- a/src/simulation_objects/MapNode.cu +++ b/src/simulation_objects/MapNode.cu @@ -37,6 +37,11 @@ __host__ __device__ MapNode::MapNode(MapNode &&other) noexcept *this = std::move(other); } +__host__ __device__ MapNode::MapNode() +{ + particle = nullptr; +} + __host__ __device__ MapNode::~MapNode() { delete particle; diff --git a/src/simulation_objects/MapNode.cuh b/src/simulation_objects/MapNode.cuh index ec2f2fb..3244da3 100644 --- a/src/simulation_objects/MapNode.cuh +++ b/src/simulation_objects/MapNode.cuh @@ -55,6 +55,17 @@ public: /// `MapNode` object move constructor __host__ __device__ MapNode(MapNode &&other) noexcept; + /** + * Creates a fake `MapNode` object + * + * Creates a `MapNode` object such that it can be destructed safely, but must not be used for any purposes. All the + * fields, which don't take part in the destruction, stay uninitialized. + * + * @warning The behaviour is undefined if you use the object constructed with this constructor in any way but + * destructing it (the object can be destructed safely) + */ + __host__ __device__ MapNode(); + /// Destructs a `MapNode` object __host__ __device__ ~MapNode(); diff --git a/src/simulation_objects/Particle.cuh b/src/simulation_objects/Particle.cuh index 8607c58..0e70433 100644 --- a/src/simulation_objects/Particle.cuh +++ b/src/simulation_objects/Particle.cuh @@ -53,6 +53,20 @@ public: */ __host__ __device__ Particle(Particle &&other) noexcept = delete; + /** + * Creates a fake `Particle` object + * + * Creates a `Particle` object such that it can be destructed safely, but must not be used for any purposes. All the + * fields, which don't take part in the destruction, stay uninitialized. + * + * @warning The behaviour is undefined if you use the object constructed with this constructor in any way but + * destructing it (the object can be destructed safely) + * + * @note `Particle` has the default destructor, automatically generated by a compiler. So this constructor does + * nothing. It was added for compatibility with other classes + */ + /* Automatically becomes `__host__ __device__`*/ Particle() = default; + /** * Moves particle in the direction in which the particle is rotated diff --git a/src/simulation_objects/SimulationMap.cu b/src/simulation_objects/SimulationMap.cu index a60ee98..8727d24 100644 --- a/src/simulation_objects/SimulationMap.cu +++ b/src/simulation_objects/SimulationMap.cu @@ -146,6 +146,11 @@ __host__ __device__ SimulationMap::SimulationMap(SimulationMap &&other) noexcept *this = std::move(other); } +__host__ __device__ SimulationMap::SimulationMap() +{ + nodes = nullptr; +} + __device__ SimulationMap::~SimulationMap() { free(nodes); diff --git a/src/simulation_objects/SimulationMap.cuh b/src/simulation_objects/SimulationMap.cuh index 4371fdb..e810df9 100644 --- a/src/simulation_objects/SimulationMap.cuh +++ b/src/simulation_objects/SimulationMap.cuh @@ -42,6 +42,17 @@ public: /// `SimulationMap` object move constructor __host__ __device__ SimulationMap(SimulationMap &&other) noexcept; + /** + * Creates a fake `SimulationMap` object + * + * Creates a `SimulationMap` object such that it can be destructed safely, but must not be used for any purposes. + * All the fields, which don't take part in the destruction, stay uninitialized. + * + * @warning The behaviour is undefined if you use the object constructed with this constructor in any way but + * destructing it (the object can be destructed safely) + */ + __host__ __device__ SimulationMap(); + /// Destructs a `SimulationMap` object __device__ ~SimulationMap(); diff --git a/src/simulation_objects/geometric/Face.cu b/src/simulation_objects/geometric/Face.cu index 7e44d3e..e44f16e 100644 --- a/src/simulation_objects/geometric/Face.cu +++ b/src/simulation_objects/geometric/Face.cu @@ -57,6 +57,11 @@ __host__ __device__ Face::Face(Face &&other) noexcept *this = std::move(other); } +__host__ __device__ Face::Face() +{ + vertices = nullptr; +} + __host__ __device__ Face::~Face() { free((void *)vertices); diff --git a/src/simulation_objects/geometric/Face.cuh b/src/simulation_objects/geometric/Face.cuh index 6a07d01..ff80a43 100644 --- a/src/simulation_objects/geometric/Face.cuh +++ b/src/simulation_objects/geometric/Face.cuh @@ -74,6 +74,17 @@ public: */ __host__ __device__ Face(Face &&other) noexcept; + /** + * Creates a fake `Face` object + * + * Creates a `Face` object such that it can be destructed safely, but must not be used for any purposes. All the + * fields, which don't take part in the destruction, stay uninitialized. + * + * @warning The behaviour is undefined if you use the object constructed with this constructor in any way but + * destructing it (the object can be destructed safely) + */ + __host__ __device__ Face(); + /// Destructs a `Face` object __host__ __device__ ~Face(); diff --git a/src/simulation_objects/geometric/Polyhedron.cu b/src/simulation_objects/geometric/Polyhedron.cu index 04b129d..d22f378 100644 --- a/src/simulation_objects/geometric/Polyhedron.cu +++ b/src/simulation_objects/geometric/Polyhedron.cu @@ -48,6 +48,11 @@ __host__ __device__ Polyhedron::Polyhedron(Polyhedron &&other) noexcept *this = std::move(other); } +__host__ __device__ Polyhedron::Polyhedron() +{ + faces = nullptr; +} + __host__ __device__ Polyhedron::~Polyhedron() { free((void *)faces); diff --git a/src/simulation_objects/geometric/Polyhedron.cuh b/src/simulation_objects/geometric/Polyhedron.cuh index 2be15bf..26c2cc0 100644 --- a/src/simulation_objects/geometric/Polyhedron.cuh +++ b/src/simulation_objects/geometric/Polyhedron.cuh @@ -52,6 +52,17 @@ public: */ __host__ __device__ Polyhedron(Polyhedron &&other) noexcept; + /** + * Creates a fake `Polyhedron` object + * + * Creates a `Polyhedron` object such that it can be destructed safely, but must not be used for any purposes. All + * the fields, which don't take part in the destruction, stay uninitialized. + * + * @warning The behaviour is undefined if you use the object constructed with this constructor in any way but + * destructing it (the object can be destructed safely) + */ + __host__ __device__ Polyhedron(); + /// Destructs a `Polyhedron` object __host__ __device__ ~Polyhedron(); From c970dd3408adead6e7efc7fbe7520b27aa010c0a Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 18:03:09 +0300 Subject: [PATCH 2/6] `malloc_and_copy` -> `newalloc_and_copy`, replaced `free`s with `delete[]`s Also fixes a doc of `newalloc_and_copy` --- src/common.cuh | 8 ++++---- src/simulation_objects/geometric/Face.cu | 6 +++--- src/simulation_objects/geometric/Polyhedron.cu | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/common.cuh b/src/common.cuh index b53e22b..f036182 100644 --- a/src/common.cuh +++ b/src/common.cuh @@ -16,19 +16,19 @@ /** - * Returns pointer to a copied array + * Allocates a new array of size `count` of type `T` with the operator `new` * * @tparam T Type of an array * - * @param source Pointer-represented array to copy + * @param source Copied pointer-represented array * @param count Number of elements to copy * * @returns Pointer to a copied array */ template -__host__ __device__ static T *malloc_and_copy(const T *source, int count) +__host__ __device__ static T *newalloc_and_copy(const T *source, int count) { - T *new_array = (T *)malloc(count * sizeof(T)); + T *new_array = new T[count]; for(int i = 0; i < count; ++i) { new_array[i] = source[i]; diff --git a/src/simulation_objects/geometric/Face.cu b/src/simulation_objects/geometric/Face.cu index e44f16e..c4c2e10 100644 --- a/src/simulation_objects/geometric/Face.cu +++ b/src/simulation_objects/geometric/Face.cu @@ -14,7 +14,7 @@ __host__ __device__ SpacePoint calculate_normal(const SpacePoint *vertices) __host__ __device__ Face::Face(const SpacePoint *vertices, int n_of_vertices) : - vertices(malloc_and_copy(vertices, n_of_vertices)), n_of_vertices(n_of_vertices), + vertices(newalloc_and_copy(vertices, n_of_vertices)), n_of_vertices(n_of_vertices), normal(calculate_normal(vertices)), node(nullptr) { @@ -24,7 +24,7 @@ __host__ __device__ Face &Face::operator=(const Face &other) { if(this != &other) { - vertices = malloc_and_copy(other.vertices, other.n_of_vertices); + vertices = newalloc_and_copy(other.vertices, other.n_of_vertices); n_of_vertices = other.n_of_vertices; normal = other.normal; node = nullptr; @@ -64,7 +64,7 @@ __host__ __device__ Face::Face() __host__ __device__ Face::~Face() { - free((void *)vertices); + delete[] vertices; } diff --git a/src/simulation_objects/geometric/Polyhedron.cu b/src/simulation_objects/geometric/Polyhedron.cu index d22f378..797d476 100644 --- a/src/simulation_objects/geometric/Polyhedron.cu +++ b/src/simulation_objects/geometric/Polyhedron.cu @@ -10,7 +10,7 @@ __host__ __device__ Polyhedron::Polyhedron(Face *faces, int n_of_faces) : - faces(malloc_and_copy(faces, n_of_faces)), n_of_faces(n_of_faces) + faces(newalloc_and_copy(faces, n_of_faces)), n_of_faces(n_of_faces) { } @@ -19,7 +19,7 @@ __host__ __device__ Polyhedron &Polyhedron::operator=(const Polyhedron &other) { if(this != &other) { - faces = malloc_and_copy(other.faces, other.n_of_faces); + faces = newalloc_and_copy(other.faces, other.n_of_faces); n_of_faces = other.n_of_faces; } return *this; @@ -55,7 +55,7 @@ __host__ __device__ Polyhedron::Polyhedron() __host__ __device__ Polyhedron::~Polyhedron() { - free((void *)faces); + delete[] faces; } From bd8280f3f0e2e56ae63e82e4ba5bd909d4c245a9 Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 18:14:34 +0300 Subject: [PATCH 3/6] Replaced `malloc`/`free`s with `new[]`/`delete[]`s in SimulationMap.cu Removed the `.detach_particle()` line, mentioned in #32 --- src/simulation_objects/SimulationMap.cu | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/simulation_objects/SimulationMap.cu b/src/simulation_objects/SimulationMap.cu index 8727d24..4e5338e 100644 --- a/src/simulation_objects/SimulationMap.cu +++ b/src/simulation_objects/SimulationMap.cu @@ -30,7 +30,7 @@ __device__ SimulationMap::SimulationMap(Polyhedron *polyhedron) : SpacePoint start_node_coordinates = (start_face->get_vertices()[0] + start_face->get_vertices()[1] + start_face->get_vertices()[2]) / 3; - nodes = (MapNode *)malloc(sizeof(MapNode) * max_number_of_nodes); + nodes = new MapNode[max_number_of_nodes]; nodes[0] = MapNode(polyhedron, start_face, start_node_coordinates); n_of_nodes = 1; @@ -43,7 +43,7 @@ __device__ SimulationMap::SimulationMap(Polyhedron *polyhedron) : * Array of direction vectors to top neighbors for each polyhedron face * `top_neighbor_directions_for_faces[i]` corresponds to `polyhedron->get_faces()[i]` (i. e. indexes are same) */ - auto *top_neighbor_directions_for_faces = (SpacePoint *)malloc(sizeof(SpacePoint) * polyhedron->get_n_of_faces()); + auto *top_neighbor_directions_for_faces = new SpacePoint[polyhedron->get_n_of_faces()]; top_neighbor_directions_for_faces[find_face_index(start_face)] = direction_vector * mapnode_dist / get_distance(direction_vector, origin); @@ -51,7 +51,7 @@ __device__ SimulationMap::SimulationMap(Polyhedron *polyhedron) : * Boolean array where i-th element tells whether the i-th face have nodes or not * `does_face_have_nodes[i]` value corresponds to `polyhedron->faces[i]` face */ - auto *does_face_have_nodes = (bool *)malloc(sizeof(bool) * polyhedron->get_n_of_faces()); + auto *does_face_have_nodes = new bool[polyhedron->get_n_of_faces()]; does_face_have_nodes[0] = true; for(int i = 1; i < polyhedron->get_n_of_faces(); ++i) does_face_have_nodes[i] = false; @@ -123,8 +123,8 @@ __device__ SimulationMap::SimulationMap(Polyhedron *polyhedron) : } } - free(top_neighbor_directions_for_faces); - free(does_face_have_nodes); + delete[] top_neighbor_directions_for_faces; + delete[] does_face_have_nodes; } __host__ __device__ SimulationMap &SimulationMap::operator=(SimulationMap &&other) noexcept @@ -153,7 +153,7 @@ __host__ __device__ SimulationMap::SimulationMap() __device__ SimulationMap::~SimulationMap() { - free(nodes); + delete[] nodes; } @@ -268,7 +268,7 @@ __device__ int SimulationMap::get_neighbor_node_id(int current_node_id, SpacePoi else if(current_face == next_face || !does_face_have_nodes[next_face_index]) { // Neighbor node does not exist, but it can be created - nodes[n_of_nodes].detach_particle(); + nodes[n_of_nodes] = MapNode(polyhedron, next_face, neighbor_coordinates); set_direction_to_top_neighbor(current_node_id, n_of_nodes, top_neighbor_directions_for_faces, angle); From 0ed4c807400f8bdcd4eb63ebeed8840efa803230 Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 18:24:19 +0300 Subject: [PATCH 4/6] `MapNode`: TODOs, docs --- src/simulation_objects/MapNode.cuh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/simulation_objects/MapNode.cuh b/src/simulation_objects/MapNode.cuh index 3244da3..3329452 100644 --- a/src/simulation_objects/MapNode.cuh +++ b/src/simulation_objects/MapNode.cuh @@ -11,7 +11,7 @@ class Particle; class Polyhedron; -// TODO: add @see to the modified model description to the following docstring +// TODO: tell, what `MapNode`s are used for /** * Object describing a node of `SimulationMap` * @@ -66,7 +66,12 @@ public: */ __host__ __device__ MapNode(); - /// Destructs a `MapNode` object + /** + * Destructs a `MapNode` object + * + * @warning `MapNode` destruction will cause the `Particle` attached to it to be `delete`d. Use + * `MapNode::detach_particle` before the node will be destructed if you want to prevent this behaviour + */ __host__ __device__ ~MapNode(); @@ -216,15 +221,16 @@ public: /** * Marks the node as not occupied (not containing a particle) / Detaches particle from the node * - * @note The operation is thread-safe - * * @warning Detaching particle from a map node does not free memory, allocated for `Particle`, so if you want * to free memory, you have to firstly obtain a pointer to the `Particle` if you don't have it yet (can be done * via `get_particle()`), then detach the particle from it's node (call `detach_particle()`), and then free * memory. * - * @warning Remember about thread-safety: `MapNode` does not guarantee that the `Particle` being removed didn't change - * since calling `get_particle()` + * @warning Remember about thread-safety: `MapNode` does not guarantee that the `Particle` being removed didn't + * change since calling `get_particle()`. If you want to be sure about what particle you are detaching, do + * something like `p = node.get_particle(); node.detach_particle(p);` + * + * @note If the node does not contain a particle, nothing happens * * @see MapNode::attach_particle, MapNode::get_particle */ @@ -237,8 +243,6 @@ public: * * @returns `true`, if the given `Particle` was attached to the node (which means it was successfully removed), * otherwise `false` - * - * @note This operation is thread-safe */ __device__ bool detach_particle(Particle *p); From 54760821bb603da9483ad81ac34ddb3508c05aa4 Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 19:11:47 +0300 Subject: [PATCH 5/6] Moved `Polyhedron` initialization to `init_simulation_objects` (+), added `_reset_destructively` methods to `Polyhedron` and `SimulationMap` Updated signature of `init_simulation_objects`. Of course, updated its docs too, to fit all the above --- src/main_logic/iterations_wrapper.cuh | 14 +++++++++----- src/main_logic/main.cpp | 9 +++++---- src/main_logic/main.cu | 8 +++----- src/main_logic/simulation_logic.cu | 2 +- src/main_logic/simulation_logic.cuh | 2 +- src/simulation_objects/SimulationMap.cu | 8 +++++++- src/simulation_objects/SimulationMap.cuh | 10 ++++++++++ src/simulation_objects/geometric/Polyhedron.cu | 8 +++++++- src/simulation_objects/geometric/Polyhedron.cuh | 10 ++++++++++ 9 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/main_logic/iterations_wrapper.cuh b/src/main_logic/iterations_wrapper.cuh index 2481585..74bd028 100644 --- a/src/main_logic/iterations_wrapper.cuh +++ b/src/main_logic/iterations_wrapper.cuh @@ -36,21 +36,25 @@ typedef void (*RunIterationFunc)(SimulationMap *, int *); * This function is used to initialize simulation objects on device. It at the moment only initializes `SimulationMap`, * but can be extended to initialize more objects * - * @param simulation_map Pointer to `SimulationMap`. A constructed simulation map will be moved there * @param polyhedron Pointer to a polyhedron to be used to initialize `SimulationMap` (constructor's parameter) + * @param simulation_map Pointer to `SimulationMap`. A constructed simulation map will be moved there * - * @warning While `polyhedron` parameter must point to a real `Polyhedron` object, `simulation_map` might contain an - * existing map already, but it will be destructed in this case. Note that if the pointer doesn't contain an - * object the destructor will be called anyway, but it should be safe (???) + * @warning Both `polyhedron` and `simulation_map` must point to an allocated memory area, not initialized with + * anything. If they are pointing to constructed objects, no destructors will be called, so a memory leak will + * occur. * * @see destruct_simulation_objects */ -__global__ void init_simulation_objects(SimulationMap *const simulation_map, Polyhedron *const polyhedron) +__global__ void init_simulation_objects(Polyhedron *const polyhedron, SimulationMap *const simulation_map) { #ifndef COMPILE_FOR_CPU STOP_ALL_THREADS_EXCEPT_FIRST; #endif + polyhedron->_reset_destructively(); + simulation_map->_reset_destructively(); + + *polyhedron = generate_cube(); *simulation_map = SimulationMap(polyhedron); } diff --git a/src/main_logic/main.cpp b/src/main_logic/main.cpp index e2a7602..cc6ad82 100644 --- a/src/main_logic/main.cpp +++ b/src/main_logic/main.cpp @@ -33,12 +33,13 @@ void wrapped_run_iteration_cleanup(SimulationMap *const simulation_map, int *con int main() { - auto *simulation_map = (SimulationMap *)malloc(sizeof(SimulationMap)); - auto *polyhedron = (Polyhedron *)malloc(sizeof(Polyhedron)); + // `malloc`s and `free`s are not replaced with `new`/`delete`s in this function to make it as similar with the + // main function from main.cu as possible - *polyhedron = generate_cube(); + auto *polyhedron = (Polyhedron *)malloc(sizeof(Polyhedron)); + auto *simulation_map = (SimulationMap *)malloc(sizeof(SimulationMap)); - init_simulation_objects(simulation_map, polyhedron); + init_simulation_objects(polyhedron, simulation_map); init_environment(simulation_map); int iteration_number = 0; // Incremented inside of `run_iteration_cleanup` diff --git a/src/main_logic/main.cu b/src/main_logic/main.cu index 7b02805..09a714d 100644 --- a/src/main_logic/main.cu +++ b/src/main_logic/main.cu @@ -97,14 +97,12 @@ __host__ int main() init_rand<<<1, 1>>>(time(nullptr)); // Initializing simulation objects + Polyhedron *polyhedron; + cudaMalloc((void **)&polyhedron, sizeof(Polyhedron)); SimulationMap *simulation_map; cudaMallocManaged((void **)&simulation_map, sizeof(SimulationMap)); - Polyhedron *polyhedron; - cudaMallocManaged((void **)&polyhedron, sizeof(Polyhedron)); - - *polyhedron = generate_cube(); - init_simulation_objects<<<1, 1>>>(simulation_map, polyhedron); + init_simulation_objects<<<1, 1>>>(polyhedron, simulation_map); init_environment<<<1, 1>>>(simulation_map); int *iteration_number; // Incremented inside of `run_iteration_cleanup` diff --git a/src/main_logic/simulation_logic.cu b/src/main_logic/simulation_logic.cu index 14f3260..3dc78e2 100644 --- a/src/main_logic/simulation_logic.cu +++ b/src/main_logic/simulation_logic.cu @@ -127,7 +127,7 @@ __device__ void division_test(MapNode *node) } -__host__ Polyhedron generate_cube(double edge_length) +__device__ Polyhedron generate_cube(double edge_length) { SpacePoint vertices1[] = { {0, 0, 0}, diff --git a/src/main_logic/simulation_logic.cuh b/src/main_logic/simulation_logic.cuh index 1747b0e..4a8c444 100644 --- a/src/main_logic/simulation_logic.cuh +++ b/src/main_logic/simulation_logic.cuh @@ -130,7 +130,7 @@ __device__ void division_test(MapNode *node); * * @returns Cube represented wth a `Polyhedron` object */ -__host__ Polyhedron generate_cube(double edge_length = 200); +__device__ Polyhedron generate_cube(double edge_length = 200); #endif //MIND_S_CRAWL_FUCKING_SHIT_CUH diff --git a/src/simulation_objects/SimulationMap.cu b/src/simulation_objects/SimulationMap.cu index 4e5338e..43cf112 100644 --- a/src/simulation_objects/SimulationMap.cu +++ b/src/simulation_objects/SimulationMap.cu @@ -148,7 +148,7 @@ __host__ __device__ SimulationMap::SimulationMap(SimulationMap &&other) noexcept __host__ __device__ SimulationMap::SimulationMap() { - nodes = nullptr; + _reset_destructively(); } __device__ SimulationMap::~SimulationMap() @@ -157,6 +157,12 @@ __device__ SimulationMap::~SimulationMap() } +__host__ __device__ void SimulationMap::_reset_destructively() +{ + nodes = nullptr; +} + + __device__ int SimulationMap::get_n_of_nodes() const { return this->n_of_nodes; diff --git a/src/simulation_objects/SimulationMap.cuh b/src/simulation_objects/SimulationMap.cuh index e810df9..5118a14 100644 --- a/src/simulation_objects/SimulationMap.cuh +++ b/src/simulation_objects/SimulationMap.cuh @@ -57,6 +57,16 @@ public: __device__ ~SimulationMap(); + /** + * Resets `SimulationMap` to a state when it is guaranteed to destruct safely, even if the object wasn't ever + * constructed (you shouldn't use this method in any other situations) + * + * @warning Calling this method for an object, constructed in a usual way, will result in a memory leak. It can only + * be used for objects, allocated in a c-like way + */ + __host__ __device__ void _reset_destructively(); + + /** * Returns the number of nodes in the simulation * diff --git a/src/simulation_objects/geometric/Polyhedron.cu b/src/simulation_objects/geometric/Polyhedron.cu index 797d476..3df8da4 100644 --- a/src/simulation_objects/geometric/Polyhedron.cu +++ b/src/simulation_objects/geometric/Polyhedron.cu @@ -50,7 +50,7 @@ __host__ __device__ Polyhedron::Polyhedron(Polyhedron &&other) noexcept __host__ __device__ Polyhedron::Polyhedron() { - faces = nullptr; + _reset_destructively(); } __host__ __device__ Polyhedron::~Polyhedron() @@ -59,6 +59,12 @@ __host__ __device__ Polyhedron::~Polyhedron() } +__host__ __device__ void Polyhedron::_reset_destructively() +{ + faces = nullptr; +} + + __host__ __device__ Face *Polyhedron::find_face_by_point(SpacePoint point) const { for(int i = 0; i < n_of_faces; ++i) diff --git a/src/simulation_objects/geometric/Polyhedron.cuh b/src/simulation_objects/geometric/Polyhedron.cuh index 26c2cc0..fb37575 100644 --- a/src/simulation_objects/geometric/Polyhedron.cuh +++ b/src/simulation_objects/geometric/Polyhedron.cuh @@ -67,6 +67,16 @@ public: __host__ __device__ ~Polyhedron(); + /** + * Resets `Polyhedron` to a state when it is guaranteed to destruct safely, even if the object wasn't ever + * constructed (you shouldn't use this method in any other situations) + * + * @warning Calling this method for an object, constructed in a usual way, will result in a memory leak. It can only + * be used for objects, allocated in a c-like way + */ + __host__ __device__ void _reset_destructively(); + + /** * Finds a face the given point belongs to * From d355f058baefee59292d3d352471210ee36c15ad Mon Sep 17 00:00:00 2001 From: Nikolay Nechaev Date: Thu, 19 Nov 2020 19:57:46 +0300 Subject: [PATCH 6/6] `destruct_simulation_objects`: destruct `Polyhedron` --- src/main_logic/iterations_wrapper.cuh | 10 ++++++---- src/main_logic/main.cpp | 2 +- src/main_logic/main.cu | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main_logic/iterations_wrapper.cuh b/src/main_logic/iterations_wrapper.cuh index 74bd028..4caf95e 100644 --- a/src/main_logic/iterations_wrapper.cuh +++ b/src/main_logic/iterations_wrapper.cuh @@ -85,20 +85,22 @@ __global__ void init_environment(SimulationMap *const simulation_map) /** * The opposite of `init_simulation_objects` * - * This function destructs the objects constructed in `init_simulation_objects` (at the moment only a `SimulationMap`) - * to let you safely free memory without breaking any invariants etc + * This function destructs the objects constructed in `init_simulation_objects` to let you safely free memory without + * breaking any invariants, causing memory leaks etc * - * @param simulation_map Pointer to the `SimulationMap` to be destructed + * @param polyhedron Pointer to a `Polyhedron` object to be destructed + * @param simulation_map Pointer to a `SimulationMap` object to be destructed * * @see init_simulation_objects */ -__global__ void destruct_simulation_objects(SimulationMap *const simulation_map) +__global__ void destruct_simulation_objects(Polyhedron *const polyhedron, SimulationMap *const simulation_map) { #ifndef COMPILE_FOR_CPU STOP_ALL_THREADS_EXCEPT_FIRST; #endif simulation_map->~SimulationMap(); + polyhedron->~Polyhedron(); } diff --git a/src/main_logic/main.cpp b/src/main_logic/main.cpp index cc6ad82..9625f7e 100644 --- a/src/main_logic/main.cpp +++ b/src/main_logic/main.cpp @@ -68,7 +68,7 @@ int main() } } - destruct_simulation_objects(simulation_map); + destruct_simulation_objects(polyhedron, simulation_map); free(polyhedron); free(simulation_map); } diff --git a/src/main_logic/main.cu b/src/main_logic/main.cu index 09a714d..4cb1fe9 100644 --- a/src/main_logic/main.cu +++ b/src/main_logic/main.cu @@ -168,7 +168,7 @@ __host__ int main() cudaFree(nodes); cudaFree(iteration_number); - destruct_simulation_objects<<<1, 1>>>(simulation_map); + destruct_simulation_objects<<<1, 1>>>(polyhedron, simulation_map); cudaFree(polyhedron); cudaFree(simulation_map);