Skip to content

Commit fd92730

Browse files
Merge pull request #161 from Devsh-Graphics-Programming/yas_jpeg_benchmark
Yas jpeg benchmark
2 parents fc629be + ed112d1 commit fd92730

File tree

4 files changed

+271
-0
lines changed

4 files changed

+271
-0
lines changed

68_JpegLoading/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
include(common RESULT_VARIABLE RES)
2+
if(NOT RES)
3+
message(FATAL_ERROR "common.cmake not found. Should be in {repo_root}/cmake directory")
4+
endif()
5+
6+
nbl_create_executable_project("" "" "" "" "${NBL_EXECUTABLE_PROJECT_CREATION_PCH_TARGET}")
7+
8+
if(NBL_EMBED_BUILTIN_RESOURCES)
9+
set(_BR_TARGET_ ${EXECUTABLE_NAME}_builtinResourceData)
10+
set(RESOURCE_DIR "app_resources")
11+
12+
get_filename_component(_SEARCH_DIRECTORIES_ "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
13+
get_filename_component(_OUTPUT_DIRECTORY_SOURCE_ "${CMAKE_CURRENT_BINARY_DIR}/src" ABSOLUTE)
14+
get_filename_component(_OUTPUT_DIRECTORY_HEADER_ "${CMAKE_CURRENT_BINARY_DIR}/include" ABSOLUTE)
15+
16+
file(GLOB_RECURSE BUILTIN_RESOURCE_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_DIR}" CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_DIR}/*")
17+
foreach(RES_FILE ${BUILTIN_RESOURCE_FILES})
18+
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "${RES_FILE}")
19+
endforeach()
20+
21+
ADD_CUSTOM_BUILTIN_RESOURCES(${_BR_TARGET_} RESOURCES_TO_EMBED "${_SEARCH_DIRECTORIES_}" "${RESOURCE_DIR}" "nbl::this_example::builtin" "${_OUTPUT_DIRECTORY_HEADER_}" "${_OUTPUT_DIRECTORY_SOURCE_}")
22+
23+
LINK_BUILTIN_RESOURCES_TO_TARGET(${EXECUTABLE_NAME} ${_BR_TARGET_})
24+
endif()
25+
26+
add_dependencies(${EXECUTABLE_NAME} argparse)
27+
target_include_directories(${EXECUTABLE_NAME} PUBLIC $<TARGET_PROPERTY:argparse,INTERFACE_INCLUDE_DIRECTORIES>)

