Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] PathProperty -p repartion for openvino backbone and layer #2937

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
9 changes: 8 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ add_project_arguments('-DVERSION_MAJOR=' + nntrainer_version_split[0], language:
add_project_arguments('-DVERSION_MINOR=' + nntrainer_version_split[1], language: ['c', 'cpp'])
add_project_arguments('-DVERSION_MICRO=' + nntrainer_version_split[2], language: ['c', 'cpp'])

if get_option('enable-test')# and get_option('enable-openvino-backbone').enabled()
gtest_proj = subproject('gtest')
endif

extra_defines = ['-DMIN_CPP_VERSION=201703L']

cc = meson.get_compiler('c')
cxx = meson.get_compiler('cpp')

# Older libc++ has <filesystem> in seperate library
opt_stdcpp_fs_dep = cxx.find_library('stdc++fs', required: false)

if get_option('platform') == 'tizen'
# Pass __TIZEN__ to the compiler
add_project_arguments('-D__TIZEN__=1', language:['c','cpp'])
Expand Down Expand Up @@ -493,7 +500,7 @@ if get_option('enable-app')
endif
endif

if get_option('platform') != 'android'
if get_option('platform') != 'android' and get_option('enable-nnstreamer-backbone')
nnstreamer_dep = dependency('nnstreamer')
message('building nnstreamer')
subdir('nnstreamer')
Expand Down
4 changes: 2 additions & 2 deletions nntrainer/dataset/raw_file_data_producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ RawFileDataProducer::size(const std::vector<TensorDim> &input_dims,
// << " Given file does not align with the given sample size, sample size: "
// << sample_size << " file_size: " << file_size;

return static_cast<unsigned int>(file_size) /
(sample_size * RawFileDataProducer::pixel_size);
return static_cast<unsigned int>(
file_size / (sample_size * RawFileDataProducer::pixel_size));
}

void RawFileDataProducer::exportTo(
Expand Down
25 changes: 9 additions & 16 deletions nntrainer/layers/common_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@

#include <regex>
#include <sstream>
#include <sys/stat.h>
#include <utility>
#include <vector>

namespace fs = std::filesystem;

namespace nntrainer {
namespace props {

Expand Down Expand Up @@ -56,30 +57,22 @@ void RandomTranslate::set(const float &value) {
Property<float>::set(std::abs(value));
}

bool FilePath::isValid(const std::string &v) const {
std::ifstream file(v, std::ios::binary | std::ios::ate);
return file.good();
}

void FilePath::set(const std::string &v) {
Property<std::string>::set(v);
std::ifstream file(v, std::ios::binary | std::ios::ate);
cached_pos_size = file.tellg();
bool FilePath::isValid(const fs::path &v) const {
const bool regular = PathProperty::isRegularFile(v);
const bool is_readable = PathProperty::isReadAccessible(v);
return regular && is_readable;
}

std::ifstream::pos_type FilePath::file_size() { return cached_pos_size; }
std::uintmax_t FilePath::file_size() const { return fs::file_size(*this); }

bool LossScaleForMixed::isValid(const float &value) const {
return (value != 0);
}

bool DirPath::isValid(const std::string &v) const {
struct stat dir;
return (stat(v.c_str(), &dir) == 0);
bool DirPath::isValid(const fs::path &v) const {
return PathProperty::isDirectory(v);
}

void DirPath::set(const std::string &v) { Property<std::string>::set(v); }

ReturnSequences::ReturnSequences(bool value) { set(value); }

Bidirectional::Bidirectional(bool value) { set(value); }
Expand Down
55 changes: 26 additions & 29 deletions nntrainer/layers/common_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -664,82 +664,79 @@ class RandomTranslate : public nntrainer::Property<float> {
* @brief Props containing file path value
*
*/
class FilePath : public Property<std::string> {
class FilePath : public PathProperty {
public:
/**
* @brief Construct a new File Path object
*/
FilePath() : Property<std::string>() {}
FilePath() = default;

/**
* @brief Construct a new File Path object
*
* @param path path to set
*/
FilePath(const std::string &path) { set(path); }
static constexpr const char *key = "path"; /**< unique key to access */
using prop_tag = str_prop_tag; /**< property type */
explicit FilePath(const std::string &path) : PathProperty(path) {}

/**
* @brief check if given value is valid
* @brief Construct a new File Path object
*
* @param v value to check
* @return bool true if valid
* @param path path to set
*/
bool isValid(const std::string &v) const override;
explicit FilePath(const std::filesystem::path &path) : PathProperty(path) {}
static constexpr const char *key = "path"; /**< unique key to access */
using prop_tag = path_prop_tag; /**< property type */

/**
* @brief setter
* @brief check if given value is valid
*
* @param v value to set
* @param v value to check
* @return bool true if valid
*/
void set(const std::string &v) override;
bool isValid(const std::filesystem::path &v) const override;

/**
* @brief return file size
*
* @return std::ifstream::pos_type size of the file
* @return std::uintmax_t size of the file
*/
std::ifstream::pos_type file_size();

private:
std::ifstream::pos_type cached_pos_size;
std::uintmax_t file_size() const;
};

/**
* @brief Props containing directory path value
*
*/
class DirPath : public Property<std::string> {
class DirPath : public PathProperty {
public:
/**
* @brief Construct a new Dir Path object
*/
DirPath() : Property<std::string>() {}
DirPath() = default;

/**
* @brief Construct a new Dir Path object
*
* @param path path to set
*/
DirPath(const std::string &path) { set(path); }
static constexpr const char *key = "dir_path"; /**< unique key to access */
using prop_tag = str_prop_tag; /**< property type */
explicit DirPath(const std::string &path) : PathProperty(path) { set(path); }

/**
* @brief check if given value is valid
* @brief Construct a new Dir Path object
*
* @param v value to check
* @return bool true if valid
* @param path path to set
*/
bool isValid(const std::string &v) const override;
explicit DirPath(const std::filesystem::path &path) : PathProperty(path) {}
static constexpr const char *key = "dir_path"; /**< unique key to access */
using prop_tag = path_prop_tag; /**< property type */

/**
* @brief setter
* @brief check if given value is valid
*
* @param v value to set
* @param v value to check
* @return bool true if valid
*/
void set(const std::string &v) override;
bool isValid(const std::filesystem::path &v) const override;
};

/**
Expand Down
3 changes: 2 additions & 1 deletion nntrainer/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ nntrainer_base_deps=[
libm_dep,
libdl_dep,
thread_dep,
openmp_dep
openmp_dep,
opt_stdcpp_fs_dep
]

if get_option('platform') == 'tizen'
Expand Down
8 changes: 3 additions & 5 deletions nntrainer/models/model_common_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,19 @@ class LossType : public Property<std::string> {
* @brief model save path property
*
*/
class SavePath : public Property<std::string> {
class SavePath : public PathProperty {
public:
static constexpr const char *key = "save_path"; /**< unique key to access */
using prop_tag = str_prop_tag; /**< property type */
};

/**
* @brief model save path property
*
*/
class SaveBestPath : public Property<std::string> {
class SaveBestPath : public PathProperty {
public:
static constexpr const char *key =
"save_best_path"; /**< unique key to access */
using prop_tag = str_prop_tag; /**< property type */
"save_best_path"; /**< unique key to access */
};

/**
Expand Down
13 changes: 6 additions & 7 deletions nntrainer/models/neuralnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,14 +624,13 @@ void NeuralNetwork::save(const std::string &file_path,
break;

case ml::train::ModelFormat::MODEL_FORMAT_INI_WITH_BIN: {
auto old_save_path = std::get<props::SavePath>(model_flex_props);
auto bin_file_name =
file_path.substr(0, file_path.find_last_of('.')) + ".bin";

std::get<props::SavePath>(model_flex_props).set(bin_file_name);
auto old_save_path_prop = std::get<props::SavePath>(model_flex_props);
auto bin_file_path = old_save_path_prop.get();
bin_file_path.replace_extension("bin");
std::get<props::SavePath>(model_flex_props).set(bin_file_path);
save(file_path, ml::train::ModelFormat::MODEL_FORMAT_INI);
save(bin_file_name, ml::train::ModelFormat::MODEL_FORMAT_BIN);
std::get<props::SavePath>(model_flex_props) = old_save_path;
save(bin_file_path, ml::train::ModelFormat::MODEL_FORMAT_BIN);
std::get<props::SavePath>(model_flex_props) = old_save_path_prop;
break;
}
default:
Expand Down
104 changes: 104 additions & 0 deletions nntrainer/utils/base_properties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,82 @@
*/
#include <base_properties.h>

#include <cerrno>
#include <regex>
#include <sstream>
#include <string>
#include <system_error>
#include <vector>

#if !defined(_WIN32)
#include <unistd.h>
#endif

namespace fs = std::filesystem;

namespace {

/**
* @brief constructs system error_code from POSIX errno
*/
[[maybe_unused]] auto make_system_error_code() {
return std::error_code{errno, std::system_category()};
}

bool isFileReadAccessisble(fs::path p, std::error_code &ec) {
#if defined(_POSIX_VERSION)
// Check if we have read permissions to path pointing this file
auto r = ::access(p.c_str(), R_OK);
if (r == 0) {
ec = std::error_code{};
return true;
}

ec = make_system_error_code();

return false;
#else
ec = std::error_code{};
// Unless it is POSIX, best bet is to try it
std::ifstream file(p, std::ios::binary | std::ios::ate);
return file.good();
#endif
}

/**
* @brief Helper for testing path kind looking behind symlinks.
*/
template <typename FileCheckFn_>
bool isPathKindHelper(const fs::path v, FileCheckFn_ &&file_check_fn) noexcept {
// Reject empty and non-existing paths
{
std::error_code ec;
if (v.empty() || !exists(v, ec))
return false;

if (ec)
return false;
}

// Check if it is a path is of file_check_fn kind
{
std::error_code ec;
auto real_path = is_symlink(v) ? read_symlink(v, ec) : v;

if (ec)
return false;

if (!file_check_fn(real_path, ec))
return false;

if (ec)
return false;
}

return true;
}
} // namespace

namespace nntrainer {
bool PositiveIntegerProperty::isValid(const unsigned int &value) const {
return value > 0;
Expand All @@ -33,6 +104,18 @@ std::string str_converter<str_prop_tag, std::string>::from_string(
return value;
}

template <>
std::string
str_converter<path_prop_tag, fs::path>::to_string(const fs::path &value) {
return value;
}

template <>
fs::path
str_converter<path_prop_tag, fs::path>::from_string(const std::string &value) {
return fs::path{value};
}

template <>
std::string str_converter<bool_prop_tag, bool>::to_string(const bool &value) {
return value ? "true" : "false";
Expand Down Expand Up @@ -144,4 +227,25 @@ TensorDim str_converter<dimension_prop_tag, TensorDim>::from_string(
return target;
}

PathProperty::~PathProperty() = default;

bool PathProperty::isRegularFile(const fs::path &v) noexcept {
return isPathKindHelper(
v, [](const auto &v, auto ec) { return fs::is_regular_file(v, ec); });
}

bool PathProperty::isDirectory(const fs::path &v) noexcept {
return isPathKindHelper(
v, [](const auto &v, auto ec) { return fs::is_directory(v, ec); });
}

bool PathProperty::isReadAccessible(const fs::path &v) noexcept {
std::error_code ec;

if (!isFileReadAccessisble(v, ec))
return false;

return !ec;
}

} // namespace nntrainer
Loading