Skip to content

Commit 42f73b5

Browse files
committed
OpenMP BF
1 parent 8666545 commit 42f73b5

File tree

8 files changed

+149
-13
lines changed

8 files changed

+149
-13
lines changed

.vscode/c_cpp_properties.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"defines": [],
1010
"compilerPath": "/usr/bin/mpic++",
1111
"cppStandard": "gnu++20",
12-
"intelliSenseMode": "linux-gcc-x64"
12+
"intelliSenseMode": "linux-gcc-x64",
1313
//"configurationProvider": "ms-vscode.cmake-tools"
1414
}
1515
],

.vscode/settings.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,16 @@
5555
"iomanip": "cpp",
5656
"cstring": "cpp",
5757
"list": "cpp",
58-
"variant": "cpp"
58+
"variant": "cpp",
59+
"compare": "cpp",
60+
"concepts": "cpp",
61+
"condition_variable": "cpp",
62+
"future": "cpp",
63+
"mutex": "cpp",
64+
"numbers": "cpp",
65+
"semaphore": "cpp",
66+
"stop_token": "cpp",
67+
"thread": "cpp"
5968
},
6069
"cSpell.words": [
6170
"Allgather",

benchmarks/quickbench.py

+17-10
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@
77
#Quick bench Paramaters
88

99
#Proof to quickbench
10-
proof = "../proofs/hyperslate/benchmarks/Tree16.slt"
11-
ranks = [1, 2, 3, 4, 5, 6, 7, 8] #Num Ranks to test
10+
proof = "../proofs/hyperslate/benchmarks/Tree14.slt"
11+
ranks = [1, 2, 3, 4, 5, 6] #Num Ranks to test
1212
#ParallelVerifier Args to test with
13-
args = [
14-
("Original", "Serial"),
15-
("NoOpt", "Serial"),
16-
("LoadBalance", "Serial")
13+
MPIArgs = [
14+
# ("Original", "Serial"),
15+
# ("NoOpt", "Serial"),
16+
# ("LoadBalance", "Serial")
1717
]
1818

19+
OMPArgs = [
20+
"OG",
21+
"LB",
22+
"BF"
23+
]
24+
25+
1926
def extractCycles(s):
2027
return int(str(s).split()[2])
2128

@@ -27,25 +34,25 @@ def extractCycles(s):
2734

2835
#OMP Parallel Results
2936
my_env = os.environ.copy()
30-
for method in ["OG", "LB"]:
37+
for method in OMPArgs:
3138
cycles = []
3239
for rank in ranks:
3340
my_env["OMP_NUM_THREADS"] = str(rank) #Set OpneMP threads
3441
rawOutput = subprocess.check_output(['../build/bin/OMPVerifier', proof, method], env=my_env)
3542
cycle = extractCycles(rawOutput)
3643
cycles.append(cycle)
3744
print("OMP", method, rank, "Cycles", cycle)
38-
plt.plot(ranks, cycles, label="(OMP," + method + ")")
45+
plt.plot(ranks, cycles, label=f"OMP: {method}")
3946

4047
#MPI Parallel Results
41-
for arg in args:
48+
for arg in MPIArgs:
4249
cycles = []
4350
for rank in ranks:
4451
rawOutput = subprocess.check_output(['mpirun', '-N', str(rank), '../build/bin/ParallelVerifier', proof] + list(arg))
4552
cycle = extractCycles(rawOutput)
4653
cycles.append(cycle)
4754
print("MPI", str(arg), "Rank", rank, "Cycles", cycle)
48-
plt.plot(ranks, cycles, label=str(arg))
55+
plt.plot(ranks, cycles, label=f"MPI: {str(arg)}")
4956

5057
plt.yscale('log')
5158
plt.title('growth')

benchmarks/res.png

-4.84 KB
Loading

src/LibOMPVerifier/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ target_sources(LibOMPVerifier PRIVATE
1212
LibOMPVerifier.hpp
1313
verifyOpenMPOriginal.cpp
1414
verifyOpenMPLB.cpp
15+
verifyOpenMPBF.cpp
1516
)

src/LibOMPVerifier/LibOMPVerifier.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
namespace OMPVerifier {
77
bool OMPVerifyOriginal(const Proof& p);
88
bool OMPVerifyLB(const Proof& p);
9+
bool OMPVerifyBF(const Proof& p);
910
}

src/LibOMPVerifier/verifyOpenMPBF.cpp

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
2+
#include "../SharedVerifier/SharedVerifier.hpp"
3+
#include "LibOMPVerifier.hpp"
4+
5+
6+
//Recursive helper for getLayerAndDepthMapsSerial
7+
//Returns the depth of a node id, in a proof p, using and modifying
8+
//a global depth map for the proof.
9+
size_t getNodeDepthBF(const Proof& p, VertId id, DepthMap& depthMap){
10+
//Base case 1, we already know the depth of the node
11+
DepthMap::const_iterator depthMapIter = depthMap.find(id);
12+
if(depthMapIter != depthMap.end()){
13+
return depthMapIter->second;
14+
}
15+
//Base case 2, we're an assumption
16+
std::unordered_set<VertId> parents = p.nodeLookup.at(id).parents;
17+
if(parents.size() == 0){
18+
depthMap[id] = 0;
19+
return 0;
20+
}
21+
22+
//Recursive case
23+
std::unordered_set<int>::const_iterator itr = parents.begin();
24+
size_t maxDepth = getNodeDepthBF(p, *itr, depthMap);
25+
itr++;
26+
for(;itr != parents.end(); itr++){
27+
size_t curDepth = getNodeDepthBF(p, *itr, depthMap);
28+
if(curDepth > maxDepth){
29+
maxDepth = curDepth;
30+
}
31+
}
32+
depthMap[id] = maxDepth + 1;
33+
return maxDepth + 1;
34+
}
35+
36+
using FastLayerMap = std::vector<std::vector<VertId>>;
37+
using NodeVec = std::vector<VertId>;
38+
//O(n) serial construction of the depth and layer maps for a proof.
39+
//n is the number of nodes in the proof
40+
std::pair<FastLayerMap, NodeVec> getLayerMapBF(const Proof& p){
41+
//Depthmap construction is O(n) via dynamic programming
42+
DepthMap depthMap;
43+
NodeVec allNodes;
44+
allNodes.reserve(p.nodeLookup.size());
45+
size_t maxDepth = 0;
46+
for(const auto& [id, node] : p.nodeLookup){
47+
size_t curDepth = getNodeDepthBF(p, id, depthMap);
48+
allNodes.push_back(id);
49+
if(curDepth > maxDepth){
50+
maxDepth = curDepth;
51+
}
52+
}
53+
54+
//LayerMap construction O(n)
55+
//std::list fill constructor
56+
FastLayerMap layerVector(maxDepth + 1, std::vector<VertId>());
57+
for(const auto& [id, depth] : depthMap){
58+
layerVector[depth].push_back(id);
59+
}
60+
61+
return std::make_pair(layerVector, allNodes);
62+
}
63+
64+
bool OMPVerifier::OMPVerifyBF(const Proof& p){
65+
66+
// Compute Layers in Serial
67+
auto [layerMap, allNodes] = getLayerMapBF(p);
68+
69+
bool result = true;
70+
#pragma omp parallel for reduction (&&:result)
71+
for(int i = 0; i < allNodes.size(); i++){
72+
result = SharedVerifier::verifyVertexSyntax(p, allNodes[i]);
73+
}
74+
if (!result) {
75+
return false;
76+
}
77+
78+
Assumptions assumptions;
79+
for(size_t j = 0; j < layerMap.size(); j++){
80+
std::vector<VertId> layer = layerMap[j];
81+
82+
#ifdef PRINT_DEBUG
83+
std::cout<< "Layer " <<j<<" Assumptions "<< \
84+
SharedVerifier::assumptionsToString(assumptions) << std::endl;
85+
#endif
86+
87+
// Thread-safe data structures
88+
std::vector<std::unordered_set<VertId>> resultAssumptions(layer.size(), std::unordered_set<VertId>());
89+
90+
// Parallel Reduction
91+
#pragma omp parallel for reduction (&&:result)
92+
for(size_t i = 0; i < layer.size(); i++){
93+
result = SharedVerifier::verifyVertexSemantics(p, layer[i], assumptions, resultAssumptions[i]);
94+
}
95+
96+
if (!result) {
97+
return false;
98+
}
99+
100+
#ifdef PRINT_DEBUG
101+
std::cout<<"Result Assumptions: ";
102+
for(size_t i = 0; i < layer.size(); i++){
103+
std::cout<<layer[i]<<":(";
104+
for(VertId assumpt : resultAssumptions[i]){
105+
std::cout<<assumpt<<",";
106+
}
107+
std::cout<<"\b),";
108+
}
109+
std::cout<<"\b"<<std::endl;
110+
#endif
111+
// Update assumptions for each node we just verified
112+
for(size_t i = 0; i < layer.size(); i++){
113+
assumptions[layer[i]] = std::move(resultAssumptions[i]);
114+
}
115+
}
116+
return true;
117+
}

src/OMPVerify.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ using OMPVerif = bool(*)(const Proof&);
88
using PVMap = std::unordered_map<std::string, OMPVerif>;
99
const PVMap pvArgMap = {
1010
{"OG", OMPVerifier::OMPVerifyOriginal},
11-
{"LB", OMPVerifier::OMPVerifyLB}
11+
{"LB", OMPVerifier::OMPVerifyLB},
12+
{"BF", OMPVerifier::OMPVerifyBF}
1213
};
1314

1415

0 commit comments

Comments
 (0)