Skip to content

[CTL] Add support for defaults #1216

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

KFilipek
Copy link
Contributor

@KFilipek KFilipek commented Mar 21, 2025

[CTL] Add support for defaults

Description

This PR introduces initial support for setting up default values.

Checklist

  • Code compiles without errors locally
  • All tests pass locally
  • CI workflows execute properly

@KFilipek KFilipek added the enhancement New feature or request label Mar 21, 2025
@KFilipek KFilipek self-assigned this Mar 21, 2025
@KFilipek KFilipek linked an issue Mar 21, 2025 that may be closed by this pull request
@KFilipek KFilipek force-pushed the ctl-default branch 5 times, most recently from 2ec6659 to 408f2c4 Compare March 24, 2025 08:16
@KFilipek KFilipek marked this pull request as ready for review March 24, 2025 09:43
@KFilipek KFilipek requested a review from a team as a code owner March 24, 2025 09:43
umf_os_memory_provider_params_handle_t os_memory_provider_params = NULL;
umf_memory_provider_ops_t *os_provider_ops = umfOsMemoryProviderOps();
if (os_provider_ops == NULL) {
GTEST_SKIP() << "OS memory provider is not supported!";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding such skip msg, I guess we should add this test in CMake only when OS prov and disjoint pool are enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's what for we've added a dummy function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yy? not sure what you mean

@@ -35,7 +35,7 @@ TEST_F(test, ctl_by_handle_os_provider) {

int ipc_enabled = 0xBAD;
ret = umfCtlGet("umf.provider.by_handle.params.ipc_enabled", hProvider,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have any test for umfCtlGet that pass something else than 0?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I see it's not a part of this PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're adding a new paramter and without testing values other than 0 it's not properly tested. At least mark in tests a TODO for future.

Copy link
Contributor Author

@KFilipek KFilipek Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This callback discard completely size, so such test will cover completely nothing and will test nothing.

static int CTL_READ_HANDLER(ipc_enabled)(void *ctx,
                                         umf_ctl_query_source_t source,
                                         void *arg, size_t size,
                                         umf_ctl_index_utlist_t *indexes,
                                         const char *extra_name,
                                         umf_ctl_query_type_t query_type) {
    /* suppress unused-parameter errors */
    (void)source, (void)indexes, (void)ctx, (void)extra_name, (void)query_type,
        (void)size;

    int *arg_out = arg;
    os_memory_provider_t *os_provider = (os_memory_provider_t *)ctx;
    *arg_out = os_provider->IPC_enabled;
    return 0;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reading your last comment as "size is useless" ;)

Let me re-phrase - whenever size is used, please add a test with various values (user may give some input we may not expect, e.g. on wrong assumptions on how this func works) or mark a TODO for adding tests in the future.

@KFilipek KFilipek force-pushed the ctl-default branch 4 times, most recently from b7324ed to 8e3a2fc Compare March 25, 2025 13:00
Copy link
Contributor

@lplewa lplewa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

umf_result_t umfCtlExec(const char *name, void *ctx, void *arg); should also have arg size imho.

const char *extra_name,
umf_ctl_query_type_t queryType) {
(void)indexes, (void)source, (void)size, (void)ctx;
assert(queryType == CTL_QUERY_WRITE && "not supported query type");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not an assert. This sould return a correct error code to the user.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • read should work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

@KFilipek KFilipek force-pushed the ctl-default branch 2 times, most recently from 338947a to 29380ba Compare March 25, 2025 16:02
@@ -35,7 +35,7 @@ TEST_F(test, ctl_by_handle_os_provider) {

int ipc_enabled = 0xBAD;
ret = umfCtlGet("umf.provider.by_handle.params.ipc_enabled", hProvider,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're adding a new paramter and without testing values other than 0 it's not properly tested. At least mark in tests a TODO for future.

umf_os_memory_provider_params_handle_t os_memory_provider_params = NULL;
umf_memory_provider_ops_t *os_provider_ops = umfOsMemoryProviderOps();
if (os_provider_ops == NULL) {
GTEST_SKIP() << "OS memory provider is not supported!";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yy? not sure what you mean

@KFilipek KFilipek force-pushed the ctl-default branch 4 times, most recently from a8a7fe8 to 56b5408 Compare March 26, 2025 11:57
@KFilipek KFilipek force-pushed the ctl-default branch 2 times, most recently from f55ddb1 to 141d7bc Compare April 15, 2025 11:54
@KFilipek KFilipek force-pushed the ctl-default branch 9 times, most recently from 33ceeeb to 77692e1 Compare April 17, 2025 09:59
@KFilipek KFilipek requested a review from lplewa April 17, 2025 09:59
@KFilipek KFilipek force-pushed the ctl-default branch 4 times, most recently from 0c02aaa to f7c7900 Compare April 20, 2025 09:02
@KFilipek
Copy link
Contributor Author

Please, re-review.

}

umf_result_t free(void *ptr, [[maybe_unused]] size_t size) noexcept {
// do the actual free only when we expect the success
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need such functionality here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's taken from above, generally, I tried to be consistent with the rest of the file. Common code should be extracted as separate PR.

#define RETURN_SUCCESS(ret) ASSERT_EQ(ret, UMF_RESULT_SUCCESS)

// Encapsulating class for pool creation and destruction
class PoolWrapper {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why we can't use existing poolCreateExtUnique?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The poolFixtures.hpp forces to compile with *_compliance_test:

/usr/bin/ld: CMakeFiles/test_ctl_api.dir/ctl/ctl_api.cpp.o: in function `umfPoolTest_malloc_compliance_Test::TestBody()':
/home/kfilipek/Development/unified-memory-framework/test/poolFixtures.hpp:485:(.text+0x8c00): undefined reference to `malloc_compliance_test(umf_memory_pool_t*)'

I can rewrite it as a separate PR and move poolCreateExtUnique as a separate header file.

@bratpiorka
Copy link
Contributor

@KFilipek please work with other reviewers to close all conversations

#include <umf/memory_pool.h>
#include <umf/memory_provider.h>
#include <umf/pools/pool_scalable.h>
#include <umf/providers/provider_os_memory.h>

#include "../common/base.hpp"
#include "umf/pools/pool_disjoint.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use <> for umf/* headers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right

@KFilipek KFilipek requested a review from Copilot May 8, 2025 08:13
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces support for default values in the CTL interface and updates the CTL query API across the codebase by adding an extra size parameter. Key changes include updates to unit tests to verify default value handling (including multithreaded tests), modifications to CTL handler APIs in providers, pools, and CTL modules, and corresponding documentation updates.

Reviewed Changes

Copilot reviewed 21 out of 23 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/ctl/ctl_unittest.cpp Added extra size parameter to ctl_query calls in unit tests.
test/ctl/ctl_api.cpp Extended tests with default handling and updated query template.
test/ctl/ctl_debug.c Updated CTL handlers with new extra size parameter.
src/provider/.c & src/provider/.h Updated CTL query signatures to include the size parameter.
src/pool/*.c Adjusted CTL query calls and added default value integration.
src/memory_provider.c, src/memory_pool.c Updated CTL API use and logic for setting defaults.
src/libumf.c, src/ctl/ctl.[ch] Updated CTL API function signatures and internal query logic.
include/umf/*.h Updated documentation and API prototypes with new size parameter.
benchmark/benchmark_umf.hpp Minor update to supply size parameter for CTL queries.
Files not reviewed (2)
  • src/libumf.def: Language not supported
  • test/CMakeLists.txt: Language not supported
Comments suppressed due to low confidence (1)

src/memory_pool.c:160

  • Using strstr to match the default entry with the result of ops->get_name(NULL) may lead to unintended substring matches. Consider using a strict equality comparison to correctly detect a matching default property.
if (CTL_DEFAULT_ENTRIES[i][0] != '\0' && strstr(CTL_DEFAULT_ENTRIES[i], ops->get_name(NULL))) {

AI suggested

Co-authored-by: Copilot <[email protected]>
/// @param pool pointer to the memory pool
/// @return name of the memory pool
///
const char *(*get_name)(void *pool);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document this as optional - so this ptr can be null

ensure if pool do not support this call, umfPoolName returns unsupported error. Do it similar way to providers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document it how it must work with null ptr.

umf_ctl_node_t root[CTL_MAX_ENTRIES];
int first_free;
};

struct ctl *ctl_new(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bump

return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
// using ctx is disallowed for default settings
if (ctx && strstr(name, ".default.")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do this check in default subtree handler. This is ugly hack which will not work in some cases
i.e: umf.pool.byhandle.default.something

}
if (UMF_DEFAULT_SIZE == i) {
LOG_ERR("Default entries array is full");
return -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please decide if this function returns int error codes, or umf result

Comment on lines +78 to +84
const char *prefix = "disjoint.";
const char *name_wo_prefix = strstr(name, "disjoint.");

// Check if the name has the prefix
if ((name_wo_prefix = strstr(name, prefix)) == NULL) {
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this code does, but it's incorrect. there should never be "disjoint" in string here. And there should be no special string parsing outside of ctl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CTL - setting global namespace
4 participants