-
Notifications
You must be signed in to change notification settings - Fork 47
Add support for growing allocations #1340
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
base: master
Are you sure you want to change the base?
Changes from all commits
7735994
78475d7
cb5afdb
17be7f0
15c11de
eae7ad1
42d33de
213598b
02cd27e
8d6a772
8896ed1
43d7f40
0f6afd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
|
||
add_subdirectory( bindings ) | ||
add_subdirectory( bindings ) | ||
add_subdirectory( test ) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,6 +111,8 @@ class reapi_t { | |
* allocate. | ||
* MATCH_ALLOCATE_W_SATISFIABILITY: try to allocate and run | ||
* satisfiability check if resources are not available. | ||
* MATCH_GROW_ALLOCATION: try to grow an existing allocation | ||
* now and fail if resources aren't available. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
No, that won't work with these changes. There's a lot more machinery needed to detect cases where the reservation wouldn't start before the current allocation ends, or the reservation time changes and becomes invalid. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which makes me realize that even with |
||
* \param jobspec jobspec string. | ||
* \param jobid jobid of the uint64_t type. | ||
* \param reserved Boolean into which to return true if this job has been | ||
|
@@ -150,6 +152,8 @@ class reapi_t { | |
* aren't available. | ||
* MATCH_ALLOCATE_ORELSE_RESERVE : Try to allocate and reseve | ||
* if resources aren't available now. | ||
* MATCH_GROW_ALLOCATION: try to grow an existing allocation | ||
* now and fail if resources aren't available. | ||
* MATCH_SATISFIABILITY: Do a satisfiablity check and do not | ||
* allocate. | ||
* MATCH_ALLOCATE_W_SATISFIABILITY: try to allocate and run | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,14 @@ int reapi_cli_t::match_allocate (void *h, | |
rc = -1; | ||
goto out; | ||
} | ||
if (match_op == match_op_t::MATCH_GROW_ALLOCATION) { | ||
if (!rq->job_exists (jobid)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this function be called separately from the other place that does this same check (and that is why we do the check for the job id existing twice)? If we can just do one, maybe the check could be done closest to when the request to grow is made. If we require both, I'm wondering if there could be some race condition where it is allowed to pass through a first check, but by the second check the job id doesn't exist. I guess that would warrant the second check, and it would be OK as long as there wasn't some state partially changed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Which place are you thinking of? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I'm honest, I can't remember, and you can disregard this comment. I wish I had linked to the location of "other place!" It could be in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's not likely given Fluxion is serial, but I suppose it is possible with RPCs.
That code is responsible for handling RPCs from a REAPI module client rather than function calls to a context via a CLI client. |
||
m_err_msg += __FUNCTION__; | ||
m_err_msg += ": ERROR: Nonexistent jobid: " + std::to_string (jobid) + "\n"; | ||
rc = -1; | ||
goto out; | ||
} | ||
} | ||
|
||
try { | ||
Flux::Jobspec::Jobspec job{jobspec}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,7 +103,9 @@ extern "C" int reapi_cli_match (reapi_cli_ctx_t *ctx, | |
goto out; | ||
} | ||
|
||
*jobid = ctx->rqt->get_job_counter (); | ||
if (match_op != match_op_t::MATCH_GROW_ALLOCATION) { | ||
*jobid = ctx->rqt->get_job_counter (); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To write out my understanding - normally in match allocate we make a new id, and it is just derived from the counter. But in |
||
} | ||
if ((rc = reapi_cli_t:: | ||
match_allocate (ctx->rqt, match_op, jobspec, *jobid, *reserved, R_buf, *at, *ov)) | ||
< 0) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
add_executable(reapi_cli_cxx_test reapi_cli_test_cxx.cpp) | ||
add_sanitizers(reapi_cli_cxx_test) | ||
target_link_libraries(reapi_cli_cxx_test PRIVATE reapi_cli intern Catch2::Catch2WithMain) | ||
flux_add_test(NAME reapi_cli_cxx_test COMMAND reapi_cli_cxx_test) | ||
set_property(TEST reapi_cli_cxx_test APPEND PROPERTY ENVIRONMENT "TESTRESRC_INPUT_FILE=$(CMAKE_SOURCE_DIR)/conf/hype.lua") | ||
|
||
add_executable(reapi_cli_c_test reapi_cli_test_c.cpp) | ||
add_sanitizers(reapi_cli_c_test) | ||
target_link_libraries(reapi_cli_c_test PRIVATE reapi_cli intern Catch2::Catch2WithMain) | ||
flux_add_test(NAME reapi_cli_c_test COMMAND reapi_cli_c_test) | ||
set_property(TEST reapi_cli_c_test APPEND PROPERTY ENVIRONMENT "TESTRESRC_INPUT_FILE=$(CMAKE_SOURCE_DIR)/conf/hype.lua") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#define CATCH_CONFIG_MAIN | ||
|
||
#include <catch2/catch_test_macros.hpp> | ||
#include <resource/reapi/bindings/c/reapi_cli.h> | ||
#include <fstream> | ||
#include <iostream> | ||
|
||
namespace Flux::resource_model::detail { | ||
|
||
TEST_CASE ("Initialize REAPI CLI", "[initialize C]") | ||
{ | ||
const std::string options = "{}"; | ||
std::stringstream buffer; | ||
std::ifstream inputFile ("../../../t/data/resource/jgfs/tiny.json"); | ||
|
||
if (!inputFile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
buffer << inputFile.rdbuf (); | ||
std::string rgraph = buffer.str (); | ||
|
||
reapi_cli_ctx_t *ctx = nullptr; | ||
ctx = reapi_cli_new (); | ||
REQUIRE (ctx); | ||
} | ||
|
||
TEST_CASE ("Match basic jobspec", "[match C]") | ||
{ | ||
int rc = -1; | ||
const std::string options = "{}"; | ||
std::stringstream gbuffer, jbuffer; | ||
std::ifstream graphfile ("../../../t/data/resource/jgfs/tiny.json"); | ||
std::ifstream jobspecfile ("../../../t/data/resource/jobspecs/basics/test006.yaml"); | ||
|
||
if (!graphfile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
jbuffer << jobspecfile.rdbuf (); | ||
std::string jobspec = jbuffer.str (); | ||
|
||
if (!jobspecfile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
gbuffer << graphfile.rdbuf (); | ||
std::string rgraph = gbuffer.str (); | ||
|
||
reapi_cli_ctx_t *ctx = nullptr; | ||
ctx = reapi_cli_new (); | ||
REQUIRE (ctx); | ||
|
||
rc = reapi_cli_initialize (ctx, rgraph.c_str (), options.c_str ()); | ||
REQUIRE (rc == 0); | ||
|
||
match_op_t match_op = match_op_t::MATCH_ALLOCATE; | ||
bool reserved = false; | ||
char *R; | ||
uint64_t jobid = 1; | ||
double ov = 0.0; | ||
int64_t at = 0; | ||
|
||
rc = reapi_cli_match (ctx, match_op, jobspec.c_str (), &jobid, &reserved, &R, &at, &ov); | ||
REQUIRE (rc == 0); | ||
REQUIRE (reserved == false); | ||
REQUIRE (at == 0); | ||
} | ||
|
||
TEST_CASE ("Match shrink basic jobspec", "[match shrink C]") | ||
{ | ||
int rc = -1; | ||
const std::string options = "{\"load_format\": \"rv1exec\"}"; | ||
std::stringstream gbuffer, jbuffer, cbuffer; | ||
std::ifstream graphfile ("../../../t/data/resource/rv1exec/tiny_rv1exec.json"); | ||
std::ifstream jobspecfile ("../../../t/data/resource/jobspecs/cancel/test018.yaml"); | ||
std::ifstream cancelfile ("../../../t/data/resource/rv1exec/cancel/rank1_cancel.json"); | ||
|
||
if (!graphfile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
if (!jobspecfile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
if (!cancelfile.is_open ()) { | ||
std::cerr << "Error opening file!" << std::endl; | ||
} | ||
|
||
gbuffer << graphfile.rdbuf (); | ||
std::string rgraph = gbuffer.str (); | ||
jbuffer << jobspecfile.rdbuf (); | ||
std::string jobspec = jbuffer.str (); | ||
cbuffer << cancelfile.rdbuf (); | ||
std::string cancel_string = cbuffer.str (); | ||
|
||
reapi_cli_ctx_t *ctx = nullptr; | ||
ctx = reapi_cli_new (); | ||
REQUIRE (ctx); | ||
|
||
rc = reapi_cli_initialize (ctx, rgraph.c_str (), options.c_str ()); | ||
REQUIRE (rc == 0); | ||
|
||
match_op_t match_op = match_op_t::MATCH_ALLOCATE; | ||
bool reserved = false; | ||
char *R; | ||
uint64_t jobid = 1; | ||
double ov = 0.0; | ||
int64_t at = 0; | ||
|
||
rc = reapi_cli_match (ctx, match_op, jobspec.c_str (), &jobid, &reserved, &R, &at, &ov); | ||
REQUIRE (rc == 0); | ||
REQUIRE (reserved == false); | ||
REQUIRE (at == 0); | ||
|
||
bool noent_ok = false; | ||
bool full_removal = true; | ||
rc = reapi_cli_partial_cancel (ctx, jobid, cancel_string.c_str (), noent_ok, &full_removal); | ||
REQUIRE (rc == 0); | ||
REQUIRE (full_removal == false); | ||
} | ||
|
||
} // namespace Flux::resource_model::detail |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion for naming consistency:
I shouldn't be reviewing this early, I've read that word less than 10 times and am getting semantic satiation. "ALLOCATE" looks like some kind of fruit name to me right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I waffled on this and am back to preferring
MATCH_GROW_ALLOCATION
. My current thinking is that the pattern is verb_verb_{noun/verb/conjunction}, andGROW_ALLOCATION
is clearer.