Added timing tests for matrix math
This commit is contained in:
1
unit-tests/.gitignore
vendored
Normal file
1
unit-tests/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
matrix-test-timings-temp.txt
|
||||||
14
unit-tests/matrix-test-timings.txt
Normal file
14
unit-tests/matrix-test-timings.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Addition: 0.55 s
|
||||||
|
Subtraction: 0.548 s
|
||||||
|
Multiplication: 3.404 s
|
||||||
|
Scalar Multiplication: 0.453 s
|
||||||
|
Element Multiply: 0.347 s
|
||||||
|
Element Divide: 0.347 s
|
||||||
|
Minor Matrix: 0.44 s
|
||||||
|
Determinant: 0.251 s
|
||||||
|
Matrix of Minors: 1.044 s
|
||||||
|
Invert: 0.262 s
|
||||||
|
Transpose: 0.26 s
|
||||||
|
Normalize: 0.333 s
|
||||||
|
GET ROW: 0.683 s
|
||||||
|
GET COLUMN: 0.427 s
|
||||||
@@ -303,8 +303,98 @@ TEST_CASE("Timing Tests", "Matrix") {
|
|||||||
Matrix<50, 50> mat2{arr2};
|
Matrix<50, 50> mat2{arr2};
|
||||||
Matrix<50, 50> mat3{};
|
Matrix<50, 50> mat3{};
|
||||||
|
|
||||||
// TODO: the timing results should be saved to a temporary text file
|
// A smaller matrix to use for really badly optimized operations
|
||||||
// TODO: after the timing results are complete we should read in the old
|
std::array<float, 16> arr4{1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
// result file, calculate the timing increase/decrease and update the file
|
9, 10, 11, 12, 13, 14, 15, 16};
|
||||||
// with the new results and increase/decrease
|
Matrix<4, 4> mat4{arr4};
|
||||||
|
Matrix<4, 4> mat5{};
|
||||||
|
|
||||||
|
SECTION("Addition") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat3 = mat1 + mat2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Subtraction") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat3 = mat1 - mat2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Multiplication") {
|
||||||
|
for (uint32_t i{0}; i < 1000; i++) {
|
||||||
|
mat3 = mat1 * mat2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Scalar Multiplication") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat3 = mat1 * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Element Multiply") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat1.ElementMultiply(mat2, mat3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Element Divide") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat1.ElementDivide(mat2, mat3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Minor Matrix") {
|
||||||
|
// what about matrices of 0,0 or 1,1?
|
||||||
|
// minor matrix for 2x2 matrix
|
||||||
|
Matrix<49, 49> minorMat1{};
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat1.MinorMatrix(minorMat1, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Determinant") {
|
||||||
|
for (uint32_t i{0}; i < 100000; i++) {
|
||||||
|
float det1 = mat4.Det();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Matrix of Minors") {
|
||||||
|
for (uint32_t i{0}; i < 100000; i++) {
|
||||||
|
mat4.MatrixOfMinors(mat5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Invert") {
|
||||||
|
for (uint32_t i{0}; i < 100000; i++) {
|
||||||
|
mat4.Invert(mat5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SECTION("Transpose") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat1.Transpose(mat3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Normalize") {
|
||||||
|
for (uint32_t i{0}; i < 10000; i++) {
|
||||||
|
mat1.Normalize(mat3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("GET ROW") {
|
||||||
|
Matrix<1, 50> mat1Rows{};
|
||||||
|
for (uint32_t i{0}; i < 1000000; i++) {
|
||||||
|
mat1.GetRow(0, mat1Rows);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("GET COLUMN") {
|
||||||
|
Matrix<50, 1> mat1Columns{};
|
||||||
|
for (uint32_t i{0}; i < 1000000; i++) {
|
||||||
|
mat1.GetColumn(0, mat1Columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
7
unit-tests/run-matrix-timing-test.sh
Executable file
7
unit-tests/run-matrix-timing-test.sh
Executable file
@@ -0,0 +1,7 @@
|
|||||||
|
# be in the root folder of this project when you run this
|
||||||
|
cd build/
|
||||||
|
ninja matrix-tests
|
||||||
|
echo "Running tests. This will take a while."
|
||||||
|
./unit-tests/matrix-tests -n "Timing Tests" -d yes > ../unit-tests/matrix-test-timings-temp.txt
|
||||||
|
cd ../unit-tests/
|
||||||
|
python3 test-timing-post-process.py
|
||||||
108
unit-tests/test-timing-post-process.py
Normal file
108
unit-tests/test-timing-post-process.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
class Timing:
|
||||||
|
def __init__(self, time: float, test_name: str):
|
||||||
|
self.time = time
|
||||||
|
self.test_name: str = test_name
|
||||||
|
self.difference = -1
|
||||||
|
|
||||||
|
def __eq__(self, other: "Timing"):
|
||||||
|
return self.test_name.lower() == other.test_name.lower()
|
||||||
|
|
||||||
|
def __sub__(self, other: "Timing"):
|
||||||
|
return self.time - other.time
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return f"{self.test_name}: {self.time} s"
|
||||||
|
|
||||||
|
def to_string_w_diff(self):
|
||||||
|
diff = self.difference
|
||||||
|
if diff == -1:
|
||||||
|
diff = 0
|
||||||
|
return f"{self.test_name}: {round(self.time,3)} s, Difference: {round(diff,3)}"
|
||||||
|
|
||||||
|
def create_timing_from_test_line(line: str) -> Timing:
|
||||||
|
time_end_idx: int = line.find(" ")
|
||||||
|
if time_end_idx == -1:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
time: float = float(line[0:time_end_idx])
|
||||||
|
except:
|
||||||
|
print("Couldn't convert: " + line[0:time_end_idx] + " to a float")
|
||||||
|
return None
|
||||||
|
|
||||||
|
test_name = line[time_end_idx+4:-1]
|
||||||
|
return Timing(time, test_name)
|
||||||
|
|
||||||
|
def parse_test_file(file_path: str) -> list[Timing]:
|
||||||
|
timings: list[Timing] = []
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
previous_line = ""
|
||||||
|
for line in file:
|
||||||
|
if line.find("Timing Tests") != -1:
|
||||||
|
timing = create_timing_from_test_line(previous_line)
|
||||||
|
if timing is not None:
|
||||||
|
timings.append(timing)
|
||||||
|
previous_line = line[:] # deep copy line
|
||||||
|
return timings
|
||||||
|
|
||||||
|
def parse_timing_file(file_path: str) -> list[Timing]:
|
||||||
|
timings: list[Timing] = []
|
||||||
|
with open(file_path, 'r') as file:
|
||||||
|
for line in file:
|
||||||
|
seperator_idx = line.find(":")
|
||||||
|
if seperator_idx == -1:
|
||||||
|
continue
|
||||||
|
test_name = line[:seperator_idx]
|
||||||
|
try:
|
||||||
|
time = float(line[seperator_idx+2:-2])
|
||||||
|
print(time)
|
||||||
|
except:
|
||||||
|
print("Couldn't convert: " + line[seperator_idx:-2] + " to a float")
|
||||||
|
continue
|
||||||
|
timings.append(Timing(time, test_name))
|
||||||
|
|
||||||
|
|
||||||
|
return timings
|
||||||
|
|
||||||
|
def save_timings(timings: list[Timing], file_path: str):
|
||||||
|
with open(file_path, 'w') as file:
|
||||||
|
for timing in timings:
|
||||||
|
file.write(f"{timing.to_string()}\n")
|
||||||
|
|
||||||
|
parse_file_path = "matrix-test-timings-temp.txt"
|
||||||
|
save_file_path = "matrix-test-timings.txt"
|
||||||
|
|
||||||
|
# get the new timings
|
||||||
|
new_timings = parse_test_file(parse_file_path)
|
||||||
|
|
||||||
|
# get the old timings
|
||||||
|
old_timings = parse_timing_file(save_file_path)
|
||||||
|
|
||||||
|
difference_increased = ""
|
||||||
|
# calculate the timing difference
|
||||||
|
for new_timing in new_timings:
|
||||||
|
for old_timing in old_timings:
|
||||||
|
if new_timing == old_timing:
|
||||||
|
new_timing.difference = new_timing - old_timing
|
||||||
|
if new_timing.difference >= 0.03:
|
||||||
|
difference_increased += f"{new_timing.test_name}, "
|
||||||
|
|
||||||
|
def save_option():
|
||||||
|
# save the new timings
|
||||||
|
while True:
|
||||||
|
option = input("Save Results? (y/n)")
|
||||||
|
if option[0].lower() == 'y':
|
||||||
|
save_timings(new_timings, save_file_path)
|
||||||
|
print("Saved.")
|
||||||
|
break
|
||||||
|
elif option[0].lower() == 'n':
|
||||||
|
break
|
||||||
|
|
||||||
|
# print the new timing results along with the difference
|
||||||
|
for timing in new_timings:
|
||||||
|
print(timing.to_string_w_diff())
|
||||||
|
|
||||||
|
if len(difference_increased) > 0:
|
||||||
|
print("You increased the time it takes to run for:" + difference_increased)
|
||||||
|
save_option()
|
||||||
|
else:
|
||||||
|
print("No times have changed outside the margin of error.")
|
||||||
Reference in New Issue
Block a user