Skip to content

Commit

Permalink
Force default locale for cache model write/read (openvinotoolkit#24431)
Browse files Browse the repository at this point in the history
### Details:
- Check the value of setlocale for export/import, if different with "C"
will set to "C" and record the original value, after export/import done
will reset to the original.
- *Fix the error caused by pugixml library with The setlocale function
installs the specified system locale or its portion as the new C locale.
different C may return unexpected results with setlocal()*

### Tickets:
 - openvinotoolkit#24370

---------

Signed-off-by: Zhai, Xuejun <[email protected]>
Co-authored-by: Chen Peter <[email protected]>
Co-authored-by: River Li <[email protected]>
  • Loading branch information
3 people authored May 17, 2024
1 parent b2db8b4 commit 7e64e41
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
24 changes: 24 additions & 0 deletions src/inference/src/cache_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@

namespace ov {

/**
* @brief This class limits the locale env to a special value in sub-scope
*
*/
class ScopedLocale {
public:
ScopedLocale(int category, std::string newLocale) : m_category(category) {
m_oldLocale = setlocale(category, nullptr);
setlocale(m_category, newLocale.c_str());
}
~ScopedLocale() {
setlocale(m_category, m_oldLocale.c_str());
}

private:
int m_category;
std::string m_oldLocale;
};

/**
* @brief This class represents private interface for Cache Manager
*
Expand Down Expand Up @@ -99,11 +118,16 @@ class FileStorageCacheManager final : public ICacheManager {

private:
void write_cache_entry(const std::string& id, StreamWriter writer) override {
// Fix the bug caused by pugixml, which may return unexpected results if the locale is different from "C".
ScopedLocale plocal_C(LC_ALL, "C");

std::ofstream stream(getBlobFile(id), std::ios_base::binary | std::ofstream::out);
writer(stream);
}

void read_cache_entry(const std::string& id, StreamReader reader) override {
// Fix the bug caused by pugixml, which may return unexpected results if the locale is different from "C".
ScopedLocale plocal_C(LC_ALL, "C");
auto blobFileName = getBlobFile(id);
if (ov::util::file_exists(blobFileName)) {
std::ifstream stream(blobFileName, std::ios_base::binary);
Expand Down
66 changes: 65 additions & 1 deletion src/inference/tests/functional/local_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

#include <gtest/gtest.h>

#include "common_test_utils/file_utils.hpp"
#include "common_test_utils/ov_tensor_utils.hpp"
#include "common_test_utils/subgraph_builders/split_multi_conv_concat.hpp"
#include "openvino/op/roi_align.hpp"
#include "openvino/op/util/rnn_cell_base.hpp"
#include "openvino/runtime/core.hpp"
Expand Down Expand Up @@ -285,4 +288,65 @@ TEST_F(LocaleTests, DISABLED_WithUSLocaleCPP) {
testBody();
std::locale::global(prev);
}
#endif // defined(ENABLE_OV_IR_FRONTEND)

class LocaleTestsWithCacheDir : public ::testing::Test {
std::string originalLocale;
std::string cache_dir = "test_cache";
std::shared_ptr<ov::Model> model;

public:
protected:
void SetUp() override {
originalLocale = setlocale(LC_ALL, nullptr);
model = ov::test::utils::make_split_multi_conv_concat();
}
void TearDown() override {
setlocale(LC_ALL, originalLocale.c_str());
if (!cache_dir.empty()) {
ov::test::utils::removeDir(cache_dir);
}
}
void testBody() const {
std::map<ov::Output<ov::Node>, ov::Tensor> inputs;
for (const auto& input : model->inputs()) {
auto tensor = ov::test::utils::create_and_fill_tensor_normal_distribution(input.get_element_type(),
input.get_shape(),
0.0f,
0.2f,
7235346);
inputs.insert({input, tensor});
}

ov::Core core;
ov::AnyMap properties = {ov::hint::inference_precision(ov::element::f32), ov::cache_dir(cache_dir)};

auto getOutputBlob = [&]() {
auto compiled_model = core.compile_model(model, "CPU", properties);
auto req = compiled_model.create_infer_request();
for (const auto& input : inputs) {
req.set_tensor(input.first, input.second);
}
auto output_tensor = ov::Tensor(model->output().get_element_type(), model->output().get_shape());
req.set_output_tensor(output_tensor);
req.infer();
return output_tensor;
};

auto output_from_model_read = getOutputBlob();
auto output_from_model_cached = getOutputBlob();

ov::test::utils::compare(output_from_model_read, output_from_model_cached);
ov::test::utils::removeFilesWithExt(cache_dir, "blob");
}
};

TEST_F(LocaleTestsWithCacheDir, WithRULocale) {
setlocale(LC_ALL, "ru_RU.UTF-8");
testBody();
}

TEST_F(LocaleTestsWithCacheDir, WithUSLocale) {
setlocale(LC_ALL, "en_US.UTF-8");
testBody();
}
#endif // defined(ENABLE_OV_IR_FRONTEND)

0 comments on commit 7e64e41

Please sign in to comment.