Skip to content
Snippets Groups Projects
Commit 067d608b authored by Philipp Spilger's avatar Philipp Spilger
Browse files

Separate initial config generation from ExecutionInstanceBuilder

* allows independent operations on the config such as constructing
  differentials for iterative execution approaches

Change-Id: I7d88e2419b04a08a3f9a5ecee9d4de9ee8dafe32
parent 08d7666b
No related branches found
Tags EOL_hx_v2
No related merge requests found
......@@ -46,7 +46,7 @@ public:
coordinate::ExecutionInstance const& execution_instance,
IODataMap const& input_list,
IODataMap const& data_output,
lola::vx::v2::Chip const& chip_config,
std::optional<lola::vx::v2::PPUElfFile::symbols_type> const& ppu_symbols,
ExecutionInstancePlaybackHooks& playback_hooks) SYMBOL_VISIBLE;
/**
......@@ -56,7 +56,6 @@ public:
struct PlaybackPrograms
{
stadls::vx::v2::PlaybackProgram static_config;
std::vector<stadls::vx::v2::PlaybackProgram> realtime;
bool has_hook_around_realtime;
};
......@@ -89,7 +88,7 @@ private:
ConstantReferenceIODataMap m_local_external_data;
lola::vx::v2::Chip m_initial_config;
std::optional<lola::vx::v2::PPUElfFile::symbols_type> m_ppu_symbols;
ExecutionInstancePlaybackHooks& m_playback_hooks;
......
......@@ -46,14 +46,14 @@ ExecutionInstanceBuilder::ExecutionInstanceBuilder(
coordinate::ExecutionInstance const& execution_instance,
IODataMap const& input_list,
IODataMap const& data_output,
lola::vx::v2::Chip const& chip_config,
std::optional<lola::vx::v2::PPUElfFile::symbols_type> const& ppu_symbols,
ExecutionInstancePlaybackHooks& playback_hooks) :
m_graph(graph),
m_execution_instance(execution_instance),
m_input_list(input_list),
m_data_output(data_output),
m_local_external_data(),
m_initial_config(chip_config),
m_ppu_symbols(ppu_symbols),
m_playback_hooks(playback_hooks),
m_post_vertices(),
m_local_data(),
......@@ -827,37 +827,16 @@ ExecutionInstanceBuilder::PlaybackPrograms ExecutionInstanceBuilder::generate()
builder.merge_back(m_playback_hooks.pre_realtime);
builder.merge_back(m_playback_hooks.post_realtime);
m_chunked_program = {builder.done()};
return {{}, m_chunked_program, false};
return {m_chunked_program, false};
}
// playback builder sequence to be concatenated in the end
std::vector<PlaybackProgramBuilder> builders;
// add pre static config playback hook
auto config_builder = std::move(m_playback_hooks.pre_static_config);
// generate static configuration
auto [static_config, ppu_symbols] =
ExecutionInstanceConfigVisitor(m_graph, m_execution_instance, m_initial_config)();
config_builder.write(ChipOnDLS(), static_config);
// wait for CapMem to settle
config_builder.block_until(BarrierOnFPGA(), Barrier::omnibus);
config_builder.write(TimerOnDLS(), Timer());
config_builder.block_until(
TimerOnDLS(), Timer::Value(100000 * Timer::Value::fpga_clock_cycles_per_us));
// bring PPUs in running state
bool const enable_ppu = static_cast<bool>(ppu_symbols);
if (enable_ppu) {
for (auto const ppu : iter_all<PPUOnDLS>()) {
PPUControlRegister ctrl;
ctrl.set_inhibit_reset(true);
config_builder.write(ppu.toPPUControlRegisterOnDLS(), ctrl);
}
}
// generate playback snippet for neuron resets
auto [builder_neuron_reset, _] = stadls::vx::generate(m_neuron_resets);
auto const enable_ppu = static_cast<bool>(m_ppu_symbols);
bool const has_cadc_readout = std::any_of(
m_ticket_requests.begin(), m_ticket_requests.end(), [](auto const v) { return v; });
assert(has_cadc_readout ? enable_ppu : true);
......@@ -884,14 +863,14 @@ ExecutionInstanceBuilder::PlaybackPrograms ExecutionInstanceBuilder::generate()
std::optional<PPUMemoryBlockOnPPU> ppu_scheduler_event_drop_count_coord;
std::vector<PPUMemoryBlockOnPPU> ppu_timer_event_drop_count_coord;
if (enable_ppu) {
assert(ppu_symbols);
ppu_status_coord = ppu_symbols->at("status").coordinate.toMin();
ppu_result_coord = ppu_symbols->at("cadc_result").coordinate;
ppu_runtime_coord = ppu_symbols->at("runtime").coordinate.toMin();
if (ppu_symbols->contains("scheduler_event_drop_count")) {
assert(m_ppu_symbols);
ppu_status_coord = m_ppu_symbols->at("status").coordinate.toMin();
ppu_result_coord = m_ppu_symbols->at("cadc_result").coordinate;
ppu_runtime_coord = m_ppu_symbols->at("runtime").coordinate.toMin();
if (m_ppu_symbols->contains("scheduler_event_drop_count")) {
ppu_scheduler_event_drop_count_coord.emplace(
ppu_symbols->at("scheduler_event_drop_count").coordinate);
for (auto const& [name, symbol] : *ppu_symbols) {
m_ppu_symbols->at("scheduler_event_drop_count").coordinate);
for (auto const& [name, symbol] : *m_ppu_symbols) {
if (name.starts_with("timer") && name.ends_with("event_drop_count")) {
ppu_timer_event_drop_count_coord.push_back(symbol.coordinate);
}
......@@ -931,19 +910,6 @@ ExecutionInstanceBuilder::PlaybackPrograms ExecutionInstanceBuilder::generate()
wait_for_ppu_command_idle.block_until(
PollingOmnibusBlockOnFPGA(), PollingOmnibusBlock());
}
// wait for PPUs to be ready
for (auto const ppu : iter_all<PPUOnDLS>()) {
PollingOmnibusBlockConfig config;
config.set_address(PPUMemoryWord::addresses<PollingOmnibusBlockConfig::Address>(
PPUMemoryWordOnDLS(ppu_status_coord, ppu))
.at(0));
config.set_target(
PollingOmnibusBlockConfig::Value(static_cast<uint32_t>(ppu::Status::idle)));
config.set_mask(PollingOmnibusBlockConfig::Value(0xffffffff));
config_builder.write(PollingOmnibusBlockConfigOnFPGA(), config);
config_builder.block_until(BarrierOnFPGA(), Barrier::omnibus);
config_builder.block_until(PollingOmnibusBlockOnFPGA(), PollingOmnibusBlock());
}
}
// get whether any of {pre,post}_realtime hooks are present
......@@ -1192,7 +1158,7 @@ ExecutionInstanceBuilder::PlaybackPrograms ExecutionInstanceBuilder::generate()
if (!builder.empty()) {
m_chunked_program.push_back(builder.done());
}
return {config_builder.done(), m_chunked_program, has_hook_around_realtime};
return {m_chunked_program, has_hook_around_realtime};
}
} // namespace grenade::vx
......@@ -2,6 +2,10 @@
#include "grenade/vx/backend/connection.h"
#include "grenade/vx/backend/run.h"
#include "grenade/vx/execution_instance_config_visitor.h"
#include "grenade/vx/ppu/status.h"
#include "haldls/vx/v2/barrier.h"
#include "haldls/vx/v2/timer.h"
#include "hate/timer.h"
#include <log4cxx/logger.h>
......@@ -33,8 +37,16 @@ void ExecutionInstanceNode::operator()(tbb::flow::continue_msg)
using namespace halco::common;
using namespace halco::hicann_dls::vx::v2;
hate::Timer const initial_config_timer;
lola::vx::v2::Chip initial_config = chip_config;
auto const ppu_symbols =
std::get<1>(ExecutionInstanceConfigVisitor(graph, execution_instance, initial_config)());
LOG4CXX_TRACE(
logger,
"operator(): Constructed initial configuration in " << initial_config_timer.print() << ".");
ExecutionInstanceBuilder builder(
graph, execution_instance, input_data_map, data_map, chip_config, playback_hooks);
graph, execution_instance, input_data_map, data_map, ppu_symbols, playback_hooks);
hate::Timer const preprocess_timer;
builder.pre_process();
......@@ -43,6 +55,46 @@ void ExecutionInstanceNode::operator()(tbb::flow::continue_msg)
// build PlaybackProgram
hate::Timer const build_timer;
// add pre static config playback hook
auto config_builder = std::move(playback_hooks.pre_static_config);
// generate static configuration
config_builder.write(ChipOnDLS(), initial_config);
// wait for CapMem to settle
config_builder.block_until(BarrierOnFPGA(), haldls::vx::v2::Barrier::omnibus);
config_builder.write(TimerOnDLS(), haldls::vx::v2::Timer());
config_builder.block_until(
TimerOnDLS(), haldls::vx::v2::Timer::Value(
100000 * haldls::vx::v2::Timer::Value::fpga_clock_cycles_per_us));
// bring PPUs in running state
if (ppu_symbols) {
for (auto const ppu : iter_all<PPUOnDLS>()) {
haldls::vx::v2::PPUControlRegister ctrl;
ctrl.set_inhibit_reset(true);
config_builder.write(ppu.toPPUControlRegisterOnDLS(), ctrl);
}
auto const ppu_status_coord = ppu_symbols->at("status").coordinate.toMin();
// wait for PPUs to be ready
for (auto const ppu : iter_all<PPUOnDLS>()) {
using namespace haldls::vx::v2;
PollingOmnibusBlockConfig config;
config.set_address(PPUMemoryWord::addresses<PollingOmnibusBlockConfig::Address>(
PPUMemoryWordOnDLS(ppu_status_coord, ppu))
.at(0));
config.set_target(
PollingOmnibusBlockConfig::Value(static_cast<uint32_t>(ppu::Status::idle)));
config.set_mask(PollingOmnibusBlockConfig::Value(0xffffffff));
config_builder.write(PollingOmnibusBlockConfigOnFPGA(), config);
config_builder.block_until(BarrierOnFPGA(), Barrier::omnibus);
config_builder.block_until(PollingOmnibusBlockOnFPGA(), PollingOmnibusBlock());
}
}
auto initial_config_program = config_builder.done();
// build realtime programs
auto program = builder.generate();
LOG4CXX_TRACE(logger, "operator(): Built PlaybackPrograms in " << build_timer.print() << ".");
......@@ -56,10 +108,10 @@ void ExecutionInstanceNode::operator()(tbb::flow::continue_msg)
// execute
hate::Timer const exec_timer;
if (!program.realtime.empty() || !program.static_config.empty()) {
if (!program.realtime.empty() || !initial_config_program.empty()) {
std::lock_guard lock(continuous_chunked_program_execution_mutex);
auto static_config_reinit = connection.create_reinit_stack_entry();
static_config_reinit.set(program.static_config, true);
auto initial_config_reinit = connection.create_reinit_stack_entry();
initial_config_reinit.set(initial_config_program, true);
for (auto& p : program.realtime) {
backend::run(connection, p);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment