342 add compiler directives and optimized instructions to cxp functions - #345
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR enhances the library’s constexpr math and saturate behavior (including CUDA/host paths) and adds/updates unit tests to validate bit-exact results and edge cases.
Changes:
- Expanded
constexpr_cmathwith constexpr-capableisnan/isinf,signbit, improvedround/floor/nearbyint, updatedfmax/fmin, and added “universal” comparison helpers. - Refactored saturate logic by introducing
cxp::saturate_floatand wiring it into the image-processingSaturateop. - Added new utests for
saturate_floatand bit-exactexpf, plus expanded cmath-related test coverage.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
utests/core/constexpr_libs/utest_constexpr_saturate.h |
New compile-time + runtime tests for cxp::saturate_float. |
utests/core/constexpr_libs/utest_constexpr_expf_exact.h |
New bit-exact constexpr + runtime verification for cxp::expf. |
utests/core/constexpr_libs/utest_constexpr_cmath.h |
Expanded/adjusted constexpr and runtime coverage for new cmath behaviors. |
utests/algorithm/image_processing/utest_saturate/utest_saturate_common.h |
Updates min-value expectation logic to use universal comparator. |
include/fused_kernel/core/constexpr_libs/constexpr_saturate.h |
Refactor + new saturate_float implementation and helper macro. |
include/fused_kernel/core/constexpr_libs/constexpr_cmath.h |
Major constexpr math improvements and API additions/aliases. |
include/fused_kernel/algorithms/image_processing/saturate.h |
Uses cxp::saturate_float instead of manual clamp. |
include/fused_kernel/algorithms/image_processing/morphology.h |
Adjusts constexpr macro for host/device usage. |
.github/copilot-instructions.md |
Updates documentation, but formatting/code fences look broken in this diff. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated 4 comments.
Suppressed comments (2)
utests/core/constexpr_libs/utest_constexpr_cmath.h:221
test_cmp_less_equal()(and its comment) now testscmp_less_equal_u, notcmp_less_equal. Since you addedtest_cmp_less_equal_only_ct()later for direct coverage, consider renaming this function/comment to reflect what it actually validates (e.g.,test_cmp_less_equal_u) to avoid confusion and keep the test intent clear.
// Test cmp_less_equal function
constexpr bool test_cmp_less_equal() {
static_assert(cxp::cmp_less_equal_u::f(4, 5), "4 <= 5 should be true");
static_assert(cxp::cmp_less_equal_u::f(5, 5), "5 <= 5 should be true");
static_assert(!cxp::cmp_less_equal_u::f(5, 4), "5 <= 4 should be false");
static_assert(cxp::cmp_less_equal_u::f(-1, 5u), "-1 <= 5u should be true");
static_assert(cxp::cmp_less_equal_u::f(0, 0u), "0 <= 0u should be true");
.github/copilot-instructions.md:116
- This edit breaks Markdown formatting: text that should be separated by newlines/code fences is concatenated (
... returning intimmediately followed by#include ..., and}immediately followed byFiles ending ...). Please restore proper newlines and fenced code blocks so the instructions render correctly in GitHub.
Every test header must define a `launch()` function returning `int`:#include <tests/main.h>
#include <fused_kernel/fused_kernel.h>
// ... other FKL headers
int launch() {
// test code here
return 0; // 0 = pass, non-zero = fail
}Files ending in `_common.h` (matching `*_common.*`) are shared helpers, not test entry points — they are excluded from test discovery.
| static_assert(std::is_same_v<decltype(cxp::saturate_float::f(0.5f)), float>, | ||
| "saturate_float should return float"); |
Add repository layout section with directory structure.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated 7 comments.
Suppressed comments (7)
utests/core/constexpr_libs/utest_constexpr_saturate.h:20
- This test header uses
std::is_same_vbut does not include<type_traits>, which can cause compilation failures depending on transitive includes. Add#include <type_traits>to make the test self-contained (and consistent with other utests).
#include <fused_kernel/core/constexpr_libs/constexpr_saturate.h>
#include <limits>
#include <iostream>
utests/core/constexpr_libs/utest_constexpr_saturate.h:60
- This test header uses
std::is_same_vbut does not include<type_traits>, which can cause compilation failures depending on transitive includes. Add#include <type_traits>to make the test self-contained (and consistent with other utests).
static_assert(std::is_same_v<decltype(cxp::saturate_float::f(0.5f)), float>,
"saturate_float should return float");
utests/core/constexpr_libs/utest_constexpr_saturate.h:17
- Other utest headers consistently include
<tests/main.h>(per repository conventions) to integrate with the test harness/autodiscovery. Consider adding#include <tests/main.h>at the top to align with the project’s test entrypoint pattern and avoid harness/tooling assumptions about required includes.
#ifndef FK_TEST_CONSTEXPR_SATURATE_H
#define FK_TEST_CONSTEXPR_SATURATE_H
#include <fused_kernel/core/constexpr_libs/constexpr_saturate.h>
#include <limits>
#include <iostream>
utests/core/constexpr_libs/utest_constexpr_expf_exact.h:14
- This test relies on the project-specific
uintalias, even though the file already includes<cstdint>. To make the test more self-contained and unambiguous across toolchains, consider switching these touint32_t(and updatingbit_casttargets accordingly).
template <uint Bits>
struct CtExp {
static constexpr float value = cxp::expf::f(cxp::bit_cast<float>(Bits));
static constexpr uint bits = cxp::bit_cast<uint>(value);
};
utests/core/constexpr_libs/utest_constexpr_expf_exact.h:49
- This test relies on the project-specific
uintalias, even though the file already includes<cstdint>. To make the test more self-contained and unambiguous across toolchains, consider switching these touint32_t(and updatingbit_casttargets accordingly).
constexpr uint inputs[] = {0x00000000u, 0x80000000u, 0x39C6BE5Bu, 0x3F800000u, 0xBF800000u,
0x40000000u, 0xC0000000u, 0x42AF0000u, 0x42B17214u, 0xC2AF0000u,
0xC2C60000u, 0x42B17218u, 0xC2D20000u};
utests/core/constexpr_libs/utest_constexpr_cmath.h:221
- The function
test_cmp_less_equal()now testscmp_less_equal_urather thancmp_less_equal, which is confusing when scanning failures and coverage. Consider renaming this test function totest_cmp_less_equal_u()(or similar) to match what it validates.
constexpr bool test_cmp_less_equal() {
static_assert(cxp::cmp_less_equal_u::f(4, 5), "4 <= 5 should be true");
static_assert(cxp::cmp_less_equal_u::f(5, 5), "5 <= 5 should be true");
static_assert(!cxp::cmp_less_equal_u::f(5, 4), "5 <= 4 should be false");
static_assert(cxp::cmp_less_equal_u::f(-1, 5u), "-1 <= 5u should be true");
static_assert(cxp::cmp_less_equal_u::f(0, 0u), "0 <= 0u should be true");
include/fused_kernel/core/constexpr_libs/constexpr_cmath.h:99
- The
CXP_F_FUNCwrapper now takes all arguments by value, which can introduce unnecessary copies (especially for vector types) and can inhibit passing non-trivially-copyable types if they appear in the future. Consider switching back toconst Types&...or using forwarding references (Types&&...withstd::forward) to avoid copies while preserving call-site ergonomics.
#define CXP_F_FUNC \
template <typename... Types> \
FK_HOST_DEVICE_FUSE auto f(const Types... vals) { \
return Exec<BaseFunc>::exec(vals...); \
}
| ### Configure and Build (typical) | ||
| ```bash | ||
| # Linux (Ninja) | ||
| cmake -G "Ninja" -B build -DCMAKE_BUILD_TYPE=Release -S . | ||
| cmake --build build --config Release | ||
| cmake --build build --config Release --parallel 32 | ||
|
|
||
| # Windows (Ninja, inside VS Developer Shell) | ||
| cmake -G "Ninja" -B build -DCMAKE_BUILD_TYPE=Release -S . | ||
| cmake --build build --config Release | ||
| ``` | ||
| cmake --build build --config Release --parallel 32 |
| Every test header must define a `launch()` function returning `int`: | ||
| ```cpp | ||
| #include <tests/main.h> | ||
| Every test header must define a `launch()` function returning `int`:#include <tests/main.h> |
| ``` | ||
|
|
||
| Files ending in `_common.h` (matching `*_common.*`) are shared helpers, not test entry points — they are excluded from test discovery. | ||
| }Files ending in `_common.h` (matching `*_common.*`) are shared helpers, not test entry points — they are excluded from test discovery. |
| The library defines CUDA-compatible type aliases (also available in CPU mode): | ||
| ```cpp | ||
| using uchar = unsigned char; | ||
| The library defines CUDA-compatible type aliases (also available in CPU mode):using uchar = unsigned char; |
| ``` | ||
|
|
||
| ### CUDA Error Checking | ||
| using ulonglong = unsigned long long;### CUDA Error Checking |
| The primary entry point is `fk::executeOperations<DPPType>(stream, op1, op2, ...)`: | ||
| ```cpp | ||
| #include <fused_kernel/fused_kernel.h> | ||
| The primary entry point is `fk::executeOperations<DPPType>(stream, op1, op2, ...)`:#include <fused_kernel/fused_kernel.h> |
| ``` | ||
|
|
||
| ### Operation Building Pattern | ||
| stream.sync();### Operation Building Pattern |
…to-cxp-functions' of https://github.com/Libraries-Openly-Fused/FusedKernelLibrary into 342-add-compiler-directives-and-optimized-instructions-to-cxp-functions
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.github/copilot-instructions.md:118
- The markdown formatting is broken: code fences were removed and multiple sentences/code tokens were concatenated onto single lines (e.g.,
...int:#include ...and}Files ending...`). Please restore proper fenced code blocks and line breaks so the instructions render correctly and remain copy/pasteable.
Every test header must define a `launch()` function returning `int`:#include <tests/main.h>
#include <fused_kernel/fused_kernel.h>
// ... other FKL headers
int launch() {
// test code here
return 0; // 0 = pass, non-zero = fail
}Files ending in `_common.h` (matching `*_common.*`) are shared helpers, not test entry points — they are excluded from test discovery.
utests/core/constexpr_libs/utest_constexpr_saturate.h:20
- This test uses
std::is_same_vlater but does not include<type_traits>, which can cause non-portable builds depending on transitive includes. Add#include <type_traits>explicitly (and consider including<tests/main.h>as done in other utest headers, if the test harness expects it).
#include <fused_kernel/core/constexpr_libs/constexpr_saturate.h>
#include <limits>
#include <iostream>
utests/core/constexpr_libs/utest_constexpr_expf_exact.h:65
- Hardcoding
std::expbit patterns intostatic_asserts is inherently platform/libm/compiler-flag dependent, so this can fail at compile time on legitimate platforms (even though your runtime re-check would have caught drift). To improve portability, consider limiting compile-timestatic_asserts to platform-invariant identities (e.g., exp(0)=1, monotonicity, overflow/underflow behavior), and keep the bit-exactstd::expcomparison as runtime-only (or gate the bit-exact compile-time asserts behind a platform/stdlib check).
// The constexpr path of cxp::expf must be bit identical to std::exp on a float input.
// The expected bit patterns below were produced by std::exp and are checked against it
// again at runtime, so a divergence on either side is caught.
#define CHECK_CT_EXPF(inBits, outBits) \
static_assert(CtExp<inBits>::bits == outBits, "constexpr expf must match std::exp bit for bit")
include/fused_kernel/core/constexpr_libs/constexpr_saturate.h:25
- This header defines
CXP_F_FUNCafter includingconstexpr_cmath.h, which also defines aCXP_F_FUNCmacro. Even if the replacement text is identical, this pattern can trigger macro-redefinition warnings (often promoted to errors) and makes include order fragile. Prefer a header-specific macro name (e.g.,CXP_SATURATE_F_FUNC), or#undef CXP_F_FUNCbefore redefining (and ideally avoid cross-header macros by using a small helper base class/template instead).
#include <fused_kernel/core/constexpr_libs/constexpr_cmath.h>
#include <fused_kernel/core/constexpr_libs/constexpr_vector_exec.h>
#define CXP_F_FUNC \
template <typename... Types> FK_HOST_DEVICE_FUSE auto f(const Types... vals) { \
return Exec<BaseFunc>::exec(vals...); \
}
No description provided.