68_JpegLoading/main.cpp

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// Copyright (C) 2018-2024 - DevSH GrapMonoAssetManagerAndBuiltinResourceApplicationhics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#include "nbl/application_templates/MonoAssetManagerAndBuiltinResourceApplication.hpp"
5+
6+
#include <future>
7+
8+
#include "nlohmann/json.hpp"
9+
#include "argparse/argparse.hpp"
10+
11+
using json = nlohmann::json;
12+
13+
using namespace nbl;
14+
using namespace core;
15+
using namespace hlsl;
16+
using namespace system;
17+
using namespace asset;
18+
using namespace ui;
19+
using namespace video;
20+
21+
class ThreadPool
22+
{
23+
using task_t = std::function<void()>;
24+
public:
25+
ThreadPool(size_t workers = std::thread::hardware_concurrency())
26+
{
27+
for (size_t i = 0; i < workers; i++)
28+
{
29+
m_workers.emplace_back([this] {
30+
task_t task;
31+
32+
while (1)
33+
{
34+
{
35+
std::unique_lock<std::mutex> lock(m_queueLock);
36+
m_taskAvailable.wait(lock, [this] { return !m_tasks.empty() || m_shouldStop; });
37+
38+
if (m_shouldStop && m_tasks.empty()) {
39+
return;
40+
}
41+
42+
task = std::move(m_tasks.front());
43+
m_tasks.pop();
44+
}
45+
46+
task();
47+
}
48+
});
49+
}
50+
}
51+
52+
~ThreadPool()
53+
{
54+
m_shouldStop = true;
55+
m_taskAvailable.notify_all();
56+
57+
for (auto& worker : m_workers)
58+
{
59+
worker.join();
60+
}
61+
}
62+
63+
void enqueue(task_t task)
64+
{
65+
{
66+
std::lock_guard<std::mutex> lock(m_queueLock);
67+
m_tasks.emplace(std::move(task));
68+
}
69+
m_taskAvailable.notify_one();
70+
}
71+
private:
72+
std::mutex m_queueLock;
73+
std::condition_variable m_taskAvailable;
74+
std::vector<std::thread> m_workers;
75+
std::queue<task_t> m_tasks;
76+
std::atomic<bool> m_shouldStop = false;
77+
};
78+
79+
class JpegLoaderApp final : public application_templates::MonoAssetManagerAndBuiltinResourceApplication
80+
{
81+
using clock_t = std::chrono::steady_clock;
82+
using clock_resolution_t = std::chrono::milliseconds;
83+
using base_t = application_templates::MonoAssetManagerAndBuiltinResourceApplication;
84+
public:
85+
using base_t::base_t;
86+
87+
inline bool onAppInitialized(smart_refctd_ptr<ISystem>&& system) override
88+
{
89+
argparse::ArgumentParser program("Color Space");
90+
91+
program.add_argument<std::string>("--directory")
92+
.required()
93+
.help("Path to a directory where all JPEG files are stored (not recursive)");
94+
95+
program.add_argument<std::string>("--output")
96+
.default_value("output.json")
97+
.help("Path to the file where the benchmark result will be stored");
98+
99+
try
100+
{
101+
program.parse_args({ argv.data(), argv.data() + argv.size() });
102+
}
103+
catch (const std::exception& err)
104+
{
105+
std::cerr << err.what() << std::endl << program; // NOTE: std::cerr because logger isn't initialized yet
106+
return false;
107+
}
108+
109+
if (!base_t::onAppInitialized(std::move(system)))
110+
return false;
111+
112+
options.directory = program.get<std::string>("--directory");
113+
options.outputFile = program.get<std::string>("--output");
114+
115+
// check if directory exists
116+
if (!std::filesystem::exists(options.directory))
117+
{
118+
logFail("Provided directory doesn't exist");
119+
return false;
120+
}
121+
122+
auto start = clock_t::now();
123+
std::vector<std::string> files;
124+
125+
{
126+
ThreadPool tp;
127+
128+
constexpr auto cachingFlags = static_cast<IAssetLoader::E_CACHING_FLAGS>(IAssetLoader::ECF_DONT_CACHE_REFERENCES & IAssetLoader::ECF_DONT_CACHE_TOP_LEVEL);
129+
const IAssetLoader::SAssetLoadParams loadParams(0ull, nullptr, cachingFlags, IAssetLoader::ELPF_NONE, m_logger.get());
130+
131+
for (auto& item : std::filesystem::directory_iterator(options.directory))
132+
{
133+
auto& path = item.path();
134+
if (path.has_extension() && path.extension() == ".jpg")
135+
{
136+
files.emplace_back(std::move(path.generic_string()));
137+
138+
ISystem::future_t<smart_refctd_ptr<system::IFile>> future;
139+
m_system->createFile(future, path, IFile::ECF_READ | IFile::ECF_MAPPABLE);
140+
141+
if (auto pFile = future.acquire(); pFile && pFile->get())
142+
{
143+
auto& file = *pFile;
144+
tp.enqueue([=] {
145+
m_logger->log("Loading %S", ILogger::ELL_INFO, path.c_str());
146+
m_assetMgr->getAsset(file.get(), path.generic_string(), loadParams);
147+
});
148+
}
149+
}
150+
}
151+
}
152+
153+
auto stop = clock_t::now();
154+
auto time = std::chrono::duration_cast<clock_resolution_t>(stop - start).count();
155+
156+
m_logger->log("Process took %llu ms", ILogger::ELL_INFO, time);
157+
158+
// Dump data to JSON
159+
json j;
160+
j["loaded_files"] = files;
161+
j["duration_ms"] = time;
162+
163+
std::ofstream output(options.outputFile);
164+
if (!output.good())
165+
{
166+
logFail("Failed to open %S", options.outputFile);
167+
return false;
168+
}
169+
170+
output << j;
171+
172+
return true;
173+
}
174+
175+
inline bool keepRunning() override
176+
{
177+
return false;
178+
}
179+
180+
inline void workLoopBody() override
181+
{
182+
183+
}
184+
185+
private:
186+
struct NBL_APP_OPTIONS
187+
{
188+
std::string directory;
189+
std::string outputFile;
190+
} options;
191+
};
192+
193+
NBL_MAIN_FUNC(JpegLoaderApp)

68_JpegLoading/pipeline.groovy

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import org.DevshGraphicsProgramming.Agent
2+
import org.DevshGraphicsProgramming.BuilderInfo
3+
import org.DevshGraphicsProgramming.IBuilder
4+
5+
class CJpegLoading extends IBuilder
6+
{
7+
public CJpegLoading(Agent _agent, _info)
8+
{
9+
super(_agent, _info)
10+
}
11+
12+
@Override
13+
public boolean prepare(Map axisMapping)
14+
{
15+
return true
16+
}
17+
18+
@Override
19+
public boolean build(Map axisMapping)
20+
{
21+
IBuilder.CONFIGURATION config = axisMapping.get("CONFIGURATION")
22+
IBuilder.BUILD_TYPE buildType = axisMapping.get("BUILD_TYPE")
23+
24+
def nameOfBuildDirectory = getNameOfBuildDirectory(buildType)
25+
def nameOfConfig = getNameOfConfig(config)
26+
27+
agent.execute("cmake --build ${info.rootProjectPath}/${nameOfBuildDirectory}/${info.targetProjectPathRelativeToRoot} --target ${info.targetBaseName} --config ${nameOfConfig} -j12 -v")
28+
29+
return true
30+
}
31+
32+
@Override
33+
public boolean test(Map axisMapping)
34+
{
35+
return true
36+
}
37+
38+
@Override
39+
public boolean install(Map axisMapping)
40+
{
41+
return true
42+
}
43+
}
44+
45+
def create(Agent _agent, _info)
46+
{
47+
return new CJpegLoading(_agent, _info)
48+
}
49+
50+
return this

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ if(NBL_BUILD_EXAMPLES)
9292
add_subdirectory(0_ImportanceSamplingEnvMaps EXCLUDE_FROM_ALL) #TODO: integrate back into 42
9393

9494
add_subdirectory(67_RayQueryGeometry EXCLUDE_FROM_ALL)
95+
add_subdirectory(68_JpegLoading EXCLUDE_FROM_ALL)
9596

9697
add_subdirectory(70_FLIPFluids EXCLUDE_FROM_ALL)
9798

0 commit comments

Comments
 (0)