Spaces:
Build error
Build error
/* | |
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
* SPDX-License-Identifier: Apache-2.0 | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** @file common_host.h | |
* @author Thomas Müller, NVIDIA | |
* @brief Shared functionality among multiple neural-graphics-primitives components. | |
*/ | |
namespace ngp { | |
namespace fs = filesystem; | |
bool is_wsl(); | |
fs::path discover_executable_dir(); | |
fs::path discover_root_dir(); | |
std::string utf16_to_utf8(const std::wstring& utf16); | |
std::wstring utf8_to_utf16(const std::string& utf16); | |
std::wstring native_string(const fs::path& path); | |
std::string native_string(const fs::path& path); | |
bool ends_with(const std::string& str, const std::string& ending); | |
bool ends_with_case_insensitive(const std::string& str, const std::string& ending); | |
ETestbedMode mode_from_scene(const std::string& scene); | |
ETestbedMode mode_from_string(const std::string& str); | |
std::string to_string(ETestbedMode); | |
inline std::string replace_all(std::string str, const std::string& a, const std::string& b) { | |
std::string::size_type n = 0; | |
while ((n = str.find(a, n)) != std::string::npos) { | |
str.replace(n, a.length(), b); | |
n += b.length(); | |
} | |
return str; | |
} | |
template <typename T> T snap_to_nearest(T val, const std::vector<T>& candidates) { | |
T best_dist = std::numeric_limits<T>::max(); | |
T result = candidates.empty() ? val : candidates[0]; | |
for (T c : candidates) { | |
T dist = abs(val - c); | |
if (dist < best_dist) { | |
best_dist = dist; | |
result = c; | |
} | |
} | |
return result; | |
} | |
enum class EEmaType { | |
Time, | |
Step, | |
}; | |
template <typename T> class Ema { | |
public: | |
Ema(EEmaType type, float half_life) : | |
m_type{type}, m_decay{std::pow(0.5f, 1.0f / max(half_life, 0.000001f))}, m_creation_time{std::chrono::steady_clock::now()} {} | |
int64_t current_progress() { | |
if (m_type == EEmaType::Time) { | |
auto now = std::chrono::steady_clock::now(); | |
return std::chrono::duration_cast<std::chrono::milliseconds>(now - m_creation_time).count(); | |
} else { | |
return m_last_progress + 1; | |
} | |
} | |
void update(const T& val) { | |
int64_t cur = current_progress(); | |
int64_t elapsed = cur - m_last_progress; | |
m_last_progress = cur; | |
float decay = std::pow(m_decay, elapsed); | |
m_val = val; | |
m_ema_val = decay * m_ema_val + (1.0f - decay) * val; | |
} | |
void set(const T& val) { | |
m_last_progress = current_progress(); | |
m_val = m_ema_val = val; | |
} | |
T val() const { return m_val; } | |
T ema_val() const { return m_ema_val; } | |
private: | |
T m_val = 0.0f; | |
T m_ema_val = 0.0f; | |
EEmaType m_type; | |
float m_decay; | |
int64_t m_last_progress = 0; | |
std::chrono::time_point<std::chrono::steady_clock> m_creation_time; | |
}; | |
uint8_t* load_stbi(const fs::path& path, int* width, int* height, int* comp, int req_comp); | |
float* load_stbi_float(const fs::path& path, int* width, int* height, int* comp, int req_comp); | |
uint16_t* load_stbi_16(const fs::path& path, int* width, int* height, int* comp, int req_comp); | |
bool is_hdr_stbi(const fs::path& path); | |
int write_stbi(const fs::path& path, int width, int height, int comp, const uint8_t* pixels, int quality = 100); | |
FILE* native_fopen(const fs::path& path, const char* mode); | |
GPUMemory<float> load_exr_gpu(const fs::path& path, int* width, int* height); | |
GPUMemory<float> load_stbi_gpu(const fs::path& path, int* width, int* height); | |
template <typename T> class Buffer2D { | |
public: | |
Buffer2D() = default; | |
Buffer2D(const ivec2& resolution) { resize(resolution); } | |
T* data() const { return m_data.data(); } | |
size_t bytes() const { return m_data.bytes(); } | |
void resize(const ivec2& resolution) { | |
m_data.resize(product(resolution)); | |
m_resolution = resolution; | |
} | |
const ivec2& resolution() const { return m_resolution; } | |
Buffer2DView<T> view() const { | |
// Row major for now. | |
return {data(), m_resolution}; | |
} | |
Buffer2DView<const T> const_view() const { | |
// Row major for now. | |
return {data(), m_resolution}; | |
} | |
private: | |
GPUMemory<T> m_data; | |
ivec2 m_resolution; | |
}; | |
template <typename T> struct GPUImage { | |
GPUImage() : image{}, padding{0} {} | |
GPUImage(ivec2 resolution, uint32_t padding, cudaStream_t stream) : | |
image{resolution.y + padding * 2, resolution.x + padding * 2, stream}, padding{padding} {} | |
GPUImage(ivec2 resolution, cudaStream_t stream) : GPUImage(resolution, 0, stream) {} | |
MatrixView<T> view() const { return image.slice(padding, image.m() - 2 * padding, padding, image.n() - 2 * padding).view(); } | |
T* data() const { return image.data(); } | |
size_t n_elements_padded() const { return image.n_elements(); } | |
size_t n_elements() const { return product(resolution()); } | |
ivec2 resolution_padded() const { return {(int)image.n(), (int)image.m()}; } | |
ivec2 resolution() const { return {(int)(image.n() - 2 * padding), (int)(image.m() - 2 * padding)}; } | |
explicit operator bool() const { return image.data() != nullptr; } | |
GPUMatrix<T, RM> image; | |
uint32_t padding; | |
}; | |
struct BoundingBox; | |
struct Triangle; | |
std::ostream& operator<<(std::ostream& os, const BoundingBox& triangle); | |
std::ostream& operator<<(std::ostream& os, const Triangle& triangle); | |
} // namespace ngp | |