Skip to content

Commit

Permalink
Write performance metrics to CSV
Browse files Browse the repository at this point in the history
  • Loading branch information
shg8 committed Apr 10, 2024
1 parent bb9d6b7 commit 0c47b52
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 7 deletions.
13 changes: 11 additions & 2 deletions apps/viewer/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ int main(int argc, char** argv)
parser, "immediate-swapchain", "Set swapchain mode to immediate (VK_PRESENT_MODE_IMMEDIATE_KHR)",
{'i', "immediate-swapchain"}
};
args::ValueFlag<uint32_t> widthFlag{parser, "width", "Set window width", {'w', "width"}};
args::ValueFlag<uint32_t> heightFlag{parser, "height", "Set window height", {'h', "height"}};
args::ValueFlag<int> widthFlag{parser, "width", "Set window width", {"width"}};
args::ValueFlag<int> heightFlag{parser, "height", "Set window height", {"height"}};
args::Flag noGuiFlag{parser, "no-gui", "Disable GUI", {"no-gui"}};
args::Positional<std::string> scenePath{parser, "scene", "Path to scene file", "scene.ply"};

args::ValueFlag<std::string> benchmarkOutputFolderFlag{
parser, "benchmark-output", "Output folder for benchmark results", {'b', "benchmark-output"}
};

try
{
parser.ParseCLI(argc, argv);
Expand Down Expand Up @@ -101,6 +105,11 @@ int main(int argc, char** argv)
config.enableGui = true;
}

if (benchmarkOutputFolderFlag)
{
config.benchmarkOutputFolder = std::make_optional(args::get(benchmarkOutputFolderFlag));
}

auto width = widthFlag ? args::get(widthFlag) : 1280;
auto height = heightFlag ? args::get(heightFlag) : 720;

