Skip to content

Commit

Permalink
[rt] Create a tracer class
Browse files Browse the repository at this point in the history
  • Loading branch information
boschmitt committed Feb 7, 2024
1 parent accd645 commit 576f5e6
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 16 deletions.
2 changes: 2 additions & 0 deletions docs/sphinx/api/languages/cpp_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Common
.. doxygenclass:: cudaq::complex_matrix
:members:

.. doxygenclass:: cudaq::Trace

.. doxygenclass:: cudaq::Resources

.. doxygentypedef:: cudaq::complex_matrix::value_type
Expand Down
1 change: 1 addition & 0 deletions runtime/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ set(COMMON_RUNTIME_SRC
NoiseModel.cpp
ServerHelper.cpp
Resources.cpp
Trace.cpp
Future.cpp
)

Expand Down
4 changes: 2 additions & 2 deletions runtime/common/ExecutionContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include "Future.h"
#include "MeasureCounts.h"
#include "NoiseModel.h"
#include "Resources.h"
#include "Trace.h"
#include <optional>
#include <string_view>

Expand Down Expand Up @@ -68,7 +68,7 @@ class ExecutionContext {

/// @brief When run under the tracer context, persist the
/// traced quantum resources here.
Resources kernelResources;
Trace kernelTrace;

/// @brief The name of the kernel being executed.
std::string kernelName = "";
Expand Down
10 changes: 9 additions & 1 deletion runtime/common/Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@

namespace cudaq {

Resources Resources::compute(const Trace &trace) {
Resources resources;
for (const auto &inst : trace)
resources.appendInstruction(
Instruction(inst.name, inst.controls, inst.targets[0]));
return resources;
}

std::size_t
Resources::InstructionHash::operator()(const Instruction &instruction) const {
std::size_t seed = 0;
Expand Down Expand Up @@ -130,4 +138,4 @@ void Resources::dump(std::ostream &os) const {
os << stream.str();
}
void Resources::dump() const { dump(std::cout); }
} // namespace cudaq
} // namespace cudaq
5 changes: 4 additions & 1 deletion runtime/common/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include "Trace.h"
#include <ostream>
#include <unordered_map>
#include <vector>
Expand All @@ -28,6 +29,8 @@ class Resources {
};

public:
static Resources compute(const Trace &trace);

/// @brief The Resources::Instruction is a data type that
/// encapsulates the name of a quantum operation, the set of
/// optional control indices, and the target qubit index.
Expand Down Expand Up @@ -101,4 +104,4 @@ class Resources {
std::unordered_map<Instruction, std::size_t, InstructionHash> instructions;
};

} // namespace cudaq
} // namespace cudaq
27 changes: 27 additions & 0 deletions runtime/common/Trace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*******************************************************************************
* Copyright (c) 2022 - 2023 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/

#include "Trace.h"
#include <algorithm>
#include <cassert>

namespace cudaq {

void Trace::appendInstruction(std::string_view name, std::vector<double> params,
std::vector<std::size_t> controls,
std::vector<std::size_t> targets) {
assert(!targets.empty() && "A instruction must have at least one target");
std::size_t maxID = *std::max_element(targets.begin(), targets.end());
if (!controls.empty())
maxID =
std::max(maxID, *std::max_element(controls.begin(), controls.end()));
numQudits = std::max(numQudits, maxID + 1);
instructions.emplace_back(name, params, controls, targets);
}

} // namespace cudaq
50 changes: 50 additions & 0 deletions runtime/common/Trace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/****************************************************************-*- C++ -*-****
* Copyright (c) 2022 - 2023 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/

#pragma once

#include <string>
#include <vector>

namespace cudaq {

/// @brief A trace is a circuit representation of the executed computation, as
/// seen by the execution manager. (Here, a circuit is represented as a list
/// of instructions on qudits). Since the execution manager cannot "see" control
/// flow, the trace of a kernel with control flow represents a single execution
/// path, and thus two calls to the same kernel might produce traces.
class Trace {
public:
struct Instruction {
std::string name;
std::vector<double> params;
std::vector<std::size_t> controls;
std::vector<std::size_t> targets;

Instruction(std::string_view name, std::vector<double> params,
std::vector<std::size_t> controls,
std::vector<std::size_t> targets)
: name(name), params(params), controls(controls), targets(targets) {}
};

void appendInstruction(std::string_view name, std::vector<double> params,
std::vector<std::size_t> controls,
std::vector<std::size_t> targets);

auto getNumQudits() const { return numQudits; }

auto begin() const { return instructions.begin(); }

auto end() const { return instructions.end(); }

private:
std::size_t numQudits = 0;
std::vector<Instruction> instructions;
};

} // namespace cudaq
5 changes: 2 additions & 3 deletions runtime/cudaq/algorithms/resource_estimation.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
#pragma once

#include "common/ExecutionContext.h"
#include "common/MeasureCounts.h"
#include "cudaq/concepts.h"
#include "common/Resources.h"
#include "cudaq/platform.h"

namespace cudaq {
Expand All @@ -27,7 +26,7 @@ auto estimate_resources(QuantumKernel &&kernel, Args &&...args) {
platform.set_exec_ctx(&context);
kernel(args...);
platform.reset_exec_ctx();
return context.kernelResources;
return cudaq::Resources::compute(context.kernelTrace);
}

} // namespace cudaq
26 changes: 17 additions & 9 deletions runtime/cudaq/qis/managers/BasicExecutionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,18 +220,26 @@ class BasicExecutionManager : public cudaq::ExecutionManager {
}

void synchronize() override {
// A vector of qudit info into qudit ids.
auto convertToID = [](std::vector<QuditInfo> qudits) {
std::vector<std::size_t> ids;
ids.reserve(qudits.size());
std::transform(qudits.cbegin(), qudits.cend(), std::back_inserter(ids),
[](auto &q) { return q.id; });
return ids;
};

for (auto &instruction : instructionQueue) {
if (isInTracerMode()) {
auto [gateName, params, controls, targets, op] = instruction;
std::vector<std::size_t> controlIds;
std::transform(controls.begin(), controls.end(),
std::back_inserter(controlIds),
[](const auto &el) { return el.id; });
executionContext->kernelResources.appendInstruction(
cudaq::Resources::Instruction(gateName, controlIds, targets[0].id));
} else {
if (!isInTracerMode()) {
executeInstruction(instruction);
continue;
}

auto &&[name, params, controls, targets, op] = instruction;
std::vector<std::size_t> controlIds = convertToID(controls);
std::vector<std::size_t> targetsIds = convertToID(targets);
executionContext->kernelTrace.appendInstruction(name, params, controlIds,
targetsIds);
}
instructionQueue.clear();
}
Expand Down

0 comments on commit 576f5e6

Please sign in to comment.