Skip to content

Commit 21d562d

Browse files
committed
Added delivered directory
1 parent 4e634f0 commit 21d562d

12 files changed

+1526
-0
lines changed

delivered/CMakeLists.txt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
cmake_minimum_required (VERSION 3.5)
2+
project (bsp_pattern)
3+
cmake_policy (SET CMP0015 NEW)
4+
5+
6+
option (PRINT_FULL "Print out more information about program's variables (e.g. input and output vectors)" OFF)
7+
option (COMPUTE_SEQUENTIAL "Include computation of sequential sort of created vector" OFF)
8+
9+
10+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-parameter -pedantic -O2 -g -std=c++11 -pthread -fPIC")
11+
set (EXECUTABLE_OUTPUT_PATH bin)
12+
13+
14+
include_directories (include)
15+
16+
## Creating .o files
17+
set (SOURCE_FILES src/barrier.cpp src/workerThread.cpp src/uTimer.cpp)
18+
add_library (${PROJECT_NAME}_objs OBJECT ${SOURCE_FILES})
19+
20+
## Creating static library
21+
add_library (${PROJECT_NAME} STATIC $<TARGET_OBJECTS:${PROJECT_NAME}_objs>)
22+
23+
24+
## Creating TiskinAlgorithm executable
25+
add_executable (TiskinAlgorithm src/tiskin.cpp)
26+
target_link_libraries (TiskinAlgorithm ${PROJECT_NAME})
27+
28+
# Creating BspTester executable
29+
add_executable (BspTester tests/bspTester.cpp)
30+
target_link_libraries (BspTester ${PROJECT_NAME})
31+
32+
33+
if (${COMPUTE_SEQUENTIAL})
34+
target_compile_definitions (TiskinAlgorithm PRIVATE COMPUTE_SEQUENTIAL)
35+
endif ()
36+
37+
38+
if (${PRINT_FULL})
39+
target_compile_definitions (TiskinAlgorithm PRIVATE PRINT_FULL)
40+
endif ()

delivered/include/barrier.hpp

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* \file barrier.hpp
3+
* \brief Header file for Barrier class
4+
* \author Luca Di Mauro
5+
*/
6+
7+
#ifndef BARRIER_HPP
8+
#define BARRIER_HPP
9+
10+
#include <mutex>
11+
#include <condition_variable>
12+
#include <atomic>
13+
14+
15+
16+
/* This class represents a barrier on which activities can suspend themselves until
17+
* condition 'activitiesNumber' reaches value 0.
18+
*/
19+
class Barrier {
20+
private:
21+
std::atomic_int activitiesNumber;
22+
23+
std::mutex barrierMutex;
24+
std::condition_variable barrierCV;
25+
26+
27+
public:
28+
Barrier (int activitiesNumber);
29+
~Barrier ();
30+
31+
/* Method to decrease barrier of 1 and waiting other activities completion if there are running activities,
32+
* waking up them otherwise
33+
*/
34+
void decreaseBarrier ();
35+
36+
/* Method to wait until all the activities has finished their computation, namely until 'activitiesNumber' variable
37+
* differs from 0
38+
*/
39+
void waitForFinish ();
40+
41+
int getRemainingEntities ();
42+
void reset (int activitiesNumber);
43+
};
44+
45+
46+
#endif // BARRIER_HPP

