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

State and Line Performance Improvements #269

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions bench/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ endfunction()

add_bench(WaveBenchmark WaveBench.cpp)
add_bench(MoordynBenchmark MDBench.cpp)
add_bench(LinesBenchmark LinesBench.cpp)

add_custom_target(run_benchmarks
COMMAND $<TARGET_FILE:WaveBenchmark>
Expand Down
67 changes: 67 additions & 0 deletions bench/LinesBench.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "LinesBench.hpp"
#include "Time.hpp"
#include <benchmark/benchmark.h>
#include <sstream>

/**
* @brief Benchmarks stepping the model 0.1s
* Loads the given model file and measures the duration
* to complete an 0.1 second outer time step.
* @param state Benchmark state
* @param tScheme name of integrator to use
*/
static void
MoorDynStepWithIntegrator(benchmark::State& state, const std::string& tScheme)
{
int num_lines = state.range(0);
int num_segments = state.range(1);
std::string input_file = "Mooring/cases/" + std::to_string(num_lines) +
"_lines_" + std::to_string(num_segments) +
"_segs/lines.txt";
moordyn::MoorDyn system(input_file.c_str(), MOORDYN_NO_OUTPUT);
system.SetDisableOutput(true);

// Don't have to free this pointer because it's done by the MoorDyn system.
moordyn::TimeScheme* timeScheme = moordyn::create_time_scheme(
tScheme, system.GetLogger(), system.GetWaves());
system.SetTimeScheme(timeScheme);

// int err;
unsigned int n_dof;
n_dof = system.NCoupledDOF();
double *x = NULL, *dx = NULL;
if (n_dof) {
x = new double[n_dof];
std::fill(x, x + n_dof, 0.0);
dx = new double[n_dof];
std::fill(dx, dx + n_dof, 0.0);
}
system.Init(x, dx, true);

double t = 0.0, dt = 0.01;
double f[3];

for (auto _ : state) {
system.Step(x, dx, f, t, dt);
}
state.counters["OuterTimeStep"] = dt;
}
static void
MoordynStepCaseRK4(benchmark::State& state)
{
MoorDynStepWithIntegrator(state, "RK4");
}
BENCHMARK(MoordynStepCaseRK4)
->ArgsProduct({ { 1, 2, 4, 8, 16, 32, 64 }, { 1, 2, 4, 8, 16, 32, 64 } })
->Unit(benchmark::kMicrosecond);

static void
MoordynStepCaseRK2(benchmark::State& state)
{
MoorDynStepWithIntegrator(state, "RK2");
}
BENCHMARK(MoordynStepCaseRK2)
->ArgsProduct({ { 1, 2, 4, 8, 16, 32, 64 }, { 1, 2, 4, 8, 16, 32, 64 } })
->Unit(benchmark::kMicrosecond);

BENCHMARK_MAIN();
11 changes: 11 additions & 0 deletions bench/LinesBench.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#pragma once

#define _USE_MATH_DEFINES
#include "MoorDyn.h"
#include "MoorDyn2.hpp"
#include "Waves.hpp"
#include "Waves/SpectrumKin.hpp"

#include <cmath>
#include <iostream>
4 changes: 3 additions & 1 deletion bench/MDBench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ LineGetStateDeriv(benchmark::State& state, std::string input_file)

auto line = system.GetLines().front();

std::vector<moordyn::vec> vel{};
std::vector<moordyn::vec> acc{};
for (auto _ : state) {
line->getStateDeriv();
line->getStateDeriv(vel, acc);
}
}
BENCHMARK_CAPTURE(LineGetStateDeriv,
Expand Down
1 change: 1 addition & 0 deletions bench/Mooring/cases/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lines.txt
92 changes: 92 additions & 0 deletions bench/Mooring/cases/generate_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from itertools import product
import os
from dataclasses import dataclass

"""Simple script for generating a bunch of model files for benchmarking purposes.

Just needs basic python (tested for version >=3.8).
"""


@dataclass
class BenchmarkParams:
num_lines: int
num_segments: int


def generate_benchmark(base_output_folder, params: BenchmarkParams):
"""Generate a single benchmark model file.

The model has a user defined number of lines that each share a fixed top
point, and have their own bottom point.
They start off at a 10 degree angle from vertical.
"""
points = "\n".join(
f"{i + 2} free 34.20201433256687 0.0 -93.96926207859084 0 0 0 0 -"
for i in range(params.num_lines)
)
line_length = 100.0
lines = "\n".join(
f"{i+1} chain 1 {i + 2} {line_length} {params.num_segments} p,t"
for i in range(params.num_lines)
)

file_str = f"""--------------------- MoorDyn Input File -------------------------------------------------------
Output from generate_cases.py
----------------------- LINE TYPES --------------------------------------------------------------
TypeName Diam Mass/m EA BA/-zeta EI Cd Ca CdAx CaAx
(name) (m) (kg/m) (N) (N-s/-) (N-m^2) (-) (-) (-) (-)
chain 0.252 390 16000000.0 -0.3 0.0 1.37 0.64 1.0 0.0
----------------------- POINTS -------------------------------------------------------------------
Node Type X Y Z M V CdA CA
(-) (-) (m) (m) (m) (kg) (m^3) (m^2) (-)
1 free 0.0 0.0 0.0 0 0 0 0 -
{points}
-------------------------- LINES -----------------------------------------------------------------
Line LineType NodeA NodeB UnstrLen NumSegs Flags/Outputs
(-) (-) (-) (-) (m) (-) (-)
{lines}
-------------------------- SOLVER OPTIONS---------------------------
0 writeLog - Write a log file
0.001 dtM - time step to use in mooring integration
rk4 tScheme
3000000.0 kb - bottom stiffness
300000.0 cb - bottom damping
200.0 WtrDpth - water depth
4.0 ICDfac - factor to scale drag coeff during IC
1.5e-06 threshIC - threshold for IC convergence
0.0 TmaxIC - threshold for IC convergence
1e-05 dtIC - Time lapse between convergence tests (s)
9.81 g - gravitational force constant
1025 rho - water density
0 WaveKin - waves mode
0 Currents - current mode
------------------------- need this line --------------------------------------
"""

folder_name = f"{params.num_lines}_lines_{params.num_segments}_segs"

output_folder = os.path.join(base_output_folder, folder_name)
try:
os.mkdir(output_folder)
except FileExistsError:
pass

out_path = os.path.join(output_folder, "lines.txt")

with open(out_path, "w") as f:
f.write(file_str)


def main():

number_of_lines = [2**n for n in range(7)]
number_of_segments = [2**n for n in range(7)]

for vals in product(number_of_lines, number_of_segments):
params = BenchmarkParams(*vals)
generate_benchmark("./", params)


if __name__ == "__main__":
main()
Loading
Loading