GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/ax.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 54 55 98.2%
Functions: 5 5 100.0%
Branches: 68 126 54.0%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 #include "ax.h"
5 #include "ast/AST.h"
6 #include "compiler/Compiler.h"
7 #include "compiler/PointExecutable.h"
8 #include "compiler/VolumeExecutable.h"
9
10 #include <llvm/InitializePasses.h>
11 #include <llvm/PassRegistry.h>
12 #include <llvm/Config/llvm-config.h> // version numbers
13 #include <llvm/Support/TargetSelect.h> // InitializeNativeTarget
14 #include <llvm/Support/ManagedStatic.h> // llvm_shutdown
15 #include <llvm/ExecutionEngine/MCJIT.h> // LLVMLinkInMCJIT
16
17 #include <mutex>
18
19 namespace openvdb {
20 OPENVDB_USE_VERSION_NAMESPACE
21 namespace OPENVDB_VERSION_NAME {
22 namespace ax {
23
24 /// @note Implementation for initialize, isInitialized and uninitialized
25 /// reamins in compiler/Compiler.cc
26
27 14 void run(const char* ax, openvdb::GridBase& grid, const AttributeBindings& bindings)
28 {
29 // Construct a generic compiler
30 22 openvdb::ax::Compiler compiler;
31
32
3/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 5 times.
14 if (grid.isType<points::PointDataGrid>()) {
33 // Compile for Point support and produce an executable
34 // @note Throws compiler errors on invalid code. On success, returns
35 // the executable which can be used multiple times on any inputs
36 const openvdb::ax::PointExecutable::Ptr exe =
37
5/8
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
18 compiler.compile<openvdb::ax::PointExecutable>(ax);
38
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 assert(exe);
39
40 //Set the attribute bindings
41
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 exe->setAttributeBindings(bindings);
42 // Execute on the provided points
43 // @note Throws on invalid point inputs such as mismatching types
44
1/2
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
6 exe->execute(static_cast<points::PointDataGrid&>(grid));
45 }
46 else {
47 // Compile for numerical grid support and produce an executable
48 // @note Throws compiler errors on invalid code. On success, returns
49 // the executable which can be used multiple times on any inputs
50 const openvdb::ax::VolumeExecutable::Ptr exe =
51
5/8
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
16 compiler.compile<openvdb::ax::VolumeExecutable>(ax);
52
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(exe);
53
54 // Set the attribute bindings
55
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 exe->setAttributeBindings(bindings);
56 // Execute on the provided numerical grid
57 // @note Throws on invalid grid inputs such as mismatching types
58
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 exe->execute(grid);
59 }
60 8 }
61
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 void run(const char* ax, openvdb::GridPtrVec& grids, const AttributeBindings& bindings)
63 {
64
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (grids.empty()) return;
65 // Check the type of all grids. If they are all points, run for point data.
66 // Otherwise, run for numerical volumes. Throw if the container has both.
67 13 const bool points = grids.front()->isType<points::PointDataGrid>();
68
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 11 times.
38 for (auto& grid : grids) {
69
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 25 times.
27 if (points ^ grid->isType<points::PointDataGrid>()) {
70
2/6
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
8 OPENVDB_THROW(AXCompilerError,
71 "Unable to process both OpenVDB Points and OpenVDB Volumes in "
72 "a single invocation of ax::run()");
73 }
74 }
75 // Construct a generic compiler
76 16 openvdb::ax::Compiler compiler;
77
78
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 6 times.
11 if (points) {
79 // Compile for Point support and produce an executable
80 // @note Throws compiler errors on invalid code. On success, returns
81 // the executable which can be used multiple times on any inputs
82 const openvdb::ax::PointExecutable::Ptr exe =
83
5/8
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
10 compiler.compile<openvdb::ax::PointExecutable>(ax);
84
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 assert(exe);
85
86 //Set the attribute bindings
87
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 exe->setAttributeBindings(bindings);
88 // Execute on the provided points individually
89 // @note Throws on invalid point inputs such as mismatching types
90
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
6 for (auto& grid : grids) {
91
1/2
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 exe->execute(static_cast<points::PointDataGrid&>(*grid));
92 }
93 }
94 else {
95 // Compile for Volume support and produce an executable
96 // @note Throws compiler errors on invalid code. On success, returns
97 // the executable which can be used multiple times on any inputs
98 const openvdb::ax::VolumeExecutable::Ptr exe =
99
5/8
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3 times.
18 compiler.compile<openvdb::ax::VolumeExecutable>(ax);
100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 assert(exe);
101
102 //Set the attribute bindings
103
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 exe->setAttributeBindings(bindings);
104 // Execute on the provided volumes
105 // @note Throws on invalid grid inputs such as mismatching types
106
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 exe->execute(grids);
107 }
108 }
109
110 namespace {
111 // Declare this at file scope to ensure thread-safe initialization.
112 std::mutex sInitMutex;
113 bool sIsInitialized = false;
114 bool sShutdown = false;
115 }
116
117 2 bool isInitialized()
118 {
119 std::lock_guard<std::mutex> lock(sInitMutex);
120
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 return sIsInitialized;
121 }
122
123 1 void initialize()
124 {
125 std::lock_guard<std::mutex> lock(sInitMutex);
126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sIsInitialized) return;
127
128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (sShutdown) {
129 OPENVDB_THROW(AXCompilerError,
130 "Unable to re-initialize LLVM target after uninitialize has been called.");
131 }
132
133 // Init JIT
134 if (llvm::InitializeNativeTarget() ||
135 llvm::InitializeNativeTargetAsmPrinter() ||
136 llvm::InitializeNativeTargetAsmParser())
137 {
138 OPENVDB_THROW(AXCompilerError,
139 "Failed to initialize LLVM target for JIT");
140 }
141
142 // required on some systems
143
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 LLVMLinkInMCJIT();
144
145 // Initialize passes
146 /// @note This is not strictly necessary as LLVM passes are initialized
147 /// thread-safe on-demand into a static registry. ax::initialise should
148 /// perform as much static set-up as possible so that the first run of
149 /// Compiler::compiler has no extra overhead. The default pass pipeline
150 /// is constantly changing and, as a result, explicitly registering certain
151 /// passes here can cause annoying compiler failures between LLVM versions.
152 /// The below passes are wrappers around pass categories whose API should
153 /// change less frequently and include 99% of used passed.
154 ///
155 /// Note that, as well as the llvm::PassManagerBuilder, the majority of
156 /// passes are initialized through llvm::TargetMachine::adjustPassManager
157 /// and llvm::TargetMachine::addPassesToEmitMC (called through the EE).
158 /// To track passes, use llvm::PassRegistry::addRegistrationListener.
159
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::PassRegistry& registry = *llvm::PassRegistry::getPassRegistry();
160
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeCore(registry);
161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeScalarOpts(registry);
162
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeVectorization(registry);
163
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeIPO(registry);
164
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeAnalysis(registry);
165
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeTransformUtils(registry);
166
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeInstCombine(registry);
167 #if LLVM_VERSION_MAJOR > 6
168
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeAggressiveInstCombine(registry);
169 #endif
170
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeInstrumentation(registry);
171
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeGlobalISel(registry);
172
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeTarget(registry);
173
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::initializeCodeGen(registry);
174
175
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 sIsInitialized = true;
176 }
177
178 1 void uninitialize()
179 {
180 std::lock_guard<std::mutex> lock(sInitMutex);
181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!sIsInitialized) return;
182
183 // @todo consider replacing with storage to Support/InitLLVM
184
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 llvm::llvm_shutdown();
185
186 1 sIsInitialized = false;
187
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 sShutdown = true;
188 }
189
190 } // namespace ax
191 } // namespace OPENVDB_VERSION_NAME
192 } // namespace openvdb
193
194