Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ inline std::vector<std::string> Session::GetInputNames() const {
size_t node_count = GetInputCount();
std::vector<std::string> out(node_count);
for (size_t i = 0; i < node_count; i++) {
char* tmp = GetInputName(i, allocator);
out[i] = tmp;
allocator.Free(tmp); // prevent memory leak
auto tmp = GetInputNameAllocated(i, allocator);
out[i] = tmp.get();
}
return out;
}
Expand All @@ -47,9 +46,8 @@ inline std::vector<std::string> Session::GetOutputNames() const {
size_t node_count = GetOutputCount();
std::vector<std::string> out(node_count);
for (size_t i = 0; i < node_count; i++) {
char* tmp = GetOutputName(i, allocator);
out[i] = tmp;
allocator.Free(tmp); // prevent memory leak
auto tmp = GetOutputNameAllocated(i, allocator);
out[i] = tmp.get();
}
return out;
}
Expand All @@ -59,9 +57,8 @@ inline std::vector<std::string> Session::GetOverridableInitializerNames() const
size_t init_count = GetOverridableInitializerCount();
std::vector<std::string> out(init_count);
for (size_t i = 0; i < init_count; i++) {
char* tmp = GetOverridableInitializerName(i, allocator);
out[i] = tmp;
allocator.Free(tmp); // prevent memory leak
auto tmp = GetOverridableInitializerNameAllocated(i, allocator);
out[i] = tmp.get();
}
return out;
}
Expand Down
36 changes: 36 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_cxx_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,16 @@ struct TypeInfo;
struct Value;
struct ModelMetadata;

// Light functor to release memory with OrtAllocator
namespace detail {
struct AllocatedFree {
OrtAllocator* allocator_;
explicit AllocatedFree(OrtAllocator* allocator)
: allocator_(allocator) {}
void operator()(void* ptr) const { allocator_->Free(allocator_, ptr); }
};
} // namespace detail