delivered/include/bsp.hpp

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/**
2+
* \file bsp.hpp
3+
* \brief Header file for Bsp class
4+
* \author Luca Di Mauro
5+
*/
6+
7+
#ifndef BSP_HPP
8+
#define BSP_HPP
9+
10+
#include <workerThread.hpp>
11+
#include <superstep.hpp>
12+
#include <uTimer.hpp>
13+
14+
#include <vector>
15+
16+
17+
/* Class which represents an instance of a BSP computation */
18+
template <typename T>
19+
class BSP {
20+
public:
21+
using SuperstepPointer = std::shared_ptr<Superstep<T>>;
22+
23+
24+
private:
25+
std::vector<WorkerThread> workers;
26+
std::vector<SuperstepPointer> supersteps;
27+
28+
void setupWorkers (bool setAffinity);
29+
void swapVectors (std::vector<std::vector<T>> &a, std::vector<LockableVector<T>> &b);
30+
31+
const int NEXT_STEP_FLAG = -2; // Flag to go to next step during computation
32+
const int EOC_FLAG = -1; // Flag which identifis the end of computation
33+
34+
35+
public:
36+
BSP ();
37+
~BSP ();
38+
39+
40+
uint addSuperstep (SuperstepPointer step);
41+
42+
void runAndWait (std::vector<std::vector<T>> &input, std::vector<std::vector<T>> &ouput, bool setAffinity);
43+
};
44+
45+
46+
47+
48+
/* ========== ========== ========== ========== ========== */
49+
/* ========== ========== ========== ========== ========== */
50+
51+
52+
53+
54+
template<typename T>
55+
BSP<T>::BSP () {
56+
// Do nothing
57+
}
58+
59+
60+
61+
62+
template<typename T>
63+
BSP<T>::~BSP () {
64+
std::for_each (workers.begin(), workers.end(), [] (WorkerThread &w) {
65+
w.stopWorker ();
66+
});
67+
}
68+
69+
70+
71+
72+
template<typename T>
73+
uint BSP<T>::addSuperstep (SuperstepPointer step) {
74+
supersteps.emplace_back (step);
75+
return supersteps.size()-1;
76+
}
77+
78+
79+
80+
81+
/* Method to setup workers used during pattern computation */
82+
template<typename T>
83+
void BSP<T>::setupWorkers (bool setAffinity) {
84+
uint maxActivities = 0;
85+
for (size_t i=0; i<supersteps.size(); i++) {
86+
uint tmpNum = supersteps[i]->getActivitiesNumber();
87+
maxActivities = (maxActivities >= tmpNum) ? maxActivities : tmpNum;
88+
};
89+
90+
workers = std::vector<WorkerThread> (maxActivities);
91+
uint cpusNum = std::thread::hardware_concurrency();
92+
93+
if (setAffinity) {
94+
uint idx = 0;
95+
std::for_each (workers.begin(), workers.end(), [&idx, cpusNum] (WorkerThread &w) {
96+
w.setAffinity ((idx++) % cpusNum);
97+
});
98+
}
99+
}
100+
101+
102+
103+
104+
/* This method is used during supersteps computation to swap vectors contained in 'a' vector with vectors contained in 'b' vector
105+
*/
106+
template<typename T>
107+
void BSP<T>::swapVectors (std::vector<std::vector<T>> &a, std::vector<LockableVector<T>> &b) {
108+
int aSize = a.size ();
109+
int bSize = b.size ();
110+
111+
// Checking if vectors have different sizes
112+
if (aSize > bSize) {
113+
b.resize (aSize);
114+
}
115+
else if ( aSize < bSize) {
116+
a.resize (bSize);
117+
}
118+
119+
for (size_t i=0; i< b.size(); i++) {
120+
b[i].swap (a[i]);
121+
}
122+
123+
for (size_t i=0; i< b.size(); i++) {
124+
b[i].getVector().clear ();
125+
}
126+
127+
a.shrink_to_fit ();
128+
b.shrink_to_fit ();
129+
}
130+
131+
132+
133+
134+
/* Main method of BSP class which actually realizes pattern computation: it executes supersteps taking into account value
135+
* returned at the end of each superstep computation and handling their input and output vectors */
136+
template<typename T>
137+
void BSP<T>::runAndWait (std::vector<std::vector<T>> &input, std::vector<std::vector<T>> &output, bool setAffinity) {
138+
int retVal = 0;
139+
int nextStep = 0;
140+
std::vector<LockableVector<T>> lockableVectors (output.size());
141+
142+
setupWorkers (setAffinity);
143+
144+
swapVectors (output, lockableVectors);
145+
146+
147+
while (retVal != EOC_FLAG && nextStep < (int) supersteps.size()) {
148+
149+
{
150+
UTimer timer ("Superstep " + std::to_string (nextStep));
151+
std::cout << "\n\nRunning superstep " << nextStep << std::endl;
152+
153+
retVal = supersteps[nextStep]->runStep (workers, input, lockableVectors);
154+
155+
// Swapping vectors
156+
if (retVal == NEXT_STEP_FLAG) {
157+
nextStep++;
158+
}
159+
else if (retVal == EOC_FLAG) {
160+
// Do nothing
161+
}
162+
else if (retVal>=0) {
163+
nextStep = retVal;
164+
}
165+
else
166+
throw std::runtime_error ("Wrong number of superstep returned by 'atExit' function");
167+
168+
swapVectors (input, lockableVectors);
169+
}
170+
}
171+
172+
173+
std::swap (output, input);
174+
175+
std::for_each (workers.begin(), workers.end(), [] (WorkerThread &w) {
176+
w.stopWorker ();
177+
});
178+
}
179+
180+
181+
#endif // BSP_HPP

