Skip to content

Commit

Permalink
allocation cleanup and benchmarking integration
Browse files Browse the repository at this point in the history
  • Loading branch information
thadeuluiz committed Dec 23, 2019
1 parent 7beddb0 commit fd56557
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 115 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
build/
.clangd/
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(PkgConfig REQUIRED)

# external packages
find_package(Catch2 REQUIRED)
find_package(Boost REQUIRED)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(CUDA REQUIRED)
Expand Down
17 changes: 8 additions & 9 deletions lib/circuit/src/circuit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,31 +172,30 @@ namespace rtspice::circuit {
assert(row_begin == nodes_.pointers.end() && "not all coordinates used");

//get optimal pattern
const auto perm = std::make_unique<int[]>(m);
int perm[m];
auto status = cusolverSpXcsrsymmdqHost(context_.solver_handle, m, nnz,
sys.desc_A, sys.row.get(), sys.col.get(), perm.get());
sys.desc_A, sys.row.get(), sys.col.get(), perm);
assert(status == CUSOLVER_STATUS_SUCCESS);

//allocate permutation worksize
size_t bsize;
status = cusolverSpXcsrperm_bufferSizeHost(context_.solver_handle, m, m, nnz,
sys.desc_A, sys.row.get(), sys.col.get(), perm.get(), perm.get(), &bsize);
sys.desc_A, sys.row.get(), sys.col.get(), perm, perm, &bsize);
assert(status == CUSOLVER_STATUS_SUCCESS);

const auto work = std::make_unique<uint8_t[]>(bsize);
const auto map = std::make_unique<int[]>(nnz);
iota(map.get(), map.get()+nnz, 0);
uint8_t work[bsize];
int map[nnz];
iota(map, map+nnz, 0);

//perform Q * A * Q^T
status = cusolverSpXcsrpermHost(context_.solver_handle, m, m, nnz,
sys.desc_A, sys.row.get(), sys.col.get(),
perm.get(), perm.get(), map.get(),
work.get());
perm, perm, map, work);
assert(status == CUSOLVER_STATUS_SUCCESS);

//update node name map
for(auto&& [_, idx]: nodes_.names)
idx = find(perm.get(), perm.get()+m, idx) - perm.get();
idx = find(perm, perm+m, idx) - perm;