/** \brief The Env (Environment)
*
* The Env holds the logging state used by all other objects.
Expand Down Expand Up @@ -436,10 +446,36 @@ struct Session : Base<OrtSession> {
size_t GetOutputCount() const; ///< Returns the number of model outputs
size_t GetOverridableInitializerCount() const; ///< Returns the number of inputs that have defaults that can be overridden

// [[deprecated]]
Comment thread
yuslepukhin marked this conversation as resolved.
Outdated
// This interface produces a pointer that must be released
// by the specified allocator and is often leaked. Not exception safe.
// use GetInputNameAllocated()
char* GetInputName(size_t index, OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionGetInputName
// [[deprecated]]
// This interface produces a pointer that must be released
// by the specified allocator and is often leaked. Not exception safe.
// use GetOutputNameAllocated()
char* GetOutputName(size_t index, OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionGetOutputName

// The following two interfaces return unique pointers that use
// the specified allocator to free memory. The OrtAllocator instances must
// be valid at the point of memory release.
using AllocatedStringPtr = std::unique_ptr<char, detail::AllocatedFree>;
AllocatedStringPtr GetInputNameAllocated(size_t index, OrtAllocator* allocator) const;
AllocatedStringPtr GetOutputNameAllocated(size_t index, OrtAllocator* allocator) const;

// [[deprecated]]
// This interface produces a pointer that must be released
// by the specified allocator and is often leaked. Not exception safe.
// use GetOverridableInitializerNameAllocated()
char* GetOverridableInitializerName(size_t index, OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionGetOverridableInitializerName
AllocatedStringPtr GetOverridableInitializerNameAllocated(size_t index, OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionGetOverridableInitializerName
// [[deprecated]]
// This interface produces a pointer that must be released
// by the specified allocator and is often leaked. Not exception safe.
// Use EndProfilingAllocated
char* EndProfiling(OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionEndProfiling
AllocatedStringPtr EndProfilingAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionEndProfiling
uint64_t GetProfilingStartTimeNs() const; ///< Wraps OrtApi::SessionGetProfilingStartTimeNs
ModelMetadata GetModelMetadata() const; ///< Wraps OrtApi::SessionGetModelMetadata

Expand Down
24 changes: 24 additions & 0 deletions include/onnxruntime/core/session/onnxruntime_cxx_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -656,18 +656,42 @@ inline char* Session::GetOutputName(size_t index, OrtAllocator* allocator) const
return out;
}

inline Session::AllocatedStringPtr Session::GetInputNameAllocated(size_t index, OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionGetInputName(p_, index, allocator, &out));
return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
}

inline Session::AllocatedStringPtr Session::GetOutputNameAllocated(size_t index, OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionGetOutputName(p_, index, allocator, &out));
return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
}

inline char* Session::GetOverridableInitializerName(size_t index, OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionGetOverridableInitializerName(p_, index, allocator, &out));
return out;
}

inline Session::AllocatedStringPtr Session::GetOverridableInitializerNameAllocated(size_t index, OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionGetOverridableInitializerName(p_, index, allocator, &out));
return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
}

inline char* Session::EndProfiling(OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionEndProfiling(p_, allocator, &out));
return out;
}

inline Session::AllocatedStringPtr Session::EndProfilingAllocated(OrtAllocator* allocator) const {
char* out;
ThrowOnError(GetApi().SessionEndProfiling(p_, allocator, &out));
return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
}

inline uint64_t Session::GetProfilingStartTimeNs() const {
uint64_t out;
ThrowOnError(GetApi().SessionGetProfilingStartTimeNs(p_, &out));
Expand Down
5 changes: 2 additions & 3 deletions onnxruntime/test/onnx/dataitem_request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,9 @@ std::pair<EXECUTE_RESULT, TIME_SPEC> DataTaskRequestContext::RunImpl() {
size_t output_count = session_.GetOutputCount();
std::vector<std::string> output_names(output_count);
for (size_t i = 0; i != output_count; ++i) {
char* output_name = session_.GetOutputName(i, default_allocator_);
auto output_name = session_.GetOutputNameAllocated(i, default_allocator_);
assert(output_name != nullptr);
output_names[i] = output_name;
Ort::ThrowOnError(Ort::GetApi().AllocatorFree(default_allocator_, output_name));
output_names[i] = output_name.get();
}

TIME_SPEC start_time;
Expand Down
8 changes: 4 additions & 4 deletions onnxruntime/test/opaque_api/test_opaque_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,14 @@ TEST(OpaqueApiTest, RunModelWithOpaqueInputOutput) {
// Expecting one input
size_t num_input_nodes = session.GetInputCount();
EXPECT_EQ(num_input_nodes, 1U);
const char* input_name = session.GetInputName(0, allocator);
auto input_name = session.GetInputNameAllocated(0, allocator);

size_t num_output_nodes = session.GetOutputCount();
EXPECT_EQ(num_output_nodes, 1U);
const char* output_name = session.GetOutputName(0, allocator);
auto output_name = session.GetOutputNameAllocated(0, allocator);

const char* const input_names[] = {input_name};
const char* const output_names[] = {output_name};
const char* const input_names[] = {input_name.get()};
const char* const output_names[] = {output_name.get()};

// Input
const std::string input_string{"hi, hello, high, highest"};
Expand Down
5 changes: 2 additions & 3 deletions onnxruntime/test/perftest/ort_test_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -529,10 +529,9 @@ select from 'TF8', 'TF16', 'UINT8', 'FLOAT', 'ITENSOR'. \n)");
output_names_.resize(output_count);
Ort::AllocatorWithDefaultOptions a;
for (size_t i = 0; i != output_count; ++i) {
char* output_name = session_.GetOutputName(i, a);
auto output_name = session_.GetOutputNameAllocated(i, a);
assert(output_name != nullptr);
output_names_[i] = output_name;
a.Free(output_name);
output_names_[i] = output_name.get();
}
output_names_raw_ptr.resize(output_count);
for (size_t i = 0; i != output_count; ++i) {
Expand Down
22 changes: 12 additions & 10 deletions onnxruntime/test/shared_lib/test_inference.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1422,9 +1422,10 @@ TEST(CApiTest, override_initializer) {
size_t init_count = session.GetOverridableInitializerCount();
ASSERT_EQ(init_count, 1U);

char* f1_init_name = session.GetOverridableInitializerName(0, allocator.get());
ASSERT_TRUE(strcmp("F1", f1_init_name) == 0);
allocator->Free(f1_init_name);
{
auto f1_init_name = session.GetOverridableInitializerNameAllocated(0, allocator.get());
ASSERT_TRUE(strcmp("F1", f1_init_name.get()) == 0);
}

Ort::TypeInfo init_type_info = session.GetOverridableInitializerTypeInfo(0);
ASSERT_EQ(ONNX_TYPE_TENSOR, init_type_info.GetONNXType());
Expand Down Expand Up @@ -1466,10 +1467,10 @@ TEST(CApiTest, end_profiling) {
session_options_1.EnableProfiling("profile_prefix");
#endif
Ort::Session session_1(*ort_env, MODEL_WITH_CUSTOM_MODEL_METADATA, session_options_1);
char* profile_file = session_1.EndProfiling(allocator.get());

ASSERT_TRUE(std::string(profile_file).find("profile_prefix") != std::string::npos);
allocator->Free(profile_file);
{
auto profile_file = session_1.EndProfilingAllocated(allocator.get());
ASSERT_TRUE(std::string(profile_file.get()).find("profile_prefix") != std::string::npos);
}
// Create session with profiling disabled
Ort::SessionOptions session_options_2;
#ifdef _WIN32
Expand All @@ -1478,9 +1479,10 @@ TEST(CApiTest, end_profiling) {
session_options_2.DisableProfiling();
#endif
Ort::Session session_2(*ort_env, MODEL_WITH_CUSTOM_MODEL_METADATA, session_options_2);
profile_file = session_2.EndProfiling(allocator.get());
ASSERT_TRUE(std::string(profile_file) == std::string());
allocator->Free(profile_file);
{
auto profile_file = session_2.EndProfilingAllocated(allocator.get());
ASSERT_TRUE(std::string(profile_file.get()) == std::string());
}
}

TEST(CApiTest, get_profiling_start_time) {
Expand Down