delivered/include/lockableVector.hpp

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* \file lockableVector.hpp
3+
* \brief Definition and implementation of LockableVector class
4+
* \author Luca Di Mauro
5+
*/
6+
7+
#ifndef LOCAKBLE_VECTOR_HPP
8+
#define LOCAKBLE_VECTOR_HPP
9+
10+
#include <vector>
11+
#include <mutex>
12+
#include <condition_variable>
13+
14+
// Forward class declaration
15+
template<typename T>
16+
class LockableVector;
17+
18+
19+
20+
/* Class which represent an already locked vector owned by related 'LockableVector' class instance.
21+
* In the destructor, original vector is released.
22+
*/
23+
template<typename T>
24+
class LockedVector {
25+
private :
26+
LockableVector<T>& parent;
27+
public :
28+
std::vector<T>& data;
29+
LockedVector (std::vector<T>& origVect, LockableVector<T> *locker) : parent (*locker), data (origVect) {}
30+
~LockedVector () {
31+
parent.releaseVector ();
32+
}
33+
};
34+
35+
36+
37+
38+
/* Class which stores a vector of type T and allows to get it either in a shared environment using synchronization mechanisms,
39+
* or obtaining it without synchronization.
40+
*/
41+
template <typename T>
42+
class LockableVector {
43+
private:
44+
friend class LockedVector<T>;
45+
std::vector<T> dataVector;
46+
std::mutex vectorMutex;
47+
std::condition_variable vectorCV;
48+
49+
void releaseVector () {
50+
vectorMutex.unlock ();
51+
}
52+
53+
54+
public:
55+
LockableVector (std::vector<T> &externalVector) : dataVector(externalVector) {
56+
}
57+
58+
LockableVector (LockableVector &&lv) {
59+
dataVector = std::vector<T> (lv.dataVector.size());
60+
}
61+
62+
LockableVector () {
63+
// Do nothing
64+
}
65+
66+
67+
~LockableVector () {
68+
// Do nothing
69+
}
70+
71+
72+
bool isEmpty () {
73+
std::unique_lock<std::mutex> lock (vectorMutex);
74+
return dataVector.empty ();
75+
}
76+
77+
78+
std::vector<T>& getVector () {
79+
return dataVector;
80+
}
81+
82+
void swap (std::vector<T> &targetVector) {
83+
std::unique_lock<std::mutex> lock (vectorMutex);
84+
std::swap (dataVector, targetVector);
85+
}
86+
87+
88+
std::shared_ptr<LockedVector<T>> lockAndGet () {
89+
vectorMutex.lock ();
90+
return std::shared_ptr<LockedVector<T>> (new LockedVector<T> (dataVector, this));
91+
}
92+
93+
94+
std::shared_ptr<LockedVector<T>> tryLockAndGet () {
95+
if (vectorMutex.try_lock ()) {
96+
return std::shared_ptr<LockedVector<T>> (new LockedVector<T> (dataVector, this));
97+
}
98+
throw std::logic_error ("No lock acquired");
99+
}
100+
};
101+
102+
103+
#endif // LOCAKBLE_VECTOR_HPP

0 commit comments

Comments
 (0)