for(auto&& kv: nodes_.pointers){

Expand Down
10 changes: 4 additions & 6 deletions lib/circuit/test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
add_executable(circuit_test circuit_test.cpp)
target_link_libraries(
circuit_test
PRIVATE
circuit
test_main
)
target_link_libraries(circuit_test PRIVATE circuit test_main)

include(Catch)
catch_discover_tests(circuit_test)
114 changes: 15 additions & 99 deletions lib/circuit/test/circuit_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <fstream>
#include <iterator>

#define CATCH_CONFIG_ENABLE_BENCHMARKING
#include <catch2/catch.hpp>


Expand All @@ -38,9 +39,6 @@ using namespace rtspice::components;

using std::vector;

using std::chrono::high_resolution_clock;
using std::chrono::nanoseconds;

using rtspice::circuit::circuit;

SCENARIO("circuit initialization", "[circuit]") {
Expand Down Expand Up @@ -80,17 +78,12 @@ SCENARIO("circuit initialization", "[circuit]") {
CHECK(*c.get_x("1") == Approx(1.0f));
CHECK(*c.get_x("2") == Approx(0.5f));

constexpr auto NITER = 44100;

const auto start = high_resolution_clock::now();

for(auto i = 0; i < NITER; i++)
// check stability and benchmark
BENCHMARK("Newton-Raphson step on DC"){
c.nr_step_();
};

const auto delta = high_resolution_clock::now() - start;
const auto avgTime = nanoseconds{delta}.count()/NITER;

INFO( "average iteration time: " << avgTime << " ns");
CHECK(*c.get_x("1") == Approx(1.0f));
CHECK(*c.get_x("2") == Approx(0.5f));
}
Expand All @@ -111,36 +104,16 @@ SCENARIO("nonlinear simulation", "[circuit]") {
circuit c{components};

THEN("Newton-Raphson converges") {
{
const auto start = high_resolution_clock::now();

const auto i = c.nr_step_();

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeDC = nanoseconds{delta}.count();


INFO("DC Runtime = " << RunTimeDC << " ns");
INFO("V[diode] = " << *c.get_x("2") << " V");
CHECK( i > 0 );
}

{
const auto start = high_resolution_clock::now();

for(auto i = 0; i < 100; i++) c.nr_step_();

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeBasicStep = nanoseconds{delta}.count();
}


INFO("Average Runtime Basic Step = " << RunTimeBasicStep/100 << " ns");
INFO("V[diode] = " << *c.get_x("2") << " V");
REQUIRE(true);
}

}
BENCHMARK("Newton-Raphson step on Diode"){
c.nr_step_();
};

INFO("V[diode] = " << *c.get_x("2") << " V");
}

}
Expand All @@ -162,14 +135,7 @@ SCENARIO("dynamic simulation", "[circuit]") {
constexpr int niter = 10;

THEN("time simulation converges") {
const auto start = high_resolution_clock::now();

const auto i = c.advance_(delta_t);

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();

INFO("Transient step Runtime = " << RunTimeTran << " ns");
INFO("V[cap] = " << *c.get_x("2") << " V");
REQUIRE( i > 0 );
}
Expand All @@ -181,23 +147,15 @@ SCENARIO("dynamic simulation", "[circuit]") {

const auto vptr = c.get_x("2");

const auto start = high_resolution_clock::now();

for(auto iter = 0; iter < niter; ++iter) {
is[iter] = c.advance_(delta_t);
vs[iter] = *vptr;
}

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();

for(auto iter = 0; iter < niter; ++iter) {
INFO("V[cap] = " << vs[iter] << " V");
CHECK(is[iter] > 0);
}
INFO("Transient step Runtime = " << RunTimeTran/niter << " ns");
REQUIRE(true);

}

}
Expand All @@ -222,14 +180,7 @@ SCENARIO("nonlinear dynamic simulation", "[circuit]") {
constexpr int niter = 10;

THEN("time simulation converges") {
const auto start = high_resolution_clock::now();

const auto i = c.advance_(delta_t);

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();

INFO("Transient step Runtime = " << RunTimeTran << " ns");
INFO("V[cap] = " << *c.get_x("2") << " V");
REQUIRE( i > 0 );
}
Expand All @@ -241,22 +192,15 @@ SCENARIO("nonlinear dynamic simulation", "[circuit]") {

const auto vptr = c.get_x("2");

const auto start = high_resolution_clock::now();

for(auto iter = 0; iter < niter; ++iter) {
is[iter] = c.advance_(delta_t);
vs[iter] = *vptr;
}

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();

for(auto iter = 0; iter < niter; ++iter) {
INFO("V[cap] = " << vs[iter] << " V");
REQUIRE(is[iter] > 0);
}
INFO("Transient step Runtime = " << RunTimeTran/niter << " ns");
REQUIRE(true);

}

Expand All @@ -269,19 +213,12 @@ SCENARIO("nonlinear dynamic simulation", "[circuit]") {

const auto vptr = c.get_x("2");

const auto start = high_resolution_clock::now();

for(auto iter = 0; iter < sim_size; ++iter) {
is[iter] = c.advance_(delta_t);
vs[iter] = *vptr;
}

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();

REQUIRE(std::all_of(is.cbegin(), is.cend(), [](auto i){ return i > 0; }));
INFO("Transient step Runtime = " << RunTimeTran/sim_size << " ns");
REQUIRE(true);

std::ofstream v_file("sim_v.txt");
std::copy(vs.cbegin(), vs.cend(), std::ostream_iterator<float>(v_file, "\n"));
Expand Down Expand Up @@ -337,45 +274,24 @@ SCENARIO("basic circuit simulation", "[circuit]") {
circuit c{components};

constexpr float delta_t = 1.0 / 44100.0;
constexpr int niter = 44100;

THEN("basic simulation") {

//std::vector<float> vs(niter);
std::vector<int> is(niter);
std::vector<int> is;
//std::vector<std::chrono::time_point<high_resolution_clock>> ts(niter);

const auto vptr = c.get_x("7");

//c.nr_step_(); //dc point

const auto start = high_resolution_clock::now();

for(auto iter = 0; iter < niter; ++iter) {
is[iter] = c.advance_(delta_t);
//vs[iter] = *vptr;
//ts[iter] = high_resolution_clock::now();
}
BENCHMARK_ADVANCED("basic simulation")(Catch::Benchmark::Chronometer meter) {
auto niter = meter.runs();
is.resize(niter);
meter.measure([&](auto i){ is[i] = c.advance_(delta_t); });
};

const auto delta = high_resolution_clock::now() - start;
const auto RunTimeTran = nanoseconds{delta}.count();
CHECK(std::all_of(is.cbegin(), is.cend(), [](auto i){ return i > 0; }));

const auto inner_it = std::accumulate(is.cbegin(), is.cend(), 0);

INFO("Average solve runtime = " << RunTimeTran/inner_it << " ns");
REQUIRE(true);

//std::ofstream v_file("sim_vout.txt");
//std::copy(vs.cbegin(), vs.cend(), std::ostream_iterator<float>(v_file, "\n"));

//std::ofstream i_file("sim_steps.txt");
//std::copy(is.cbegin(), is.cend(), std::ostream_iterator<int>(i_file, "\n"));

//std::ofstream t_file("sim_times.txt");
//auto it = std::ostream_iterator<int>(t_file, "\n");
//for(auto i = 1; i < niter; ++i)
// *it++ = nanoseconds{ts[i] - ts[i-1]}.count();
}

}
Expand Down
1 change: 1 addition & 0 deletions test/src/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
* GNU General Public License as published by the Free Software Foundation.
*/

#define CATCH_CONFIG_ENABLE_BENCHMARKING
#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"
2 changes: 1 addition & 1 deletion third_party/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
add_subdirectory(Catch2/)
#add_subdirectory(Catch2/)

0 comments on commit fd56557

Please sign in to comment.