Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default constructors #40

Merged
merged 6 commits into from
Nov 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/common.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -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<class T>
__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];
Expand Down
24 changes: 15 additions & 9 deletions src/main_logic/iterations_wrapper.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -81,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();
}


Expand Down
11 changes: 6 additions & 5 deletions src/main_logic/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -67,7 +68,7 @@ int main()
}
}

destruct_simulation_objects(simulation_map);
destruct_simulation_objects(polyhedron, simulation_map);
free(polyhedron);
free(simulation_map);
}
10 changes: 4 additions & 6 deletions src/main_logic/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down Expand Up @@ -170,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);

Expand Down
2 changes: 1 addition & 1 deletion src/main_logic/simulation_logic.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
2 changes: 1 addition & 1 deletion src/main_logic/simulation_logic.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 5 additions & 0 deletions src/simulation_objects/MapNode.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
31 changes: 23 additions & 8 deletions src/simulation_objects/MapNode.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -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`
*
Expand Down Expand Up @@ -55,7 +55,23 @@ public:
/// `MapNode` object move constructor
__host__ __device__ MapNode(MapNode &&other) noexcept;

/// Destructs a `MapNode` object
/**
* Creates a <b>fake</b> `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
*
* @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();


Expand Down Expand Up @@ -205,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 <b>does not</b> 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
*/
Expand All @@ -226,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);

Expand Down
14 changes: 14 additions & 0 deletions src/simulation_objects/Particle.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ public:
*/
__host__ __device__ Particle(Particle &&other) noexcept = delete;

/**
* Creates a <b>fake</b> `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
Expand Down
25 changes: 18 additions & 7 deletions src/simulation_objects/SimulationMap.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -43,15 +43,15 @@ __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);

/**
* 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;
Expand Down Expand Up @@ -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
Expand All @@ -146,9 +146,20 @@ __host__ __device__ SimulationMap::SimulationMap(SimulationMap &&other) noexcept
*this = std::move(other);
}

__host__ __device__ SimulationMap::SimulationMap()
{
_reset_destructively();
}

__device__ SimulationMap::~SimulationMap()
{
free(nodes);
delete[] nodes;
}


__host__ __device__ void SimulationMap::_reset_destructively()
{
nodes = nullptr;
}


Expand Down Expand Up @@ -263,7 +274,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);
Expand Down
21 changes: 21 additions & 0 deletions src/simulation_objects/SimulationMap.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,31 @@ public:
/// `SimulationMap` object move constructor
__host__ __device__ SimulationMap(SimulationMap &&other) noexcept;

/**
* Creates a <b>fake</b> `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();


/**
* 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
*
Expand Down
11 changes: 8 additions & 3 deletions src/simulation_objects/geometric/Face.cu
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{

Expand All @@ -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;
Expand Down Expand Up @@ -57,9 +57,14 @@ __host__ __device__ Face::Face(Face &&other) noexcept
*this = std::move(other);
}

__host__ __device__ Face::Face()
{
vertices = nullptr;
}

__host__ __device__ Face::~Face()
{
free((void *)vertices);
delete[] vertices;
}


Expand Down
Loading