Expand Down
1 change: 1 addition & 0 deletions include/3dgs/3dgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class VulkanSplatting {
bool enableVulkanValidationLayers = false;
std::optional<uint8_t> physicalDeviceId = std::nullopt;
std::string scene;
std::optional<std::string> benchmarkOutputFolder = std::nullopt;

float fov = 45.0f;
float near = 0.2f;
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ add_library(3dgs_cpp STATIC
vulkan/targets/OpenXRStereo.h
vulkan/targets/ManagedSwapchain.cpp
vulkan/targets/ManagedSwapchain.h
utils/CSVWriter.h
)

target_include_directories(3dgs_cpp
Expand Down
11 changes: 11 additions & 0 deletions src/GSScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ struct VertexStorage {
void GSScene::load(const std::shared_ptr<VulkanContext>&context) {
auto startTime = std::chrono::high_resolution_clock::now();

// Check if the file is a folder
auto path = std::filesystem::path(filename);
if (std::filesystem::is_directory(filename)) {
// Check if cameras.json exists
auto camerasPath = path / "cameras.json";
if (std::filesystem::exists(camerasPath)) {
spdlog::info("Dataset folder detected, loading cameras.json");
assert(false && "Not implemented");
}
}

std::ifstream plyFile(filename, std::ios::binary);
loadPlyHeader(plyFile);

Expand Down
34 changes: 32 additions & 2 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "vulkan/targets/OpenXRStereo.h"

void Renderer::initialize() {
initializeCsvWriter();
initializeVulkan();
createGui();
loadSceneToGPU();
Expand Down Expand Up @@ -100,6 +101,13 @@ void Renderer::retrieveTimestamps() {
if (configuration.enableGui)
guiManager.pushMetric(metric.first, metric.second / 1000000.0);
}

if (csvWriter) {
metrics["num_instances"] = numInstances;
metrics["timestamp"] = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now().time_since_epoch()).count();
csvWriter.value().log(metrics);
}
}

void Renderer::recreatePipelines() {
Expand Down Expand Up @@ -223,6 +231,28 @@ void Renderer::createGui() {
guiManager.init();
}

void Renderer::initializeCsvWriter() {
auto folder = configuration.benchmarkOutputFolder;
// Create folder if it does not exist
if (!folder.has_value()) {
return;
}

std::filesystem::create_directories(folder.value());

const auto path = std::filesystem::path(folder.value());

// Format the date and time
const auto now = std::chrono::system_clock::now();
const auto in_time_t = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d_%H-%M-%S");
const auto time = ss.str();

const auto filename = path / (time + ".csv");
csvWriter = std::move(CSVWriter(filename.string()));
}

void Renderer::createPrefixSumPipeline() {
spdlog::debug("Creating prefix sum pipeline");
prefixSumPingBuffer = Buffer::storage(context, scene->getNumVertices() * sizeof(uint32_t), false);
Expand Down Expand Up @@ -538,9 +568,9 @@ bool Renderer::recordRenderCommandBuffer(uint32_t currentFrame) {
vk::CommandBufferAllocateInfo(commandPool.get(), vk::CommandBufferLevel::ePrimary, 1))[0]);
}

uint32_t numInstances = totalSumBufferHost->readOne<uint32_t>();
numInstances = totalSumBufferHost->readOne<uint32_t>();
// spdlog::debug("Num instances: {}", numInstances);
guiManager.pushTextMetric("instances", numInstances);
guiManager.pushTextMetric("instances", static_cast<float>(numInstances));
if (numInstances > scene->getNumVertices() * sortBufferSizeMultiplier) {
auto old = sortBufferSizeMultiplier;
while (numInstances > scene->getNumVertices() * sortBufferSizeMultiplier) {
Expand Down
5 changes: 5 additions & 0 deletions src/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class Renderer {

void createGui();

void initializeCsvWriter();

void initialize();

void handleInput();
Expand All @@ -88,6 +90,7 @@ class Renderer {

private:
VulkanSplatting::RendererConfiguration configuration;
std::optional<CSVWriter> csvWriter = std::nullopt;
std::shared_ptr<VulkanContext> context;
std::shared_ptr<RenderTarget> renderTarget;
std::shared_ptr<ImguiManager> imguiManager;
Expand Down Expand Up @@ -118,6 +121,8 @@ class Renderer {

std::shared_ptr<DescriptorSet> inputSet;

uint32_t numInstances;

std::atomic<bool> running = true;

std::vector<vk::UniqueFence> inflightFences;
Expand Down
88 changes: 88 additions & 0 deletions src/utils/CSVWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#ifndef CSVWRITER_H
#define CSVWRITER_H

#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <unordered_map>
#include <cstdint>
#include <ranges>

class CSVWriter {
private:
std::vector<std::string> columns;
std::ofstream file;

public:
// Constructor that takes a vector of column names
explicit CSVWriter(const std::string& filename) {
// assert that the file does not exist
if (std::ifstream(filename)) {
throw std::runtime_error("File already exists");
}

file.open(filename, std::ios::out | std::ios::trunc);
}

CSVWriter(const CSVWriter &other) = delete;

CSVWriter(CSVWriter &&other) noexcept
: columns(std::move(other.columns)),
file(std::move(other.file)) {
}

CSVWriter & operator=(const CSVWriter &other) = delete;

CSVWriter & operator=(CSVWriter &&other) noexcept {
if (this == &other)
return *this;
columns = std::move(other.columns);
file = std::move(other.file);
return *this;
}

// Log function to write a row of data
void log(const std::vector<std::string>& rowData) {
if (!file.is_open()) {
throw std::runtime_error("File is not open");
}
// Write the row data
for (size_t i = 0; i < rowData.size(); ++i) {
file << rowData[i];
if (i < rowData.size() - 1) file << ",";
}
file << "\n";
}

void log(const std::unordered_map<std::string, uint64_t>& row) {
if (columns.empty()) {
for (const auto& columnName : std::ranges::views::keys(row)) {
columns.push_back(columnName);
}
log(columns);
}

if (!file.is_open()) {
throw std::runtime_error("File is not open");
}

// Write the row data
for (size_t i = 0; i < columns.size(); ++i) {
file << row.at(columns[i]);
if (i < columns.size() - 1) file << ",";
}
file << "\n";
}

// Destructor to close the file if it's open
~CSVWriter() {
if (file.is_open()) {
file.close();
}
}
};



#endif //CSVWRITER_H
12 changes: 9 additions & 3 deletions src/vulkan/QueryManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@
#include <chrono>
#include <string>

#include "../utils/CSVWriter.h"


class QueryManager {
public:
uint32_t registerQuery(const std::string &name);

[[nodiscard]] uint32_t getQueryId(const std::string &name);

std::unordered_map<std::string, uint64_t> parseResults(const std::vector<uint64_t>& results);
std::unordered_map<std::string, uint64_t> parseResults(const std::vector<uint64_t> &results);

int nextId = 0;

private:
std::mutex mutex;
std::unordered_map<std::string, uint32_t> registry;
std::unordered_map<std::string, std::vector<uint64_t>> results;
std::unordered_map<std::string, std::vector<uint64_t> > results;
std::chrono::time_point<std::chrono::high_resolution_clock> lastPrint;
};
}
;



Expand Down

0 comments on commit 0c47b52

Please sign in to comment.