Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 20 additions & 24 deletions bindings/dd/register_dd_export.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
#include "nanobind/nanobind.h"
#include "nanobind/stl/string.h" // NOLINT(misc-include-cleaner)

#include <cstring>
#include <filesystem>
#include <ios>
#include <sstream>
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

#include <string>
#include <utility>

namespace mqt {

Expand All @@ -33,9 +33,9 @@ void registerDDExport(nanobind::class_<dd::Edge<Node>>& edgeClass) {
edgeClass.def(
"to_bytes",
[](const dd::Edge<Node>& e, const bool binary = true) {
std::ostringstream os(std::ios::out | std::ios::binary);
std::string data;
llvm::raw_string_ostream os(data);
dd::serialize(e, os, binary);
const auto data = os.view();
return nb::bytes(data.data(), data.size());
},
"binary"_a = true, R"pb(Serialize the DD to bytes.
Expand All @@ -53,9 +53,8 @@ void registerDDExport(nanobind::class_<dd::Edge<Node>>& edgeClass) {
edgeClass.def_static(
"from_bytes",
[](dd::Package& p, const nb::bytes& data, const bool binary = true) {
std::istringstream is(std::string(data.c_str(), data.size()),
std::ios::in | std::ios::binary);
return p.deserialize<Node>(is, binary);
return p.deserialize<Node>(llvm::StringRef(data.c_str(), data.size()),
binary);
},
"dd_package"_a, "data"_a, "binary"_a = true,
// keep the DD package alive while the returned DD is alive.
Expand All @@ -78,9 +77,10 @@ void registerDDExport(nanobind::class_<dd::Edge<Node>>& edgeClass) {
[](const dd::Edge<Node>& e, const bool colored = true,
const bool edgeLabels = false, const bool classic = false,
const bool memory = false, const bool formatAsPolar = true) {
std::ostringstream os;
std::string data;
llvm::raw_string_ostream os(data);
dd::toDot(e, os, colored, edgeLabels, classic, memory, formatAsPolar);
return std::move(os).str();
return data;
},
"colored"_a = true, "edge_labels"_a = false, "classic"_a = false,
"memory"_a = false, "format_as_polar"_a = true,
Expand All @@ -102,8 +102,8 @@ void registerDDExport(nanobind::class_<dd::Edge<Node>>& edgeClass) {
const bool colored = true, const bool edgeLabels = false,
const bool classic = false, const bool memory = false,
const bool formatAsPolar = true) {
const auto dotFilename =
std::filesystem::u8path(filename).replace_extension(".dot");
llvm::SmallString<128> dotFilename(filename);
llvm::sys::path::replace_extension(dotFilename, ".dot");
nb::object pygraphviz;
try {
pygraphviz = nb::module_::import_("pygraphviz");
Expand All @@ -122,16 +122,12 @@ void registerDDExport(nanobind::class_<dd::Edge<Node>>& edgeClass) {
!usePyGraphviz, formatAsPolar);
if (usePyGraphviz) {
auto svgFilename = dotFilename;
svgFilename.replace_extension(".svg");
const auto utf8Path = [](const std::filesystem::path& path) {
const auto bytes = path.u8string();
std::string value(bytes.size(), '\0');
std::memcpy(value.data(), bytes.data(), bytes.size());
return value;
};
pygraphviz.attr("AGraph")("filename"_a = utf8Path(dotFilename))
.attr("draw")(utf8Path(svgFilename), "format"_a = "svg",
"prog"_a = "dot");
llvm::sys::path::replace_extension(svgFilename, ".svg");
pygraphviz
.attr("AGraph")("filename"_a = nb::str(dotFilename.data(),
dotFilename.size()))
.attr("draw")(nb::str(svgFilename.data(), svgFilename.size()),
"format"_a = "svg", "prog"_a = "dot");
}
},
"filename"_a, "colored"_a = true, "edge_labels"_a = false,
Expand Down
1 change: 1 addition & 0 deletions cmake/mqt-core-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ if(mqt-core_Development_FOUND
find_package(LLVM @LLVM_VERSION_MAJOR@.@LLVM_VERSION_MINOR@ CONFIG QUIET)
if(LLVM_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/mqt-core-development-targets.cmake")
target_include_directories(MQT::CoreDD SYSTEM INTERFACE ${LLVM_INCLUDE_DIRS})
target_include_directories(MQT::CoreQDMICommon SYSTEM INTERFACE ${LLVM_INCLUDE_DIRS})
target_include_directories(MQT::CoreBench SYSTEM INTERFACE ${LLVM_INCLUDE_DIRS})
target_include_directories(MQT::CoreQDMIScDeviceConfig SYSTEM INTERFACE ${LLVM_INCLUDE_DIRS})
Expand Down
13 changes: 13 additions & 0 deletions docs/cpp_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,16 @@ part of the installed public-header reference above. See
[device compilation from C++](mlir/target_compilation.md#c-source-tree-api), the
{doc}`QIR runtime guide <qir/index>`, and the
{doc}`MLIR dialect and pass references <mlir/index>`.

## DD input and output

DD serializers, DOT exporters, statistics and number printers write to
`llvm::raw_ostream`. The caller owns the stream and checks any sink errors;
file-writing overloads report failures with exceptions. Use
`llvm::raw_string_ostream` to collect output in a `std::string`.

`Package::deserialize` reads borrowed `llvm::StringRef` bytes, including
embedded NUL bytes. Use `Package::deserializeFile` for a filename. Binary
serialization retains its native representation and is not portable between
architectures. Serialized decimal weights are locale-independent; finite
subnormal values are preserved.
7 changes: 4 additions & 3 deletions include/mqt-core/dd/Complex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
#include "dd/DDDefinitions.hpp"
#include "dd/RealNumber.hpp"

#include "llvm/Support/raw_ostream.h"

#include <bit>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <string>

namespace dd {
Expand Down Expand Up @@ -105,7 +106,7 @@ struct Complex {
///
/// @param os The output stream to write to.
/// @see RealNumber::writeBinary
void writeBinary(std::ostream& os) const;
void writeBinary(llvm::raw_ostream& os) const;

/// Convert the Complex number to an std::complex<fp>.
///
Expand All @@ -123,7 +124,7 @@ struct Complex {
/// @param os The output stream to write to.
/// @param c The complex number to print.
/// @returns The output stream.
std::ostream& operator<<(std::ostream& os, const Complex& c);
llvm::raw_ostream& operator<<(llvm::raw_ostream& os, const Complex& c);

ComplexValue operator*(const Complex& c1, const ComplexValue& c2);
ComplexValue operator*(const ComplexValue& c1, const Complex& c2);
Expand Down
24 changes: 9 additions & 15 deletions include/mqt-core/dd/ComplexValue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@

#include "dd/DDDefinitions.hpp"

#include "llvm/Support/raw_ostream.h"

#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <string>
#include <utility>

Expand Down Expand Up @@ -80,18 +81,9 @@ struct ComplexValue {
/// stream.
///
/// @param os The output stream to write to.
void writeBinary(std::ostream& os) const;
void writeBinary(llvm::raw_ostream& os) const;

/// Read a binary representation of the complex number from the given input
/// stream.
///
/// @param is The input stream to read from.
void readBinary(std::istream& is);

/// Construct a complex number from a string.
///
/// @param realStr The string representation of the real part.
/// @param imagStr The string representation of the imaginary part.
/// Parse the real and imaginary parts of a serialized complex value.
void fromString(const std::string& realStr, std::string imagStr);

/// Get the closest fraction to the given number.
Expand All @@ -108,14 +100,16 @@ struct ComplexValue {
/// @param os The output stream to write to.
/// @param num The number to print.
/// @param imaginary Whether the number is imaginary.
static void printFormatted(std::ostream& os, fp num, bool imaginary = false);
/// @param precision Significant decimal digits; negative uses six, zero one.
static void printFormatted(llvm::raw_ostream& os, fp num,
bool imaginary = false, int precision = -1);

/// Print the given complex number to the given output stream.
///
/// @param real The real part of the complex number.
/// @param imag The imaginary part of the complex number.
/// @param formatted Whether to pretty print the number.
/// @param precision The precision to use for printing numbers..
/// @param precision Significant decimal digits; negative uses six, zero one.
/// @returns The string representation of the complex number.
static std::string toString(const fp& real, const fp& imag,
bool formatted = true, int precision = -1);
Expand Down Expand Up @@ -151,7 +145,7 @@ ComplexValue operator/(const ComplexValue& c1, const ComplexValue& c2);
/// @param os The output stream to write to.
/// @param c The complex value to print.
/// @returns The output stream.
std::ostream& operator<<(std::ostream& os, const ComplexValue& c);
llvm::raw_ostream& operator<<(llvm::raw_ostream& os, const ComplexValue& c);
} // namespace dd

/// Hash function for complex values
Expand Down
6 changes: 4 additions & 2 deletions include/mqt-core/dd/ComputeTable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
#include "dd/DDDefinitions.hpp"
#include "dd/statistics/TableStatistics.hpp"

#include "llvm/Support/raw_ostream.h"

#include <bit>
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <vector>

Expand Down Expand Up @@ -148,7 +149,8 @@ class ComputeTable {
///
/// @param os The output stream to print to
/// @return The output stream
std::ostream& printStatistics(std::ostream& os = std::cout) const {
llvm::raw_ostream&
printStatistics(llvm::raw_ostream& os = llvm::outs()) const {
return os << stats;
}

Expand Down
10 changes: 6 additions & 4 deletions include/mqt-core/dd/DDDefinitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#pragma once

#include "llvm/Support/raw_ostream.h"

#include <array>
#include <complex>
#include <cstddef>
Expand All @@ -21,7 +23,6 @@
#include <map>
#include <numbers>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
Expand Down Expand Up @@ -60,10 +61,11 @@ struct Control {
// NOLINTEND(misc-explicit-constructor)

[[nodiscard]] std::string toString() const {
std::ostringstream oss{};
oss << "Control(qubit=" << qubit << ", type_=\""
std::string result;
llvm::raw_string_ostream(result)
<< "Control(qubit=" << qubit << ", type_=\""
<< (type == Type::Pos ? "Pos" : "Neg") << "\")";
return oss.str();
return result;
}
};

Expand Down
Loading
Loading