Skip to content

Commit

Permalink
feat(avm): deduplicating event emitters
Browse files Browse the repository at this point in the history
  • Loading branch information
fcarreiro committed Feb 20, 2025
1 parent 8effaa1 commit 5db5e4e
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
4 changes: 2 additions & 2 deletions barretenberg/cpp/src/barretenberg/vm2/common/map.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "barretenberg/vm2/common/ankerl_map.hpp"
#include "barretenberg/vm2/common/ankerl_dense.hpp"

namespace bb::avm2 {

Expand All @@ -16,4 +16,4 @@ template <class Key, class T> using unordered_flat_map = ::ankerl::unordered_den
// Note: if we eventually want to have lower memory usage at the cost of some speed,
// we can use ::ankerl::unordered_dense::segmented_map instead.

} // namespace bb::avm2
} // namespace bb::avm2
13 changes: 13 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm2/common/set.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include "barretenberg/vm2/common/ankerl_dense.hpp"

namespace bb::avm2 {

// We use an alternative single-header implementation that is faster and more memory efficient.
// https://github.com/martinus/unordered_dense
// https://martin.ankerl.com/2019/04/01/hashmap-benchmarks-01-overview/
// https://github.com/martinus/robin-hood-hashing is archived and recommends ankerl::unordered_dense.
template <class Key> using unordered_flat_set = ::ankerl::unordered_dense::set<Key>;

} // namespace bb::avm2
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ Instruction TxBytecodeManager::read_instruction(BytecodeId bytecode_id, uint32_t
// TODO: catch errors etc.
Instruction instruction = decode_instruction(bytecode, pc);

// The event will be deduplicated internally.
fetching_events.emit(
{ .bytecode_id = bytecode_id, .pc = pc, .instruction = instruction, .bytecode = bytecode_ptr });

return instruction;
}

} // namespace bb::avm2::simulation
} // namespace bb::avm2::simulation
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ struct InstructionFetchingEvent {
// TODO: Do we want to have a dep on Instruction here or do we redefine what we need?
Instruction instruction;
std::shared_ptr<std::vector<uint8_t>> bytecode;

// To be used with deduplicating event emitters.
using Key = std::tuple<BytecodeId, uint32_t>;
Key get_key() const { return { bytecode_id, pc }; }
};

} // namespace bb::avm2::simulation
} // namespace bb::avm2::simulation
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#pragma once

#include <functional>
#include <list>
#include <vector>

#include "barretenberg/vm2/common/set.hpp"

namespace bb::avm2::simulation {

template <typename Event> class EventEmitterInterface {
Expand Down Expand Up @@ -30,6 +33,29 @@ template <typename Event> class EventEmitter : public EventEmitterInterface<Even
Container events;
};

// This is an EventEmmiter that eagerly deduplicates events based on a provided key.
template <typename Event> class DeduplicatingEventEmitter : public EventEmitter<Event> {
public:
virtual ~DeduplicatingEventEmitter() = default;

void emit(Event&& event) override
{
typename Event::Key key = event.get_key();
if (!elements_seen.contains(key)) {
elements_seen.insert(key);
EventEmitter<Event>::emit(std::move(event));
}
};
EventEmitter<Event>::Container dump_events() override
{
elements_seen.clear();
return EventEmitter<Event>::dump_events();
}

private:
unordered_flat_set<typename Event::Key> elements_seen;
};

// This is an event emmiter that offers stable references to the events.
// It lets you access the last event that was emitted.
// Note: this is currently unused but it might be needed for the execution trace (calls).
Expand Down Expand Up @@ -64,4 +90,4 @@ template <typename Event> class NoopEventEmitter : public EventEmitterInterface<
Container dump_events() override { return {}; }
};

} // namespace bb::avm2::simulation
} // namespace bb::avm2::simulation
4 changes: 3 additions & 1 deletion barretenberg/cpp/src/barretenberg/vm2/simulation_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ namespace {
// Configuration for full simulation (for proving).
struct ProvingSettings {
template <typename E> using DefaultEventEmitter = EventEmitter<E>;
template <typename E> using DefaultDeduplicatingEventEmitter = DeduplicatingEventEmitter<E>;
};

// Configuration for fast simulation.
struct FastSettings {
template <typename E> using DefaultEventEmitter = NoopEventEmitter<E>;
template <typename E> using DefaultDeduplicatingEventEmitter = NoopEventEmitter<E>;
};

} // namespace
Expand All @@ -58,7 +60,7 @@ template <typename S> EventsContainer AvmSimulationHelper::simulate_with_setting
typename S::template DefaultEventEmitter<BytecodeRetrievalEvent> bytecode_retrieval_emitter;
typename S::template DefaultEventEmitter<BytecodeHashingEvent> bytecode_hashing_emitter;
typename S::template DefaultEventEmitter<BytecodeDecompositionEvent> bytecode_decomposition_emitter;
typename S::template DefaultEventEmitter<InstructionFetchingEvent> instruction_fetching_emitter;
typename S::template DefaultDeduplicatingEventEmitter<InstructionFetchingEvent> instruction_fetching_emitter;
typename S::template DefaultEventEmitter<AddressDerivationEvent> address_derivation_emitter;
typename S::template DefaultEventEmitter<ClassIdDerivationEvent> class_id_derivation_emitter;
typename S::template DefaultEventEmitter<SiloingEvent> siloing_emitter;
Expand Down

0 comments on commit 5db5e4e

Please sign in to comment.