Skip to content
Closed
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
37 changes: 37 additions & 0 deletions backends/native/runtime/graph/Scalar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// All rights reserved.
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#include <executorch/backends/native/runtime/graph/Scalar.h>

#include <stdexcept>

namespace ptn {

int64_t Scalar::to_int() const {
const int64_t* v = std::get_if<int64_t>(&value_);
if (v == nullptr) {
throw std::runtime_error("Scalar::to_int: scalar is not an Int");
}
return *v;
}

double Scalar::to_double() const {
const double* v = std::get_if<double>(&value_);
if (v == nullptr) {
throw std::runtime_error("Scalar::to_double: scalar is not a Double");
}
return *v;
}

bool Scalar::to_bool() const {
const bool* v = std::get_if<bool>(&value_);
if (v == nullptr) {
throw std::runtime_error("Scalar::to_bool: scalar is not a Bool");
}
return *v;
}

} // namespace ptn
61 changes: 61 additions & 0 deletions backends/native/runtime/graph/Scalar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
// All rights reserved.
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

#pragma once

#include <cstdint>
#include <variant>

namespace ptn {

// A concrete scalar value, analogous to c10::Scalar: one alternative per
// domain — integral, floating point, boolean — each stored at its widest type.
// A narrower value is stored exactly, and to<T>() narrows it back on read.
// There is no "none" state — the graph's Value owns that.
class Scalar {
private:
std::variant<int64_t, double, bool> value_ = int64_t{0};

public:
constexpr Scalar() = default;
// Implicit by design (ergonomic: `Scalar s = 5;`). The int overload
// disambiguates `Scalar(5)` — without it int -> {int64_t,double,bool} is an
// ambiguous conversion.
// cppcheck-suppress-begin noExplicitConstructor
/* implicit */ constexpr Scalar(int v) : value_(static_cast<int64_t>(v)) {}
/* implicit */ constexpr Scalar(int64_t v) : value_(v) {}
/* implicit */ constexpr Scalar(double v) : value_(v) {}
/* implicit */ constexpr Scalar(bool v) : value_(v) {}
// cppcheck-suppress-end noExplicitConstructor
// Every pointer converts to bool, so without this `Scalar s = some_ptr;`
// would quietly yield a Bool.
template <typename T>
Scalar(T*) = delete;

constexpr bool is_int() const {
return std::holds_alternative<int64_t>(value_);
}
constexpr bool is_double() const {
return std::holds_alternative<double>(value_);
}
constexpr bool is_bool() const {
return std::holds_alternative<bool>(value_);
}

// Strict accessors: throw std::runtime_error unless that alternative is live.
int64_t to_int() const;
double to_double() const;
bool to_bool() const;

// Promoting read: static_cast whichever alternative is live to T, like
// c10::Scalar::to<T>().
template <typename T>
constexpr T to() const {
return std::visit([](auto v) { return static_cast<T>(v); }, value_);
}
};

} // namespace ptn
11 changes: 11 additions & 0 deletions backends/native/runtime/graph/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ def define_common_targets():
visibility = ["//executorch/backends/native/..."],
)

runtime.cxx_library(
name = "scalar",
srcs = ["Scalar.cpp"],
exported_headers = [
"Scalar.h",
],
visibility = ["//executorch/backends/native/..."],
)

runtime.cxx_library(
name = "tensor_meta",
srcs = ["TensorMeta.cpp"],
Expand All @@ -39,7 +48,9 @@ def define_common_targets():
"utils/Print.h",
],
exported_deps = [
":scalar",
":tensor_meta",
],
deps = [":string_format"],
visibility = ["//executorch/backends/native/..."],
)
12 changes: 12 additions & 0 deletions backends/native/runtime/graph/utils/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <cstddef>
#include <string>

#include <executorch/backends/native/runtime/graph/StringFormat.h>

namespace ptn {

std::string to_string(const TensorMeta& meta) {
Expand All @@ -31,4 +33,14 @@ std::string to_string(const TensorMeta& meta) {
return s;
}

std::string to_string(const Scalar& scalar) {
if (scalar.is_bool()) {
return scalar.to_bool() ? "true" : "false";
}
if (scalar.is_int()) {
return std::to_string(scalar.to_int());
}
return format_double(scalar.to_double());
}

} // namespace ptn
4 changes: 4 additions & 0 deletions backends/native/runtime/graph/utils/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <string>

#include <executorch/backends/native/runtime/graph/Scalar.h>
#include <executorch/backends/native/runtime/graph/TensorMeta.h>

namespace ptn {
Expand All @@ -21,4 +22,7 @@ namespace ptn {
// (unbounded).
std::string to_string(const TensorMeta& meta);

// The live alternative only: "true", "-3", "1.5e-08".
std::string to_string(const Scalar& scalar);

} // namespace ptn
Loading