From cdcc047d9d493f5fcf76a5eb38a6ca7996d591aa Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 21 Oct 2025 17:06:59 +0300 Subject: [PATCH 01/36] add submodule --- .gitmodules | 3 +++ 3rdparty/CMakeLists.txt | 1 + 3rdparty/oneDNN | 1 + 3 files changed, 5 insertions(+) create mode 160000 3rdparty/oneDNN diff --git a/.gitmodules b/.gitmodules index 1495d0c1d..1faffb935 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "3rdparty/Json"] path = 3rdparty/Json url = https://github.com/nlohmann/json +[submodule "3rdparty/oneDNN"] + path = 3rdparty/oneDNN + url = https://github.com/uxlfoundation/oneDNN.git diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 02559b9fd..cc5e26ce0 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(googletest) +add_subdirectory(oneDNN) # Unified TBB Configuration option(TBB_TEST "Build TBB tests" OFF) diff --git a/3rdparty/oneDNN b/3rdparty/oneDNN new file mode 160000 index 000000000..ceb0d6c8c --- /dev/null +++ b/3rdparty/oneDNN @@ -0,0 +1 @@ +Subproject commit ceb0d6c8c5685ee9af1eb6c07a3508248e886673 From a514899b8d22583c3db4e32fb4d6e1453b6433f7 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 22 Oct 2025 12:26:08 +0300 Subject: [PATCH 02/36] add EWLayer_oneDNN --- app/Graph/CMakeLists.txt | 1 + app/Graph/acc_check.cpp | 10 +- app/Graph/build.cpp | 67 +++++--- app/Graph/build.hpp | 8 +- app/Graph/graph_build.cpp | 8 +- include/CMakeLists.txt | 3 + include/layers_oneDNN/EWLayer_oneDNN.hpp | 51 ++++++ src/layers/CMakeLists.txt | 1 + src/layers_oneDNN/CMakeLists.txt | 9 ++ src/layers_oneDNN/EWLayer_oneDNN.cpp | 137 ++++++++++++++++ test/single_layer/test_ewlayer_onednn.cpp | 182 ++++++++++++++++++++++ 11 files changed, 449 insertions(+), 28 deletions(-) create mode 100644 include/layers_oneDNN/EWLayer_oneDNN.hpp create mode 100644 src/layers_oneDNN/CMakeLists.txt create mode 100644 src/layers_oneDNN/EWLayer_oneDNN.cpp create mode 100644 test/single_layer/test_ewlayer_onednn.cpp diff --git a/app/Graph/CMakeLists.txt b/app/Graph/CMakeLists.txt index f953547a4..15f16e4dd 100644 --- a/app/Graph/CMakeLists.txt +++ b/app/Graph/CMakeLists.txt @@ -11,6 +11,7 @@ target_link_libraries(BuildGraph PUBLIC ${OpenCV_LIBS}) target_link_libraries(BuildGraph PUBLIC reader_lib) target_link_libraries(BuildGraph PUBLIC TBB_unified) target_link_libraries(BuildGraph PUBLIC layers_lib) +target_link_libraries(BuildGraph PUBLIC layers_oneDNN_lib) target_link_libraries(BuildGraph PUBLIC gtest_main) target_include_directories(BuildGraph PUBLIC ${CMAKE_SOURCE_DIR}/3rdparty/Json/include) diff --git a/app/Graph/acc_check.cpp b/app/Graph/acc_check.cpp index 673b40130..7478e1e72 100644 --- a/app/Graph/acc_check.cpp +++ b/app/Graph/acc_check.cpp @@ -14,12 +14,14 @@ using namespace it_lab_ai; int main(int argc, char* argv[]) { std::string model_name = "alexnet_mnist"; bool parallel = false; - + bool onednn = false; for (int i = 1; i < argc; ++i) { if (std::string(argv[i]) == "--parallel") { parallel = true; } else if (std::string(argv[i]) == "--model" && i + 1 < argc) { model_name = argv[++i]; + } else if (std::string(argv[i]) == "--onednn") { + onednn = true; } } @@ -70,7 +72,7 @@ int main(int argc, char* argv[]) { for (int j = 0; j < 28; ++j) { size_t a = ind; for (size_t n = 0; n < name; n++) a += counts[n] + 1; - res[(a) * 28 * 28 + i * 28 + j] = channels[0].at(j, i); + res[(a)*28 * 28 + i * 28 + j] = channels[0].at(j, i); } } } @@ -78,7 +80,7 @@ int main(int argc, char* argv[]) { Shape sh({static_cast(count_pic), 1, 28, 28}); Tensor t = make_tensor(res, sh); input = t; - build_graph_linear(input, output, false, parallel); + build_graph_linear(input, output, false, parallel, onednn); std::vector> tmp_output = softmax(*output.as(), 10); std::vector indices; @@ -185,7 +187,7 @@ int main(int argc, char* argv[]) { it_lab_ai::Tensor output = it_lab_ai::Tensor(output_shape, it_lab_ai::Type::kFloat); - build_graph(input, output, json_path, false, parallel); + build_graph(input, output, json_path, false, parallel, onednn); std::vector> processed_outputs; const std::vector& raw_output = *output.as(); diff --git a/app/Graph/build.cpp b/app/Graph/build.cpp index 6a1f51f7f..814e81f07 100644 --- a/app/Graph/build.cpp +++ b/app/Graph/build.cpp @@ -5,7 +5,7 @@ using namespace it_lab_ai; void build_graph_linear(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, - bool comments, bool parallel) { + bool comments, bool parallel, bool onednn) { if (comments) { for (size_t i = 0; i < input.get_shape().dims(); i++) { std::cout << input.get_shape()[i] << ' '; @@ -80,7 +80,12 @@ void build_graph_linear(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, if (comments) std::cout << "ConvLayer added to layers." << std::endl; } if (layer_type.find("relu") != std::string::npos) { - auto ew_layer = std::make_shared("relu"); + std::shared_ptr ew_layer; + if (onednn) { + ew_layer = std::make_shared("relu"); + } else { + ew_layer = std::make_shared("relu"); + } layers.push_back(ew_layer); layerpostop.push_back(true); if (comments) @@ -230,7 +235,8 @@ std::string layerTypeToString(it_lab_ai::LayerType type) { } void build_graph(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, - const std::string& json_path, bool comments, bool parallel) { + const std::string& json_path, bool comments, bool parallel, + bool onednn) { if (comments) { for (size_t i = 0; i < input.get_shape().dims(); i++) { std::cout << input.get_shape()[i] << ' '; @@ -251,7 +257,7 @@ void build_graph(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, } } - auto parse_result = parse_json_model(json_path, comments, parallel); + auto parse_result = parse_json_model(json_path, comments, parallel, onednn); auto& layers = parse_result.layers; auto& name_to_layer = parse_result.name_to_layer; @@ -371,7 +377,7 @@ void build_graph(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, } ParseResult parse_json_model(const std::string& json_path, bool comments, - bool parallel) { + bool parallel, bool use_onednn) { ParseResult result; auto& layers = result.layers; @@ -488,12 +494,21 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, layer = conv_layer; } else if (layer_type.find("Relu") != std::string::npos || layer_type.find("relu") != std::string::npos) { - auto ew_layer = std::make_shared("relu"); + std::shared_ptr ew_layer; + if (use_onednn) { + ew_layer = std::make_shared("relu"); + } else { + ew_layer = std::make_shared("relu"); + } layer = ew_layer; } else if (layer_type.find("Sigmoid") != std::string::npos) { - auto ew_layer = std::make_shared("sigmoid"); + std::shared_ptr ew_layer; + if (use_onednn) { + ew_layer = std::make_shared("sigmoid"); + } else { + ew_layer = std::make_shared("sigmoid"); + } layer = ew_layer; - } else if (layer_type.find("Dense") != std::string::npos || layer_type.find("FullyConnected") != std::string::npos) { it_lab_ai::Tensor tensor = it_lab_ai::create_tensor_from_json( @@ -717,22 +732,38 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, if (layer_type == "Mul") { ew_operation = "linear"; - auto ew_layer = - std::make_shared(ew_operation, value, 0.0F); - layer = ew_layer; - if (comments) { - std::cout << "Created binary " << layer_type << " operation with " - << value << "scalar" << std::endl; + std::shared_ptr ew_layer; + if (use_onednn) { + ew_layer = std::make_shared( + ew_operation, value, 0.0F); + } else { + ew_layer = std::make_shared(ew_operation, + value, 0.0F); } + layer = ew_layer; } else if (layer_type == "Add") { ew_operation = "linear"; - auto ew_layer = - std::make_shared(ew_operation, 1.0F, value); + std::shared_ptr ew_layer; + if (use_onednn && + it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { + ew_layer = std::make_shared( + ew_operation, 1.0F, value); + } else { + ew_layer = std::make_shared(ew_operation, + 1.0F, value); + } layer = ew_layer; } else if (layer_type == "Sub") { ew_operation = "linear"; - auto ew_layer = std::make_shared(ew_operation, - 1.0F, -value); + std::shared_ptr ew_layer; + if (use_onednn && + it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { + ew_layer = std::make_shared( + ew_operation, 1.0F, -value); + } else { + ew_layer = std::make_shared(ew_operation, + 1.0F, -value); + } layer = ew_layer; } else { continue; diff --git a/app/Graph/build.hpp b/app/Graph/build.hpp index 76b5d1df8..9032b4462 100644 --- a/app/Graph/build.hpp +++ b/app/Graph/build.hpp @@ -31,6 +31,7 @@ #include "layers/SplitLayer.hpp" #include "layers/Tensor.hpp" #include "layers/TransposeLayer.hpp" +#include "layers_oneDNN/EWLayer_oneDNN.hpp" std::unordered_map model_paths = { {"alexnet_mnist", MODEL_PATH_H5}, @@ -57,14 +58,15 @@ struct ParseResult { void build_graph(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, const std::string& json_path, bool comments, - bool parallel = false); + bool parallel = false, bool onednn = false); void build_graph_linear(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, - bool comments, bool parallel = false); + bool comments, bool parallel = false, + bool onednn = false); std::unordered_map load_class_names( const std::string& filename); ParseResult parse_json_model(const std::string& json_path, bool comments, - bool parallel); + bool parallel, bool use_onednn); std::vector get_input_shape_from_json(const std::string& json_path); std::vector process_model_output(const std::vector& output, diff --git a/app/Graph/graph_build.cpp b/app/Graph/graph_build.cpp index 3a7330c60..d2a50d3eb 100644 --- a/app/Graph/graph_build.cpp +++ b/app/Graph/graph_build.cpp @@ -11,12 +11,14 @@ using namespace it_lab_ai; int main(int argc, char* argv[]) { std::string model_name = "alexnet_mnist"; bool parallel = false; - + bool onednn = false; for (int i = 1; i < argc; ++i) { if (std::string(argv[i]) == "--parallel") { parallel = true; } else if (std::string(argv[i]) == "--model" && i + 1 < argc) { model_name = argv[++i]; + } else if (std::string(argv[i]) == "--onednn") { + onednn = true; } } @@ -62,7 +64,7 @@ int main(int argc, char* argv[]) { std::vector vec(75, 3); it_lab_ai::Tensor output = it_lab_ai::make_tensor(vec, sh1); - build_graph_linear(input, output, true, parallel); + build_graph_linear(input, output, true, parallel, onednn); std::vector tmp_output = softmax(*output.as()); int top_n = std::min(3, static_cast(tmp_output.size())); std::vector indices(tmp_output.size()); @@ -92,7 +94,7 @@ int main(int argc, char* argv[]) { size_t output_classes = 1000; it_lab_ai::Tensor output({1, output_classes}, it_lab_ai::Type::kFloat); - build_graph(input, output, json_path, false, parallel); + build_graph(input, output, json_path, false, parallel, onednn); std::vector tmp_output = process_model_output(*output.as(), model_name); diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 418c50061..760af1d8b 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -7,6 +7,9 @@ set(GRAPHT_HEADERS "${graphT_headers}" PARENT_SCOPE) file(GLOB_RECURSE layers_headers layers/*.h layers/*.hpp) set(LAYERS_HEADERS "${layers_headers}" PARENT_SCOPE) +file(GLOB_RECURSE layers_oneDNN_headers layers_oneDNN/*.h layers_oneDNN/*.hpp) +set(LAYERS_ONEDNN_HEADERS "${layers_oneDNN_headers}" PARENT_SCOPE) + file(GLOB_RECURSE perf_headers perf/*.h perf/*.hpp) set(PERF_HEADERS "${perf_headers}" PARENT_SCOPE) diff --git a/include/layers_oneDNN/EWLayer_oneDNN.hpp b/include/layers_oneDNN/EWLayer_oneDNN.hpp new file mode 100644 index 000000000..c1b6503ab --- /dev/null +++ b/include/layers_oneDNN/EWLayer_oneDNN.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include +#include + +#include "layers/Layer.hpp" + +namespace it_lab_ai { + +class EWLayer_oneDNN : public Layer { + public: + EWLayer_oneDNN() + : Layer(kElementWise), func_("none"), alpha_(0.0F), beta_(0.0F) {} + + EWLayer_oneDNN(std::string function, float alpha = 0.0F, float beta = 0.0F) + : Layer(kElementWise), + func_(std::move(function)), + alpha_(alpha), + beta_(beta) {} + + void run(const std::vector& input, + std::vector& output) override; + static bool is_function_supported(const std::string& function); + +#ifdef ENABLE_STATISTIC_WEIGHTS + Tensor get_weights() override { + std::vector v = {0}; + Tensor a = make_tensor(v); + return a; + } +#endif + + private: + void initialize_onednn(const Shape& shape); + dnnl::algorithm get_algorithm() const; + void validate_input(const std::vector& input) const; + + std::string func_; + float alpha_; + float beta_; + + std::unique_ptr engine_; + std::unique_ptr stream_; + std::unique_ptr eltwise_prim_; + dnnl::memory::desc memory_desc_; + bool initialized_ = false; +}; + +} // namespace it_lab_ai \ No newline at end of file diff --git a/src/layers/CMakeLists.txt b/src/layers/CMakeLists.txt index d3426e04a..235dcdef2 100644 --- a/src/layers/CMakeLists.txt +++ b/src/layers/CMakeLists.txt @@ -1,3 +1,4 @@ file(GLOB_RECURSE layers_src *.cpp) add_library(layers_lib STATIC "${LAYERS_HEADERS}" "${layers_src}") target_link_libraries(layers_lib PUBLIC TBB_unified) +target_link_libraries(layers_lib PUBLIC dnnl) \ No newline at end of file diff --git a/src/layers_oneDNN/CMakeLists.txt b/src/layers_oneDNN/CMakeLists.txt new file mode 100644 index 000000000..0a41cbed4 --- /dev/null +++ b/src/layers_oneDNN/CMakeLists.txt @@ -0,0 +1,9 @@ +file(GLOB_RECURSE layers_oneDNN_src *.cpp) +add_library(layers_oneDNN_lib STATIC "${LAYERS_ONEDNN_HEADERS}" "${layers_oneDNN_src}") +target_link_libraries(layers_oneDNN_lib PUBLIC dnnl TBB_unified) +target_include_directories(layers_oneDNN_lib PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../include +) +target_compile_definitions(layers_oneDNN_lib PRIVATE + DNNL_ENABLE_CONCURRENT_EXEC=1 +) \ No newline at end of file diff --git a/src/layers_oneDNN/EWLayer_oneDNN.cpp b/src/layers_oneDNN/EWLayer_oneDNN.cpp new file mode 100644 index 000000000..ed7fddcd0 --- /dev/null +++ b/src/layers_oneDNN/EWLayer_oneDNN.cpp @@ -0,0 +1,137 @@ +#include "layers_oneDNN/EWLayer_oneDNN.hpp" + +#include +#include + +namespace it_lab_ai { + +void EWLayer_oneDNN::run(const std::vector& input, + std::vector& output) { + validate_input(input); + + const Tensor& input_tensor = input[0]; + + if (!initialized_) { + initialize_onednn(input_tensor.get_shape()); + } + if (input_tensor.get_type() != Type::kFloat) { + throw std::runtime_error("oneDNN EWLayer supports only float tensors"); + } + + try { + const std::vector& input_data = *input_tensor.as(); + std::vector output_data(input_data.size()); + dnnl::memory src_mem = dnnl::memory(memory_desc_, *engine_, + const_cast(input_data.data())); + dnnl::memory dst_mem = + dnnl::memory(memory_desc_, *engine_, output_data.data()); + eltwise_prim_->execute(*stream_, + {{DNNL_ARG_SRC, src_mem}, {DNNL_ARG_DST, dst_mem}}); + stream_->wait(); + output[0] = make_tensor(output_data, input_tensor.get_shape()); + + } catch (const std::exception& e) { + std::cerr << "oneDNN execution failed: " << e.what() << std::endl; + throw; + } +} + +void EWLayer_oneDNN::validate_input(const std::vector& input) const { + if (input.size() != 1) { + throw std::runtime_error("EWLayer_oneDNN: Expected exactly 1 input tensor"); + } + + if (!is_function_supported(func_)) { + throw std::invalid_argument("Unsupported function for oneDNN: " + func_); + } +} + +void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { + try { + engine_ = std::make_unique(dnnl::engine::kind::cpu, 0); + stream_ = std::make_unique(*engine_); + + std::vector dims; + for (size_t i = 0; i < shape.dims(); i++) { + dims.push_back(static_cast(shape.at(i))); + } + dnnl::memory::format_tag format; + switch (dims.size()) { + case 1: + format = dnnl::memory::format_tag::a; + break; + case 2: + format = dnnl::memory::format_tag::ab; + break; + case 3: + format = dnnl::memory::format_tag::abc; + break; + case 4: + format = dnnl::memory::format_tag::abcd; + break; + case 5: + format = dnnl::memory::format_tag::abcde; + break; + default: + format = dnnl::memory::format_tag::a; + break; + } + + memory_desc_ = + dnnl::memory::desc(dims, dnnl::memory::data_type::f32, format); + + dnnl::algorithm algo = get_algorithm(); + + float primitive_alpha = 0.0f; + float primitive_beta = 0.0f; + + if (func_ == "relu") { + primitive_alpha = 0.0f; + } else if (func_ == "linear") { + primitive_alpha = alpha_; + primitive_beta = beta_; + } + + auto eltwise_pd = dnnl::eltwise_forward::primitive_desc( + *engine_, dnnl::prop_kind::forward_inference, algo, memory_desc_, + memory_desc_, primitive_alpha, primitive_beta); + + eltwise_prim_ = std::make_unique(eltwise_pd); + + initialized_ = true; + + std::cout << "oneDNN EWLayer initialized for function: " << func_ + << " with shape: ["; + for (size_t i = 0; i < dims.size(); ++i) { + std::cout << dims[i]; + if (i < dims.size() - 1) std::cout << ", "; + } + std::cout << "]" << std::endl; + + } catch (const std::exception& e) { + std::cerr << "oneDNN initialization failed for function '" << func_ + << "': " << e.what() << std::endl; + throw; + } +} + +dnnl::algorithm EWLayer_oneDNN::get_algorithm() const { + if (func_ == "relu") { + return dnnl::algorithm::eltwise_relu; + } else if (func_ == "tanh") { + return dnnl::algorithm::eltwise_tanh; + } else if (func_ == "sigmoid") { + return dnnl::algorithm::eltwise_logistic; + } else if (func_ == "linear") { + return dnnl::algorithm::eltwise_linear; + } else { + throw std::invalid_argument("Unsupported function for oneDNN: " + func_); + } +} + +bool EWLayer_oneDNN::is_function_supported(const std::string& function) { + return (function == "relu" || function == "tanh" || function == "sigmoid" || + function == "linear"); +} + +} // namespace it_lab_ai \ No newline at end of file diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp new file mode 100644 index 000000000..37daa6c20 --- /dev/null +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -0,0 +1,182 @@ +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "layers/EWLayer.hpp" +#include "layers_oneDNN/EWLayer_oneDNN.hpp" + +using namespace it_lab_ai; + +TEST(ewlayer_onednn, supported_functions_check) { + EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("relu")); + EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("tanh")); + EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("sigmoid")); + EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("linear")); + + EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("sin")); + EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("minus")); + EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("nonexistent")); +} + +TEST(ewlayer_onednn, relu_float) { + EWLayer_oneDNN layer("relu"); + + Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -2.0F}); + Tensor output; + std::vector expected = {1.0F, 0.0F, 2.0F, 0.0F}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_NEAR(output_data[i], expected[i], 1e-5); + } +} + +TEST(ewlayer_onednn, linear_float) { + EWLayer_oneDNN layer("linear", 2.0f, 0.0f); + + Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -5.0F}); + Tensor output; + std::vector expected = {2.0F, -2.0F, 4.0F, -10.0F}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_NEAR(output_data[i], expected[i], 1e-5); + } +} + +TEST(ewlayer_onednn, linear_with_bias_float) { + EWLayer_oneDNN layer("linear", 1.0f, -1.0f); + + Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -5.0F}); + Tensor output; + std::vector expected = {0.0F, -2.0F, 1.0F, -6.0F}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_NEAR(output_data[i], expected[i], 1e-5); + } +} + +TEST(ewlayer_onednn, tanh_float) { + EWLayer_oneDNN layer("tanh"); + + Tensor input = make_tensor({0.0F, 1.0F, -1.0F, 2.0F}); + Tensor output; + std::vector expected; + + std::vector input_data = *input.as(); + for (auto val : input_data) { + expected.push_back(std::tanh(val)); + } + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_NEAR(output_data[i], expected[i], 1e-5); + } +} + +TEST(ewlayer_onednn, sigmoid_float) { + EWLayer_oneDNN layer("sigmoid"); + + Tensor input = make_tensor({0.0F, 1.0F, -1.0F, 2.0F}); + Tensor output; + std::vector expected; + + std::vector input_data = *input.as(); + for (auto val : input_data) { + expected.push_back(1.0f / (1.0f + std::exp(-val))); + } + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_NEAR(output_data[i], expected[i], 1e-5); + } +} + +TEST(ewlayer_onednn, multidim_tensor_relu) { + Shape shape({1, 3, 2, 2}); + + EWLayer_oneDNN layer("relu"); + + std::vector input_data(1 * 3 * 2 * 2); + for (size_t i = 0; i < input_data.size(); i++) { + input_data[i] = static_cast(i) - 2.0f; + } + + Tensor input = make_tensor(input_data, shape); + Tensor output; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), input_data.size()); + + for (size_t i = 0; i < output_data.size(); i++) { + float expected = std::max(0.0f, input_data[i]); + EXPECT_NEAR(output_data[i], expected, 1e-5); + } +} + +TEST(ewlayer_onednn, unsupported_function_throws) { + EXPECT_THROW({ EWLayer_oneDNN layer("unsupported_function"); }, + std::invalid_argument); +} + +TEST(ewlayer_onednn, compare_with_naive_relu) { + EWLayer_oneDNN onednn_layer("relu"); + + EWLayer naive_layer("relu"); + + std::vector input_data(100); + for (size_t i = 0; i < input_data.size(); i++) { + input_data[i] = static_cast(i) - 50.0f; + } + + Tensor input_tensor = make_tensor(input_data); + + Tensor onednn_output; + std::vector onednn_in{input_tensor}; + std::vector onednn_out{onednn_output}; + onednn_layer.run(onednn_in, onednn_out); + auto onednn_result = *onednn_out[0].as(); + + Tensor naive_output; + std::vector naive_in{input_tensor}; + std::vector naive_out{naive_output}; + naive_layer.run(naive_in, naive_out); + auto naive_result = *naive_out[0].as(); + + ASSERT_EQ(onednn_result.size(), naive_result.size()); + for (size_t i = 0; i < onednn_result.size(); i++) { + EXPECT_NEAR(onednn_result[i], naive_result[i], 1e-5); + } +} From 1b844c2a481c6aa72f53a165cf21874d5a110332 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 22 Oct 2025 17:19:18 +0300 Subject: [PATCH 03/36] Update .gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 1faffb935..f19f40a5b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,4 +12,4 @@ url = https://github.com/nlohmann/json [submodule "3rdparty/oneDNN"] path = 3rdparty/oneDNN - url = https://github.com/uxlfoundation/oneDNN.git + url = https://github.com/uxlfoundation/oneDNN From 499ed467817a15962b2e1f82735efaae3f8b56e5 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 22 Oct 2025 17:27:05 +0300 Subject: [PATCH 04/36] fix --- CMakeLists.txt | 1 + app/Graph/acc_check.cpp | 2 +- app/Graph/build.cpp | 12 ++++++------ app/Graph/build.hpp | 2 +- test/CMakeLists.txt | 10 +++++++++- test/single_layer/test_ewlayer_onednn.cpp | 4 ++-- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d609a282f..d7a98e6d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,4 +51,5 @@ endforeach() add_subdirectory(app) add_subdirectory(include) add_subdirectory(src) +add_subdirectory(src/layers_oneDNN) add_subdirectory(test) diff --git a/app/Graph/acc_check.cpp b/app/Graph/acc_check.cpp index 7478e1e72..dbd3d16b0 100644 --- a/app/Graph/acc_check.cpp +++ b/app/Graph/acc_check.cpp @@ -72,7 +72,7 @@ int main(int argc, char* argv[]) { for (int j = 0; j < 28; ++j) { size_t a = ind; for (size_t n = 0; n < name; n++) a += counts[n] + 1; - res[(a)*28 * 28 + i * 28 + j] = channels[0].at(j, i); + res[(a) * 28 * 28 + i * 28 + j] = channels[0].at(j, i); } } } diff --git a/app/Graph/build.cpp b/app/Graph/build.cpp index 814e81f07..76bdb819d 100644 --- a/app/Graph/build.cpp +++ b/app/Graph/build.cpp @@ -377,7 +377,7 @@ void build_graph(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, } ParseResult parse_json_model(const std::string& json_path, bool comments, - bool parallel, bool use_onednn) { + bool parallel, bool onednn) { ParseResult result; auto& layers = result.layers; @@ -495,7 +495,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, } else if (layer_type.find("Relu") != std::string::npos || layer_type.find("relu") != std::string::npos) { std::shared_ptr ew_layer; - if (use_onednn) { + if (onednn) { ew_layer = std::make_shared("relu"); } else { ew_layer = std::make_shared("relu"); @@ -503,7 +503,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, layer = ew_layer; } else if (layer_type.find("Sigmoid") != std::string::npos) { std::shared_ptr ew_layer; - if (use_onednn) { + if (onednn) { ew_layer = std::make_shared("sigmoid"); } else { ew_layer = std::make_shared("sigmoid"); @@ -733,7 +733,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, if (layer_type == "Mul") { ew_operation = "linear"; std::shared_ptr ew_layer; - if (use_onednn) { + if (onednn) { ew_layer = std::make_shared( ew_operation, value, 0.0F); } else { @@ -744,7 +744,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, } else if (layer_type == "Add") { ew_operation = "linear"; std::shared_ptr ew_layer; - if (use_onednn && + if (onednn && it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { ew_layer = std::make_shared( ew_operation, 1.0F, value); @@ -756,7 +756,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, } else if (layer_type == "Sub") { ew_operation = "linear"; std::shared_ptr ew_layer; - if (use_onednn && + if (onednn && it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { ew_layer = std::make_shared( ew_operation, 1.0F, -value); diff --git a/app/Graph/build.hpp b/app/Graph/build.hpp index 9032b4462..b863c1fcb 100644 --- a/app/Graph/build.hpp +++ b/app/Graph/build.hpp @@ -66,7 +66,7 @@ std::unordered_map load_class_names( const std::string& filename); ParseResult parse_json_model(const std::string& json_path, bool comments, - bool parallel, bool use_onednn); + bool parallel, bool onednn); std::vector get_input_shape_from_json(const std::string& json_path); std::vector process_model_output(const std::vector& output, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 318354de2..d12670de7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(run_test ${TEST_SRC_FILES}) if (NOT WIN32) target_link_libraries(run_test PUBLIC OpenMP::OpenMP_CXX) endif() -target_link_libraries(run_test PUBLIC perf_lib layers_lib) +target_link_libraries(run_test PUBLIC perf_lib layers_lib layers_oneDNN_lib) target_link_libraries(run_test PUBLIC gtest) target_link_libraries(run_test PUBLIC ReadLib) target_link_libraries(run_test PUBLIC reader_lib) @@ -26,6 +26,14 @@ if (WIN32) "${CMAKE_BINARY_DIR}/bin/") endif() +if (WIN32) + add_custom_command(TARGET run_test POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy + $ + $ + ) +endif() + add_test(UnitTests ${CMAKE_BINARY_DIR}/bin/run_test) file(DOWNLOAD diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 37daa6c20..3e7f8b25c 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -147,8 +147,8 @@ TEST(ewlayer_onednn, multidim_tensor_relu) { } TEST(ewlayer_onednn, unsupported_function_throws) { - EXPECT_THROW({ EWLayer_oneDNN layer("unsupported_function"); }, - std::invalid_argument); + EXPECT_THROW( + { EWLayer_oneDNN layer("unsupported_function"); },std::invalid_argument); } TEST(ewlayer_onednn, compare_with_naive_relu) { From 9a6af4b46b825daea748e0cd9e2ab5e6fe06bef9 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 22 Oct 2025 17:28:48 +0300 Subject: [PATCH 05/36] clang --- test/single_layer/test_ewlayer_onednn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 3e7f8b25c..0ae329fc4 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -148,7 +148,7 @@ TEST(ewlayer_onednn, multidim_tensor_relu) { TEST(ewlayer_onednn, unsupported_function_throws) { EXPECT_THROW( - { EWLayer_oneDNN layer("unsupported_function"); },std::invalid_argument); + { EWLayer_oneDNN layer("unsupported_function"); }, std::invalid_argument); } TEST(ewlayer_onednn, compare_with_naive_relu) { From d86e1c16c47e46d6a323eb89da8241bd47cbe7d3 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:43:59 +0300 Subject: [PATCH 06/36] Update ci.yml --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b08551e57..75f0b0a8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,9 @@ jobs: -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -DOPENCV_PATH=build/3rdparty/opencv_build \ + -DDNNL_GRAPH_DISABLE=ON \ # ← отключаем Graph + -DDNNL_BUILD_EXAMPLES=OFF \ + -DDNNL_BUILD_TESTS=OFF \ ${{ matrix.stats && '-DENABLE_STATISTIC_TENSORS=ON' || '' }} \ ${{ matrix.stats && '-DENABLE_STATISTIC_TIME=ON' || '' }} \ ${{ matrix.stats && '-DENABLE_STATISTIC_WEIGHTS=ON' || '' }} From 00d79bb3a4b25256523dc5d4709dc9f0255efc37 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 22 Oct 2025 18:44:38 +0300 Subject: [PATCH 07/36] fix unused --- test/single_layer/test_ewlayer_onednn.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 0ae329fc4..2666cf229 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -146,11 +146,6 @@ TEST(ewlayer_onednn, multidim_tensor_relu) { } } -TEST(ewlayer_onednn, unsupported_function_throws) { - EXPECT_THROW( - { EWLayer_oneDNN layer("unsupported_function"); }, std::invalid_argument); -} - TEST(ewlayer_onednn, compare_with_naive_relu) { EWLayer_oneDNN onednn_layer("relu"); From b3cdf0c18dd1e8954919f4d118098cbce64b212a Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Thu, 23 Oct 2025 19:38:49 +0300 Subject: [PATCH 08/36] fix cmake, default with err --- CMakeLists.txt | 1 - src/CMakeLists.txt | 3 ++- src/layers/CMakeLists.txt | 2 +- src/layers_oneDNN/CMakeLists.txt | 2 +- src/layers_oneDNN/EWLayer_oneDNN.cpp | 6 ++---- test/CMakeLists.txt | 1 - 6 files changed, 6 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d7a98e6d4..d609a282f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,5 +51,4 @@ endforeach() add_subdirectory(app) add_subdirectory(include) add_subdirectory(src) -add_subdirectory(src/layers_oneDNN) add_subdirectory(test) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ba0d466da..ab526f5b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(graph) add_subdirectory(graph_transformations) add_subdirectory(perf) add_subdirectory(layers) -add_subdirectory(Weights_Reader) \ No newline at end of file +add_subdirectory(layers_oneDNN) +add_subdirectory(Weights_Reader) diff --git a/src/layers/CMakeLists.txt b/src/layers/CMakeLists.txt index 235dcdef2..f8ac6d84b 100644 --- a/src/layers/CMakeLists.txt +++ b/src/layers/CMakeLists.txt @@ -1,4 +1,4 @@ file(GLOB_RECURSE layers_src *.cpp) add_library(layers_lib STATIC "${LAYERS_HEADERS}" "${layers_src}") target_link_libraries(layers_lib PUBLIC TBB_unified) -target_link_libraries(layers_lib PUBLIC dnnl) \ No newline at end of file +target_link_libraries(layers_lib PUBLIC dnnl) diff --git a/src/layers_oneDNN/CMakeLists.txt b/src/layers_oneDNN/CMakeLists.txt index 0a41cbed4..e4ee067e1 100644 --- a/src/layers_oneDNN/CMakeLists.txt +++ b/src/layers_oneDNN/CMakeLists.txt @@ -6,4 +6,4 @@ target_include_directories(layers_oneDNN_lib PUBLIC ) target_compile_definitions(layers_oneDNN_lib PRIVATE DNNL_ENABLE_CONCURRENT_EXEC=1 -) \ No newline at end of file +) diff --git a/src/layers_oneDNN/EWLayer_oneDNN.cpp b/src/layers_oneDNN/EWLayer_oneDNN.cpp index ed7fddcd0..af1598ad5 100644 --- a/src/layers_oneDNN/EWLayer_oneDNN.cpp +++ b/src/layers_oneDNN/EWLayer_oneDNN.cpp @@ -73,8 +73,8 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { format = dnnl::memory::format_tag::abcde; break; default: - format = dnnl::memory::format_tag::a; - break; + throw std::invalid_argument("Unsupported tensor dimensionality: " + + std::to_string(dims.size())); } memory_desc_ = @@ -100,8 +100,6 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { initialized_ = true; - std::cout << "oneDNN EWLayer initialized for function: " << func_ - << " with shape: ["; for (size_t i = 0; i < dims.size(); ++i) { std::cout << dims[i]; if (i < dims.size() - 1) std::cout << ", "; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d12670de7..fc95325c7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -55,4 +55,3 @@ target_compile_definitions(run_test PRIVATE TEST_DATA_PATH="${CMAKE_SOURCE_DIR}/ target_compile_definitions(run_test PUBLIC TESTS_BINARY_PATH="${CMAKE_CURRENT_BINARY_DIR}") - From b57dba8c0d904db4c09504e321b475314db9077f Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Thu, 23 Oct 2025 19:46:05 +0300 Subject: [PATCH 09/36] Update ci.yml --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75f0b0a8e..8890522bd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,7 +45,7 @@ jobs: -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -DOPENCV_PATH=build/3rdparty/opencv_build \ - -DDNNL_GRAPH_DISABLE=ON \ # ← отключаем Graph + -DDNNL_GRAPH_DISABLE=ON \ -DDNNL_BUILD_EXAMPLES=OFF \ -DDNNL_BUILD_TESTS=OFF \ ${{ matrix.stats && '-DENABLE_STATISTIC_TENSORS=ON' || '' }} \ From d09f86f683d9a190a435f2578aa62fbcee62dae3 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 12:08:16 +0300 Subject: [PATCH 10/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index cc5e26ce0..93fcb9238 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,4 +1,12 @@ add_subdirectory(googletest) + +set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") +set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") +set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") +set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") + +set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") + add_subdirectory(oneDNN) # Unified TBB Configuration From 96ccc435a87ab178d0c6b0157a130c92a2bf7dac Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 13:16:17 +0300 Subject: [PATCH 11/36] Update ci.yml --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8890522bd..b08551e57 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,9 +45,6 @@ jobs: -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ -DOPENCV_PATH=build/3rdparty/opencv_build \ - -DDNNL_GRAPH_DISABLE=ON \ - -DDNNL_BUILD_EXAMPLES=OFF \ - -DDNNL_BUILD_TESTS=OFF \ ${{ matrix.stats && '-DENABLE_STATISTIC_TENSORS=ON' || '' }} \ ${{ matrix.stats && '-DENABLE_STATISTIC_TIME=ON' || '' }} \ ${{ matrix.stats && '-DENABLE_STATISTIC_WEIGHTS=ON' || '' }} From 60f5e614ee2e0cf900cafaee5317b146746aa20a Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 13:16:36 +0300 Subject: [PATCH 12/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 93fcb9238..67385ccba 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -4,7 +4,6 @@ set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") - set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") add_subdirectory(oneDNN) From 7d2afb5d6962431cb9665929907091f9c18aeb54 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 13:43:47 +0300 Subject: [PATCH 13/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 67385ccba..f120841c4 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -5,6 +5,12 @@ set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") +set(DNNL_GRAPH_BUILD_TESTS OFF) +set(DNNL_GRAPH_BUILD_EXAMPLES OFF) + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(DNNL_ARCH_OPT_FLAGS "-O2" CACHE STRING "Architecture optimization flags") +endif() add_subdirectory(oneDNN) From 2ac1d8f632d480b10b84ed2ca739bd6dda5c7358 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 17:04:34 +0300 Subject: [PATCH 14/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index f120841c4..eae27f3d2 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,19 +1,24 @@ add_subdirectory(googletest) -set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") -set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") -set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") -set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") -set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") +set(DNNL_BUILD_EXAMPLES OFF) +set(DNNL_BUILD_TESTS OFF) +set(DNNL_CPU_RUNTIME "OMP") +set(DNNL_GRAPH_DISABLE ON) set(DNNL_GRAPH_BUILD_TESTS OFF) set(DNNL_GRAPH_BUILD_EXAMPLES OFF) -if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(DNNL_ARCH_OPT_FLAGS "-O2" CACHE STRING "Architecture optimization flags") +if(UNIX AND NOT APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -j2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -j2") endif() add_subdirectory(oneDNN) +if(UNIX AND NOT APPLE) + set(CMAKE_C_FLAGS "") + set(CMAKE_CXX_FLAGS "") +endif() + # Unified TBB Configuration option(TBB_TEST "Build TBB tests" OFF) option(TBB_EXAMPLES "Build TBB examples" OFF) From b252d6c023dc1b0cf8582c26f49fdd8bf9609a59 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 17:08:47 +0300 Subject: [PATCH 15/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index eae27f3d2..69195e8dc 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,24 +1,34 @@ add_subdirectory(googletest) -set(DNNL_BUILD_EXAMPLES OFF) -set(DNNL_BUILD_TESTS OFF) -set(DNNL_CPU_RUNTIME "OMP") -set(DNNL_GRAPH_DISABLE ON) -set(DNNL_GRAPH_BUILD_TESTS OFF) -set(DNNL_GRAPH_BUILD_EXAMPLES OFF) +include(ExternalProject) -if(UNIX AND NOT APPLE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -j2") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -j2") -endif() +set(ONEDNN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/oneDNN) +set(ONEDNN_BINARY_DIR ${CMAKE_BINARY_DIR}/oneDNN_build) -add_subdirectory(oneDNN) +ExternalProject_Add(oneDNN_external + SOURCE_DIR ${ONEDNN_SOURCE_DIR} + BINARY_DIR ${ONEDNN_BINARY_DIR} + CMAKE_ARGS + -DDNNL_BUILD_EXAMPLES=OFF + -DDNNL_BUILD_TESTS=OFF + -DDNNL_CPU_RUNTIME=OMP + -DDNNL_GRAPH_DISABLE=ON + -DDNNL_GRAPH_BUILD_TESTS=OFF + -DDNNL_GRAPH_BUILD_EXAMPLES=OFF + -DCMAKE_BUILD_PARALLEL_LEVEL=2 + INSTALL_COMMAND "" + BUILD_BYPRODUCTS + ${ONEDNN_BINARY_DIR}/src/libdnnl.a + ${ONEDNN_BINARY_DIR}/src/libdnnl.so +) -if(UNIX AND NOT APPLE) - set(CMAKE_C_FLAGS "") - set(CMAKE_CXX_FLAGS "") -endif() +add_library(dnnl STATIC IMPORTED) +set_target_properties(dnnl PROPERTIES + IMPORTED_LOCATION ${ONEDNN_BINARY_DIR}/src/libdnnl.a + INTERFACE_INCLUDE_DIRECTORIES ${ONEDNN_SOURCE_DIR}/include +) +add_dependencies(dnnl oneDNN_external) # Unified TBB Configuration option(TBB_TEST "Build TBB tests" OFF) option(TBB_EXAMPLES "Build TBB examples" OFF) From 9e879fe2d84c1c7e9bda6678f775138fc7a14d39 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:20:30 +0300 Subject: [PATCH 16/36] Update ci.yml --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b08551e57..75ae2493d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,8 @@ jobs: key: ccache-${{ github.job }} - name: Build run: | + export CMAKE_BUILD_PARALLEL_LEVEL=2 + export MAKEFLAGS="-j2" cmake -S . -B build \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ From 09099ac66fb932c025da14913ee42ef41bda537c Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 17:20:49 +0300 Subject: [PATCH 17/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 69195e8dc..f120841c4 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,34 +1,19 @@ add_subdirectory(googletest) -include(ExternalProject) +set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") +set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") +set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") +set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") +set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") +set(DNNL_GRAPH_BUILD_TESTS OFF) +set(DNNL_GRAPH_BUILD_EXAMPLES OFF) -set(ONEDNN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/oneDNN) -set(ONEDNN_BINARY_DIR ${CMAKE_BINARY_DIR}/oneDNN_build) - -ExternalProject_Add(oneDNN_external - SOURCE_DIR ${ONEDNN_SOURCE_DIR} - BINARY_DIR ${ONEDNN_BINARY_DIR} - CMAKE_ARGS - -DDNNL_BUILD_EXAMPLES=OFF - -DDNNL_BUILD_TESTS=OFF - -DDNNL_CPU_RUNTIME=OMP - -DDNNL_GRAPH_DISABLE=ON - -DDNNL_GRAPH_BUILD_TESTS=OFF - -DDNNL_GRAPH_BUILD_EXAMPLES=OFF - -DCMAKE_BUILD_PARALLEL_LEVEL=2 - INSTALL_COMMAND "" - BUILD_BYPRODUCTS - ${ONEDNN_BINARY_DIR}/src/libdnnl.a - ${ONEDNN_BINARY_DIR}/src/libdnnl.so -) +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(DNNL_ARCH_OPT_FLAGS "-O2" CACHE STRING "Architecture optimization flags") +endif() -add_library(dnnl STATIC IMPORTED) -set_target_properties(dnnl PROPERTIES - IMPORTED_LOCATION ${ONEDNN_BINARY_DIR}/src/libdnnl.a - INTERFACE_INCLUDE_DIRECTORIES ${ONEDNN_SOURCE_DIR}/include -) +add_subdirectory(oneDNN) -add_dependencies(dnnl oneDNN_external) # Unified TBB Configuration option(TBB_TEST "Build TBB tests" OFF) option(TBB_EXAMPLES "Build TBB examples" OFF) From 38f4588d811d8982b213e3541f9729ba01e86d6b Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:59:19 +0300 Subject: [PATCH 18/36] Update ci.yml --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75ae2493d..d2cf08258 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -177,6 +177,7 @@ jobs: key: ccache-${{ github.job }} - name: Build and Test run: | + export MAKEFLAGS="-j2" cmake -S . -B build \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ @@ -185,6 +186,7 @@ jobs: cmake --build build -t test env: CTEST_OUTPUT_ON_FAILURE: 1 + CMAKE_BUILD_PARALLEL_LEVEL: 2 codecov: runs-on: ubuntu-latest steps: From a44af977ba5511b8595fd8b9da160ac26d3f4caa Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 18:13:18 +0300 Subject: [PATCH 19/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index f120841c4..30b5d01cd 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -4,10 +4,25 @@ set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") -set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") set(DNNL_GRAPH_BUILD_TESTS OFF) set(DNNL_GRAPH_BUILD_EXAMPLES OFF) +set(DNNL_ENABLE_PRIMITIVE_CACHE ON CACHE BOOL "Enable primitive cache") +set(DNNL_ENABLE_CONCURRENT_EXEC OFF CACHE BOOL "Disable concurrent execution") +set(DNNL_ENABLE_ITT_TASKS OFF CACHE BOOL "Disable ITT tasks") +set(DNNL_ENABLE_JIT_DUMP OFF CACHE BOOL "Disable JIT dump") +set(DNNL_ENABLE_JIT_PROFILING OFF CACHE BOOL "Disable JIT profiling") +set(DNNL_ENABLE_MEM_DEBUG OFF CACHE BOOL "Disable memory debug") +set(DNNL_ENABLE_PRIMITIVE_LOG OFF CACHE BOOL "Disable primitive log") +set(DNNL_VERBOSE OFF CACHE BOOL "Disable verbose output") + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + set(DNNL_TARGET_ARCH "AARCH64" CACHE STRING "Target architecture") + set(DNNL_AARCH64_USE_ACL OFF CACHE BOOL "Disable ARM Compute Library") + set(DNNL_AARCH64_USE_DNNL OFF CACHE BOOL "Use minimal DNNL for ARM") +endif() + +# Для Clang if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(DNNL_ARCH_OPT_FLAGS "-O2" CACHE STRING "Architecture optimization flags") endif() From 24d7e520ee77f9c54800a157be5602156110bc2d Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 18:26:49 +0300 Subject: [PATCH 20/36] Update ci.yml --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2cf08258..cd92dcdf5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -177,8 +177,7 @@ jobs: key: ccache-${{ github.job }} - name: Build and Test run: | - export MAKEFLAGS="-j2" - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_BUILD_TYPE=Release @@ -186,7 +185,6 @@ jobs: cmake --build build -t test env: CTEST_OUTPUT_ON_FAILURE: 1 - CMAKE_BUILD_PARALLEL_LEVEL: 2 codecov: runs-on: ubuntu-latest steps: From 9393e7b0ac9cc2fea7837064c3de0bc13585f44e Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 18:46:39 +0300 Subject: [PATCH 21/36] Update ci.yml --- .github/workflows/ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd92dcdf5..c9389c26e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: max-size: 2G - name: Build run: | - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \ @@ -94,7 +94,7 @@ jobs: run: | export CMAKE_BUILD_PARALLEL_LEVEL=2 export MAKEFLAGS="-j2" - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_C_COMPILER=clang \ @@ -127,7 +127,7 @@ jobs: key: ccache-${{ github.job }} - name: Build run: | - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_C_FLAGS="-I$(brew --prefix libomp)/include" \ @@ -203,7 +203,7 @@ jobs: max-size: 2G - name: Build run: | - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_C_FLAGS="--coverage" \ @@ -245,7 +245,8 @@ jobs: libtbb12 \ libjpeg-dev \ libpng-dev \ - libtiff-dev + libtiff-dev \ + libopenjp2-7 sudo ldconfig - name: Generate model JSON run: | From 070a477e3513ff5052258fa9aa59b783b920dde6 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 18:47:18 +0300 Subject: [PATCH 22/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index 30b5d01cd..bf279eb57 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -4,28 +4,9 @@ set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") +set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") set(DNNL_GRAPH_BUILD_TESTS OFF) set(DNNL_GRAPH_BUILD_EXAMPLES OFF) -set(DNNL_ENABLE_PRIMITIVE_CACHE ON CACHE BOOL "Enable primitive cache") - -set(DNNL_ENABLE_CONCURRENT_EXEC OFF CACHE BOOL "Disable concurrent execution") -set(DNNL_ENABLE_ITT_TASKS OFF CACHE BOOL "Disable ITT tasks") -set(DNNL_ENABLE_JIT_DUMP OFF CACHE BOOL "Disable JIT dump") -set(DNNL_ENABLE_JIT_PROFILING OFF CACHE BOOL "Disable JIT profiling") -set(DNNL_ENABLE_MEM_DEBUG OFF CACHE BOOL "Disable memory debug") -set(DNNL_ENABLE_PRIMITIVE_LOG OFF CACHE BOOL "Disable primitive log") -set(DNNL_VERBOSE OFF CACHE BOOL "Disable verbose output") - -if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") - set(DNNL_TARGET_ARCH "AARCH64" CACHE STRING "Target architecture") - set(DNNL_AARCH64_USE_ACL OFF CACHE BOOL "Disable ARM Compute Library") - set(DNNL_AARCH64_USE_DNNL OFF CACHE BOOL "Use minimal DNNL for ARM") -endif() - -# Для Clang -if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(DNNL_ARCH_OPT_FLAGS "-O2" CACHE STRING "Architecture optimization flags") -endif() add_subdirectory(oneDNN) From d00b0d4ed2cfb53572cd2b64026b8ed3b4736add Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Tue, 28 Oct 2025 19:16:12 +0300 Subject: [PATCH 23/36] fix parallel in cmake --- 3rdparty/CMakeLists.txt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt index bf279eb57..5319b259d 100644 --- a/3rdparty/CMakeLists.txt +++ b/3rdparty/CMakeLists.txt @@ -1,13 +1,5 @@ add_subdirectory(googletest) -set(DNNL_BUILD_EXAMPLES OFF CACHE BOOL "Build examples") -set(DNNL_BUILD_TESTS OFF CACHE BOOL "Build tests") -set(DNNL_CPU_RUNTIME "OMP" CACHE STRING "CPU runtime") -set(DNNL_GRAPH_DISABLE ON CACHE BOOL "Disable dnnl graph") -set(CMAKE_BUILD_PARALLEL_LEVEL 2 CACHE STRING "Parallel build level") -set(DNNL_GRAPH_BUILD_TESTS OFF) -set(DNNL_GRAPH_BUILD_EXAMPLES OFF) - add_subdirectory(oneDNN) # Unified TBB Configuration From 1fbb7cf6a77b0e409bc0cdc64070c87c6fe2ad9c Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:17:17 +0300 Subject: [PATCH 24/36] Update static-analysis.yml --- .github/workflows/static-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 3eb5eff68..e37195a72 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -32,7 +32,7 @@ jobs: key: ccache-${{ github.job }} - name: Build run: | - cmake -S . -B build \ + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ -DCMAKE_C_COMPILER=clang \ From cfa6aeab1eec9f2c71494ab3a79a711d4069bb7f Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 10:50:29 +0300 Subject: [PATCH 25/36] Update ci.yml --- .github/workflows/ci.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9389c26e..9854d9892 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -296,16 +296,16 @@ jobs: - name: Run evaluation run: | - echo "### Pre-run checks ###" - export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu - echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" - - LD_DEBUG=files "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist 2> ld_debug.log - echo "### Library loading debug ###" - grep -i "opencv_imgcodecs" ld_debug.log - - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" > accuracy.txt - echo "Accuracy: $(cat accuracy.txt)" + echo "### Running evaluation ###" + export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu + echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" + + echo "Running ACC evaluation..." + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist > accuracy.txt 2>&1 || \ + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" > accuracy.txt 2>&1 + + echo "Evaluation output:" + cat accuracy.txt - name: Update README (master only) if: github.ref == 'refs/heads/master' From 4e56912c6a64af7ffb55ad0b7094e61cccf400a8 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:03:09 +0300 Subject: [PATCH 26/36] check evaluate --- .github/workflows/ci.yml | 87 ++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9854d9892..3b7ff728b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -224,19 +224,47 @@ jobs: slug: embedded-dev-research/ITLabAI evaluate-model: - runs-on: ubuntu-latest - needs: [build-linux] - permissions: - contents: write + runs-on: ubuntu-latest + needs: [build-linux] + permissions: + contents: write - steps: + steps: - uses: actions/checkout@v4 with: fetch-depth: 0 + + - name: Download binary and libs + uses: actions/download-artifact@v4 + with: + name: mnist-RELEASE + path: build/ + + - name: Verify downloaded artifacts + run: | + echo "### Verifying downloaded artifacts ###" + echo "Current directory: $(pwd)" + echo "Build directory contents:" + ls -la build/ || echo "No build directory" + echo "Looking for ACC binary:" + find build/ -name "ACC" -type f 2>/dev/null || echo "ACC not found" + echo "Checking bin directory:" + ls -la build/bin/ 2>/dev/null || echo "No bin directory" + - name: Set binary path id: set_eval_binary run: | - echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT + # Проверяем существует ли бинарник + if [ -f "build/bin/ACC" ]; then + echo "ACC binary found at build/bin/ACC" + echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT + else + echo "ERROR: ACC binary not found at build/bin/ACC" + echo "Available files:" + find build/ -type f -name "*" 2>/dev/null | head -20 + exit 1 + fi + - name: Install system dependencies run: | sudo apt-get update @@ -248,9 +276,10 @@ jobs: libtiff-dev \ libopenjp2-7 sudo ldconfig + - name: Generate model JSON run: | - cd docs && mkdir jsons + cd docs && mkdir -p jsons cd .. cd app/Converters pip install -r requirements.txt @@ -276,14 +305,12 @@ jobs: rm -rf main.zip MNIST_dataset-main echo "Downloaded $(ls docs/mnist/mnist/test | wc -l) images" - - name: Download binary and libs - uses: actions/download-artifact@v4 - with: - name: mnist-RELEASE - path: build/ - - name: Prepare environment run: | + echo "### Preparing environment ###" + echo "Binary path: ${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" + + ls -la "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" chmod +x "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu @@ -291,12 +318,24 @@ jobs: - name: Verify library integrity run: | - echo "### Library verification ###" - file build/bin/opencv_libs/libopencv_imgcodecs.so.4.12.0 | grep "shared object" + echo "### Library verification ###" + ls -la build/bin/opencv_libs/ || echo "No opencv_libs directory" + file build/bin/opencv_libs/libopencv_imgcodecs.so* 2>/dev/null | head -1 || echo "No opencv_imgcodecs library found" + + - name: Test binary execution + run: | + echo "### Testing binary execution ###" + export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu + + echo "Binary dependencies:" + ldd "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" 2>/dev/null || echo "ldd failed" + + echo "Testing help command:" + timeout 10s "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --help > /dev/null 2>&1 || echo "Help test completed" - name: Run evaluation run: | - echo "### Running evaluation ###" + echo "### Running evaluation ###" export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" @@ -307,19 +346,23 @@ jobs: echo "Evaluation output:" cat accuracy.txt + - name: Extract accuracy value + run: | + echo "### Extracting accuracy ###" + ACCURACY=$(grep -oE '[0-9]+\.?[0-9]*%' accuracy.txt | head -1 || echo "0%") + echo "Accuracy: $ACCURACY" + echo "$ACCURACY" > accuracy_value.txt + - name: Update README (master only) if: github.ref == 'refs/heads/master' run: | - ACCURACY=$(cat accuracy.txt | sed 's/%//g') + ACCURACY=$(cat accuracy_value.txt | sed 's/%//g') DATE=$(date '+%Y-%m-%d') echo "Updating README with:" - echo "Accuracy: $ACCURACY" + echo "Accuracy: $ACCURACY%" echo "Date: $DATE" - echo "Current README content:" - grep -A 2 -B 2 "ACCURACY_PLACEHOLDER" README.md || echo "Placeholder not found" - sed -i "s/.*/Accuracy: ${ACCURACY}% (updated: ${DATE})/" README.md echo "Updated README content:" @@ -336,7 +379,7 @@ jobs: if git diff-index --quiet HEAD --; then echo "No changes to commit" else - git commit -m "[CI] Update accuracy: $(cat accuracy.txt)%" + git commit -m "[CI] Update accuracy: $(cat accuracy_value.txt)" git push origin master echo "Changes pushed to master branch" fi From 8cb7a2c4a3d8f60268e685675e49cb485223fd4c Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:26:24 +0300 Subject: [PATCH 27/36] Update ci.yml --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b7ff728b..d93239f2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -274,7 +274,8 @@ jobs: libjpeg-dev \ libpng-dev \ libtiff-dev \ - libopenjp2-7 + libopenjp2-7 \ + libdnnl3 sudo ldconfig - name: Generate model JSON From 920a37763181ef83d7639e3346cb171ab7dbd203 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 29 Oct 2025 11:38:45 +0300 Subject: [PATCH 28/36] analisys, add int --- app/Graph/build.cpp | 16 ++-- include/layers_oneDNN/EWLayer_oneDNN.hpp | 8 +- src/layers_oneDNN/EWLayer_oneDNN.cpp | 112 ++++++++++++++-------- test/single_layer/test_ewlayer_onednn.cpp | 89 +++++++++++++---- 4 files changed, 159 insertions(+), 66 deletions(-) diff --git a/app/Graph/build.cpp b/app/Graph/build.cpp index 76bdb819d..addd71f27 100644 --- a/app/Graph/build.cpp +++ b/app/Graph/build.cpp @@ -82,7 +82,7 @@ void build_graph_linear(it_lab_ai::Tensor& input, it_lab_ai::Tensor& output, if (layer_type.find("relu") != std::string::npos) { std::shared_ptr ew_layer; if (onednn) { - ew_layer = std::make_shared("relu"); + ew_layer = std::make_shared("relu"); } else { ew_layer = std::make_shared("relu"); } @@ -496,7 +496,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, layer_type.find("relu") != std::string::npos) { std::shared_ptr ew_layer; if (onednn) { - ew_layer = std::make_shared("relu"); + ew_layer = std::make_shared("relu"); } else { ew_layer = std::make_shared("relu"); } @@ -504,7 +504,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, } else if (layer_type.find("Sigmoid") != std::string::npos) { std::shared_ptr ew_layer; if (onednn) { - ew_layer = std::make_shared("sigmoid"); + ew_layer = std::make_shared("sigmoid"); } else { ew_layer = std::make_shared("sigmoid"); } @@ -734,7 +734,7 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, ew_operation = "linear"; std::shared_ptr ew_layer; if (onednn) { - ew_layer = std::make_shared( + ew_layer = std::make_shared( ew_operation, value, 0.0F); } else { ew_layer = std::make_shared(ew_operation, @@ -745,8 +745,8 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, ew_operation = "linear"; std::shared_ptr ew_layer; if (onednn && - it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { - ew_layer = std::make_shared( + it_lab_ai::EwLayerOneDnn::is_function_supported("linear")) { + ew_layer = std::make_shared( ew_operation, 1.0F, value); } else { ew_layer = std::make_shared(ew_operation, @@ -757,8 +757,8 @@ ParseResult parse_json_model(const std::string& json_path, bool comments, ew_operation = "linear"; std::shared_ptr ew_layer; if (onednn && - it_lab_ai::EWLayer_oneDNN::is_function_supported("linear")) { - ew_layer = std::make_shared( + it_lab_ai::EwLayerOneDnn::is_function_supported("linear")) { + ew_layer = std::make_shared( ew_operation, 1.0F, -value); } else { ew_layer = std::make_shared(ew_operation, diff --git a/include/layers_oneDNN/EWLayer_oneDNN.hpp b/include/layers_oneDNN/EWLayer_oneDNN.hpp index c1b6503ab..6a04f8dd0 100644 --- a/include/layers_oneDNN/EWLayer_oneDNN.hpp +++ b/include/layers_oneDNN/EWLayer_oneDNN.hpp @@ -9,12 +9,12 @@ namespace it_lab_ai { -class EWLayer_oneDNN : public Layer { +class EwLayerOneDnn : public Layer { public: - EWLayer_oneDNN() + EwLayerOneDnn() : Layer(kElementWise), func_("none"), alpha_(0.0F), beta_(0.0F) {} - EWLayer_oneDNN(std::string function, float alpha = 0.0F, float beta = 0.0F) + EwLayerOneDnn(std::string function, float alpha = 0.0F, float beta = 0.0F) : Layer(kElementWise), func_(std::move(function)), alpha_(alpha), @@ -33,7 +33,7 @@ class EWLayer_oneDNN : public Layer { #endif private: - void initialize_onednn(const Shape& shape); + void initialize_onednn(const Shape& shape, Type data_type); dnnl::algorithm get_algorithm() const; void validate_input(const std::vector& input) const; diff --git a/src/layers_oneDNN/EWLayer_oneDNN.cpp b/src/layers_oneDNN/EWLayer_oneDNN.cpp index af1598ad5..c59346ca2 100644 --- a/src/layers_oneDNN/EWLayer_oneDNN.cpp +++ b/src/layers_oneDNN/EWLayer_oneDNN.cpp @@ -1,34 +1,60 @@ -#include "layers_oneDNN/EWLayer_oneDNN.hpp" +#include "layers_oneDNN/EwLayer_oneDnn.hpp" #include #include namespace it_lab_ai { -void EWLayer_oneDNN::run(const std::vector& input, - std::vector& output) { +void EwLayerOneDnn::run(const std::vector& input, + std::vector& output) { validate_input(input); const Tensor& input_tensor = input[0]; + Type data_type = input_tensor.get_type(); if (!initialized_) { - initialize_onednn(input_tensor.get_shape()); - } - if (input_tensor.get_type() != Type::kFloat) { - throw std::runtime_error("oneDNN EWLayer supports only float tensors"); + initialize_onednn(input_tensor.get_shape(), data_type); } try { - const std::vector& input_data = *input_tensor.as(); - std::vector output_data(input_data.size()); - dnnl::memory src_mem = dnnl::memory(memory_desc_, *engine_, - const_cast(input_data.data())); - dnnl::memory dst_mem = - dnnl::memory(memory_desc_, *engine_, output_data.data()); - eltwise_prim_->execute(*stream_, - {{DNNL_ARG_SRC, src_mem}, {DNNL_ARG_DST, dst_mem}}); - stream_->wait(); - output[0] = make_tensor(output_data, input_tensor.get_shape()); + if (data_type == Type::kFloat) { + const std::vector& input_data = *input_tensor.as(); + std::vector output_data(input_data.size()); + dnnl::memory src_mem = dnnl::memory( + memory_desc_, *engine_, const_cast(input_data.data())); + dnnl::memory dst_mem = + dnnl::memory(memory_desc_, *engine_, output_data.data()); + eltwise_prim_->execute( + *stream_, {{DNNL_ARG_SRC, src_mem}, {DNNL_ARG_DST, dst_mem}}); + stream_->wait(); + output[0] = make_tensor(output_data, input_tensor.get_shape()); + } else if (data_type == Type::kInt) { + const std::vector& input_data = *input_tensor.as(); + std::vector output_data(input_data.size()); + + std::vector float_input; + float_input.reserve(input_data.size()); + for (int val : input_data) { + float_input.push_back(static_cast(val)); + } + + std::vector float_output(input_data.size()); + + dnnl::memory src_mem = + dnnl::memory(memory_desc_, *engine_, float_input.data()); + dnnl::memory dst_mem = + dnnl::memory(memory_desc_, *engine_, float_output.data()); + eltwise_prim_->execute( + *stream_, {{DNNL_ARG_SRC, src_mem}, {DNNL_ARG_DST, dst_mem}}); + stream_->wait(); + + for (size_t i = 0; i < float_output.size(); ++i) { + output_data[i] = static_cast(std::round(float_output[i])); + } + output[0] = make_tensor(output_data, input_tensor.get_shape()); + } else { + throw std::runtime_error("EwLayerOneDnn: Unsupported data type"); + } } catch (const std::exception& e) { std::cerr << "oneDNN execution failed: " << e.what() << std::endl; @@ -36,17 +62,23 @@ void EWLayer_oneDNN::run(const std::vector& input, } } -void EWLayer_oneDNN::validate_input(const std::vector& input) const { +void EwLayerOneDnn::validate_input(const std::vector& input) const { if (input.size() != 1) { - throw std::runtime_error("EWLayer_oneDNN: Expected exactly 1 input tensor"); + throw std::runtime_error("EwLayerOneDnn: Expected exactly 1 input tensor"); } if (!is_function_supported(func_)) { throw std::invalid_argument("Unsupported function for oneDNN: " + func_); } + + Type data_type = input[0].get_type(); + if (data_type != Type::kFloat && data_type != Type::kInt) { + throw std::runtime_error( + "EwLayerOneDnn supports only float and int tensors"); + } } -void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { +void EwLayerOneDnn::initialize_onednn(const Shape& shape, Type data_type) { try { engine_ = std::make_unique(dnnl::engine::kind::cpu, 0); stream_ = std::make_unique(*engine_); @@ -55,6 +87,7 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { for (size_t i = 0; i < shape.dims(); i++) { dims.push_back(static_cast(shape.at(i))); } + dnnl::memory::format_tag format; switch (dims.size()) { case 1: @@ -77,16 +110,22 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { std::to_string(dims.size())); } - memory_desc_ = - dnnl::memory::desc(dims, dnnl::memory::data_type::f32, format); + dnnl::memory::data_type dnnl_data_type; + if (data_type == Type::kFloat) { + dnnl_data_type = dnnl::memory::data_type::f32; + } else { + dnnl_data_type = dnnl::memory::data_type::f32; + } + + memory_desc_ = dnnl::memory::desc(dims, dnnl_data_type, format); dnnl::algorithm algo = get_algorithm(); - float primitive_alpha = 0.0f; - float primitive_beta = 0.0f; + float primitive_alpha = 0.0F; + float primitive_beta = 0.0F; if (func_ == "relu") { - primitive_alpha = 0.0f; + primitive_alpha = 0.0F; } else if (func_ == "linear") { primitive_alpha = alpha_; primitive_beta = beta_; @@ -100,12 +139,6 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { initialized_ = true; - for (size_t i = 0; i < dims.size(); ++i) { - std::cout << dims[i]; - if (i < dims.size() - 1) std::cout << ", "; - } - std::cout << "]" << std::endl; - } catch (const std::exception& e) { std::cerr << "oneDNN initialization failed for function '" << func_ << "': " << e.what() << std::endl; @@ -113,21 +146,24 @@ void EWLayer_oneDNN::initialize_onednn(const Shape& shape) { } } -dnnl::algorithm EWLayer_oneDNN::get_algorithm() const { +dnnl::algorithm EwLayerOneDnn::get_algorithm() const { if (func_ == "relu") { return dnnl::algorithm::eltwise_relu; - } else if (func_ == "tanh") { + } + if (func_ == "tanh") { return dnnl::algorithm::eltwise_tanh; - } else if (func_ == "sigmoid") { + } + if (func_ == "sigmoid") { return dnnl::algorithm::eltwise_logistic; - } else if (func_ == "linear") { + } + if (func_ == "linear") { return dnnl::algorithm::eltwise_linear; - } else { - throw std::invalid_argument("Unsupported function for oneDNN: " + func_); } + + throw std::invalid_argument("Unsupported function for oneDNN: " + func_); } -bool EWLayer_oneDNN::is_function_supported(const std::string& function) { +bool EwLayerOneDnn::is_function_supported(const std::string& function) { return (function == "relu" || function == "tanh" || function == "sigmoid" || function == "linear"); } diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 2666cf229..2f791cae4 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -5,23 +5,23 @@ #include "gtest/gtest.h" #include "layers/EWLayer.hpp" -#include "layers_oneDNN/EWLayer_oneDNN.hpp" +#include "layers_oneDNN/EwLayer_oneDnn.hpp" using namespace it_lab_ai; TEST(ewlayer_onednn, supported_functions_check) { - EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("relu")); - EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("tanh")); - EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("sigmoid")); - EXPECT_TRUE(EWLayer_oneDNN::is_function_supported("linear")); - - EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("sin")); - EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("minus")); - EXPECT_FALSE(EWLayer_oneDNN::is_function_supported("nonexistent")); + EXPECT_TRUE(EwLayerOneDnn::is_function_supported("relu")); + EXPECT_TRUE(EwLayerOneDnn::is_function_supported("tanh")); + EXPECT_TRUE(EwLayerOneDnn::is_function_supported("sigmoid")); + EXPECT_TRUE(EwLayerOneDnn::is_function_supported("linear")); + + EXPECT_FALSE(EwLayerOneDnn::is_function_supported("sin")); + EXPECT_FALSE(EwLayerOneDnn::is_function_supported("minus")); + EXPECT_FALSE(EwLayerOneDnn::is_function_supported("nonexistent")); } TEST(ewlayer_onednn, relu_float) { - EWLayer_oneDNN layer("relu"); + EwLayerOneDnn layer("relu"); Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -2.0F}); Tensor output; @@ -38,8 +38,26 @@ TEST(ewlayer_onednn, relu_float) { } } +TEST(ewlayer_onednn, relu_int) { + EwLayerOneDnn layer("relu"); + + Tensor input = make_tensor({1, -1, 2, -2, 0, -5}); + Tensor output; + std::vector expected = {1, 0, 2, 0, 0, 0}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_EQ(output_data[i], expected[i]); + } +} + TEST(ewlayer_onednn, linear_float) { - EWLayer_oneDNN layer("linear", 2.0f, 0.0f); + EwLayerOneDnn layer("linear", 2.0f, 0.0f); Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -5.0F}); Tensor output; @@ -56,8 +74,26 @@ TEST(ewlayer_onednn, linear_float) { } } +TEST(ewlayer_onednn, linear_int) { + EwLayerOneDnn layer("linear", 2.0f, 1.0f); + + Tensor input = make_tensor({1, -1, 2, -5, 0}); + Tensor output; + std::vector expected = {3, -1, 5, -9, 1}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_EQ(output_data[i], expected[i]); + } +} + TEST(ewlayer_onednn, linear_with_bias_float) { - EWLayer_oneDNN layer("linear", 1.0f, -1.0f); + EwLayerOneDnn layer("linear", 1.0f, -1.0f); Tensor input = make_tensor({1.0F, -1.0F, 2.0F, -5.0F}); Tensor output; @@ -75,7 +111,7 @@ TEST(ewlayer_onednn, linear_with_bias_float) { } TEST(ewlayer_onednn, tanh_float) { - EWLayer_oneDNN layer("tanh"); + EwLayerOneDnn layer("tanh"); Tensor input = make_tensor({0.0F, 1.0F, -1.0F, 2.0F}); Tensor output; @@ -98,7 +134,7 @@ TEST(ewlayer_onednn, tanh_float) { } TEST(ewlayer_onednn, sigmoid_float) { - EWLayer_oneDNN layer("sigmoid"); + EwLayerOneDnn layer("sigmoid"); Tensor input = make_tensor({0.0F, 1.0F, -1.0F, 2.0F}); Tensor output; @@ -123,7 +159,7 @@ TEST(ewlayer_onednn, sigmoid_float) { TEST(ewlayer_onednn, multidim_tensor_relu) { Shape shape({1, 3, 2, 2}); - EWLayer_oneDNN layer("relu"); + EwLayerOneDnn layer("relu"); std::vector input_data(1 * 3 * 2 * 2); for (size_t i = 0; i < input_data.size(); i++) { @@ -146,8 +182,29 @@ TEST(ewlayer_onednn, multidim_tensor_relu) { } } +TEST(ewlayer_onednn, multidim_tensor_relu_int) { + Shape shape({2, 2, 2}); + + EwLayerOneDnn layer("relu"); + + std::vector input_data = {1, -1, 2, -2, 0, -3, 4, -4}; + Tensor input = make_tensor(input_data, shape); + Tensor output; + std::vector expected = {1, 0, 2, 0, 0, 0, 4, 0}; + + std::vector in{input}; + std::vector out{output}; + layer.run(in, out); + + auto output_data = *out[0].as(); + ASSERT_EQ(output_data.size(), expected.size()); + for (size_t i = 0; i < output_data.size(); i++) { + EXPECT_EQ(output_data[i], expected[i]); + } +} + TEST(ewlayer_onednn, compare_with_naive_relu) { - EWLayer_oneDNN onednn_layer("relu"); + EwLayerOneDnn onednn_layer("relu"); EWLayer naive_layer("relu"); From 0352eb96231341946ad5091a267aeec9feda6933 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 11:43:54 +0300 Subject: [PATCH 29/36] check evaluate --- .github/workflows/ci.yml | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d93239f2a..376adfbcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -340,12 +340,39 @@ jobs: export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" - echo "Running ACC evaluation..." - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist > accuracy.txt 2>&1 || \ - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" > accuracy.txt 2>&1 + echo "### Checking binary execution permissions ###" + ls -la "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" + file "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" + + echo "### Testing direct execution ###" + set +e + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --version > version_output.txt 2>&1 + VERSION_EXIT_CODE=$? + echo "Version command exit code: $VERSION_EXIT_CODE" + cat version_output.txt + + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --help > help_output.txt 2>&1 + HELP_EXIT_CODE=$? + echo "Help command exit code: $HELP_EXIT_CODE" + cat help_output.txt + + echo "### Running MNIST evaluation ###" + mkdir -p docs/mnist/mnist/test - echo "Evaluation output:" + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist > accuracy.txt 2>&1 + EVAL_EXIT_CODE=$? + echo "Evaluation exit code: $EVAL_EXIT_CODE" + + if [ $EVAL_EXIT_CODE -ne 0 ]; then + echo "Trying without --model parameter..." + "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" > accuracy.txt 2>&1 + EVAL_EXIT_CODE=$? + echo "Fallback evaluation exit code: $EVAL_EXIT_CODE" + fi + + echo "### Evaluation output ###" cat accuracy.txt + set -e - name: Extract accuracy value run: | From afbf56b3c0b8ffade3e9764528c5b1ea476d5f20 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 29 Oct 2025 12:05:32 +0300 Subject: [PATCH 30/36] add tests --- src/layers_oneDNN/EWLayer_oneDNN.cpp | 2 +- test/single_layer/test_ewlayer_onednn.cpp | 79 ++++++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/src/layers_oneDNN/EWLayer_oneDNN.cpp b/src/layers_oneDNN/EWLayer_oneDNN.cpp index c59346ca2..0381fac79 100644 --- a/src/layers_oneDNN/EWLayer_oneDNN.cpp +++ b/src/layers_oneDNN/EWLayer_oneDNN.cpp @@ -1,4 +1,4 @@ -#include "layers_oneDNN/EwLayer_oneDnn.hpp" +#include "layers_oneDNN/EWLayer_oneDNN.hpp" #include #include diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 2f791cae4..deda51d4f 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -5,7 +5,7 @@ #include "gtest/gtest.h" #include "layers/EWLayer.hpp" -#include "layers_oneDNN/EwLayer_oneDnn.hpp" +#include "layers_oneDNN/EwLayer_oneDNN.hpp" using namespace it_lab_ai; @@ -232,3 +232,80 @@ TEST(ewlayer_onednn, compare_with_naive_relu) { EXPECT_NEAR(onednn_result[i], naive_result[i], 1e-5); } } + +TEST(ewlayer_onednn, multiple_input_tensors) { + EwLayerOneDnn layer("relu"); + + Tensor input1 = make_tensor({1.0F, 2.0F}); + Tensor input2 = make_tensor({3.0F, 4.0F}); + Tensor output; + + std::vector in{input1, input2}; + std::vector out{output}; + + EXPECT_THROW({ layer.run(in, out); }, std::runtime_error); +} + +TEST(ewlayer_onednn, unsupported_function) { + EXPECT_THROW({ EwLayerOneDnn layer("unsupported_func"); }, + std::invalid_argument); +} + +TEST(ewlayer_onednn, unsupported_tensor_dimensionality) { + EwLayerOneDnn layer("relu"); + + Shape shape_6d({2, 3, 4, 5, 6, 7}); + std::vector data_6d(2 * 3 * 4 * 5 * 6 * 7, 1.0f); + Tensor input = make_tensor(data_6d, shape_6d); + + Tensor output; + std::vector in{input}; + std::vector out{output}; + + EXPECT_THROW({ layer.run(in, out); }, std::invalid_argument); +} + +TEST(ewlayer_onednn, empty_input_tensor) { + EwLayerOneDnn layer("relu"); + + Tensor input = make_tensor({}); + Tensor output; + std::vector in{input}; + std::vector out{output}; + EXPECT_NO_THROW({ layer.run(in, out); }); +} + +TEST(ewlayer_onednn, invalid_function_algorithm_mapping) { + EwLayerOneDnn layer("relu"); + EXPECT_THROW( + { + EwLayerOneDnn invalid_layer("invalid_function_123"); + Tensor input = make_tensor({1.0F}); + Tensor output; + std::vector in{input}; + std::vector out{output}; + invalid_layer.run(in, out); + }, + std::invalid_argument); +} + +TEST(ewlayer_onednn, initialization_failure_propagation) { + EwLayerOneDnn layer("relu"); + + Shape shape_7d({2, 2, 2, 2, 2, 2, 2}); + std::vector data_7d(128, 1.0f); + Tensor input = make_tensor(data_7d, shape_7d); + + Tensor output; + std::vector in{input}; + std::vector out{output}; + + try { + layer.run(in, out); + FAIL() << "Expected std::invalid_argument exception"; + } catch (const std::invalid_argument& e) { + EXPECT_NE(std::string(e.what()).find("dimensionality"), std::string::npos); + } catch (...) { + FAIL() << "Expected std::invalid_argument exception"; + } +} From 89ef1aee7ac3189ba40133e3417a17c04d9d0374 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 29 Oct 2025 12:14:29 +0300 Subject: [PATCH 31/36] fix --- test/single_layer/test_ewlayer_onednn.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index deda51d4f..93e5015f7 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -5,7 +5,7 @@ #include "gtest/gtest.h" #include "layers/EWLayer.hpp" -#include "layers_oneDNN/EwLayer_oneDNN.hpp" +#include "layers_oneDNN/EWLayer_oneDNN.hpp" using namespace it_lab_ai; @@ -246,11 +246,6 @@ TEST(ewlayer_onednn, multiple_input_tensors) { EXPECT_THROW({ layer.run(in, out); }, std::runtime_error); } -TEST(ewlayer_onednn, unsupported_function) { - EXPECT_THROW({ EwLayerOneDnn layer("unsupported_func"); }, - std::invalid_argument); -} - TEST(ewlayer_onednn, unsupported_tensor_dimensionality) { EwLayerOneDnn layer("relu"); From cc68ec8a8d064831d03c24eee450eed142982080 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 12:32:20 +0300 Subject: [PATCH 32/36] clean ci.yml --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 376adfbcb..26538f9b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,8 +92,6 @@ jobs: key: ccache-${{ github.job }} - name: Build run: | - export CMAKE_BUILD_PARALLEL_LEVEL=2 - export MAKEFLAGS="-j2" cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ @@ -254,7 +252,6 @@ jobs: - name: Set binary path id: set_eval_binary run: | - # Проверяем существует ли бинарник if [ -f "build/bin/ACC" ]; then echo "ACC binary found at build/bin/ACC" echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT From a4ce91e3ade5257cdf47c87a096c52af26a04e40 Mon Sep 17 00:00:00 2001 From: Semyon1104 Date: Wed, 29 Oct 2025 13:06:56 +0300 Subject: [PATCH 33/36] rename files --- app/Graph/build.hpp | 2 +- include/layers_oneDNN/{EWLayer_oneDNN.hpp => EWLayer.hpp} | 0 src/layers_oneDNN/{EWLayer_oneDNN.cpp => EWLayer.cpp} | 2 +- test/single_layer/test_ewlayer_onednn.cpp | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename include/layers_oneDNN/{EWLayer_oneDNN.hpp => EWLayer.hpp} (100%) rename src/layers_oneDNN/{EWLayer_oneDNN.cpp => EWLayer.cpp} (99%) diff --git a/app/Graph/build.hpp b/app/Graph/build.hpp index b863c1fcb..5d4d651e3 100644 --- a/app/Graph/build.hpp +++ b/app/Graph/build.hpp @@ -31,7 +31,7 @@ #include "layers/SplitLayer.hpp" #include "layers/Tensor.hpp" #include "layers/TransposeLayer.hpp" -#include "layers_oneDNN/EWLayer_oneDNN.hpp" +#include "layers_oneDNN/EWLayer.hpp" std::unordered_map model_paths = { {"alexnet_mnist", MODEL_PATH_H5}, diff --git a/include/layers_oneDNN/EWLayer_oneDNN.hpp b/include/layers_oneDNN/EWLayer.hpp similarity index 100% rename from include/layers_oneDNN/EWLayer_oneDNN.hpp rename to include/layers_oneDNN/EWLayer.hpp diff --git a/src/layers_oneDNN/EWLayer_oneDNN.cpp b/src/layers_oneDNN/EWLayer.cpp similarity index 99% rename from src/layers_oneDNN/EWLayer_oneDNN.cpp rename to src/layers_oneDNN/EWLayer.cpp index 0381fac79..fc838705b 100644 --- a/src/layers_oneDNN/EWLayer_oneDNN.cpp +++ b/src/layers_oneDNN/EWLayer.cpp @@ -1,4 +1,4 @@ -#include "layers_oneDNN/EWLayer_oneDNN.hpp" +#include "layers_oneDNN/EWLayer.hpp" #include #include diff --git a/test/single_layer/test_ewlayer_onednn.cpp b/test/single_layer/test_ewlayer_onednn.cpp index 93e5015f7..3b6ff3afb 100644 --- a/test/single_layer/test_ewlayer_onednn.cpp +++ b/test/single_layer/test_ewlayer_onednn.cpp @@ -5,7 +5,7 @@ #include "gtest/gtest.h" #include "layers/EWLayer.hpp" -#include "layers_oneDNN/EWLayer_oneDNN.hpp" +#include "layers_oneDNN/EWLayer.hpp" using namespace it_lab_ai; From 3566fd4284f3d23dfc62211f8664affc57499750 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 19:05:22 +0300 Subject: [PATCH 34/36] try macos --- .github/workflows/ci.yml | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 26538f9b7..48c723d14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -125,12 +125,23 @@ jobs: key: ccache-${{ github.job }} - name: Build run: | - cmake -S . -B build -G Ninja \ + OPENMP_PATH=$(brew --prefix libomp) + echo "OpenMP path: $OPENMP_PATH" + cmake -S . -B build -G Ninja \ -DCMAKE_C_COMPILER_LAUNCHER=ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ - -DCMAKE_C_FLAGS="-I$(brew --prefix libomp)/include" \ - -DCMAKE_CXX_FLAGS="-I$(brew --prefix libomp)/include" + -DCMAKE_PREFIX_PATH=$OPENMP_PATH \ + -DCMAKE_INCLUDE_PATH=$OPENMP_PATH/include \ + -DCMAKE_LIBRARY_PATH=$OPENMP_PATH/lib \ + -DOpenMP_C_FLAGS="-Xclang -fopenmp -I$OPENMP_PATH/include" \ + -DOpenMP_CXX_FLAGS="-Xclang -fopenmp -I$OPENMP_PATH/include" \ + -DOpenMP_C_LIB_NAMES="omp" \ + -DOpenMP_CXX_LIB_NAMES="omp" \ + -DOpenMP_omp_LIBRARY="$OPENMP_PATH/lib/libomp.dylib" cmake --build build --parallel + env: + LDFLAGS: "-L$(brew --prefix libomp)/lib" + CPPFLAGS: "-I$(brew --prefix libomp)/include" - name: Test run: cmake --build build -t test env: From c6ac48e7c34ce6b104eec56b13b0c1632ee908aa Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Wed, 29 Oct 2025 19:21:57 +0300 Subject: [PATCH 35/36] macos --- .github/workflows/ci.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48c723d14..b2ab4fd3e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: submodules: true - name: Install prerequisites run: | - brew install libomp + brew install libomp ninja brew link libomp --overwrite --force - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 @@ -137,10 +137,12 @@ jobs: -DOpenMP_CXX_FLAGS="-Xclang -fopenmp -I$OPENMP_PATH/include" \ -DOpenMP_C_LIB_NAMES="omp" \ -DOpenMP_CXX_LIB_NAMES="omp" \ - -DOpenMP_omp_LIBRARY="$OPENMP_PATH/lib/libomp.dylib" + -DOpenMP_omp_LIBRARY="$OPENMP_PATH/lib/libomp.dylib" \ + -DCMAKE_EXE_LINKER_FLAGS="-L$OPENMP_PATH/lib -lomp" \ + -DCMAKE_SHARED_LINKER_FLAGS="-L$OPENMP_PATH/lib -lomp" cmake --build build --parallel - env: - LDFLAGS: "-L$(brew --prefix libomp)/lib" + env: + LDFLAGS: "-L$(brew --prefix libomp)/lib -lomp" CPPFLAGS: "-I$(brew --prefix libomp)/include" - name: Test run: cmake --build build -t test From 24a4934b268b5916d3e927bfc2654878a76b5121 Mon Sep 17 00:00:00 2001 From: Semyon1104 <129722895+Semyon1104@users.noreply.github.com> Date: Sun, 2 Nov 2025 11:46:38 +0300 Subject: [PATCH 36/36] clean --- .github/workflows/ci.yml | 120 ++++----------------------------------- 1 file changed, 11 insertions(+), 109 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2ab4fd3e..79ec09682 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,19 +51,18 @@ jobs: cmake --build build --parallel env: CTEST_OUTPUT_ON_FAILURE: 1 - - name: Prepare OpenCV libs + - name: Prepare ALL libs run: | - mkdir -p build/bin/opencv_libs - cp -a build/3rdparty/opencv_build/lib/libopencv_* build/bin/opencv_libs/ - echo "Library permissions after copy:" - stat -c "%A %n" build/bin/opencv_libs/libopencv_imgcodecs.so* - + mkdir -p build/bin/all_libs + cp -a build/3rdparty/opencv_build/lib/* build/bin/all_libs/ 2>/dev/null || true + ldd build/bin/ACC | grep "=> /" | awk '{print $3}' | xargs -I {} cp {} build/bin/all_libs/ 2>/dev/null || true - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: mnist-${{ matrix.build_type }}${{ matrix.stats && '-stats' || '' }} path: | ${{ steps.set_binaries.outputs.ACC_BINARY }} + build/bin/all_libs/* build/bin/opencv_libs/* build/setenv.sh - name: Test @@ -251,41 +250,15 @@ jobs: name: mnist-RELEASE path: build/ - - name: Verify downloaded artifacts - run: | - echo "### Verifying downloaded artifacts ###" - echo "Current directory: $(pwd)" - echo "Build directory contents:" - ls -la build/ || echo "No build directory" - echo "Looking for ACC binary:" - find build/ -name "ACC" -type f 2>/dev/null || echo "ACC not found" - echo "Checking bin directory:" - ls -la build/bin/ 2>/dev/null || echo "No bin directory" - - name: Set binary path id: set_eval_binary run: | - if [ -f "build/bin/ACC" ]; then - echo "ACC binary found at build/bin/ACC" - echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT - else - echo "ERROR: ACC binary not found at build/bin/ACC" - echo "Available files:" - find build/ -type f -name "*" 2>/dev/null | head -20 - exit 1 - fi + echo "EVAL_BINARY=build/bin/ACC" >> $GITHUB_OUTPUT - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install -y \ - libgtk-3-0 \ - libtbb12 \ - libjpeg-dev \ - libpng-dev \ - libtiff-dev \ - libopenjp2-7 \ - libdnnl3 + sudo apt-get install -y libgtk-3-0 libtbb12 libjpeg-dev libpng-dev libtiff-dev libopenjp2-7 libdnnl3 sudo ldconfig - name: Generate model JSON @@ -307,88 +280,28 @@ jobs: - name: Download MNIST test dataset if: steps.cache-mnist.outputs.cache-hit != 'true' run: | - set -e mkdir -p docs/mnist/mnist/test - echo "Downloading test images..." wget -q https://github.com/DeepTrackAI/MNIST_dataset/archive/main.zip -O main.zip unzip -q main.zip cp MNIST_dataset-main/mnist/test/*.png docs/mnist/mnist/test/ rm -rf main.zip MNIST_dataset-main - echo "Downloaded $(ls docs/mnist/mnist/test | wc -l) images" - name: Prepare environment run: | - echo "### Preparing environment ###" - echo "Binary path: ${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" - - ls -la "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" chmod +x "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" + export LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH - export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu - echo "Final LD_LIBRARY_PATH: $LD_LIBRARY_PATH" - - - name: Verify library integrity - run: | - echo "### Library verification ###" - ls -la build/bin/opencv_libs/ || echo "No opencv_libs directory" - file build/bin/opencv_libs/libopencv_imgcodecs.so* 2>/dev/null | head -1 || echo "No opencv_imgcodecs library found" - - - name: Test binary execution - run: | - echo "### Testing binary execution ###" - export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu - - echo "Binary dependencies:" - ldd "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" 2>/dev/null || echo "ldd failed" - - echo "Testing help command:" - timeout 10s "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --help > /dev/null 2>&1 || echo "Help test completed" - - name: Run evaluation run: | - echo "### Running evaluation ###" - export LD_LIBRARY_PATH=$PWD/build/bin/opencv_libs:/usr/lib/x86_64-linux-gnu - echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" - - echo "### Checking binary execution permissions ###" - ls -la "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" - file "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" - - echo "### Testing direct execution ###" - set +e - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --version > version_output.txt 2>&1 - VERSION_EXIT_CODE=$? - echo "Version command exit code: $VERSION_EXIT_CODE" - cat version_output.txt - - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --help > help_output.txt 2>&1 - HELP_EXIT_CODE=$? - echo "Help command exit code: $HELP_EXIT_CODE" - cat help_output.txt - - echo "### Running MNIST evaluation ###" - mkdir -p docs/mnist/mnist/test - + export LD_LIBRARY_PATH=$PWD/build/bin/all_libs:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" --model alexnet_mnist > accuracy.txt 2>&1 - EVAL_EXIT_CODE=$? - echo "Evaluation exit code: $EVAL_EXIT_CODE" - - if [ $EVAL_EXIT_CODE -ne 0 ]; then - echo "Trying without --model parameter..." - "${{ steps.set_eval_binary.outputs.EVAL_BINARY }}" > accuracy.txt 2>&1 - EVAL_EXIT_CODE=$? - echo "Fallback evaluation exit code: $EVAL_EXIT_CODE" + if [ $? -ne 0 ]; then + exit 1 fi - - echo "### Evaluation output ###" - cat accuracy.txt - set -e - name: Extract accuracy value run: | - echo "### Extracting accuracy ###" ACCURACY=$(grep -oE '[0-9]+\.?[0-9]*%' accuracy.txt | head -1 || echo "0%") - echo "Accuracy: $ACCURACY" echo "$ACCURACY" > accuracy_value.txt - name: Update README (master only) @@ -396,28 +309,17 @@ jobs: run: | ACCURACY=$(cat accuracy_value.txt | sed 's/%//g') DATE=$(date '+%Y-%m-%d') - - echo "Updating README with:" - echo "Accuracy: $ACCURACY%" - echo "Date: $DATE" - sed -i "s/.*/Accuracy: ${ACCURACY}% (updated: ${DATE})/" README.md - - echo "Updated README content:" - grep -A 2 -B 2 "ACCURACY_PLACEHOLDER" README.md - name: Commit and push changes (master only) if: github.ref == 'refs/heads/master' run: | git config --global user.name "GitHub Actions" git config --global user.email "actions@github.com" - git add README.md - if git diff-index --quiet HEAD --; then echo "No changes to commit" else git commit -m "[CI] Update accuracy: $(cat accuracy_value.txt)" git push origin master - echo "Changes pushed to master branch" fi