Skip to content
Open
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
1 change: 1 addition & 0 deletions packages/react-native-executorch/cpp/core/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ jsi::Array toJsiArray(jsi::Runtime &rt, const std::vector<T> &vec) {
return arr;
}

/** Helper constant for static_assert in dependent template contexts. */
template <typename>
inline constexpr bool kAlwaysFalse = false;

Expand Down
38 changes: 38 additions & 0 deletions packages/react-native-executorch/cpp/core/dtype.h

@msluszniak msluszniak Jul 30, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now when I read the names of the functions I'm wondering why we have such name convention. Str -> parseDtype, but reverse is named toString. For the next two the convention is unified, but we only know that we convert sth to scalar and we get sth from scalar. Maybe we should name it xFromY and xToY for both conversions? Especially, because we have dtypeToCvDepth and similar.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you are right. Let's wait with this PR until #1327 lands so we can change the names.

Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,57 @@
#include <string>

namespace rnexecutorch::core::types {

/**
* Supported tensor data types across the native runtime and JavaScript interface.
*/
enum class DType {
uint8,
int32,
int64,
float32
};

/**
* Parses a string representation into a DType enum value.
*
* @param s The string name of the data type (e.g. "uint8", "int32", "int64", "float32").
* @return The corresponding DType enum value.
* @throws std::invalid_argument If the string does not match any known DType.
*/
DType parseDType(const std::string &s);

/**
* Converts a DType enum value to its string representation.
*
* @param dtype The DType enum value to convert.
* @return The string representation of the data type.
*/
std::string toString(DType dtype);

/**
* Converts a DType enum value to the corresponding ExecuTorch ScalarType.
*
* @param dtype The DType enum value to convert.
* @return The corresponding ExecuTorch ScalarType.
*/
executorch::aten::ScalarType toScalarType(DType dtype);

/**
* Converts an ExecuTorch ScalarType to the corresponding DType enum value.
*
* @param st The ExecuTorch ScalarType to convert.
* @return The corresponding DType enum value.
* @throws std::invalid_argument If the ScalarType is not supported.
*/
DType fromScalarType(executorch::aten::ScalarType st);

/**
* Returns the byte size of a single element for the specified DType.
*
* @param dtype The DType enum value.
* @return The size in bytes of a single element of that data type.
*/
size_t elementSize(DType dtype);

} // namespace rnexecutorch::core::types
18 changes: 16 additions & 2 deletions packages/react-native-executorch/cpp/core/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,31 @@ namespace types = rnexecutorch::core::types;
class TensorHostObject : public jsi::HostObject,
public std::enable_shared_from_this<TensorHostObject> {
public:
/** Data type of the tensor elements. */
const types::DType dtype_;
/** Dimensions (shape) of the tensor. */
const std::vector<std::int32_t> shape_;
/** Total number of elements contained in the tensor. */
const size_t numel_;
/** Total memory size of the tensor data buffer in bytes. */
const size_t size_;

// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays): owning runtime-sized byte buffer
std::unique_ptr<std::uint8_t[]> data_;
/** Owning byte buffer holding the raw tensor data. */
std::unique_ptr<std::uint8_t[]> data_; // NOLINT(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays): owning runtime-sized byte buffer
/** ExecuTorch TensorPtr instance wrapping the data buffer. */
executorch::extension::TensorPtr tensor_;

/** Shared mutex guarding concurrent read/write access to the tensor data. */
std::shared_mutex mutex_;

/**
* Constructs a TensorHostObject with the specified shape and data type.
*
* Allocates and zero-initializes the underlying memory buffer for the tensor data.
*
* @param shape The dimensions of the tensor.
* @param dtype The data type of the tensor elements.
*/
TensorHostObject(const std::vector<std::int32_t> &shape, types::DType dtype);

jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &name) override;
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native-executorch/cpp/extensions/cv/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

namespace rnexecutorch::extensions::cv {

/**
* Converts an ExecuTorch DType enum value to the corresponding OpenCV matrix depth constant.
*
* @param dtype The input tensor data type.
* @return The corresponding OpenCV depth constant (e.g. CV_8U, CV_32S, CV_32F).
* @throws std::invalid_argument If the data type is not supported by OpenCV depth representation.
*/
inline int dtypeToCvDepth(rnexecutorch::core::types::DType dtype) {
switch (dtype) {
case rnexecutorch::core::types::DType::uint8:
Expand Down
25 changes: 24 additions & 1 deletion packages/react-native-executorch/cpp/extensions/nlp/tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,44 @@
#include <pytorch/tokenizers/hf_tokenizer.h>

namespace rnexecutorch::extensions::nlp::tokenizer {

/**
* JSI HostObject wrapping a HuggingFace Tokenizer instance (`tokenizers::HFTokenizer`).
*
* Exposes methods to JavaScript for encoding text to token IDs, decoding token IDs
* to text, and managing tokenizer resources.
*/
class TokenizerHostObject : public facebook::jsi::HostObject,
public std::enable_shared_from_this<TokenizerHostObject> {
public:
// Loads the tokenizer from `tokenizerPath`; throws std::runtime_error on failure.
/**
* Constructs a TokenizerHostObject by loading a HuggingFace tokenizer configuration file.
*
* @param tokenizerPath File system path to the tokenizer configuration file.
* @throws std::runtime_error If loading the tokenizer fails.
*/
explicit TokenizerHostObject(std::string tokenizerPath);

facebook::jsi::Value get(facebook::jsi::Runtime &rt, const facebook::jsi::PropNameID &name) override;
std::vector<facebook::jsi::PropNameID> getPropertyNames(facebook::jsi::Runtime &rt) override;

private:
/**
* Tries to acquire a unique lock on the tokenizer's mutex.
* Throws a facebook::jsi::JSError with contextual error info if the lock cannot be acquired.
*
* @param rt The JSI runtime instance.
* @param context Context description used to generate helpful error messages.
* @return A unique lock protecting the tokenizer.
*/
[[nodiscard]] std::unique_lock<std::mutex> tryLockUnique(facebook::jsi::Runtime &rt,
std::string_view context);

/** File path to the HuggingFace tokenizer JSON configuration file. */
std::string tokenizerPath_;
/** Owning pointer to the underlying HuggingFace tokenizer instance. */
std::unique_ptr<tokenizers::HFTokenizer> tokenizer_;
/** Mutex guarding concurrent access to the tokenizer. */
std::mutex mutex_;
};

Expand Down