diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b42e4d49..f2b98ba34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(labstor) +project(hermes) #----------------------------------------------------------------------------- # Define Options @@ -93,6 +93,14 @@ if(thallium_FOUND) message(STATUS "found thallium at ${thallium_DIR}") endif() +# Boost +find_package(Boost REQUIRED COMPONENTS regex system filesystem fiber REQUIRED) +if (Boost_FOUND) + message(STATUS "found boost at ${Boost_INCLUDE_DIRS}") +endif() +include_directories(${Boost_INCLUDE_DIRS}) +message("Boost: ${Boost_LIBRARIES}") + #------------------------------------------------------------------------------ # Setup CMake Environment #------------------------------------------------------------------------------ @@ -158,7 +166,8 @@ set(Labstor_CLIENT_DEPS labstor_client) set(Labstor_RUNTIME_LIBRARIES ${Labstor_CLIENT_LIBRARIES} - labstor_runtime) + labstor_runtime + ${Boost_LIBRARIES}) set(Labstor_RUNTIME_DEPS labstor_client labstor_runtime) diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 4eb76ca54..28c07cf82 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -29,11 +29,11 @@ target_link_libraries(test_performance_exec # ${Labstor_CLIENT_LIBRARIES} hermes Catch2::Catch2 # MPI::MPI_CXX ${ZMQ_LIBRARIES}) -add_executable(test_hermes_api +add_executable(hermes_api_bench hermes_api_bench.cc) -add_dependencies(test_hermes_api +add_dependencies(hermes_api_bench ${Labstor_CLIENT_DEPS} hermes) -target_link_libraries(test_hermes_api +target_link_libraries(hermes_api_bench ${Labstor_CLIENT_LIBRARIES} hermes Catch2::Catch2 MPI::MPI_CXX) @@ -50,7 +50,7 @@ add_test(NAME test_performance COMMAND #------------------------------------------------------------------------------ install(TARGETS test_performance_exec - test_hermes_api + hermes_api_bench EXPORT ${LABSTOR_EXPORTED_TARGETS} LIBRARY DESTINATION ${LABSTOR_INSTALL_LIB_DIR} diff --git a/benchmark/hermes_api_bench.cc b/benchmark/hermes_api_bench.cc index 928d53053..018ac7c11 100644 --- a/benchmark/hermes_api_bench.cc +++ b/benchmark/hermes_api_bench.cc @@ -48,10 +48,11 @@ void PutTest(int nprocs, int rank, for (size_t i = 0; i < blobs_per_rank; ++i) { size_t blob_name_int = rank * blobs_per_rank + i; std::string name = std::to_string(blob_name_int); - bkt.Put(name, blob, ctx); + bkt.AsyncPut(name, blob, ctx); } } t.Pause(); + HILOG(kInfo, "Finished PUT") GatherTimes("Put", nprocs * blobs_per_rank * blob_size * repeat, t); } @@ -67,11 +68,10 @@ void GetTest(int nprocs, int rank, t.Resume(); for (int j = 0; j < repeat; ++j) { for (size_t i = 0; i < blobs_per_rank; ++i) { + hermes::Blob ret(blob_size); size_t blob_name_int = rank * blobs_per_rank + i; std::string name = std::to_string(blob_name_int); - hermes::Blob ret; - hermes::BlobId blob_id = bkt.GetBlobId(name); - bkt.Get(blob_id, ret, ctx); + bkt.Get(name, ret, ctx); } } t.Pause(); @@ -86,6 +86,62 @@ void PutGetTest(int nprocs, int rank, int repeat, GetTest(nprocs, rank, repeat, blobs_per_rank, blob_size); } +/** Each process PUTS into the same bucket, but with different blob names */ +void PartialPutTest(int nprocs, int rank, + int repeat, size_t blobs_per_rank, + size_t blob_size, size_t part_size) { + Timer t; + hermes::Context ctx; + hermes::Bucket bkt("hello", ctx); + hermes::Blob blob(blob_size); + t.Resume(); + for (int j = 0; j < repeat; ++j) { + for (size_t i = 0; i < blobs_per_rank; ++i) { + size_t blob_name_int = rank * blobs_per_rank + i; + std::string name = std::to_string(blob_name_int); + for (size_t cur_size = 0; cur_size < blob_size; cur_size += part_size) { + bkt.PartialPut(name, blob, cur_size, ctx); + } + } + } + t.Pause(); + GatherTimes("PartialPut", nprocs * blobs_per_rank * blob_size * repeat, t); +} + +/** + * Each process GETS from the same bucket, but with different blob names + * MUST run PutTest first. + * */ +void PartialGetTest(int nprocs, int rank, + int repeat, size_t blobs_per_rank, + size_t blob_size, size_t part_size) { + Timer t; + hermes::Context ctx; + hermes::Bucket bkt("hello", ctx); + t.Resume(); + for (int j = 0; j < repeat; ++j) { + for (size_t i = 0; i < blobs_per_rank; ++i) { + size_t blob_name_int = rank * blobs_per_rank + i; + std::string name = std::to_string(blob_name_int); + hermes::Blob ret(blob_size); + for (size_t cur_size = 0; cur_size < blob_size; cur_size += part_size) { + bkt.PartialGet(name, ret, cur_size, ctx); + } + } + } + t.Pause(); + GatherTimes("PartialGet", nprocs * blobs_per_rank * blob_size * repeat, t); +} + +/** Each process PUTs then GETs */ +void PartialPutGetTest(int nprocs, int rank, int repeat, + size_t blobs_per_rank, size_t blob_size, + size_t part_size) { + PartialPutTest(nprocs, rank, repeat, blobs_per_rank, blob_size, part_size); + MPI_Barrier(MPI_COMM_WORLD); + PartialGetTest(nprocs, rank, repeat, blobs_per_rank, blob_size, part_size); +} + /** Each process creates a set of buckets */ void CreateBucketTest(int nprocs, int rank, size_t bkts_per_rank) { @@ -120,7 +176,7 @@ void GetBucketTest(int nprocs, int rank, hapi::Bucket bkt(std::to_string(bkt_name), ctx); } t.Pause(); - GatherTimes("CreateBucket", bkts_per_rank * nprocs, t); + GatherTimes("GetBucket", bkts_per_rank * nprocs, t); } /** Each process deletes a number of buckets */ @@ -172,6 +228,7 @@ void help() { printf("USAGE: ./api_bench [mode] ...\n"); printf("USAGE: ./api_bench put [blob_size (K/M/G)] [blobs_per_rank]\n"); printf("USAGE: ./api_bench putget [blob_size (K/M/G)] [blobs_per_rank]\n"); + printf("USAGE: ./api_bench pputget [blob_size (K/M/G)] [part_size (K/M/G)] [blobs_per_rank]\n"); printf("USAGE: ./api_bench create_bkt [bkts_per_rank]\n"); printf("USAGE: ./api_bench get_bkt [bkts_per_rank]\n"); printf("USAGE: ./api_bench create_blob_1bkt [blobs_per_rank]\n"); @@ -202,33 +259,43 @@ int main(int argc, char **argv) { HIPRINT("Beginning {}\n", mode) // Run tests - if (mode == "put") { - REQUIRE_ARGC(4) - size_t blob_size = hshm::ConfigParse::ParseSize(argv[2]); - size_t blobs_per_rank = atoi(argv[3]); - PutTest(nprocs, rank, 1, blobs_per_rank, blob_size); - } else if (mode == "putget") { - REQUIRE_ARGC(4) - size_t blob_size = hshm::ConfigParse::ParseSize(argv[2]); - size_t blobs_per_rank = atoi(argv[3]); - PutGetTest(nprocs, rank, 1, blobs_per_rank, blob_size); - } else if (mode == "create_bkt") { - REQUIRE_ARGC(3) - size_t bkts_per_rank = atoi(argv[2]); - CreateBucketTest(nprocs, rank, bkts_per_rank); - } else if (mode == "get_bkt") { - REQUIRE_ARGC(3) - size_t bkts_per_rank = atoi(argv[2]); - GetBucketTest(nprocs, rank, bkts_per_rank); - } else if (mode == "del_bkt") { - REQUIRE_ARGC(4) - size_t bkt_per_rank = atoi(argv[2]); - size_t blobs_per_bkt = atoi(argv[3]); - DeleteBucketTest(nprocs, rank, bkt_per_rank, blobs_per_bkt); - } else if (mode == "del_blobs") { - REQUIRE_ARGC(4) - size_t blobs_per_rank = atoi(argv[2]); - DeleteBlobOneBucket(nprocs, rank, blobs_per_rank); + try { + if (mode == "put") { + REQUIRE_ARGC(4) + size_t blob_size = hshm::ConfigParse::ParseSize(argv[2]); + size_t blobs_per_rank = atoi(argv[3]); + PutTest(nprocs, rank, 1, blobs_per_rank, blob_size); + } else if (mode == "putget") { + REQUIRE_ARGC(4) + size_t blob_size = hshm::ConfigParse::ParseSize(argv[2]); + size_t blobs_per_rank = atoi(argv[3]); + PutGetTest(nprocs, rank, 1, blobs_per_rank, blob_size); + } else if (mode == "pputget") { + REQUIRE_ARGC(5) + size_t blob_size = hshm::ConfigParse::ParseSize(argv[2]); + size_t part_size = hshm::ConfigParse::ParseSize(argv[3]); + size_t blobs_per_rank = atoi(argv[4]); + PartialPutGetTest(nprocs, rank, 1, blobs_per_rank, blob_size, part_size); + } else if (mode == "create_bkt") { + REQUIRE_ARGC(3) + size_t bkts_per_rank = atoi(argv[2]); + CreateBucketTest(nprocs, rank, bkts_per_rank); + } else if (mode == "get_bkt") { + REQUIRE_ARGC(3) + size_t bkts_per_rank = atoi(argv[2]); + GetBucketTest(nprocs, rank, bkts_per_rank); + } else if (mode == "del_bkt") { + REQUIRE_ARGC(4) + size_t bkt_per_rank = atoi(argv[2]); + size_t blobs_per_bkt = atoi(argv[3]); + DeleteBucketTest(nprocs, rank, bkt_per_rank, blobs_per_bkt); + } else if (mode == "del_blobs") { + REQUIRE_ARGC(4) + size_t blobs_per_rank = atoi(argv[2]); + DeleteBlobOneBucket(nprocs, rank, blobs_per_rank); + } + } catch (hshm::Error &err) { + HELOG(kFatal, "Error: {}", err.what()); } MPI_Finalize(); } diff --git a/ci/hermes/packages/__init__.py b/ci/hermes/packages/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/ci/hermes/packages/hermes/package.py b/ci/hermes/packages/hermes/package.py index 8d0cda713..184922e1b 100644 --- a/ci/hermes/packages/hermes/package.py +++ b/ci/hermes/packages/hermes/package.py @@ -14,13 +14,13 @@ class Hermes(CMakePackage): variant('vfd', default=False, description='Enable HDF5 VFD') variant('ares', default=False, description='Enable full libfabric install') variant('debug', default=False, description='Enable debug mode') - variant('debug', default=False, description='Build shared libraries') variant('zmq', default=False, description='Build ZeroMQ tests') depends_on('mochi-thallium~cereal@0.10.1') depends_on('cereal') - depends_on('catch2@3.0.1') - depends_on('mpich@3.3.2:') + # depends_on('catch2@3.0.1') + depends_on('catch2') + depends_on('mpich@3.3.2') depends_on('yaml-cpp') depends_on('boost@1.7:') depends_on('hermes_shm') diff --git a/ci/hermes/packages/hermes_shm/package.py b/ci/hermes/packages/hermes_shm/package.py index 58cfbea28..76343ff00 100644 --- a/ci/hermes/packages/hermes_shm/package.py +++ b/ci/hermes/packages/hermes_shm/package.py @@ -6,9 +6,11 @@ class HermesShm(CMakePackage): version('master', branch='master') depends_on('mochi-thallium~cereal@0.10.1') depends_on('catch2@3.0.1') - depends_on('mpi') - depends_on('boost@1.7:') + # depends_on('mpi') + depends_on('mpich@3.3.2') + depends_on('boost@1.7: +context +fiber') depends_on('cereal') + depends_on('yaml-cpp') depends_on('doxygen@1.9.3') variant('debug', default=False, description='Build shared libraries') diff --git a/codegen/refresh_methods b/codegen/refresh_methods index 600e355d8..404f6a705 100755 --- a/codegen/refresh_methods +++ b/codegen/refresh_methods @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """ -USAGE: ./referesh_methods [TASK_ROOT] +USAGE: ./referesh_methods [TASK_DIR] """ import yaml @@ -9,168 +9,178 @@ import os import sys from codegen.util.paths import LABSTOR_ROOT -TASK_ROOT = sys.argv[1] -TASK_NAME = os.path.basename(TASK_ROOT) -METHODS_H = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_methods.h' -METHODS_YAML = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_methods.yaml' -LIB_EXEC_H = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_lib_exec.h' -METHOD_MACRO = f'LABSTOR_{TASK_NAME.upper()}_METHODS_H_' -LIB_EXEC_MACRO = f'LABSTOR_{TASK_NAME.upper()}_LIB_EXEC_H_' - -with open(METHODS_YAML) as fp: - methods = yaml.load(fp, Loader=yaml.FullLoader) -if methods is None: - methods = {} -if 'kLast' in methods: - del methods['kLast'] -methods = sorted(methods.items(), key=lambda x: x[1]) -if TASK_NAME != 'labstor_admin': - methods.insert(0, ('kConstruct', -2)) - methods.insert(1, ('kDestruct', -1)) - -# Produce the TASK_NAME_methods.h file -lines = [] -lines += [f'#ifndef {METHOD_MACRO}', - f'#define {METHOD_MACRO}', - '', - '/** The set of methods in the admin task */', - 'struct Method : public TaskMethod {'] -for method_enum_name, method_off in methods: - if method_enum_name == 'kConstruct': - continue - if method_enum_name == 'kDestruct': - continue - lines += f' TASK_METHOD_T {method_enum_name} = kLast + {method_off};', -lines += ['};', '', f'#endif // {METHOD_MACRO}'] -with open(METHODS_H, 'w') as fp: - fp.write('\n'.join(lines)) - - -# Produce the TASK_NAME_lib_exec.h file -lines = [] -lines += [f'#ifndef {LIB_EXEC_MACRO}', - f'#define {LIB_EXEC_MACRO}', - ''] -## Create the Run method -lines += ['/** Execute a task */', - 'void Run(u32 method, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' {method_name}(reinterpret_cast<{task_name} *>(task));', - f' break;', - f' }}'] -lines += [' }'] -lines += ['}'] - -## Create the ReplicateStart method -lines += ['/** Ensure there is space to store replicated outputs */', - 'void ReplicateStart(u32 method, u32 count, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' labstor::CALL_REPLICA_START(count, reinterpret_cast<{task_name}*>(task));', - f' break;', - f' }}'] -lines += [' }'] -lines += ['}'] - -## Create the ReplicateEnd method -lines += ['/** Determine success and handle failures */', - 'void ReplicateEnd(u32 method, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' labstor::CALL_REPLICA_END(reinterpret_cast<{task_name}*>(task));', - f' break;', - f' }}'] -lines += [' }'] -lines += ['}'] - -## Create the SaveStart Method -lines += ['/** Serialize a task when initially pushing into remote */', - 'std::vector SaveStart(u32 method, BinaryOutputArchive &ar, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' ar << *reinterpret_cast<{task_name}*>(task);', - f' break;', - f' }}'] -lines += [' }'] -lines += [' return ar.Get();'] -lines += ['}'] - -## Create the LoadStart Method -lines += ['/** Deserialize a task when popping from remote queue */', - 'TaskPointer LoadStart(u32 method, BinaryInputArchive &ar) override {', - ' TaskPointer task_ptr;', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' task_ptr.task_ = LABSTOR_CLIENT->NewEmptyTask<{task_name}>(task_ptr.p_);', - f' ar >> *reinterpret_cast<{task_name}*>(task_ptr.task_);', - f' break;', - f' }}'] -lines += [' }'] -lines += [' return task_ptr;'] -lines += ['}'] - -## Create the SaveEnd Method -lines += ['/** Serialize a task when returning from remote queue */', - 'std::vector SaveEnd(u32 method, BinaryOutputArchive &ar, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' ar << *reinterpret_cast<{task_name}*>(task);', - f' break;', - f' }}'] -lines += [' }'] -lines += [' return ar.Get();'] -lines += ['}'] - -## Create the LoadEnd Method -lines += ['/** Deserialize a task when returning from remote queue */', - 'void LoadEnd(u32 replica, u32 method, BinaryInputArchive &ar, Task *task) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' ar.Deserialize(replica, *reinterpret_cast<{task_name}*>(task));', - f' break;', - f' }}'] -lines += [' }'] -lines += ['}'] - -## Create the CheckIfConcurrent Method -lines += ['/** Get the grouping of the task */', - 'u32 GetGroup(u32 method, Task *task, hshm::charbuf &group) override {', - ' switch (method) {'] -for method_enum_name, method_off in methods: - method_name = method_enum_name.replace('k', '', 1) - task_name = method_name + "Task" - lines += [f' case Method::{method_enum_name}: {{', - f' return reinterpret_cast<{task_name}*>(task)->GetGroup(group);', - f' }}'] -lines += [' }'] -lines += [' return -1;'] -lines += ['}'] - -## Finish the file -lines += ['', f'#endif // {METHOD_MACRO}'] - -## Write TASK_NAME_lib_exec.h -with open(LIB_EXEC_H, 'w') as fp: - fp.write('\n'.join(lines)) +def refresh_methods(TASK_ROOT): + if not os.path.exists(f'{TASK_ROOT}/include'): + return + TASK_NAME = os.path.basename(TASK_ROOT) + METHODS_H = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_methods.h' + METHODS_YAML = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_methods.yaml' + LIB_EXEC_H = f'{TASK_ROOT}/include/{TASK_NAME}/{TASK_NAME}_lib_exec.h' + METHOD_MACRO = f'LABSTOR_{TASK_NAME.upper()}_METHODS_H_' + LIB_EXEC_MACRO = f'LABSTOR_{TASK_NAME.upper()}_LIB_EXEC_H_' + + with open(METHODS_YAML) as fp: + methods = yaml.load(fp, Loader=yaml.FullLoader) + if methods is None: + methods = {} + if 'kLast' in methods: + del methods['kLast'] + methods = sorted(methods.items(), key=lambda x: x[1]) + if TASK_NAME != 'labstor_admin': + methods.insert(0, ('kConstruct', -2)) + methods.insert(1, ('kDestruct', -1)) + + # Produce the TASK_NAME_methods.h file + lines = [] + lines += [f'#ifndef {METHOD_MACRO}', + f'#define {METHOD_MACRO}', + '', + '/** The set of methods in the admin task */', + 'struct Method : public TaskMethod {'] + for method_enum_name, method_off in methods: + if method_enum_name == 'kConstruct': + continue + if method_enum_name == 'kDestruct': + continue + lines += f' TASK_METHOD_T {method_enum_name} = kLast + {method_off};', + lines += ['};', '', f'#endif // {METHOD_MACRO}'] + with open(METHODS_H, 'w') as fp: + fp.write('\n'.join(lines)) + + + # Produce the TASK_NAME_lib_exec.h file + lines = [] + lines += [f'#ifndef {LIB_EXEC_MACRO}', + f'#define {LIB_EXEC_MACRO}', + ''] + ## Create the Run method + lines += ['/** Execute a task */', + 'void Run(u32 method, Task *task, RunContext &ctx) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' {method_name}(reinterpret_cast<{task_name} *>(task), ctx);', + f' break;', + f' }}'] + lines += [' }'] + lines += ['}'] + + ## Create the ReplicateStart method + lines += ['/** Ensure there is space to store replicated outputs */', + 'void ReplicateStart(u32 method, u32 count, Task *task) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' labstor::CALL_REPLICA_START(count, reinterpret_cast<{task_name}*>(task));', + f' break;', + f' }}'] + lines += [' }'] + lines += ['}'] + + ## Create the ReplicateEnd method + lines += ['/** Determine success and handle failures */', + 'void ReplicateEnd(u32 method, Task *task) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' labstor::CALL_REPLICA_END(reinterpret_cast<{task_name}*>(task));', + f' break;', + f' }}'] + lines += [' }'] + lines += ['}'] + + ## Create the SaveStart Method + lines += ['/** Serialize a task when initially pushing into remote */', + 'std::vector SaveStart(u32 method, BinaryOutputArchive &ar, Task *task) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' ar << *reinterpret_cast<{task_name}*>(task);', + f' break;', + f' }}'] + lines += [' }'] + lines += [' return ar.Get();'] + lines += ['}'] + + ## Create the LoadStart Method + lines += ['/** Deserialize a task when popping from remote queue */', + 'TaskPointer LoadStart(u32 method, BinaryInputArchive &ar) override {', + ' TaskPointer task_ptr;', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' task_ptr.task_ = LABSTOR_CLIENT->NewEmptyTask<{task_name}>(task_ptr.p_);', + f' ar >> *reinterpret_cast<{task_name}*>(task_ptr.task_);', + f' break;', + f' }}'] + lines += [' }'] + lines += [' return task_ptr;'] + lines += ['}'] + + ## Create the SaveEnd Method + lines += ['/** Serialize a task when returning from remote queue */', + 'std::vector SaveEnd(u32 method, BinaryOutputArchive &ar, Task *task) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' ar << *reinterpret_cast<{task_name}*>(task);', + f' break;', + f' }}'] + lines += [' }'] + lines += [' return ar.Get();'] + lines += ['}'] + + ## Create the LoadEnd Method + lines += ['/** Deserialize a task when returning from remote queue */', + 'void LoadEnd(u32 replica, u32 method, BinaryInputArchive &ar, Task *task) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' ar.Deserialize(replica, *reinterpret_cast<{task_name}*>(task));', + f' break;', + f' }}'] + lines += [' }'] + lines += ['}'] + + ## Create the CheckIfConcurrent Method + lines += ['/** Get the grouping of the task */', + 'u32 GetGroup(u32 method, Task *task, hshm::charbuf &group) override {', + ' switch (method) {'] + for method_enum_name, method_off in methods: + method_name = method_enum_name.replace('k', '', 1) + task_name = method_name + "Task" + lines += [f' case Method::{method_enum_name}: {{', + f' return reinterpret_cast<{task_name}*>(task)->GetGroup(group);', + f' }}'] + lines += [' }'] + lines += [' return -1;'] + lines += ['}'] + + ## Finish the file + lines += ['', f'#endif // {METHOD_MACRO}'] + + ## Write TASK_NAME_lib_exec.h + with open(LIB_EXEC_H, 'w') as fp: + fp.write('\n'.join(lines)) + +TASK_DIR = sys.argv[1] +TASK_ROOTS = [os.path.join(TASK_DIR, item) for item in os.listdir(TASK_DIR)] +for TASK_ROOT in TASK_ROOTS: + try: + refresh_methods(TASK_ROOT) + except: + pass diff --git a/config/labstor_server_default.yaml b/config/labstor_server_default.yaml index d0fc09001..2a498ff9b 100644 --- a/config/labstor_server_default.yaml +++ b/config/labstor_server_default.yaml @@ -15,8 +15,9 @@ queue_manager: shm_allocator: kScalablePageAllocator # The name of the shared memory region to create shm_name: "labstor_shm" - # The size of the shared memory region to allocate + # The size of the shared memory region to allocate for general data structures shm_size: 0g + # The size of the shared memory to allocate for data buffers ### Define properties of RPCs rpc: diff --git a/include/labstor/api/labstor_client.h b/include/labstor/api/labstor_client.h index 68c53535a..54e9d9f99 100644 --- a/include/labstor/api/labstor_client.h +++ b/include/labstor/api/labstor_client.h @@ -139,7 +139,8 @@ class Client : public ConfigurationManager { template HSHM_ALWAYS_INLINE void DelTask(TaskT *task) { - main_alloc_->DelObj(task); + // TODO(llogan): verify leak + // main_alloc_->DelObj(task); } /** Destroy a task */ @@ -187,12 +188,14 @@ class Client : public ConfigurationManager { /** Free a buffer */ HSHM_ALWAYS_INLINE void FreeBuffer(hipc::Pointer &p) { - main_alloc_->Free(p); + // TODO(llogan): verify leak + // main_alloc_->Free(p); } /** Free a buffer */ HSHM_ALWAYS_INLINE void FreeBuffer(LPointer &p) { + // TODO(llogan): verify leak main_alloc_->FreeLocalPtr(p); } }; @@ -269,7 +272,7 @@ class Client : public ConfigurationManager { hipc::LPointer> push_task =\ LABSTOR_PROCESS_QUEUE->AsyncPush(task_node,\ DomainId::GetLocal(),\ - task.shm_);\ + task);\ return push_task;\ } diff --git a/include/labstor/api/template/labstor_task_node_push_root.template b/include/labstor/api/template/labstor_task_node_push_root.template index 703048125..37b909500 100644 --- a/include/labstor/api/template/labstor_task_node_push_root.template +++ b/include/labstor/api/template/labstor_task_node_push_root.template @@ -28,6 +28,6 @@ hipc::LPointer> Async##CUSTOM##Root(Args&& .. hipc::LPointer> push_task = LABSTOR_PROCESS_QUEUE->AsyncPush(task_node, DomainId::GetLocal(), - task.shm_); + task); return push_task; } \ No newline at end of file diff --git a/include/labstor/labstor_namespace.h b/include/labstor/labstor_namespace.h index d80e18f6f..230834691 100644 --- a/include/labstor/labstor_namespace.h +++ b/include/labstor/labstor_namespace.h @@ -22,6 +22,7 @@ using labstor::TaskLib; using labstor::TaskLibClient; using labstor::config::QueueManagerInfo; using labstor::TaskPrio; +using labstor::RunContext; using hshm::RwLock; using hshm::Mutex; diff --git a/include/labstor/labstor_types.h b/include/labstor/labstor_types.h index c6594db35..9d01597b3 100644 --- a/include/labstor/labstor_types.h +++ b/include/labstor/labstor_types.h @@ -28,6 +28,10 @@ #include "hermes_shm/util/singleton.h" #include "hermes_shm/constants/macros.h" +#include + +namespace bctx = boost::context::detail; + typedef uint8_t u8; /**< 8-bit unsigned integer */ typedef uint16_t u16; /**< 16-bit unsigned integer */ typedef uint32_t u32; /**< 32-bit unsigned integer */ @@ -225,12 +229,14 @@ struct DomainId { template struct UniqueId { u32 node_id_; /**< The node the content is on */ + u32 hash_; /**< The hash of the content the ID represents */ u64 unique_; /**< A unique id for the blob */ /** Serialization */ template void serialize(Ar &ar) { ar & node_id_; + ar & hash_; ar & unique_; } @@ -239,13 +245,20 @@ struct UniqueId { UniqueId() = default; /** Emplace constructor */ - HSHM_ALWAYS_INLINE - UniqueId(u32 node_id, u64 unique) : node_id_(node_id), unique_(unique) {} + HSHM_ALWAYS_INLINE explicit + UniqueId(u32 node_id, u64 unique) + : node_id_(node_id), hash_(0), unique_(unique) {} + + /** Emplace constructor (+hash) */ + HSHM_ALWAYS_INLINE explicit + UniqueId(u32 node_id, u32 hash, u64 unique) + : node_id_(node_id), hash_(hash), unique_(unique) {} /** Copy constructor */ HSHM_ALWAYS_INLINE UniqueId(const UniqueId &other) { node_id_ = other.node_id_; + hash_ = other.hash_; unique_ = other.unique_; } @@ -254,6 +267,7 @@ struct UniqueId { HSHM_ALWAYS_INLINE UniqueId(const UniqueId &other) { node_id_ = other.node_id_; + hash_ = other.hash_; unique_ = other.unique_; } @@ -262,6 +276,7 @@ struct UniqueId { UniqueId& operator=(const UniqueId &other) { if (this != &other) { node_id_ = other.node_id_; + hash_ = other.hash_; unique_ = other.unique_; } return *this; @@ -271,6 +286,7 @@ struct UniqueId { HSHM_ALWAYS_INLINE UniqueId(UniqueId &&other) noexcept { node_id_ = other.node_id_; + hash_ = other.hash_; unique_ = other.unique_; } @@ -279,6 +295,7 @@ struct UniqueId { UniqueId& operator=(UniqueId &&other) noexcept { if (this != &other) { node_id_ = other.node_id_; + hash_ = other.hash_; unique_ = other.unique_; } return *this; @@ -301,6 +318,7 @@ struct UniqueId { HSHM_ALWAYS_INLINE void SetNull() { node_id_ = 0; + hash_ = 0; unique_ = 0; } diff --git a/include/labstor/network/rpc_thallium.h b/include/labstor/network/rpc_thallium.h index 3a722e3b3..667ddf278 100644 --- a/include/labstor/network/rpc_thallium.h +++ b/include/labstor/network/rpc_thallium.h @@ -93,7 +93,7 @@ class ThalliumRpc { tl::endpoint server = client_engine_->lookup(server_name.c_str()); client_engine_->shutdown_remote_engine(server); } catch (std::exception &e) { - HELOG(kFatal, e.what()); + HELOG(kFatal, "Stop daemon failed: {}", e.what()); } } @@ -120,7 +120,7 @@ class ThalliumRpc { /** RPC call */ template - RetT Call(u32 node_id, const char *func_name, Args&&... args) { + RetT Call(u32 node_id, const std::string &func_name, Args&&... args) { HILOG(kDebug, "Calling {} {} -> {}", func_name, rpc_->node_id_, node_id) try { std::string server_name = GetServerName(node_id); @@ -139,73 +139,79 @@ class ThalliumRpc { return remote_proc.on(server).async(std::forward(args)...); } } catch (tl::margo_exception &err) { - HELOG(kFatal, "Thallium failed on function: {}\n{}", - func_name, err.what()) + HELOG(kFatal, "(node {} -> {}) Thallium failed on function: {}: {}", + rpc_->node_id_, node_id, func_name, err.what()) exit(1); } } /** RPC call */ template - RetT SyncCall(u32 node_id, const char *func_name, Args&&... args) { + RetT SyncCall(u32 node_id, const std::string &func_name, Args&&... args) { return Call( node_id, func_name, std::forward(args)...); } /** Async RPC call */ template - thallium::async_response AsyncCall(u32 node_id, const char *func_name, Args&&... args) { + thallium::async_response AsyncCall(u32 node_id, const std::string &func_name, Args&&... args) { return Call( node_id, func_name, std::forward(args)...); } /** I/O transfers */ template - RetT IoCall(i32 node_id, const char *func_name, + RetT IoCall(i32 node_id, const std::string &func_name, IoType type, char *data, size_t size, Args&& ...args) { HILOG(kDebug, "Calling {} {} -> {}", func_name, rpc_->node_id_, node_id) - std::string server_name = GetServerName(node_id); - tl::bulk_mode flag; - switch (type) { - case IoType::kRead: { - // The "bulk" object will be modified - flag = tl::bulk_mode::write_only; - break; - } - case IoType::kWrite: { - // The "bulk" object will only be read from - flag = tl::bulk_mode::read_only; - break; - } - case IoType::kNone: { - // TODO(llogan) - HELOG(kFatal, "Cannot have none I/O type") - exit(1); + try { + std::string server_name = GetServerName(node_id); + tl::bulk_mode flag; + switch (type) { + case IoType::kRead: { + // The "bulk" object will be modified + flag = tl::bulk_mode::write_only; + break; + } + case IoType::kWrite: { + // The "bulk" object will only be read from + flag = tl::bulk_mode::read_only; + break; + } + case IoType::kNone: { + // TODO(llogan) + HELOG(kFatal, "Cannot have none I/O type") + exit(1); + } } - } - tl::remote_procedure remote_proc = client_engine_->define(func_name); - tl::endpoint server = client_engine_->lookup(server_name); + tl::remote_procedure remote_proc = client_engine_->define(func_name); + tl::endpoint server = client_engine_->lookup(server_name); - std::vector> segments(1); - segments[0].first = data; - segments[0].second = size; + std::vector> segments(1); + segments[0].first = data; + segments[0].second = size; - tl::bulk bulk = client_engine_->expose(segments, flag); - if constexpr (!ASYNC) { - if constexpr (std::is_same_v) { - remote_proc.on(server)(bulk, std::forward(args)...); + tl::bulk bulk = client_engine_->expose(segments, flag); + if constexpr (!ASYNC) { + if constexpr (std::is_same_v) { + remote_proc.on(server)(bulk, std::forward(args)...); + } else { + return remote_proc.on(server)(bulk, std::forward(args)...); + } } else { - return remote_proc.on(server)(bulk, std::forward(args)...); + return remote_proc.on(server).async(bulk, std::forward(args)...); } - } else { - return remote_proc.on(server).async(bulk, std::forward(args)...); + } catch (tl::margo_exception &err) { + HELOG(kFatal, "(node {} -> {}) Thallium failed on function: {}: {}", + rpc_->node_id_, node_id, func_name, err.what()) + exit(1); } } /** Synchronous I/O transfer */ template - RetT SyncIoCall(i32 node_id, const char *func_name, + RetT SyncIoCall(i32 node_id, const std::string &func_name, IoType type, char *data, size_t size, Args&& ...args) { return IoCall( node_id, func_name, type, data, size, std::forward(args)...); @@ -229,7 +235,7 @@ class ThalliumRpc { // The "local_bulk" object will only be read from flag = tl::bulk_mode::read_only; // flag = tl::bulk_mode::read_write; - HILOG(kInfo, "(node {}) Reading {} bytes from the server", + HILOG(kDebug, "(node {}) Reading {} bytes from the server", rpc_->node_id_, size) break; } @@ -237,7 +243,7 @@ class ThalliumRpc { // The "local_bulk" object will only be written to flag = tl::bulk_mode::write_only; // flag = tl::bulk_mode::read_write; - HILOG(kInfo, "(node {}) Writing {} bytes to the server", + HILOG(kDebug, "(node {}) Writing {} bytes to the server", rpc_->node_id_, size) break; } diff --git a/include/labstor/queue_manager/queue_manager_runtime.h b/include/labstor/queue_manager/queue_manager_runtime.h index 8164b1520..a489e6d9f 100644 --- a/include/labstor/queue_manager/queue_manager_runtime.h +++ b/include/labstor/queue_manager/queue_manager_runtime.h @@ -18,6 +18,7 @@ class QueueManagerRuntime : public QueueManager { public: ServerConfig *config_; size_t max_queues_; + size_t max_lanes_; hipc::split_ticket_queue *tickets_; u32 node_id_; @@ -35,6 +36,7 @@ class QueueManagerRuntime : public QueueManager { QueueManagerInfo &qm = config_->queue_manager_; // Initialize ticket queue (ticket 0 is for admin queue) max_queues_ = qm.max_queues_; + max_lanes_ = qm.max_lanes_; HSHM_MAKE_AR(shm.tickets_, alloc, max_queues_) for (u64 i = 1; i <= max_queues_; ++i) { shm.tickets_->emplace(i); diff --git a/include/labstor/queue_manager/queues/hshm_queue.h b/include/labstor/queue_manager/queues/hshm_queue.h index d9c32ba31..a3ee79200 100644 --- a/include/labstor/queue_manager/queues/hshm_queue.h +++ b/include/labstor/queue_manager/queues/hshm_queue.h @@ -13,6 +13,7 @@ namespace labstor { struct LaneData { hipc::Pointer p_; bool complete_; + ABT_thread thread_; LaneData() = default; diff --git a/include/labstor/task_registry/task.h b/include/labstor/task_registry/task.h index 94c4932ff..19a834109 100644 --- a/include/labstor/task_registry/task.h +++ b/include/labstor/task_registry/task.h @@ -11,6 +11,8 @@ namespace labstor { +class TaskLib; + /** This task reads a state */ #define TASK_READ BIT_OPT(u32, 0) /** This task writes to a state */ @@ -43,10 +45,19 @@ namespace labstor { #define TASK_DATA_OWNER BIT_OPT(u32, 14) /** This task is marked */ #define TASK_MARKED BIT_OPT(u32, 15) +/** This task uses co-routine wait */ +#define TASK_COROUTINE BIT_OPT(u32, 16) +/** This task uses argobot wait */ +#define TASK_PREEMPTIVE BIT_OPT(u32, 17) /** Used to define task methods */ #define TASK_METHOD_T static inline const u32 +/** Used to indicate Yield to use */ +#define TASK_YIELD_STD 0 +#define TASK_YIELD_CO 1 +#define TASK_YIELD_ABT 2 + /** The baseline set of tasks */ struct TaskMethod { TASK_METHOD_T kConstruct = 0; /**< The constructor of the task */ @@ -219,6 +230,21 @@ class TaskPrio { TASK_PRIO_T kLowLatency = 2; }; +/** Context passed to the Run method of a task */ +struct RunContext { + u32 lane_id_; /**< The lane id of the task */ + bctx::transfer_t jmp_; /**< Current execution state of the task (runtime) */ + size_t stack_size_ = KILOBYTES(64); /**< The size of the stack for the task (runtime) */ + void *stack_ptr_; /**< The pointer to the stack (runtime) */ + TaskLib *exec_; + + /** Default constructor */ + RunContext() {} + + /** Emplace constructor */ + RunContext(u32 lane_id) : lane_id_(lane_id) {} +}; + /** A generic task base class */ struct Task : public hipc::ShmContainer { SHM_CONTAINER_TEMPLATE((Task), (Task)) @@ -230,6 +256,7 @@ struct Task : public hipc::ShmContainer { u32 lane_hash_; /**< Determine the lane a task is keyed to */ u32 method_; /**< The method to call in the state */ bitfield32_t task_flags_; /**< Properties of the task */ + RunContext ctx_; /**==================================== * Task Helpers @@ -335,20 +362,57 @@ struct Task : public hipc::ShmContainer { return task_flags_.Any(TASK_MARKED); } + /** Set this task as started */ + HSHM_ALWAYS_INLINE void UnsetLongRunning() { + task_flags_.UnsetBits(TASK_LONG_RUNNING); + } + + /** Set this task as blocking */ + HSHM_ALWAYS_INLINE bool IsCoroutine() { + return task_flags_.Any(TASK_COROUTINE); + } + + /** Set this task as blocking */ + HSHM_ALWAYS_INLINE bool IsPreemptive() { + return task_flags_.Any(TASK_PREEMPTIVE); + } + + /** Yield the task */ + template + HSHM_ALWAYS_INLINE + void Yield() { + if constexpr (THREAD_MODEL == TASK_YIELD_STD) { + HERMES_THREAD_MODEL->Yield(); + } else if constexpr (THREAD_MODEL == TASK_YIELD_CO) { + ctx_.jmp_ = bctx::jump_fcontext(ctx_.jmp_.fctx, nullptr); + } else if constexpr (THREAD_MODEL == TASK_YIELD_ABT) { + ABT_thread_yield(); + } + } + /** Wait for task to complete */ template void Wait() { while (!IsComplete()) { - for (int i = 0; i < 100000; ++i) { - if (IsComplete()) { - return; - } - } - if constexpr(THREAD_MODEL == 0) { - HERMES_THREAD_MODEL->Yield(); - } else { - ABT_thread_yield(); - } +// for (int i = 0; i < 100000; ++i) { +// if (IsComplete()) { +// return; +// } +// } + Yield(); + } + } + + /** Wait for task to complete */ + template + void Wait(Task *yield_task) { + while (!IsComplete()) { +// for (int i = 0; i < 100000; ++i) { +// if (IsComplete()) { +// return; +// } +// } + yield_task->Yield(); } } diff --git a/include/labstor/task_registry/task_lib.h b/include/labstor/task_registry/task_lib.h index e67de5852..acf82efad 100644 --- a/include/labstor/task_registry/task_lib.h +++ b/include/labstor/task_registry/task_lib.h @@ -77,7 +77,7 @@ class TaskLib { virtual ~TaskLib() = default; /** Run a method of the task */ - virtual void Run(u32 method, Task *task) = 0; + virtual void Run(u32 method, Task *task, RunContext &ctx) = 0; /** Allow task to store replicas of completion */ virtual void ReplicateStart(u32 method, u32 count, Task *task) = 0; @@ -132,7 +132,8 @@ typedef const char* (*get_task_lib_name_t)(void); labstor::TaskState *exec = reinterpret_cast( \ new TYPE_UNWRAP(TRAIT_CLASS)()); \ exec->Init(task->id_, state_name); \ - exec->Run(labstor::TaskMethod::kConstruct, task); \ + RunContext ctx(0); \ + exec->Run(labstor::TaskMethod::kConstruct, task, ctx); \ return exec; \ } \ const char* get_task_lib_name(void) { return TASK_NAME; } \ diff --git a/include/labstor/work_orchestrator/worker.h b/include/labstor/work_orchestrator/worker.h index 1894df6ad..23555bd31 100644 --- a/include/labstor/work_orchestrator/worker.h +++ b/include/labstor/work_orchestrator/worker.h @@ -314,7 +314,7 @@ class Worker { return; } int ret = exec->GetGroup(task->method_, task, group_); - if (ret == TASK_UNORDERED || task->IsUnordered() || task->method_ < 2) { + if (ret == TASK_UNORDERED || task->IsUnordered()) { HILOG(kDebug, "(node {}) Decreasing depth of group remains 0 (task_node={} worker={})", LABSTOR_CLIENT->node_id_, task->task_node_, id_); return; @@ -364,6 +364,8 @@ class Worker { } void PollGrouped(WorkEntry &entry); + static void RunBlocking(bctx::transfer_t t); + static void RunPreemptive(void *data); }; } // namespace labstor diff --git a/src/worker.cc b/src/worker.cc index ee514fdae..7a943839a 100644 --- a/src/worker.cc +++ b/src/worker.cc @@ -15,8 +15,7 @@ void Worker::Loop() { try { Run(); } catch (hshm::Error &e) { - e.print(); - exit(1); + HELOG(kFatal, "(node {}) Worker {} caught an error: {}", LABSTOR_CLIENT->node_id_, id_, e.what()); } // Yield(); } @@ -42,10 +41,10 @@ void Worker::Run() { } void Worker::PollGrouped(WorkEntry &work_entry) { - Lane *lane = work_entry.lane_; + int off = 0; + Lane *&lane = work_entry.lane_; Task *task; LaneData *entry; - int off = 0; for (int i = 0; i < 1024; ++i) { // Get the task message if (lane->peek(entry, off).IsNull()) { @@ -56,8 +55,11 @@ void Worker::PollGrouped(WorkEntry &work_entry) { continue; } task = LABSTOR_CLIENT->GetPrivatePointer(entry->p_); + RunContext &ctx = task->ctx_; + ctx.lane_id_ = work_entry.lane_id_; // Get the task state - TaskState *exec = LABSTOR_TASK_REGISTRY->GetTaskState(task->task_state_); + TaskState *&exec = ctx.exec_; + exec = LABSTOR_TASK_REGISTRY->GetTaskState(task->task_state_); if (!exec) { HELOG(kFatal, "(node {}) Could not find the task state: {}", LABSTOR_CLIENT->node_id_, task->task_state_); @@ -74,9 +76,26 @@ void Worker::PollGrouped(WorkEntry &work_entry) { LABSTOR_REMOTE_QUEUE->Disperse(task, exec, ids); task->DisableRun(); task->SetUnordered(); + } else if (task->IsCoroutine()) { + if (!task->IsStarted()) { + ctx.stack_ptr_ = malloc(ctx.stack_size_); + if (ctx.stack_ptr_ == nullptr) { + HILOG(kFatal, "The stack pointer of size {} is NULL", + ctx.stack_size_, ctx.stack_ptr_); + } + ctx.jmp_.fctx = bctx::make_fcontext( + (char*)ctx.stack_ptr_ + ctx.stack_size_, + ctx.stack_size_, &RunBlocking); + task->SetStarted(); + } + ctx.jmp_ = bctx::jump_fcontext(ctx.jmp_.fctx, task); + HILOG(kDebug, "Jumping into function") + } else if (task->IsPreemptive()) { + task->DisableRun(); + entry->thread_ = LABSTOR_WORK_ORCHESTRATOR->SpawnAsyncThread(&Worker::RunPreemptive, task); } else { task->SetStarted(); - exec->Run(task->method_, task); + exec->Run(task->method_, task, ctx); } } // Cleanup on task completion @@ -84,6 +103,12 @@ void Worker::PollGrouped(WorkEntry &work_entry) { // HILOG(kDebug, "(node {}) Ending task: task_node={} task_state={} lane={} queue={} worker={}", // LABSTOR_CLIENT->node_id_, task->task_node_, task->task_state_, lane_id, queue->id_, id_); entry->complete_ = true; + if (task->IsCoroutine()) { + // TODO(llogan): verify leak + // free(ctx.stack_ptr_); + } else if (task->IsPreemptive()) { + ABT_thread_join(entry->thread_); + } RemoveTaskGroup(task, exec, work_entry.lane_id_, is_remote); EndTask(lane, task, off); } else { @@ -92,4 +117,20 @@ void Worker::PollGrouped(WorkEntry &work_entry) { } } +void Worker::RunBlocking(bctx::transfer_t t) { + Task *task = reinterpret_cast(t.data); + RunContext &ctx = task->ctx_; + TaskState *&exec = ctx.exec_; + ctx.jmp_ = t; + exec->Run(task->method_, task, ctx); + task->Yield(); +} + +void Worker::RunPreemptive(void *data) { + Task *task = reinterpret_cast(data); + TaskState *exec = LABSTOR_TASK_REGISTRY->GetTaskState(task->task_state_); + RunContext ctx(0); + exec->Run(task->method_, task, ctx); +} + } // namespace labstor \ No newline at end of file diff --git a/tasks/bdev/include/bdev/bdev_lib_exec.h b/tasks/bdev/include/bdev/bdev_lib_exec.h index d154585ad..943c61ed2 100644 --- a/tasks/bdev/include/bdev/bdev_lib_exec.h +++ b/tasks/bdev/include/bdev/bdev_lib_exec.h @@ -2,38 +2,38 @@ #define LABSTOR_BDEV_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kWrite: { - Write(reinterpret_cast(task)); + Write(reinterpret_cast(task), ctx); break; } case Method::kRead: { - Read(reinterpret_cast(task)); + Read(reinterpret_cast(task), ctx); break; } - case Method::kAlloc: { - Alloc(reinterpret_cast(task)); + case Method::kAllocate: { + Allocate(reinterpret_cast(task), ctx); break; } case Method::kFree: { - Free(reinterpret_cast(task)); + Free(reinterpret_cast(task), ctx); break; } case Method::kMonitor: { - Monitor(reinterpret_cast(task)); + Monitor(reinterpret_cast(task), ctx); break; } case Method::kUpdateCapacity: { - UpdateCapacity(reinterpret_cast(task)); + UpdateCapacity(reinterpret_cast(task), ctx); break; } } @@ -57,7 +57,7 @@ void ReplicateStart(u32 method, u32 count, Task *task) override { labstor::CALL_REPLICA_START(count, reinterpret_cast(task)); break; } - case Method::kAlloc: { + case Method::kAllocate: { labstor::CALL_REPLICA_START(count, reinterpret_cast(task)); break; } @@ -94,7 +94,7 @@ void ReplicateEnd(u32 method, Task *task) override { labstor::CALL_REPLICA_END(reinterpret_cast(task)); break; } - case Method::kAlloc: { + case Method::kAllocate: { labstor::CALL_REPLICA_END(reinterpret_cast(task)); break; } @@ -131,7 +131,7 @@ std::vector SaveStart(u32 method, BinaryOutputArchive &ar, T ar << *reinterpret_cast(task); break; } - case Method::kAlloc: { + case Method::kAllocate: { ar << *reinterpret_cast(task); break; } @@ -174,7 +174,7 @@ TaskPointer LoadStart(u32 method, BinaryInputArchive &ar) override { ar >> *reinterpret_cast(task_ptr.task_); break; } - case Method::kAlloc: { + case Method::kAllocate: { task_ptr.task_ = LABSTOR_CLIENT->NewEmptyTask(task_ptr.p_); ar >> *reinterpret_cast(task_ptr.task_); break; @@ -216,7 +216,7 @@ std::vector SaveEnd(u32 method, BinaryOutputArchive &ar, Ta ar << *reinterpret_cast(task); break; } - case Method::kAlloc: { + case Method::kAllocate: { ar << *reinterpret_cast(task); break; } @@ -254,7 +254,7 @@ void LoadEnd(u32 replica, u32 method, BinaryInputArchive &ar, Task *task) ar.Deserialize(replica, *reinterpret_cast(task)); break; } - case Method::kAlloc: { + case Method::kAllocate: { ar.Deserialize(replica, *reinterpret_cast(task)); break; } @@ -287,7 +287,7 @@ u32 GetGroup(u32 method, Task *task, hshm::charbuf &group) override { case Method::kRead: { return reinterpret_cast(task)->GetGroup(group); } - case Method::kAlloc: { + case Method::kAllocate: { return reinterpret_cast(task)->GetGroup(group); } case Method::kFree: { diff --git a/tasks/bdev/include/bdev/bdev_methods.h b/tasks/bdev/include/bdev/bdev_methods.h index 715545386..7ca9b12f4 100644 --- a/tasks/bdev/include/bdev/bdev_methods.h +++ b/tasks/bdev/include/bdev/bdev_methods.h @@ -5,7 +5,7 @@ struct Method : public TaskMethod { TASK_METHOD_T kWrite = kLast + 0; TASK_METHOD_T kRead = kLast + 1; - TASK_METHOD_T kAlloc = kLast + 2; + TASK_METHOD_T kAllocate = kLast + 2; TASK_METHOD_T kFree = kLast + 3; TASK_METHOD_T kMonitor = kLast + 4; TASK_METHOD_T kUpdateCapacity = kLast + 5; diff --git a/tasks/bdev/include/bdev/bdev_methods.yaml b/tasks/bdev/include/bdev/bdev_methods.yaml index 616b06640..70173aa3e 100644 --- a/tasks/bdev/include/bdev/bdev_methods.yaml +++ b/tasks/bdev/include/bdev/bdev_methods.yaml @@ -1,6 +1,6 @@ kWrite: 0 kRead: 1 -kAlloc: 2 +kAllocate: 2 kFree: 3 kMonitor: 4 kUpdateCapacity: 5 diff --git a/tasks/bdev/include/bdev/bdev_tasks.h b/tasks/bdev/include/bdev/bdev_tasks.h index 4837dd543..c7f7be735 100644 --- a/tasks/bdev/include/bdev/bdev_tasks.h +++ b/tasks/bdev/include/bdev/bdev_tasks.h @@ -44,12 +44,6 @@ struct ConstructTask : public CreateTaskStateTask { // Custom params info_ = info; } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy hermes_mdm */ @@ -99,7 +93,7 @@ struct AllocateTask : public Task, TaskFlags { lane_hash_ = 0; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; - method_ = Method::kAlloc; + method_ = Method::kAllocate; task_flags_.SetBits(TASK_UNORDERED); domain_id_ = domain_id; diff --git a/tasks/hermes/include/hermes/bucket.h b/tasks/hermes/include/hermes/bucket.h index 241faf477..67ade3690 100644 --- a/tasks/hermes/include/hermes/bucket.h +++ b/tasks/hermes/include/hermes/bucket.h @@ -11,6 +11,10 @@ namespace hermes { +#include "labstor/labstor_namespace.h" +using hermes::blob_mdm::PutBlobTask; +using hermes::blob_mdm::GetBlobTask; + #define HERMES_BUCKET_IS_FILE BIT_OPT(u32, 1) class Bucket { @@ -203,34 +207,41 @@ class Bucket { /** * Put \a blob_name Blob into the bucket * */ - template + template HSHM_ALWAYS_INLINE BlobId BasePut(const std::string &blob_name, + const BlobId &orig_blob_id, const Blob &blob, size_t blob_off, - const BlobId &orig_blob_id, Context &ctx) { BlobId blob_id = orig_blob_id; + bitfield32_t flags, task_flags(TASK_FIRE_AND_FORGET | TASK_DATA_OWNER | TASK_LOW_LATENCY); // Copy data to shared memory LPointer p = LABSTOR_CLIENT->AllocateBuffer(blob.size()); char *data = p.ptr_; memcpy(data, blob.data(), blob.size()); // Put to shared memory hshm::charbuf blob_name_buf = hshm::to_charbuf(blob_name); - if (blob_id.IsNull()) { - blob_id = blob_mdm_->GetOrCreateBlobIdRoot(id_, blob_name_buf); + if constexpr (!ASYNC) { + if (blob_id.IsNull()) { + flags.SetBits(HERMES_GET_BLOB_ID); + task_flags.UnsetBits(TASK_FIRE_AND_FORGET); + } } - HILOG(kDebug, "The bucket's ID is: {}", blob_id); if constexpr(!PARTIAL) { - blob_mdm_->AsyncPutBlobRoot(id_, blob_name_buf, - blob_id, 0, blob.size(), p.shm_, ctx.blob_score_, - bitfield32_t(HERMES_BLOB_REPLACE), - ctx); - } else { - blob_mdm_->AsyncPutBlobRoot(id_, blob_name_buf, - blob_id, blob_off, blob.size(), p.shm_, ctx.blob_score_, - bitfield32_t(0), - ctx); + flags.SetBits(HERMES_BLOB_REPLACE); + } + LPointer> push_task; + push_task = blob_mdm_->AsyncPutBlobRoot(id_, blob_name_buf, + blob_id, blob_off, blob.size(), p.shm_, ctx.blob_score_, + flags, ctx, task_flags); + if constexpr (!ASYNC) { + if (flags.Any(HERMES_GET_BLOB_ID)) { + push_task->Wait(); + PutBlobTask *task = push_task->get(); + blob_id = task->blob_id_; + LABSTOR_CLIENT->DelTask(push_task); + } } return blob_id; } @@ -238,64 +249,115 @@ class Bucket { /** * Put \a blob_name Blob into the bucket * */ + template + HSHM_ALWAYS_INLINE + BlobId SrlBasePut(const std::string &blob_name, + const BlobId &orig_blob_id, + const T &data, + Context &ctx) { + std::stringstream ss; + cereal::BinaryOutputArchive ar(ss); + ar << data; + Blob blob(ss.str()); + return BasePut(blob_name, orig_blob_id, blob, 0, ctx); + } + + /** + * Put \a blob_name Blob into the bucket + * */ + template BlobId Put(const std::string &blob_name, - const Blob &blob, + const T &blob, Context &ctx) { - return BasePut(blob_name, blob, 0, BlobId::GetNull(), ctx); + if (std::is_same_v) { + return BasePut(blob_name, BlobId::GetNull(), blob, 0, ctx); + } else { + return SrlBasePut(blob_name, BlobId::GetNull(), blob, ctx); + } } /** * Put \a blob_id Blob into the bucket * */ + template BlobId Put(const BlobId &blob_id, - const Blob &blob, + const T &blob, Context &ctx) { - return BasePut("", blob, 0, blob_id, ctx); + if (std::is_same_v) { + return BasePut("", blob_id, blob, 0, ctx); + } else { + return SrlBasePut("", blob_id, blob, ctx); + } } /** * Put \a blob_name Blob into the bucket * */ + HSHM_ALWAYS_INLINE + void AsyncPut(const std::string &blob_name, + const Blob &blob, + Context &ctx) { + BasePut(blob_name, BlobId::GetNull(), blob, 0, ctx); + } + + /** + * Put \a blob_id Blob into the bucket + * */ + HSHM_ALWAYS_INLINE + void AsyncPut(const BlobId &blob_id, + const Blob &blob, + Context &ctx) { + BasePut("", BlobId::GetNull(), blob, 0, ctx); + } + + /** + * PartialPut \a blob_name Blob into the bucket + * */ BlobId PartialPut(const std::string &blob_name, const Blob &blob, size_t blob_off, Context &ctx) { - return BasePut(blob_name, blob, blob_off, BlobId::GetNull(), ctx); + return BasePut(blob_name, BlobId::GetNull(), blob, blob_off, ctx); } /** - * Put \a blob_id Blob into the bucket + * PartialPut \a blob_id Blob into the bucket * */ BlobId PartialPut(const BlobId &blob_id, const Blob &blob, size_t blob_off, Context &ctx) { - return BasePut("", blob, blob_off, blob_id, ctx); + return BasePut("", blob_id, blob, blob_off, ctx); } /** - * Serialized PUT + * AsyncPartialPut \a blob_name Blob into the bucket * */ - template - BlobId Put(const std::string &blob_name, - const T &data, - Context &ctx) { - std::stringstream ss; - cereal::BinaryOutputArchive ar(ss); - ar << data; - Blob blob(ss.str()); - return Put(blob_name, blob, ctx); + void AsyncPartialPut(const std::string &blob_name, + const Blob &blob, + size_t blob_off, + Context &ctx) { + BasePut(blob_name, BlobId::GetNull(), blob, blob_off, ctx); + } + + /** + * AsyncPartialPut \a blob_id Blob into the bucket + * */ + void AsyncPartialPut(const BlobId &blob_id, + const Blob &blob, + size_t blob_off, + Context &ctx) { + BasePut("", blob_id, blob, blob_off, ctx); } /** - * Append \a blob_name Blob into the bucket + * Append \a blob_name Blob into the bucket (fully asynchronous) * */ - Status Append(const Blob &blob, size_t page_size, Context &ctx) { + void Append(const Blob &blob, size_t page_size, Context &ctx) { LPointer p = LABSTOR_CLIENT->AllocateBuffer(blob.size()); char *data = p.ptr_; memcpy(data, blob.data(), blob.size()); bkt_mdm_->AppendBlobRoot(id_, blob.size(), p.shm_, page_size, ctx.blob_score_, ctx.node_id_, ctx); - return Status(); } /** @@ -312,54 +374,132 @@ class Bucket { * Get the current size of the blob in the bucket * */ size_t GetBlobSize(const BlobId &blob_id) { - return blob_mdm_->GetBlobSizeRoot(id_, blob_id); + return blob_mdm_->GetBlobSizeRoot(id_, hshm::charbuf(""), blob_id); } /** - * Get \a blob_id Blob from the bucket + * Get the current size of the blob in the bucket * */ - BlobId BaseGet(const std::string &blob_name, - const BlobId &orig_blob_id, - Blob &blob, - size_t blob_off, - Context &ctx) { - BlobId blob_id = orig_blob_id; + size_t GetBlobSize(const std::string &name) { + return blob_mdm_->GetBlobSizeRoot(id_, hshm::charbuf(name), BlobId::GetNull()); + } + + /** + * Get \a blob_id Blob from the bucket (async) + * */ + LPointer> + HSHM_ALWAYS_INLINE + AsyncBaseGet(const std::string &blob_name, + const BlobId &blob_id, + Blob &blob, + size_t blob_off, + Context &ctx) { + bitfield32_t flags; // Get the blob ID if (blob_id.IsNull()) { - blob_id = blob_mdm_->GetBlobIdRoot(id_, hshm::to_charbuf(blob_name)); - } - if (blob_id.IsNull()) { - if (ctx.filename_.size() == 0) { - return blob_id; - } else { - // StageIn using PUT of an empty blob - hermes::Blob emtpy_blob; - blob_id = PartialPut(blob_name, emtpy_blob, 0, ctx); - } + flags.SetBits(HERMES_GET_BLOB_ID); } // Get from shared memory size_t data_size = blob.size(); - if (data_size == 0) { - data_size = GetBlobSize(blob_id); - } LPointer data_p = LABSTOR_CLIENT->AllocateBuffer(data_size); - data_size = blob_mdm_->GetBlobRoot(id_, blob_id, blob_off, data_size, data_p.shm_, ctx); - char *data = data_p.ptr_; - // Copy data to blob + LPointer> push_task; + push_task = blob_mdm_->AsyncGetBlobRoot(id_, hshm::to_charbuf(blob_name), + blob_id, blob_off, + data_size, data_p.shm_, + ctx, flags); + return push_task; + } + + /** + * Get \a blob_id Blob from the bucket (sync) + * */ + BlobId BaseGet(const std::string &blob_name, + const BlobId &orig_blob_id, + Blob &blob, + size_t blob_off, + Context &ctx) { // TODO(llogan): intercept mmap to avoid copy - blob.resize(data_size); + // TODO(llogan): make GetBlobSize work with blob_name + size_t data_size = blob.size(); + if (blob.size() == 0) { + data_size = blob_mdm_->GetBlobSizeRoot(id_, hshm::charbuf(blob_name), orig_blob_id); + blob.resize(data_size); + } + HILOG(kDebug, "Getting blob of size {}", data_size); + BlobId blob_id; + LPointer> push_task; + push_task = AsyncBaseGet(blob_name, orig_blob_id, blob, blob_off, ctx); + push_task->Wait(); + GetBlobTask *task = push_task->get(); + blob_id = task->blob_id_; + char *data = LABSTOR_CLIENT->GetPrivatePointer(task->data_); memcpy(blob.data(), data, data_size); - LABSTOR_CLIENT->FreeBuffer(data_p); + LABSTOR_CLIENT->FreeBuffer(task->data_); + LABSTOR_CLIENT->DelTask(task); return blob_id; } + /** + * Get \a blob_id Blob from the bucket (sync) + * */ + template + BlobId SrlBaseGet(const std::string &blob_name, + const BlobId &orig_blob_id, + T &data, + Context &ctx) { + std::stringstream ss; + cereal::BinaryInputArchive ar(ss); + ar >> data; + Blob blob(ss.str()); + return BaseGet(blob_name, orig_blob_id, blob, 0, ctx); + } + /** * Get \a blob_id Blob from the bucket * */ + template BlobId Get(const std::string &blob_name, - Blob &blob, + T &blob, Context &ctx) { - return BaseGet(blob_name, BlobId::GetNull(), blob, 0, ctx); + if (std::is_same_v) { + return BaseGet(blob_name, BlobId::GetNull(), blob, 0, ctx); + } else { + return SrlBaseGet(blob_name, BlobId::GetNull(), blob, ctx); + } + } + + /** + * Get \a blob_id Blob from the bucket + * */ + template + BlobId Get(const BlobId &blob_id, + T &blob, + Context &ctx) { + if (std::is_same_v) { + return BaseGet("", blob_id, blob, 0, ctx); + } else { + return SrlBaseGet("", blob_id, blob, ctx); + } + } + + /** + * AsyncGet \a blob_name Blob from the bucket + * */ + LPointer> + AsyncGet(const std::string &blob_name, + Blob &blob, + Context &ctx) { + return AsyncBaseGet(blob_name, BlobId::GetNull(), blob, 0, ctx); + } + + /** + * AsyncGet \a blob_id Blob from the bucket + * */ + LPointer> + AsyncGet(const BlobId &blob_id, + Blob &blob, + Context &ctx) { + return AsyncBaseGet("", blob_id, blob, 0, ctx); } /** @@ -372,15 +512,6 @@ class Bucket { return BaseGet(blob_name, BlobId::GetNull(), blob, blob_off, ctx); } - /** - * Get \a blob_id Blob from the bucket - * */ - BlobId Get(const BlobId &blob_id, - Blob &blob, - Context &ctx) { - return BaseGet("", blob_id, blob, 0, ctx); - } - /** * Put \a blob_name Blob into the bucket * */ @@ -391,6 +522,28 @@ class Bucket { return BaseGet("", blob_id, blob, blob_off, ctx); } + /** + * AsyncGet \a blob_name Blob from the bucket + * */ + LPointer> + AsyncPartialGet(const std::string &blob_name, + Blob &blob, + size_t blob_off, + Context &ctx) { + return AsyncBaseGet(blob_name, BlobId::GetNull(), blob, blob_off, ctx); + } + + /** + * AsyncGet \a blob_id Blob from the bucket + * */ + LPointer> + AsyncPartialGet(const BlobId &blob_id, + Blob &blob, + size_t blob_off, + Context &ctx) { + return AsyncBaseGet("", blob_id, blob, blob_off, ctx); + } + /** * Determine if the bucket contains \a blob_id BLOB * */ diff --git a/tasks/hermes_adapters/filesystem/filesystem.cc b/tasks/hermes_adapters/filesystem/filesystem.cc index 44d3a0a45..00f2656f8 100644 --- a/tasks/hermes_adapters/filesystem/filesystem.cc +++ b/tasks/hermes_adapters/filesystem/filesystem.cc @@ -130,7 +130,7 @@ size_t Filesystem::Write(File &f, AdapterStat &stat, const void *ptr, const Blob page((const char*)ptr + data_offset, p.blob_size_); if (!is_append) { std::string blob_name(p.CreateBlobName().str()); - bkt.PartialPut(blob_name, page, p.blob_off_, ctx); + bkt.AsyncPartialPut(blob_name, page, p.blob_off_, ctx); } else { bkt.Append(page, stat.page_size_, ctx); } diff --git a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_lib_exec.h b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_lib_exec.h index a491992c9..3ca8e4e03 100644 --- a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_lib_exec.h +++ b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_lib_exec.h @@ -1,19 +1,19 @@ -#ifndef LABSTOR_hermes_adapters_LIB_EXEC_H_ -#define LABSTOR_hermes_adapters_LIB_EXEC_H_ +#ifndef LABSTOR_HERMES_ADAPTERS_LIB_EXEC_H_ +#define LABSTOR_HERMES_ADAPTERS_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kCustom: { - Custom(reinterpret_cast(task)); + Custom(reinterpret_cast(task), ctx); break; } } @@ -143,4 +143,4 @@ u32 GetGroup(u32 method, Task *task, hshm::charbuf &group) override { return -1; } -#endif // LABSTOR_hermes_adapters_METHODS_H_ \ No newline at end of file +#endif // LABSTOR_HERMES_ADAPTERS_METHODS_H_ \ No newline at end of file diff --git a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_methods.h b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_methods.h index e6a468219..19d2b80a6 100644 --- a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_methods.h +++ b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_methods.h @@ -1,9 +1,9 @@ -#ifndef LABSTOR_hermes_adapters_METHODS_H_ -#define LABSTOR_hermes_adapters_METHODS_H_ +#ifndef LABSTOR_HERMES_ADAPTERS_METHODS_H_ +#define LABSTOR_HERMES_ADAPTERS_METHODS_H_ /** The set of methods in the admin task */ struct Method : public TaskMethod { TASK_METHOD_T kCustom = kLast + 0; }; -#endif // LABSTOR_hermes_adapters_METHODS_H_ \ No newline at end of file +#endif // LABSTOR_HERMES_ADAPTERS_METHODS_H_ \ No newline at end of file diff --git a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_tasks.h b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_tasks.h index 6df2570a4..cfc03fe9a 100644 --- a/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_tasks.h +++ b/tasks/hermes_adapters/include/hermes_adapters/hermes_adapters_tasks.h @@ -45,12 +45,6 @@ struct ConstructTask : public CreateTaskStateTask { ~ConstructTask() { // Custom params } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy hermes_adapters */ diff --git a/tasks/hermes_adapters/src/hermes_adapters.cc b/tasks/hermes_adapters/src/hermes_adapters.cc index 9192ef849..03d166b76 100644 --- a/tasks/hermes_adapters/src/hermes_adapters.cc +++ b/tasks/hermes_adapters/src/hermes_adapters.cc @@ -12,15 +12,15 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Custom(CustomTask *task) { + void Custom(CustomTask *task, RunContext &ctx) { task->SetModuleComplete(); } diff --git a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h index abb5be9cf..9b82d620f 100644 --- a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h +++ b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h @@ -127,15 +127,12 @@ class Client : public TaskLibClient { const hipc::Pointer &blob, float score, bitfield32_t flags, Context ctx = Context(), - bitfield32_t task_flags = bitfield32_t(TASK_FIRE_AND_FORGET | TASK_DATA_OWNER)) { - HILOG(kDebug, "Beginning PUT (task_node={})", task_node); + bitfield32_t task_flags = bitfield32_t(TASK_FIRE_AND_FORGET | TASK_DATA_OWNER | TASK_LOW_LATENCY)) { LABSTOR_CLIENT->ConstructTask( task, task_node, DomainId::GetNode(blob_id.node_id_), id_, tag_id, blob_name, blob_id, blob_off, blob_size, - blob, score, flags, ctx); - task->task_flags_ = task_flags; - HILOG(kDebug, "Constructed PUT (task_node={})", task_node); + blob, score, flags, ctx, task_flags); } LABSTOR_TASK_NODE_PUSH_ROOT(PutBlob); @@ -143,24 +140,27 @@ class Client : public TaskLibClient { void AsyncGetBlobConstruct(GetBlobTask *task, const TaskNode &task_node, const TagId &tag_id, + const hshm::charbuf &blob_name, const BlobId &blob_id, size_t off, ssize_t data_size, hipc::Pointer &data, - Context ctx = Context()) { + Context ctx = Context(), + bitfield32_t flags = bitfield32_t(0)) { HILOG(kDebug, "Beginning GET (task_node={})", task_node); LABSTOR_CLIENT->ConstructTask( task, task_node, DomainId::GetNode(blob_id.node_id_), id_, - tag_id, blob_id, off, data_size, data, ctx); + tag_id, blob_name, blob_id, off, data_size, data, ctx, flags); } size_t GetBlobRoot(const TagId &tag_id, const BlobId &blob_id, size_t off, ssize_t data_size, hipc::Pointer &data, - Context ctx = Context()) { + Context ctx = Context(), + bitfield32_t flags = bitfield32_t(0)) { LPointer> push_task = - AsyncGetBlobRoot(tag_id, blob_id, off, data_size, data); + AsyncGetBlobRoot(tag_id, hshm::charbuf(""), blob_id, off, data_size, data, ctx, flags); push_task->Wait(); GetBlobTask *task = push_task->get(); data = task->data_; @@ -293,16 +293,18 @@ class Client : public TaskLibClient { void AsyncGetBlobSizeConstruct(GetBlobSizeTask *task, const TaskNode &task_node, const TagId &tag_id, + const hshm::charbuf &blob_name, const BlobId &blob_id) { HILOG(kDebug, "Getting blob size {}", task_node); LABSTOR_CLIENT->ConstructTask( task, task_node, DomainId::GetNode(blob_id.node_id_), id_, - tag_id, blob_id); + tag_id, blob_name, blob_id); } size_t GetBlobSizeRoot(const TagId &tag_id, + const hshm::charbuf &blob_name, const BlobId &blob_id) { LPointer> push_task = - AsyncGetBlobSizeRoot(tag_id, blob_id); + AsyncGetBlobSizeRoot(tag_id, blob_name, blob_id); push_task->Wait(); GetBlobSizeTask *task = push_task->get(); size_t size = task->size_; diff --git a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_lib_exec.h b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_lib_exec.h index 251fafc96..55f37fe6d 100644 --- a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_lib_exec.h +++ b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_lib_exec.h @@ -2,74 +2,74 @@ #define LABSTOR_HERMES_BLOB_MDM_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kPutBlob: { - PutBlob(reinterpret_cast(task)); + PutBlob(reinterpret_cast(task), ctx); break; } case Method::kGetBlob: { - GetBlob(reinterpret_cast(task)); + GetBlob(reinterpret_cast(task), ctx); break; } case Method::kTruncateBlob: { - TruncateBlob(reinterpret_cast(task)); + TruncateBlob(reinterpret_cast(task), ctx); break; } case Method::kDestroyBlob: { - DestroyBlob(reinterpret_cast(task)); + DestroyBlob(reinterpret_cast(task), ctx); break; } case Method::kTagBlob: { - TagBlob(reinterpret_cast(task)); + TagBlob(reinterpret_cast(task), ctx); break; } case Method::kBlobHasTag: { - BlobHasTag(reinterpret_cast(task)); + BlobHasTag(reinterpret_cast(task), ctx); break; } case Method::kGetBlobId: { - GetBlobId(reinterpret_cast(task)); + GetBlobId(reinterpret_cast(task), ctx); break; } case Method::kGetOrCreateBlobId: { - GetOrCreateBlobId(reinterpret_cast(task)); + GetOrCreateBlobId(reinterpret_cast(task), ctx); break; } case Method::kGetBlobName: { - GetBlobName(reinterpret_cast(task)); + GetBlobName(reinterpret_cast(task), ctx); break; } case Method::kGetBlobSize: { - GetBlobSize(reinterpret_cast(task)); + GetBlobSize(reinterpret_cast(task), ctx); break; } case Method::kGetBlobScore: { - GetBlobScore(reinterpret_cast(task)); + GetBlobScore(reinterpret_cast(task), ctx); break; } case Method::kGetBlobBuffers: { - GetBlobBuffers(reinterpret_cast(task)); + GetBlobBuffers(reinterpret_cast(task), ctx); break; } case Method::kRenameBlob: { - RenameBlob(reinterpret_cast(task)); + RenameBlob(reinterpret_cast(task), ctx); break; } case Method::kReorganizeBlob: { - ReorganizeBlob(reinterpret_cast(task)); + ReorganizeBlob(reinterpret_cast(task), ctx); break; } case Method::kSetBucketMdm: { - SetBucketMdm(reinterpret_cast(task)); + SetBucketMdm(reinterpret_cast(task), ctx); break; } } diff --git a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h index e8813efcb..e487d23c3 100644 --- a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h +++ b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h @@ -51,12 +51,6 @@ struct ConstructTask : public CreateTaskStateTask { : CreateTaskStateTask(alloc, task_node, domain_id, state_name, "hermes_blob_mdm", id, queue_info) { } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy hermes_mdm */ @@ -213,8 +207,9 @@ class PutBlobPhase { #define HERMES_BLOB_REPLACE BIT_OPT(u32, 0) #define HERMES_BLOB_APPEND BIT_OPT(u32, 1) #define HERMES_DID_STAGE_IN BIT_OPT(u32, 2) -#define HERMES_BLOB_DID_CREATE BIT_OPT(u32, 3) - +#define HERMES_IS_FILE BIT_OPT(u32, 3) +#define HERMES_BLOB_DID_CREATE BIT_OPT(u32, 4) +#define HERMES_GET_BLOB_ID BIT_OPT(u32, 5) /** A task to put data in a blob */ struct PutBlobTask : public Task, TaskFlags { @@ -256,20 +251,24 @@ struct PutBlobTask : public Task, TaskFlags const hipc::Pointer &data, float score, bitfield32_t flags, - const Context &ctx) : Task(alloc) { + const Context &ctx, + bitfield32_t task_flags) : Task(alloc) { // Initialize task - HILOG(kDebug, "Beginning PUT task constructor") task_node_ = task_node; - lane_hash_ = blob_id_.unique_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kPutBlob; - task_flags_.SetBits(TASK_LOW_LATENCY); - domain_id_ = domain_id; + task_flags_ = task_flags; + if (!blob_id.IsNull()) { + lane_hash_ = blob_id.hash_; + domain_id_ = domain_id; + } else { + lane_hash_ = std::hash{}(blob_name); + domain_id_ = DomainId::GetNode(HASH_TO_NODE_ID(lane_hash_)); + } // Custom params tag_id_ = tag_id; - HILOG(kDebug, "Setting blob name {}", blob_name.str()); HSHM_MAKE_AR(blob_name_, alloc, blob_name); blob_id_ = blob_id; blob_off_ = blob_off; @@ -279,7 +278,8 @@ struct PutBlobTask : public Task, TaskFlags flags_ = flags; HSHM_MAKE_AR(filename_, alloc, ctx.filename_); page_size_ = ctx.page_size_; - HILOG(kDebug, "Finished setting blob name {}", blob_name.str()); + HILOG(kDebug, "Construct PUT task for {}, while getting BlobId is {}", + blob_name.str(), flags_.Any(HERMES_GET_BLOB_ID)); } /** Destructor */ @@ -314,7 +314,11 @@ struct PutBlobTask : public Task, TaskFlags /** (De)serialize message return */ template - void SerializeEnd(u32 replica, Ar &ar) {} + void SerializeEnd(u32 replica, Ar &ar) { + if (flags_.Any(HERMES_GET_BLOB_ID)) { + ar(blob_id_); + } + } /** Create group */ HSHM_ALWAYS_INLINE @@ -336,12 +340,14 @@ class GetBlobPhase { /** A task to get data from a blob */ struct GetBlobTask : public Task, TaskFlags { IN TagId tag_id_; - IN BlobId blob_id_; + IN hipc::ShmArchive blob_name_; + INOUT BlobId blob_id_; IN size_t blob_off_; IN hipc::Pointer data_; IN hipc::ShmArchive filename_; IN size_t page_size_; INOUT ssize_t data_size_; + IN bitfield32_t flags_; TEMP int phase_ = GetBlobPhase::kStart; TEMP hipc::ShmArchive> bdev_reads_; TEMP PutBlobTask *stage_task_ = nullptr; @@ -357,19 +363,26 @@ struct GetBlobTask : public Task, TaskFlags const DomainId &domain_id, const TaskStateId &state_id, const TagId &tag_id, + const hshm::charbuf &blob_name, const BlobId &blob_id, size_t off, ssize_t data_size, hipc::Pointer &data, - const Context &ctx) : Task(alloc) { + const Context &ctx, + bitfield32_t flags) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetBlob; task_flags_.SetBits(TASK_LOW_LATENCY); - domain_id_ = domain_id; + if (!blob_id.IsNull()) { + lane_hash_ = blob_id.hash_; + domain_id_ = domain_id; + } else { + lane_hash_ = std::hash{}(blob_name); + domain_id_ = DomainId::GetNode(HASH_TO_NODE_ID(lane_hash_)); + } // Custom params tag_id_ = tag_id; @@ -377,20 +390,27 @@ struct GetBlobTask : public Task, TaskFlags blob_off_ = off; data_size_ = data_size; data_ = data; + flags_ = flags; + HSHM_MAKE_AR(blob_name_, alloc, blob_name); HSHM_MAKE_AR(filename_, alloc, ctx.filename_); page_size_ = ctx.page_size_; } + /** Destructor */ + ~GetBlobTask() { + HSHM_DESTROY_AR(blob_name_); + HSHM_DESTROY_AR(filename_); + } + /** (De)serialize message call */ template void SaveStart(Ar &ar) { - // TODO(llogan): Make it so Get takes as input a buffer, instead of returning one DataTransfer xfer(DT_RECEIVER_WRITE, HERMES_MEMORY_MANAGER->Convert(data_), data_size_, domain_id_); task_serialize(ar); ar & xfer; - ar(tag_id_, blob_id_, blob_off_, data_size_, filename_, page_size_); + ar(tag_id_, blob_name_, blob_id_, blob_off_, data_size_, filename_, page_size_, flags_); } /** Deserialize message call */ @@ -400,12 +420,16 @@ struct GetBlobTask : public Task, TaskFlags task_serialize(ar); ar & xfer; data_ = HERMES_MEMORY_MANAGER->Convert(xfer.data_); - ar(tag_id_, blob_id_, blob_off_, data_size_, filename_, page_size_); + ar(tag_id_, blob_name_, blob_id_, blob_off_, data_size_, filename_, page_size_, flags_); } /** (De)serialize message return */ template - void SerializeEnd(u32 replica, Ar &ar) {} + void SerializeEnd(u32 replica, Ar &ar) { + if (flags_.Any(HERMES_GET_BLOB_ID)) { + ar(blob_id_); + } + } /** Create group */ HSHM_ALWAYS_INLINE @@ -438,7 +462,7 @@ struct TagBlobTask : public Task, TaskFlags { const TagId &tag) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kTagBlob; @@ -498,7 +522,7 @@ struct BlobHasTagTask : public Task, TaskFlags { // Initialize task task_node_ = task_node; task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kBlobHasTag; @@ -618,7 +642,7 @@ struct GetBlobNameTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetBlobName; @@ -662,6 +686,7 @@ struct GetBlobNameTask : public Task, TaskFlags { /** Get \a score from \a blob_id BLOB id */ struct GetBlobSizeTask : public Task, TaskFlags { IN TagId tag_id_; + IN hipc::ShmArchive blob_name_; IN BlobId blob_id_; OUT size_t size_; @@ -676,26 +701,38 @@ struct GetBlobSizeTask : public Task, TaskFlags { const DomainId &domain_id, const TaskStateId &state_id, const TagId &tag_id, + const hshm::charbuf &blob_name, const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetBlobSize; task_flags_.SetBits(TASK_LOW_LATENCY); - domain_id_ = domain_id; + if (!blob_id.IsNull()) { + lane_hash_ = blob_id.hash_; + domain_id_ = domain_id; + } else { + lane_hash_ = std::hash{}(blob_name); + domain_id_ = DomainId::GetNode(HASH_TO_NODE_ID(lane_hash_)); + } // Custom tag_id_ = tag_id; + HSHM_MAKE_AR(blob_name_, alloc, blob_name) blob_id_ = blob_id; } + /** Destructor */ + ~GetBlobSizeTask() { + HSHM_DESTROY_AR(blob_name_) + } + /** (De)serialize message call */ template void SerializeStart(Ar &ar) { task_serialize(ar); - ar(tag_id_, blob_id_); + ar(tag_id_, blob_name_, blob_id_); } /** (De)serialize message return */ @@ -734,7 +771,7 @@ struct GetBlobScoreTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetBlobScore; @@ -789,7 +826,7 @@ struct GetBlobBuffersTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetBlobBuffers; @@ -854,7 +891,7 @@ struct RenameBlobTask : public Task, TaskFlags { const hshm::charbuf &new_blob_name) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kRenameBlob; @@ -916,7 +953,7 @@ struct TruncateBlobTask : public Task, TaskFlags { u64 size) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kTruncateBlob; @@ -978,7 +1015,7 @@ struct DestroyBlobTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kDestroyBlob; @@ -1047,7 +1084,7 @@ struct ReorganizeBlobTask : public Task, TaskFlags { u32 node_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = blob_id.unique_; + lane_hash_ = blob_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kReorganizeBlob; diff --git a/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc b/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc index 049445810..df2077126 100644 --- a/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc +++ b/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc @@ -27,8 +27,8 @@ class Server : public TaskLib { /**==================================== * Maps * ===================================*/ - BLOB_ID_MAP_T blob_id_map_; - BLOB_MAP_T blob_map_; + std::vector blob_id_map_; + std::vector blob_map_; std::atomic id_alloc_; /**==================================== @@ -50,54 +50,45 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { id_alloc_ = 0; node_id_ = LABSTOR_CLIENT->node_id_; - switch (task->phase_) { - case ConstructTaskPhase::kCreateTaskStates: { - target_tasks_.reserve(HERMES_SERVER_CONF.devices_.size()); - for (DeviceInfo &dev : HERMES_SERVER_CONF.devices_) { - std::string dev_type; - if (dev.mount_dir_.empty()) { - dev_type = "ram_bdev"; - dev.mount_point_ = hshm::Formatter::format("{}/{}", dev.mount_dir_, dev.dev_name_); - } else { - dev_type = "posix_bdev"; - } - targets_.emplace_back(); - bdev::Client &client = targets_.back(); - bdev::ConstructTask *create_task = client.AsyncCreate( - task->task_node_ + 1, - DomainId::GetLocal(), - "hermes_" + dev.dev_name_, - dev_type, - dev).ptr_; - target_tasks_.emplace_back(create_task); - } - task->phase_ = ConstructTaskPhase::kWaitForTaskStates; - } - - case ConstructTaskPhase::kWaitForTaskStates: { - for (int i = (int)target_tasks_.size() - 1; i >= 0; --i) { - bdev::ConstructTask *tgt_task = target_tasks_[i]; - if (!tgt_task->IsComplete()) { - return; - } - bdev::Client &client = targets_[i]; - client.AsyncCreateComplete(tgt_task); - target_map_.emplace(client.id_, &client); - target_tasks_.pop_back(); - } - blob_mdm_.Init(id_); + // Initialize blob maps + blob_id_map_.resize(LABSTOR_QM_RUNTIME->max_lanes_); + blob_map_.resize(LABSTOR_QM_RUNTIME->max_lanes_); + // Initialize target tasks + target_tasks_.reserve(HERMES_SERVER_CONF.devices_.size()); + for (DeviceInfo &dev : HERMES_SERVER_CONF.devices_) { + std::string dev_type; + if (dev.mount_dir_.empty()) { + dev_type = "ram_bdev"; + dev.mount_point_ = hshm::Formatter::format("{}/{}", dev.mount_dir_, dev.dev_name_); + } else { + dev_type = "posix_bdev"; } - } - - // Create targets - HILOG(kInfo, "Created Blob MDM") + targets_.emplace_back(); + bdev::Client &client = targets_.back(); + bdev::ConstructTask *create_task = client.AsyncCreate( + task->task_node_ + 1, + DomainId::GetLocal(), + "hermes_" + dev.dev_name_, + dev_type, + dev).ptr_; + target_tasks_.emplace_back(create_task); + } + for (int i = 0; i < target_tasks_.size(); ++i) { + bdev::ConstructTask *tgt_task = target_tasks_[i]; + tgt_task->Wait(task); + bdev::Client &client = targets_[i]; + client.AsyncCreateComplete(tgt_task); + target_map_.emplace(client.id_, &client); + } + blob_mdm_.Init(id_); + HILOG(kInfo, "(node {}) Created Blob MDM", LABSTOR_CLIENT->node_id_); task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } @@ -116,7 +107,7 @@ class Server : public TaskLib { /** * Set the Bucket MDM * */ - void SetBucketMdm(SetBucketMdmTask *task) { + void SetBucketMdm(SetBucketMdmTask *task, RunContext &ctx) { bkt_mdm_.Init(task->bkt_mdm_); task->SetModuleComplete(); } @@ -124,24 +115,24 @@ class Server : public TaskLib { /** * Create a blob's metadata * */ - void PutBlob(PutBlobTask *task) { + void PutBlob(PutBlobTask *task, RunContext &ctx) { if (task->phase_ == PutBlobPhase::kCreate) { - PutBlobCreatePhase(task); + PutBlobCreatePhase(task, ctx); } if (task->phase_ == PutBlobPhase::kAllocate) { - PutBlobAllocatePhase(task); + PutBlobAllocatePhase(task, ctx); } if (task->phase_ == PutBlobPhase::kWaitAllocate) { if (!task->cur_bdev_alloc_->IsComplete()){ return; } - PutBlobWaitAllocatePhase(task); + PutBlobWaitAllocatePhase(task, ctx); } if (task->phase_ == PutBlobPhase::kModify) { - PutBlobModifyPhase(task); + PutBlobModifyPhase(task, ctx); } if (task->phase_ == PutBlobPhase::kWaitModify) { - PutBlobWaitModifyPhase(task); + PutBlobWaitModifyPhase(task, ctx); if (task->phase_ == PutBlobPhase::kWaitModify) { return; } @@ -149,18 +140,17 @@ class Server : public TaskLib { } /** Create blob / update metadata for the PUT */ - void PutBlobCreatePhase(PutBlobTask *task) { + void PutBlobCreatePhase(PutBlobTask *task, RunContext &ctx) { HILOG(kDebug, "PutBlobPhase::kCreate {}", task->blob_id_); + // Get the blob info data structure hshm::charbuf blob_name = hshm::to_charbuf(*task->blob_name_); - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { - task->flags_.SetBits(HERMES_BLOB_DID_CREATE); - } - if (task->flags_.Any(HERMES_BLOB_DID_CREATE)) { - blob_map_.emplace(task->blob_id_, BlobInfo()); + if (task->blob_id_.IsNull()) { + task->blob_id_ = GetOrCreateBlobId(task->tag_id_, task->lane_hash_, + blob_name, ctx, task->flags_); } - BlobInfo &blob_info = blob_map_[task->blob_id_]; + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; // Update the blob info if (task->flags_.Any(HERMES_BLOB_DID_CREATE)) { @@ -180,36 +170,45 @@ class Server : public TaskLib { blob_info.UpdateWriteStats(); } if (task->flags_.Any(HERMES_BLOB_REPLACE)) { - PutBlobFreeBuffersPhase(blob_info, task); + PutBlobFreeBuffersPhase(blob_info, task, ctx); } // Stage in blob data from FS task->data_ptr_.ptr_ = LABSTOR_CLIENT->GetPrivatePointer(task->data_); task->data_ptr_.shm_ = task->data_; - if (task->filename_->size() > 0 && blob_info.blob_size_ == 0) { + if (task->filename_->size() > 0) { adapter::BlobPlacement plcmnt; plcmnt.DecodeBlobName(*task->blob_name_); - HILOG(kDebug, "Attempting to stage {} bytes from the backend file {} at offset {}", - task->page_size_, task->filename_->str(), plcmnt.bucket_off_); - LPointer new_data_ptr = LABSTOR_CLIENT->AllocateBuffer(task->page_size_); - int fd = HERMES_POSIX_API->open(task->filename_->c_str(), O_RDONLY); - if (fd < 0) { - HELOG(kError, "Failed to open file {}", task->filename_->str()); - } - int ret = HERMES_POSIX_API->pread(fd, new_data_ptr.ptr_, task->page_size_, (off_t)plcmnt.bucket_off_); - if (ret < 0) { - // TODO(llogan): ret != page_size_ will require knowing file size before-hand - HELOG(kError, "Failed to stage in {} bytes from {}", task->page_size_, task->filename_->str()); - } - HERMES_POSIX_API->close(fd); - memcpy(new_data_ptr.ptr_ + plcmnt.blob_off_, task->data_ptr_.ptr_, task->data_size_); - task->data_ptr_ = new_data_ptr; - task->blob_off_ = 0; - task->data_size_ = ret; + task->flags_.SetBits(HERMES_IS_FILE); task->data_off_ = plcmnt.bucket_off_ + task->blob_off_ + task->data_size_; - task->flags_.SetBits(HERMES_DID_STAGE_IN); - HILOG(kDebug, "Staged {} bytes from the backend file {}", - task->data_size_, task->filename_->str()); + if (blob_info.blob_size_ == 0 && + task->blob_off_ == 0 && + task->data_size_ < task->page_size_) { + HILOG(kDebug, "Attempting to stage {} bytes from the backend file {} at offset {}", + task->page_size_, task->filename_->str(), plcmnt.bucket_off_); + LPointer new_data_ptr = LABSTOR_CLIENT->AllocateBuffer(task->page_size_); + int fd = HERMES_POSIX_API->open(task->filename_->c_str(), O_RDONLY); + if (fd < 0) { + HELOG(kError, "Failed to open file {}", task->filename_->str()); + } + int ret = HERMES_POSIX_API->pread(fd, new_data_ptr.ptr_, task->page_size_, (off_t)plcmnt.bucket_off_); + if (ret < 0) { + // TODO(llogan): ret != page_size_ will require knowing file size before-hand + HELOG(kError, "Failed to stage in {} bytes from {}", task->page_size_, task->filename_->str()); + } + HERMES_POSIX_API->close(fd); + memcpy(new_data_ptr.ptr_ + plcmnt.blob_off_, task->data_ptr_.ptr_, task->data_size_); + task->data_ptr_ = new_data_ptr; + task->blob_off_ = 0; + if (ret < task->blob_off_ + task->data_size_) { + task->data_size_ = task->blob_off_ + task->data_size_; + } else { + task->data_size_ = ret; + } + task->flags_.SetBits(HERMES_DID_STAGE_IN); + HILOG(kDebug, "Staged {} bytes from the backend file {}", + task->data_size_, task->filename_->str()); + } } // Determine amount of additional buffering space needed @@ -218,7 +217,7 @@ class Server : public TaskLib { if (needed_space > blob_info.max_blob_size_) { size_diff = needed_space - blob_info.max_blob_size_; } - if (!task->flags_.Any(HERMES_DID_STAGE_IN)) { + if (!task->flags_.Any(HERMES_IS_FILE)) { task->data_off_ = size_diff; } blob_info.blob_size_ += size_diff; @@ -241,7 +240,7 @@ class Server : public TaskLib { } /** Release buffers */ - void PutBlobFreeBuffersPhase(BlobInfo &blob_info, PutBlobTask *task) { + void PutBlobFreeBuffersPhase(BlobInfo &blob_info, PutBlobTask *task, RunContext &ctx) { for (BufferInfo &buf : blob_info.buffers_) { TargetInfo &target = *target_map_[buf.tid_]; std::vector buf_vec = {buf}; @@ -253,8 +252,9 @@ class Server : public TaskLib { } /** Resolve the current sub-placement using BPM */ - void PutBlobAllocatePhase(PutBlobTask *task) { - BlobInfo &blob_info = blob_map_[task->blob_id_]; + void PutBlobAllocatePhase(PutBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; PlacementSchema &schema = (*task->schema_)[task->plcmnt_idx_]; SubPlacement &placement = schema.plcmnts_[task->sub_plcmnt_idx_]; TargetInfo &bdev = *target_map_[placement.tid_]; @@ -266,8 +266,9 @@ class Server : public TaskLib { } /** Wait for the current-subplacement to complete */ - void PutBlobWaitAllocatePhase(PutBlobTask *task) { - BlobInfo &blob_info = blob_map_[task->blob_id_]; + void PutBlobWaitAllocatePhase(PutBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; PlacementSchema &schema = (*task->schema_)[task->plcmnt_idx_]; ++task->sub_plcmnt_idx_; if (task->sub_plcmnt_idx_ >= schema.plcmnts_.size()) { @@ -292,8 +293,9 @@ class Server : public TaskLib { } /** Update the data on storage */ - void PutBlobModifyPhase(PutBlobTask *task) { - BlobInfo &blob_info = blob_map_[task->blob_id_]; + void PutBlobModifyPhase(PutBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; char *blob_buf = task->data_ptr_.ptr_; std::vector &write_tasks = *task->bdev_writes_; size_t blob_off = 0, buf_off = 0; @@ -327,15 +329,15 @@ class Server : public TaskLib { } /** Wait for the update to complete */ - void PutBlobWaitModifyPhase(PutBlobTask *task) { + void PutBlobWaitModifyPhase(PutBlobTask *task, RunContext &ctx) { std::vector &write_tasks = *task->bdev_writes_; - for (int i = (int)write_tasks.size() - 1; i >= 0; --i) { - bdev::WriteTask *write_task = write_tasks[i]; + for (bdev::WriteTask *&write_task : write_tasks) { if (!write_task->IsComplete()) { return; } + } + for (bdev::WriteTask *&write_task : write_tasks) { LABSTOR_CLIENT->DelTask(write_task); - write_tasks.pop_back(); } HILOG(kDebug, "PutBlobTask complete"); HSHM_DESTROY_AR(task->schema_); @@ -345,7 +347,7 @@ class Server : public TaskLib { } // Update the bucket statistics int update_mode = bucket_mdm::UpdateSizeMode::kAdd; - if (task->flags_.Any(HERMES_DID_STAGE_IN)) { + if (task->flags_.Any(HERMES_IS_FILE)) { update_mode = bucket_mdm::UpdateSizeMode::kCap; } bkt_mdm_.AsyncUpdateSize(task->task_node_ + 1, @@ -361,25 +363,28 @@ class Server : public TaskLib { } /** Get a blob's data */ - void GetBlob(GetBlobTask *task) { + void GetBlob(GetBlobTask *task, RunContext &ctx) { switch (task->phase_) { case GetBlobPhase::kStart: { - GetBlobGetPhase(task); + GetBlobGetPhase(task, ctx); } case GetBlobPhase::kWait: { - GetBlobWaitPhase(task); + GetBlobWaitPhase(task, ctx); } } } - void GetBlobGetPhase(GetBlobTask *task) { - BlobInfo &blob_info = blob_map_[task->blob_id_]; + void GetBlobGetPhase(GetBlobTask *task, RunContext &ctx) { + if (task->blob_id_.IsNull()) { + hshm::charbuf blob_name = hshm::to_charbuf(*task->blob_name_); + task->blob_id_ = GetOrCreateBlobId(task->tag_id_, task->lane_hash_, + blob_name, ctx, task->flags_); + } + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; HSHM_MAKE_AR0(task->bdev_reads_, nullptr); std::vector &read_tasks = *task->bdev_reads_; read_tasks.reserve(blob_info.buffers_.size()); - if (task->data_size_ < 0) { - task->data_size_ = (ssize_t)(blob_info.blob_size_ - task->blob_off_); - } HILOG(kDebug, "Getting blob {} of size {} starting at offset {} (total_blob_size={}, buffers={})", task->blob_id_, task->data_size_, task->blob_off_, blob_info.blob_size_, blob_info.buffers_.size()); size_t blob_off = 0, buf_off = 0; @@ -408,15 +413,15 @@ class Server : public TaskLib { task->phase_ = GetBlobPhase::kWait; } - void GetBlobWaitPhase(GetBlobTask *task) { + void GetBlobWaitPhase(GetBlobTask *task, RunContext &ctx) { std::vector &read_tasks = *task->bdev_reads_; - for (auto it = read_tasks.rbegin(); it != read_tasks.rend(); ++it) { - bdev::ReadTask *read_task = *it; + for (bdev::ReadTask *&read_task : read_tasks) { if (!read_task->IsComplete()) { return; } + } + for (bdev::ReadTask *&read_task : read_tasks) { LABSTOR_CLIENT->DelTask(read_task); - read_tasks.pop_back(); } HSHM_DESTROY_AR(task->bdev_reads_); HILOG(kDebug, "GetBlobTask complete"); @@ -426,9 +431,10 @@ class Server : public TaskLib { /** * Tag a blob * */ - void TagBlob(TagBlobTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void TagBlob(TagBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -440,9 +446,10 @@ class Server : public TaskLib { /** * Check if blob has a tag * */ - void BlobHasTag(BlobHasTagTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void BlobHasTag(BlobHasTagTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -456,17 +463,26 @@ class Server : public TaskLib { /** * Create \a blob_id BLOB ID * */ - void GetOrCreateBlobId(GetOrCreateBlobIdTask *task) { + BlobId GetOrCreateBlobId(TagId &tag_id, u32 lane_hash, + const hshm::charbuf &blob_name, RunContext &ctx, + bitfield32_t &flags) { + hshm::charbuf blob_name_unique = GetBlobNameWithBucket(tag_id, blob_name); + BLOB_ID_MAP_T &blob_id_map = blob_id_map_[ctx.lane_id_]; + auto it = blob_id_map.find(blob_name_unique); + if (it == blob_id_map.end()) { + BlobId blob_id = BlobId(node_id_, lane_hash, id_alloc_.fetch_add(1)); + blob_id_map.emplace(blob_name_unique, blob_id); + flags.SetBits(HERMES_BLOB_DID_CREATE); + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + blob_map.emplace(blob_id, BlobInfo()); + return blob_id; + } + return it->second; + } + void GetOrCreateBlobId(GetOrCreateBlobIdTask *task, RunContext &ctx) { hshm::charbuf blob_name = hshm::to_charbuf(*task->blob_name_); - hshm::charbuf blob_name_unique = GetBlobNameWithBucket(task->tag_id_, blob_name); - auto it = blob_id_map_.find(blob_name_unique); - if (it == blob_id_map_.end()) { - task->blob_id_ = BlobId(node_id_, id_alloc_.fetch_add(1)); - blob_id_map_.emplace(blob_name_unique, task->blob_id_); - task->SetModuleComplete(); - return; - } - task->blob_id_ = it->second; + bitfield32_t flags; + task->blob_id_ = GetOrCreateBlobId(task->tag_id_, task->lane_hash_, blob_name, ctx, flags); task->SetModuleComplete(); } @@ -474,11 +490,12 @@ class Server : public TaskLib { * Get \a blob_name BLOB from \a bkt_id bucket * */ HSHM_ALWAYS_INLINE - void GetBlobId(GetBlobIdTask *task) { + void GetBlobId(GetBlobIdTask *task, RunContext &ctx) { hshm::charbuf blob_name = hshm::to_charbuf(*task->blob_name_); hshm::charbuf blob_name_unique = GetBlobNameWithBucket(task->tag_id_, blob_name); - auto it = blob_id_map_.find(blob_name_unique); - if (it == blob_id_map_.end()) { + BLOB_ID_MAP_T &blob_id_map = blob_id_map_[ctx.lane_id_]; + auto it = blob_id_map.find(blob_name_unique); + if (it == blob_id_map.end()) { task->blob_id_ = BlobId::GetNull(); task->SetModuleComplete(); HILOG(kDebug, "Failed to find blob {} in {}", blob_name.str(), task->tag_id_); @@ -492,9 +509,10 @@ class Server : public TaskLib { /** * Get \a blob_name BLOB name from \a blob_id BLOB id * */ - void GetBlobName(GetBlobNameTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void GetBlobName(GetBlobNameTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -506,9 +524,17 @@ class Server : public TaskLib { /** * Get \a score from \a blob_id BLOB id * */ - void GetBlobSize(GetBlobSizeTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void GetBlobSize(GetBlobSizeTask *task, RunContext &ctx) { + if (task->blob_id_.IsNull()) { + bitfield32_t flags; + task->blob_id_ = GetOrCreateBlobId(task->tag_id_, task->lane_hash_, + hshm::to_charbuf(*task->blob_name_), + ctx, flags); + } + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { + task->size_ = 0; task->SetModuleComplete(); return; } @@ -520,9 +546,10 @@ class Server : public TaskLib { /** * Get \a score from \a blob_id BLOB id * */ - void GetBlobScore(GetBlobScoreTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void GetBlobScore(GetBlobScoreTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -534,9 +561,10 @@ class Server : public TaskLib { /** * Get \a blob_id blob's buffers * */ - void GetBlobBuffers(GetBlobBuffersTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void GetBlobBuffers(GetBlobBuffersTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -549,15 +577,17 @@ class Server : public TaskLib { * Rename \a blob_id blob to \a new_blob_name new blob name * in \a bkt_id bucket. * */ - void RenameBlob(RenameBlobTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void RenameBlob(RenameBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } + BLOB_ID_MAP_T &blob_id_map = blob_id_map_[ctx.lane_id_]; BlobInfo &blob = it->second; - blob_id_map_.erase(blob.name_); - blob_id_map_[blob.name_] = task->blob_id_; + blob_id_map.erase(blob.name_); + blob_id_map[blob.name_] = task->blob_id_; blob.name_ = hshm::to_charbuf(*task->new_blob_name_); task->SetModuleComplete(); } @@ -565,9 +595,10 @@ class Server : public TaskLib { /** * Truncate a blob to a new size * */ - void TruncateBlob(TruncateBlobTask *task) { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + void TruncateBlob(TruncateBlobTask *task, RunContext &ctx) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -579,17 +610,19 @@ class Server : public TaskLib { /** * Destroy \a blob_id blob in \a bkt_id bucket * */ - void DestroyBlob(DestroyBlobTask *task) { + void DestroyBlob(DestroyBlobTask *task, RunContext &ctx) { switch (task->phase_) { case DestroyBlobPhase::kFreeBuffers: { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } + BLOB_ID_MAP_T &blob_id_map = blob_id_map_[ctx.lane_id_]; BlobInfo &blob_info = it->second; hshm::charbuf unique_name = GetBlobNameWithBucket(blob_info.tag_id_, blob_info.name_); - blob_id_map_.erase(unique_name); + blob_id_map.erase(unique_name); HSHM_MAKE_AR0(task->free_tasks_, nullptr); task->free_tasks_->reserve(blob_info.buffers_.size()); for (BufferInfo &buf : blob_info.buffers_) { @@ -603,21 +636,22 @@ class Server : public TaskLib { } case DestroyBlobPhase::kWaitFreeBuffers: { std::vector &free_tasks = *task->free_tasks_; - for (auto it = free_tasks.rbegin(); it != free_tasks.rend(); ++it) { - bdev::FreeTask *free_task = *it; + for (bdev::FreeTask *&free_task : free_tasks) { if (!free_task->IsComplete()) { return; } + } + for (bdev::FreeTask *&free_task : free_tasks) { LABSTOR_CLIENT->DelTask(free_task); - free_tasks.pop_back(); } - BlobInfo &blob_info = blob_map_[task->blob_id_]; + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + BlobInfo &blob_info = blob_map[task->blob_id_]; bkt_mdm_.AsyncUpdateSize(task->task_node_ + 1, task->tag_id_, -(ssize_t)blob_info.blob_size_, bucket_mdm::UpdateSizeMode::kAdd); HSHM_DESTROY_AR(task->free_tasks_); - blob_map_.erase(task->blob_id_); + blob_map.erase(task->blob_id_); task->SetModuleComplete(); } } @@ -626,11 +660,12 @@ class Server : public TaskLib { /** * Reorganize \a blob_id blob in \a bkt_id bucket * */ - void ReorganizeBlob(ReorganizeBlobTask *task) { + void ReorganizeBlob(ReorganizeBlobTask *task, RunContext &ctx) { switch (task->phase_) { case ReorganizeBlobPhase::kGet: { - auto it = blob_map_.find(task->blob_id_); - if (it == blob_map_.end()) { + BLOB_MAP_T &blob_map = blob_map_[ctx.lane_id_]; + auto it = blob_map.find(task->blob_id_); + if (it == blob_map.end()) { task->SetModuleComplete(); return; } @@ -639,6 +674,7 @@ class Server : public TaskLib { task->data_size_ = blob_info.blob_size_; task->get_task_ = blob_mdm_.AsyncGetBlob(task->task_node_ + 1, task->tag_id_, + hshm::charbuf(""), task->blob_id_, 0, task->data_size_, diff --git a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_lib_exec.h b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_lib_exec.h index f1d58e0ab..def2f8430 100644 --- a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_lib_exec.h +++ b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_lib_exec.h @@ -2,66 +2,66 @@ #define LABSTOR_HERMES_BUCKET_MDM_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kGetOrCreateTag: { - GetOrCreateTag(reinterpret_cast(task)); + GetOrCreateTag(reinterpret_cast(task), ctx); break; } case Method::kGetTagId: { - GetTagId(reinterpret_cast(task)); + GetTagId(reinterpret_cast(task), ctx); break; } case Method::kGetTagName: { - GetTagName(reinterpret_cast(task)); + GetTagName(reinterpret_cast(task), ctx); break; } case Method::kRenameTag: { - RenameTag(reinterpret_cast(task)); + RenameTag(reinterpret_cast(task), ctx); break; } case Method::kDestroyTag: { - DestroyTag(reinterpret_cast(task)); + DestroyTag(reinterpret_cast(task), ctx); break; } case Method::kTagAddBlob: { - TagAddBlob(reinterpret_cast(task)); + TagAddBlob(reinterpret_cast(task), ctx); break; } case Method::kTagRemoveBlob: { - TagRemoveBlob(reinterpret_cast(task)); + TagRemoveBlob(reinterpret_cast(task), ctx); break; } case Method::kTagClearBlobs: { - TagClearBlobs(reinterpret_cast(task)); + TagClearBlobs(reinterpret_cast(task), ctx); break; } case Method::kUpdateSize: { - UpdateSize(reinterpret_cast(task)); + UpdateSize(reinterpret_cast(task), ctx); break; } case Method::kAppendBlobSchema: { - AppendBlobSchema(reinterpret_cast(task)); + AppendBlobSchema(reinterpret_cast(task), ctx); break; } case Method::kAppendBlob: { - AppendBlob(reinterpret_cast(task)); + AppendBlob(reinterpret_cast(task), ctx); break; } case Method::kGetSize: { - GetSize(reinterpret_cast(task)); + GetSize(reinterpret_cast(task), ctx); break; } case Method::kSetBlobMdm: { - SetBlobMdm(reinterpret_cast(task)); + SetBlobMdm(reinterpret_cast(task), ctx); break; } } diff --git a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h index f40c18ea2..2dca04d1b 100644 --- a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h +++ b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h @@ -41,12 +41,6 @@ struct ConstructTask : public CreateTaskStateTask { : CreateTaskStateTask(alloc, task_node, domain_id, state_name, "hermes_bucket_mdm", id, queue_info) { } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy hermes_bucket_mdm */ @@ -129,7 +123,7 @@ struct SetBlobMdmTask : public Task, TaskFlags { class UpdateSizeMode { public: TASK_METHOD_T kAdd = 0; - TASK_METHOD_T kCap = 0; + TASK_METHOD_T kCap = 1; }; /** Update bucket size */ @@ -153,7 +147,7 @@ struct UpdateSizeTask : public Task, TaskFlags { int mode) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kUpdateSize; @@ -236,7 +230,7 @@ struct AppendBlobSchemaTask : public Task, TaskFlags { size_t page_size) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kAppendBlobSchema; @@ -305,7 +299,7 @@ struct AppendBlobTask : public Task, TaskFlags { const Context &ctx) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kAppendBlob; @@ -481,7 +475,7 @@ struct GetTagNameTask : public Task, TaskFlags { const TagId &tag_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetTagName; @@ -539,7 +533,7 @@ struct RenameTagTask : public Task, TaskFlags { const hshm::charbuf &tag_name) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kRenameTag; @@ -604,7 +598,7 @@ struct DestroyTagTask : public Task, TaskFlags { TagId tag_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kDestroyTag; @@ -655,7 +649,7 @@ struct TagAddBlobTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kTagAddBlob; @@ -707,7 +701,7 @@ struct TagRemoveBlobTask : public Task, TaskFlags { const BlobId &blob_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kTagRemoveBlob; @@ -766,7 +760,7 @@ struct TagClearBlobsTask : public Task, TaskFlags { TagId tag_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kTagClearBlobs; @@ -816,7 +810,7 @@ struct GetSizeTask : public Task, TaskFlags { TagId tag_id) : Task(alloc) { // Initialize task task_node_ = task_node; - lane_hash_ = tag_id.unique_; + lane_hash_ = tag_id.hash_; prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kGetSize; diff --git a/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc b/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc index e03639c1a..5d1a96fc0 100644 --- a/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc +++ b/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc @@ -17,8 +17,8 @@ typedef std::unordered_map TAG_MAP_T; class Server : public TaskLib { public: - TAG_ID_MAP_T tag_id_map_; - TAG_MAP_T tag_map_; + std::vector tag_id_map_; + std::vector tag_map_; u32 node_id_; std::atomic id_alloc_; Client bkt_mdm_; @@ -27,34 +27,39 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { id_alloc_ = 0; node_id_ = LABSTOR_CLIENT->node_id_; bkt_mdm_.Init(id_); + tag_id_map_.resize(LABSTOR_QM_RUNTIME->max_lanes_); + tag_map_.resize(LABSTOR_QM_RUNTIME->max_lanes_); task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } /** * Set the Blob MDM * */ - void SetBlobMdm(SetBlobMdmTask *task) { + void SetBlobMdm(SetBlobMdmTask *task, RunContext &ctx) { blob_mdm_.Init(task->blob_mdm_); task->SetModuleComplete(); } /** Update the size of the bucket */ - void UpdateSize(UpdateSizeTask *task) { - TagInfo &tag_info = tag_map_[task->tag_id_]; + void UpdateSize(UpdateSizeTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + TagInfo &tag_info = tag_map[task->tag_id_]; ssize_t internal_size = (ssize_t) tag_info.internal_size_; if (task->mode_ == UpdateSizeMode::kAdd) { internal_size += task->update_; } else { internal_size = std::max(task->update_, internal_size); } + HILOG(kDebug, "Updating size of tag {} from {} to {} with update {} (mode={})", + task->tag_id_, tag_info.internal_size_, internal_size, task->update_, task->mode_) tag_info.internal_size_ = (size_t) internal_size; task->SetModuleComplete(); } @@ -62,12 +67,13 @@ class Server : public TaskLib { /** * Create the PartialPuts for append operations. * */ - void AppendBlobSchema(AppendBlobSchemaTask *task) { + void AppendBlobSchema(AppendBlobSchemaTask *task, RunContext &ctx) { switch (task->phase_) { case AppendBlobPhase::kGetBlobIds: { HILOG(kDebug, "(node {}) Getting blob IDs for tag {} (task_node={})", LABSTOR_CLIENT->node_id_, task->tag_id_, task->task_node_) - TagInfo &tag_info = tag_map_[task->tag_id_]; + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + TagInfo &tag_info = tag_map[task->tag_id_]; size_t bucket_size = tag_info.internal_size_; size_t cur_page = bucket_size / task->page_size_; size_t cur_page_off = bucket_size % task->page_size_; @@ -121,7 +127,7 @@ class Server : public TaskLib { * are named 0 ... N. Each blob is assumed to have a certain * fixed page size. * */ - void AppendBlob(AppendBlobTask *task) { + void AppendBlob(AppendBlobTask *task, RunContext &ctx) { switch (task->phase_) { case AppendBlobPhase::kGetBlobIds: { HILOG(kDebug, "(node {}) Appending {} bytes to bucket {} (task_node={})", @@ -182,33 +188,36 @@ class Server : public TaskLib { } /** Get or create a tag */ - void GetOrCreateTag(GetOrCreateTagTask *task) { + void GetOrCreateTag(GetOrCreateTagTask *task, RunContext &ctx) { TagId tag_id; - HILOG(kDebug, "Creating a tag") + HILOG(kDebug, "Creating a tag on lane {}", ctx.lane_id_); // Check if the tag exists + TAG_ID_MAP_T &tag_id_map = tag_id_map_[ctx.lane_id_]; hshm::charbuf tag_name = hshm::to_charbuf(*task->tag_name_); bool did_create = false; if (tag_name.size() > 0) { - did_create = tag_id_map_.find(tag_name) == tag_id_map_.end(); + did_create = tag_id_map.find(tag_name) == tag_id_map.end(); } // Emplace bucket if it does not already exist if (did_create) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; tag_id.unique_ = id_alloc_.fetch_add(1); + tag_id.hash_ = task->lane_hash_; tag_id.node_id_ = LABSTOR_RUNTIME->rpc_.node_id_; HILOG(kDebug, "Creating tag for the first time: {} {}", tag_name.str(), tag_id) - tag_id_map_.emplace(tag_name, tag_id); - tag_map_.emplace(tag_id, TagInfo()); - TagInfo &info = tag_map_[tag_id]; - info.name_ = tag_name; - info.tag_id_ = tag_id; - info.owner_ = task->blob_owner_; - info.internal_size_ = task->backend_size_; + tag_id_map.emplace(tag_name, tag_id); + tag_map.emplace(tag_id, TagInfo()); + TagInfo &tag_info = tag_map[tag_id]; + tag_info.name_ = tag_name; + tag_info.tag_id_ = tag_id; + tag_info.owner_ = task->blob_owner_; + tag_info.internal_size_ = task->backend_size_; } else { if (tag_name.size()) { HILOG(kDebug, "Found existing tag: {}", tag_name.str()) - tag_id = tag_id_map_[tag_name]; + tag_id = tag_id_map[tag_name]; } else { HILOG(kDebug, "Found existing tag: {}", task->tag_id_) tag_id = task->tag_id_; @@ -221,10 +230,11 @@ class Server : public TaskLib { } /** Get tag ID */ - void GetTagId(GetTagIdTask *task) { + void GetTagId(GetTagIdTask *task, RunContext &ctx) { + TAG_ID_MAP_T &tag_id_map = tag_id_map_[ctx.lane_id_]; hshm::charbuf tag_name = hshm::to_charbuf(*task->tag_name_); - auto it = tag_id_map_.find(tag_name); - if (it == tag_id_map_.end()) { + auto it = tag_id_map.find(tag_name); + if (it == tag_id_map.end()) { task->tag_id_ = TagId::GetNull(); task->SetModuleComplete(); return; @@ -234,9 +244,10 @@ class Server : public TaskLib { } /** Get tag name */ - void GetTagName(GetTagNameTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void GetTagName(GetTagNameTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->SetModuleComplete(); return; } @@ -245,9 +256,10 @@ class Server : public TaskLib { } /** Rename tag */ - void RenameTag(RenameTagTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void RenameTag(RenameTagTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->SetModuleComplete(); return; } @@ -256,11 +268,13 @@ class Server : public TaskLib { } /** Destroy tag */ - void DestroyTag(DestroyTagTask *task) { + void DestroyTag(DestroyTagTask *task, RunContext &ctx) { switch (task->phase_) { case DestroyTagPhase::kDestroyBlobs: { - TagInfo &tag = tag_map_[task->tag_id_]; - tag_id_map_.erase(tag.name_); + TAG_ID_MAP_T &tag_id_map = tag_id_map_[ctx.lane_id_]; + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + TagInfo &tag = tag_map[task->tag_id_]; + tag_id_map.erase(tag.name_); HSHM_MAKE_AR0(task->destroy_blob_tasks_, nullptr); std::vector blob_tasks = *task->destroy_blob_tasks_; blob_tasks.reserve(tag.blobs_.size()); @@ -274,25 +288,27 @@ class Server : public TaskLib { } case DestroyTagPhase::kWaitDestroyBlobs: { std::vector blob_tasks = *task->destroy_blob_tasks_; - for (auto it = blob_tasks.rbegin(); it != blob_tasks.rend(); ++it) { - blob_mdm::DestroyBlobTask *blob_task = *it; + for (blob_mdm::DestroyBlobTask *&blob_task : blob_tasks) { if (!blob_task->IsComplete()) { return; } + } + for (blob_mdm::DestroyBlobTask *&blob_task : blob_tasks) { LABSTOR_CLIENT->DelTask(blob_task); - blob_tasks.pop_back(); } HSHM_DESTROY_AR(task->destroy_blob_tasks_); - tag_map_.erase(task->tag_id_); + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + tag_map.erase(task->tag_id_); task->SetModuleComplete(); } } } /** Add a blob to a tag */ - void TagAddBlob(TagAddBlobTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void TagAddBlob(TagAddBlobTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->SetModuleComplete(); return; } @@ -302,9 +318,10 @@ class Server : public TaskLib { } /** Remove a blob from a tag */ - void TagRemoveBlob(TagRemoveBlobTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void TagRemoveBlob(TagRemoveBlobTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->SetModuleComplete(); return; } @@ -315,9 +332,10 @@ class Server : public TaskLib { } /** Clear blobs from a tag */ - void TagClearBlobs(TagClearBlobsTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void TagClearBlobs(TagClearBlobsTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->SetModuleComplete(); return; } @@ -328,9 +346,10 @@ class Server : public TaskLib { } /** Get size of the bucket */ - void GetSize(GetSizeTask *task) { - auto it = tag_map_.find(task->tag_id_); - if (it == tag_map_.end()) { + void GetSize(GetSizeTask *task, RunContext &ctx) { + TAG_MAP_T &tag_map = tag_map_[ctx.lane_id_]; + auto it = tag_map.find(task->tag_id_); + if (it == tag_map.end()) { task->size_ = 0; task->SetModuleComplete(); return; diff --git a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_lib_exec.h b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_lib_exec.h index 127126f51..2d5c8cd7b 100644 --- a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_lib_exec.h +++ b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_lib_exec.h @@ -2,14 +2,14 @@ #define LABSTOR_HERMES_MDM_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } } diff --git a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_tasks.h b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_tasks.h index 143f0b055..3a78e6de6 100644 --- a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_tasks.h +++ b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm_tasks.h @@ -60,12 +60,6 @@ struct ConstructTask : public CreateTaskStateTask { /** (De)serialize message return */ template void SerializeEnd(u32 replica, Ar &ar) {} - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy hermes_mdm */ diff --git a/tasks/hermes_mdm/src/hermes_mdm.cc b/tasks/hermes_mdm/src/hermes_mdm.cc index d424753cb..9c5557b88 100644 --- a/tasks/hermes_mdm/src/hermes_mdm.cc +++ b/tasks/hermes_mdm/src/hermes_mdm.cc @@ -25,7 +25,7 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { HILOG(kDebug, "ConstructTaskPhase::kLoadConfig") std::string config_path = task->server_config_path_->str(); HERMES_CONF->LoadServerConfig(config_path); @@ -33,7 +33,7 @@ class Server : public TaskLib { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } diff --git a/tasks/posix_bdev/src/posix_bdev.cc b/tasks/posix_bdev/src/posix_bdev.cc index f33cc8609..038debf86 100644 --- a/tasks/posix_bdev/src/posix_bdev.cc +++ b/tasks/posix_bdev/src/posix_bdev.cc @@ -17,12 +17,11 @@ namespace hermes::posix_bdev { class Server : public TaskLib { public: SlabAllocator alloc_; - char *mem_ptr_; int fd_; std::string path_; public: - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { DeviceInfo &dev_info = task->info_; alloc_.Init(id_, dev_info.capacity_, dev_info.slab_sizes_); std::string text = dev_info.mount_dir_ + @@ -31,7 +30,7 @@ class Server : public TaskLib { dev_info.mount_point_ = canon; path_ = canon; fd_ = open(dev_info.mount_point_.c_str(), - O_TRUNC | O_CREAT, 0666); + O_TRUNC | O_CREAT | O_RDWR, 0666); if (fd_ < 0) { HELOG(kError, "Failed to open file: {}", dev_info.mount_point_); } @@ -40,34 +39,34 @@ class Server : public TaskLib { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { - free(mem_ptr_); + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Alloc(AllocateTask *task) { + void Allocate(AllocateTask *task, RunContext &ctx) { alloc_.Allocate(task->size_, *task->buffers_, task->alloc_size_); HILOG(kDebug, "Allocated {}/{} bytes ({})", task->alloc_size_, task->size_, path_); task->SetModuleComplete(); } - void Free(FreeTask *task) { + void Free(FreeTask *task, RunContext &ctx) { alloc_.Free(task->buffers_); task->SetModuleComplete(); } - void Write(WriteTask *task) { - size_t count = pwrite(fd_, task->buf_, task->size_, (off_t)task->disk_off_); + void Write(WriteTask *task, RunContext &ctx) { + HILOG(kDebug, "Writing {} bytes to {}", task->size_, path_); + ssize_t count = pwrite(fd_, task->buf_, task->size_, (off_t)task->disk_off_); if (count != task->size_) { - HELOG(kError, "BORG: wrote {} bytes, but expected {}", - count, task->size_); + HELOG(kError, "BORG: wrote {} bytes, but expected {}: {}", + count, task->size_, strerror(errno)); } task->SetModuleComplete(); } - void Read(ReadTask *task) { - memcpy(task->buf_, mem_ptr_ + task->disk_off_, task->size_); - size_t count = pread(fd_, task->buf_, task->size_, (off_t)task->disk_off_); + void Read(ReadTask *task, RunContext &ctx) { + HILOG(kDebug, "Reading {} bytes from {}", task->size_, path_); + ssize_t count = pread(fd_, task->buf_, task->size_, (off_t)task->disk_off_); if (count != task->size_) { HELOG(kError, "BORG: read {} bytes, but expected {}", count, task->size_); @@ -75,10 +74,10 @@ class Server : public TaskLib { task->SetModuleComplete(); } - void Monitor(MonitorTask *task) { + void Monitor(MonitorTask *task, RunContext &ctx) { } - void UpdateCapacity(UpdateCapacityTask *task) { + void UpdateCapacity(UpdateCapacityTask *task, RunContext &ctx) { task->SetModuleComplete(); } diff --git a/tasks/ram_bdev/src/ram_bdev.cc b/tasks/ram_bdev/src/ram_bdev.cc index 9131018df..ec1ae7107 100644 --- a/tasks/ram_bdev/src/ram_bdev.cc +++ b/tasks/ram_bdev/src/ram_bdev.cc @@ -15,7 +15,7 @@ class Server : public TaskLib { char *mem_ptr_; public: - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { DeviceInfo &dev_info = task->info_; alloc_.Init(id_, dev_info.capacity_, dev_info.slab_sizes_); mem_ptr_ = (char*)malloc(dev_info.capacity_); @@ -24,37 +24,39 @@ class Server : public TaskLib { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { free(mem_ptr_); task->SetModuleComplete(); } - void Alloc(AllocateTask *task) { + void Allocate(AllocateTask *task, RunContext &ctx) { HILOG(kDebug, "Allocating {} bytes (RAM)", task->size_); alloc_.Allocate(task->size_, *task->buffers_, task->alloc_size_); HILOG(kDebug, "Allocated {} bytes (RAM)", task->alloc_size_); task->SetModuleComplete(); } - void Free(FreeTask *task) { + void Free(FreeTask *task, RunContext &ctx) { alloc_.Free(task->buffers_); task->SetModuleComplete(); } - void Write(WriteTask *task) { + void Write(WriteTask *task, RunContext &ctx) { + HILOG(kDebug, "Writing {} bytes to RAM", task->size_); memcpy(mem_ptr_ + task->disk_off_, task->buf_, task->size_); task->SetModuleComplete(); } - void Read(ReadTask *task) { + void Read(ReadTask *task, RunContext &ctx) { + HILOG(kDebug, "Reading {} bytes from RAM", task->size_); memcpy(task->buf_, mem_ptr_ + task->disk_off_, task->size_); task->SetModuleComplete(); } - void Monitor(MonitorTask *task) { + void Monitor(MonitorTask *task, RunContext &ctx) { } - void UpdateCapacity(UpdateCapacityTask *task) { + void UpdateCapacity(UpdateCapacityTask *task, RunContext &ctx) { task->SetModuleComplete(); } diff --git a/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_lib_exec.h b/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_lib_exec.h index c603dac50..95ba64a49 100644 --- a/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_lib_exec.h +++ b/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_lib_exec.h @@ -2,18 +2,18 @@ #define LABSTOR_TASK_NAME_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kCustom: { - Custom(reinterpret_cast(task)); + Custom(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_tasks.h b/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_tasks.h index 52b4c6bce..0c464e258 100644 --- a/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_tasks.h +++ b/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME_tasks.h @@ -45,12 +45,6 @@ struct ConstructTask : public CreateTaskStateTask { ~ConstructTask() { // Custom params } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy TASK_NAME */ diff --git a/tasks_required/TASK_NAME/src/TASK_NAME.cc b/tasks_required/TASK_NAME/src/TASK_NAME.cc index 9142ee436..03ff393dd 100644 --- a/tasks_required/TASK_NAME/src/TASK_NAME.cc +++ b/tasks_required/TASK_NAME/src/TASK_NAME.cc @@ -12,15 +12,15 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Custom(CustomTask *task) { + void Custom(CustomTask *task, RunContext &ctx) { task->SetModuleComplete(); } diff --git a/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_lib_exec.h b/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_lib_exec.h index 2cfe22c2b..0bcdc2d02 100644 --- a/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_lib_exec.h +++ b/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_lib_exec.h @@ -2,42 +2,42 @@ #define LABSTOR_LABSTOR_ADMIN_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kCreateTaskState: { - CreateTaskState(reinterpret_cast(task)); + CreateTaskState(reinterpret_cast(task), ctx); break; } case Method::kDestroyTaskState: { - DestroyTaskState(reinterpret_cast(task)); + DestroyTaskState(reinterpret_cast(task), ctx); break; } case Method::kRegisterTaskLib: { - RegisterTaskLib(reinterpret_cast(task)); + RegisterTaskLib(reinterpret_cast(task), ctx); break; } case Method::kDestroyTaskLib: { - DestroyTaskLib(reinterpret_cast(task)); + DestroyTaskLib(reinterpret_cast(task), ctx); break; } case Method::kGetOrCreateTaskStateId: { - GetOrCreateTaskStateId(reinterpret_cast(task)); + GetOrCreateTaskStateId(reinterpret_cast(task), ctx); break; } case Method::kGetTaskStateId: { - GetTaskStateId(reinterpret_cast(task)); + GetTaskStateId(reinterpret_cast(task), ctx); break; } case Method::kStopRuntime: { - StopRuntime(reinterpret_cast(task)); + StopRuntime(reinterpret_cast(task), ctx); break; } case Method::kSetWorkOrchQueuePolicy: { - SetWorkOrchQueuePolicy(reinterpret_cast(task)); + SetWorkOrchQueuePolicy(reinterpret_cast(task), ctx); break; } case Method::kSetWorkOrchProcPolicy: { - SetWorkOrchProcPolicy(reinterpret_cast(task)); + SetWorkOrchProcPolicy(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_tasks.h b/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_tasks.h index d236af213..dd28394e9 100644 --- a/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_tasks.h +++ b/tasks_required/labstor_admin/include/labstor_admin/labstor_admin_tasks.h @@ -147,8 +147,6 @@ struct CreateTaskStateTask : public Task, TaskFlags { IN hipc::ShmArchive state_name_; IN hipc::ShmArchive> queue_info_; INOUT TaskStateId id_; - TEMP int phase_ = 0; - TEMP GetOrCreateTaskStateIdTask *get_id_task_; /** SHM default constructor */ HSHM_ALWAYS_INLINE explicit @@ -169,7 +167,7 @@ struct CreateTaskStateTask : public Task, TaskFlags { prio_ = TaskPrio::kAdmin; task_state_ = LABSTOR_QM_CLIENT->admin_task_state_; method_ = Method::kCreateTaskState; - task_flags_.SetBits(0); + task_flags_.SetBits(TASK_COROUTINE); domain_id_ = domain_id; // Initialize @@ -198,7 +196,7 @@ struct CreateTaskStateTask : public Task, TaskFlags { template void SerializeStart(Ar &ar) { task_serialize(ar); - ar(lib_name_, state_name_, id_, queue_info_, phase_); + ar(lib_name_, state_name_, id_, queue_info_); } /** (De)serialize message return */ @@ -210,7 +208,9 @@ struct CreateTaskStateTask : public Task, TaskFlags { /** Create group */ HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; + LocalSerialize srl(group); + srl << 16; + return 0; } }; diff --git a/tasks_required/labstor_admin/src/labstor_admin.cc b/tasks_required/labstor_admin/src/labstor_admin.cc index 957756fc9..d80e4998a 100644 --- a/tasks_required/labstor_admin/src/labstor_admin.cc +++ b/tasks_required/labstor_admin/src/labstor_admin.cc @@ -16,131 +16,97 @@ class Server : public TaskLib { public: Server() : queue_sched_(nullptr), proc_sched_(nullptr) {} - void RegisterTaskLib(RegisterTaskLibTask *task) { + void RegisterTaskLib(RegisterTaskLibTask *task, RunContext &ctx) { std::string lib_name = task->lib_name_->str(); LABSTOR_TASK_REGISTRY->RegisterTaskLib(lib_name); task->SetModuleComplete(); } - void DestroyTaskLib(DestroyTaskLibTask *task) { + void DestroyTaskLib(DestroyTaskLibTask *task, RunContext &ctx) { std::string lib_name = task->lib_name_->str(); LABSTOR_TASK_REGISTRY->DestroyTaskLib(lib_name); task->SetModuleComplete(); } - void GetOrCreateTaskStateId(GetOrCreateTaskStateIdTask *task) { + void GetOrCreateTaskStateId(GetOrCreateTaskStateIdTask *task, RunContext &ctx) { std::string state_name = task->state_name_->str(); task->id_ = LABSTOR_TASK_REGISTRY->GetOrCreateTaskStateId(state_name); task->SetModuleComplete(); } - void CreateTaskState(CreateTaskStateTask *task) { - switch (task->phase_) { - case CreateTaskStatePhase::kIdAllocStart: { - std::string lib_name = task->lib_name_->str(); - std::string state_name = task->state_name_->str(); - // Check local registry for task state - TaskState *task_state = LABSTOR_TASK_REGISTRY->GetTaskState(state_name, task->id_); - if (task_state) { - task->id_ = task_state->id_; - task->SetModuleComplete(); - return; - } - // Check global registry for task state - if (task->id_.IsNull()) { -// if (task->domain_id_ == DomainId::GetLocal()) { -// HILOG(kDebug, "Domain ID is local for {} (task_node={})", state_name, task->task_node_); -// task->id_ = LABSTOR_TASK_REGISTRY->GetOrCreateTaskStateId(state_name); -// task->phase_ = CreateTaskStatePhase::kStateCreate; -// } else { - HILOG(kDebug, "Domain ID is global for {} (task_node={})", state_name, task->task_node_); - DomainId domain = DomainId::GetNode(1); - task->get_id_task_ = LABSTOR_ADMIN->AsyncGetOrCreateTaskStateId( - task->task_node_ + 1, domain, state_name).ptr_; - task->phase_ = CreateTaskStatePhase::kIdAllocWait; -// } - } else { - HILOG(kDebug, "Domain ID is given as {} for {} (task_node={})", task->id_, state_name, task->task_node_); - task->phase_ = CreateTaskStatePhase::kStateCreate; - } - return; - } - case CreateTaskStatePhase::kIdAllocWait: { - if (!task->get_id_task_->IsComplete()) { - return; - } - task->id_ = task->get_id_task_->id_; - task->phase_ = CreateTaskStatePhase::kStateCreate; - LABSTOR_CLIENT->DelTask(task->get_id_task_); - } - case CreateTaskStatePhase::kStateCreate: { - std::string lib_name = task->lib_name_->str(); - std::string state_name = task->state_name_->str(); - HILOG(kInfo, "(node {}) Creating task state {} with id {} (task_node={})", - LABSTOR_CLIENT->node_id_, state_name, task->id_, task->task_node_); - - // Verify the state isn't NULL - if (task->id_.IsNull()) { - HELOG(kError, "(node {}) The task state {} with id {} is NULL.", - LABSTOR_CLIENT->node_id_, state_name, task->id_); - task->SetModuleComplete(); - return; - } - - // Verify the state doesn't exist - if (LABSTOR_TASK_REGISTRY->TaskStateExists(task->id_)) { - HILOG(kInfo, "(node {}) The task state {} with id {} exists", - LABSTOR_CLIENT->node_id_, state_name, task->id_); - task->SetModuleComplete(); - return; - } - - // The state is being created - // NOTE(llogan): this does NOT return since task creations can have phases - task->method_ = Method::kConstruct; - - // Create the task queue for the state - QueueId qid(task->id_); - LABSTOR_QM_RUNTIME->CreateQueue( - qid, task->queue_info_->vec()); - - // Begin creating the task state - task->phase_ = 0; - task->task_state_ = task->id_; - bool ret = LABSTOR_TASK_REGISTRY->CreateTaskState( - lib_name.c_str(), - state_name.c_str(), - task->id_, - task); - if (!ret) { - task->SetModuleComplete(); - return; - } - HILOG(kInfo, "(node {}) Allocated task state {} with id {}", - LABSTOR_CLIENT->node_id_, state_name, task->task_state_); - } + void CreateTaskState(CreateTaskStateTask *task, RunContext &ctx) { + std::string lib_name = task->lib_name_->str(); + std::string state_name = task->state_name_->str(); + // Check local registry for task state + TaskState *task_state = LABSTOR_TASK_REGISTRY->GetTaskState(state_name, task->id_); + if (task_state) { + task->id_ = task_state->id_; + task->SetModuleComplete(); + return; + } + // Check global registry for task state + if (task->id_.IsNull()) { + DomainId domain = DomainId::GetNode(1); + LPointer get_id = + LABSTOR_ADMIN->AsyncGetOrCreateTaskStateId(task->task_node_ + 1, domain, state_name); + get_id->Wait(task); + task->id_ = get_id->id_; + LABSTOR_CLIENT->DelTask(get_id); + } + // Create the task state + HILOG(kInfo, "(node {}) Creating task state {} with id {} (task_node={})", + LABSTOR_CLIENT->node_id_, state_name, task->id_, task->task_node_); + if (task->id_.IsNull()) { + HELOG(kError, "(node {}) The task state {} with id {} is NULL.", + LABSTOR_CLIENT->node_id_, state_name, task->id_); + task->SetModuleComplete(); + return; + } + // Verify the state doesn't exist + if (LABSTOR_TASK_REGISTRY->TaskStateExists(task->id_)) { + HILOG(kInfo, "(node {}) The task state {} with id {} exists", + LABSTOR_CLIENT->node_id_, state_name, task->id_); + task->SetModuleComplete(); + return; + } + // Create the task queue for the state + QueueId qid(task->id_); + LABSTOR_QM_RUNTIME->CreateQueue( + qid, task->queue_info_->vec()); + // Run the task state's submethod + task->method_ = Method::kConstruct; + bool ret = LABSTOR_TASK_REGISTRY->CreateTaskState( + lib_name.c_str(), + state_name.c_str(), + task->id_, + task); + if (!ret) { + task->SetModuleComplete(); + return; } + HILOG(kInfo, "(node {}) Allocated task state {} with id {}", + LABSTOR_CLIENT->node_id_, state_name, task->task_state_); } - void GetTaskStateId(GetTaskStateIdTask *task) { + void GetTaskStateId(GetTaskStateIdTask *task, RunContext &ctx) { std::string state_name = task->state_name_->str(); task->id_ = LABSTOR_TASK_REGISTRY->GetTaskStateId(state_name); task->SetModuleComplete(); } - void DestroyTaskState(DestroyTaskStateTask *task) { + void DestroyTaskState(DestroyTaskStateTask *task, RunContext &ctx) { LABSTOR_TASK_REGISTRY->DestroyTaskState(task->id_); task->SetModuleComplete(); } - void StopRuntime(StopRuntimeTask *task) { + void StopRuntime(StopRuntimeTask *task, RunContext &ctx) { HILOG(kInfo, "Stopping (server mode)"); LABSTOR_WORK_ORCHESTRATOR->FinalizeRuntime(); LABSTOR_THALLIUM->StopThisDaemon(); task->SetModuleComplete(); } - void SetWorkOrchQueuePolicy(SetWorkOrchQueuePolicyTask *task) { + void SetWorkOrchQueuePolicy(SetWorkOrchQueuePolicyTask *task, RunContext &ctx) { if (queue_sched_) { queue_sched_->SetModuleComplete(); } @@ -155,7 +121,7 @@ class Server : public TaskLib { task->SetModuleComplete(); } - void SetWorkOrchProcPolicy(SetWorkOrchProcPolicyTask *task) { + void SetWorkOrchProcPolicy(SetWorkOrchProcPolicyTask *task, RunContext &ctx) { if (proc_sched_) { proc_sched_->SetModuleComplete(); } diff --git a/tasks_required/proc_queue/include/proc_queue/proc_queue.h b/tasks_required/proc_queue/include/proc_queue/proc_queue.h index b6aa51aab..527bf3ec1 100644 --- a/tasks_required/proc_queue/include/proc_queue/proc_queue.h +++ b/tasks_required/proc_queue/include/proc_queue/proc_queue.h @@ -59,7 +59,7 @@ class Client : public TaskLibClient { void AsyncPushConstruct(labpq::TypedPushTask *task, const TaskNode &task_node, const DomainId &domain_id, - const hipc::Pointer &subtask) { + const hipc::LPointer &subtask) { LABSTOR_CLIENT->ConstructTask( task, task_node, domain_id, id_, subtask); } @@ -68,7 +68,7 @@ class Client : public TaskLibClient { LPointer> AsyncPush(const TaskNode &task_node, const DomainId &domain_id, - const hipc::Pointer &subtask) { + const hipc::LPointer &subtask) { LPointer> push_task = LABSTOR_CLIENT->AllocateTask>(); AsyncPushConstruct(push_task.ptr_, task_node, domain_id, subtask); diff --git a/tasks_required/proc_queue/include/proc_queue/proc_queue_lib_exec.h b/tasks_required/proc_queue/include/proc_queue/proc_queue_lib_exec.h index bea645d52..f7f4ef23f 100644 --- a/tasks_required/proc_queue/include/proc_queue/proc_queue_lib_exec.h +++ b/tasks_required/proc_queue/include/proc_queue/proc_queue_lib_exec.h @@ -2,18 +2,18 @@ #define LABSTOR_PROC_QUEUE_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kPush: { - Push(reinterpret_cast(task)); + Push(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/proc_queue/include/proc_queue/proc_queue_tasks.h b/tasks_required/proc_queue/include/proc_queue/proc_queue_tasks.h index 002f42436..9372d1307 100644 --- a/tasks_required/proc_queue/include/proc_queue/proc_queue_tasks.h +++ b/tasks_required/proc_queue/include/proc_queue/proc_queue_tasks.h @@ -42,12 +42,6 @@ struct ConstructTask : public CreateTaskStateTask { ~ConstructTask() { // Custom params } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy proc_queue */ @@ -84,9 +78,8 @@ class PushTaskPhase { * */ template struct TypedPushTask : public Task, TaskFlags { - IN hipc::Pointer subtask_; //< SHM pointer to the subtask - TEMP TaskT *subtask_ptr_; //< Pointer to the subtask (client) - TEMP TaskT *ptr_; //< Pointer to the subtask (server) + IN LPointer sub_cli_; /**< Pointer to the subtask (client + SHM) */ + TEMP LPointer sub_run_; /**< Pointer to the subtask (runtime) */ TEMP int phase_ = PushTaskPhase::kSchedule; /** SHM default constructor */ @@ -99,7 +92,7 @@ struct TypedPushTask : public Task, TaskFlags { const TaskNode &task_node, const DomainId &domain_id, const TaskStateId &state_id, - const hipc::Pointer &subtask) : Task(alloc) { + const hipc::LPointer &subtask) : Task(alloc) { // Initialize task hshm::NodeThreadId tid; task_node_ = task_node; @@ -111,8 +104,16 @@ struct TypedPushTask : public Task, TaskFlags { domain_id_ = domain_id; // Custom params - subtask_ = subtask; - subtask_ptr_ = (TaskT*)LABSTOR_CLIENT->GetPrivatePointer(subtask_); + sub_cli_ = subtask; + } + + /** Destructor */ + ~TypedPushTask() { + if (!IsFireAndForget()) { + LABSTOR_CLIENT->DelTask(sub_cli_); + } else { + LABSTOR_CLIENT->DelTask(sub_run_); + } } /** Create group */ @@ -126,7 +127,7 @@ struct TypedPushTask : public Task, TaskFlags { /** Get the task address */ HSHM_ALWAYS_INLINE TaskT* get() { - return subtask_ptr_; + return sub_cli_.ptr_; } }; diff --git a/tasks_required/proc_queue/src/proc_queue.cc b/tasks_required/proc_queue/src/proc_queue.cc index 31016b865..7a74ce5d8 100644 --- a/tasks_required/proc_queue/src/proc_queue.cc +++ b/tasks_required/proc_queue/src/proc_queue.cc @@ -12,32 +12,35 @@ class Server : public TaskLib { public: Server() = default; - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Push(PushTask *task) { + void Push(PushTask *task, RunContext &ctx) { switch (task->phase_) { case PushTaskPhase::kSchedule: { - task->ptr_ = LABSTOR_CLIENT->GetPrivatePointer(task->subtask_); + task->sub_run_.shm_ = task->sub_cli_.shm_; + task->sub_run_.ptr_ = LABSTOR_CLIENT->GetPrivatePointer(task->sub_cli_.shm_); + Task *&ptr = task->sub_run_.ptr_; HILOG(kDebug, "Scheduling task {} on state {} tid {}", - task->ptr_->task_node_, task->ptr_->task_state_, GetLinuxTid()); - if (task->ptr_->IsFireAndForget()) { - task->ptr_->UnsetFireAndForget(); + ptr->task_node_, ptr->task_state_, GetLinuxTid()); + if (ptr->IsFireAndForget()) { + ptr->UnsetFireAndForget(); } - MultiQueue *real_queue = LABSTOR_CLIENT->GetQueue(QueueId(task->ptr_->task_state_)); - real_queue->Emplace(task->ptr_->prio_, task->ptr_->lane_hash_, task->subtask_); + MultiQueue *real_queue = LABSTOR_CLIENT->GetQueue(QueueId(ptr->task_state_)); + real_queue->Emplace(ptr->prio_, ptr->lane_hash_, task->sub_run_.shm_); task->phase_ = PushTaskPhase::kWaitSchedule; } case PushTaskPhase::kWaitSchedule: { - if (!task->ptr_->IsComplete()) { + Task *&ptr = task->sub_run_.ptr_; + if (!ptr->IsComplete()) { return; } - LABSTOR_CLIENT->DelTask(task->ptr_); + // TODO(llogan): handle fire & forget tasks gracefully task->SetModuleComplete(); } } diff --git a/tasks_required/remote_queue/include/remote_queue/remote_queue.h b/tasks_required/remote_queue/include/remote_queue/remote_queue.h index e733c2b42..f0cf88119 100644 --- a/tasks_required/remote_queue/include/remote_queue/remote_queue.h +++ b/tasks_required/remote_queue/include/remote_queue/remote_queue.h @@ -35,7 +35,8 @@ class Client : public TaskLibClient { std::vector queue_info = { {1, 1, qm.queue_depth_, 0}, {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + // {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {1, 1, qm.queue_depth_, QUEUE_LOW_LATENCY} }; return LABSTOR_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info); diff --git a/tasks_required/remote_queue/include/remote_queue/remote_queue_lib_exec.h b/tasks_required/remote_queue/include/remote_queue/remote_queue_lib_exec.h index e0ff029c2..1bb6e92a9 100644 --- a/tasks_required/remote_queue/include/remote_queue/remote_queue_lib_exec.h +++ b/tasks_required/remote_queue/include/remote_queue/remote_queue_lib_exec.h @@ -2,18 +2,18 @@ #define LABSTOR_REMOTE_QUEUE_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kPush: { - Push(reinterpret_cast(task)); + Push(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/remote_queue/include/remote_queue/remote_queue_tasks.h b/tasks_required/remote_queue/include/remote_queue/remote_queue_tasks.h index a3c120771..c3e79057d 100644 --- a/tasks_required/remote_queue/include/remote_queue/remote_queue_tasks.h +++ b/tasks_required/remote_queue/include/remote_queue/remote_queue_tasks.h @@ -45,12 +45,6 @@ struct ConstructTask : public CreateTaskStateTask { "remote_queue", id, queue_info) { // Custom params } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy remote_queue */ @@ -94,10 +88,6 @@ struct PushTask : public Task, TaskFlags { IN TaskState *exec_; IN u32 exec_method_; IN std::vector xfer_; - // TEMP std::vector tl_future_; - TEMP std::vector tl_future_; - TEMP int phase_ = PushPhase::kStart; - TEMP int replica_; TEMP std::string params_; /** SHM default constructor */ @@ -121,7 +111,7 @@ struct PushTask : public Task, TaskFlags { prio_ = TaskPrio::kLowLatency; task_state_ = state_id; method_ = Method::kPush; - task_flags_.SetBits(TASK_LOW_LATENCY); + task_flags_.SetBits(TASK_LOW_LATENCY | TASK_PREEMPTIVE); domain_id_ = domain_id; // Custom params @@ -130,7 +120,6 @@ struct PushTask : public Task, TaskFlags { exec_ = exec; exec_method_ = exec_method; xfer_ = std::move(xfer); - replica_ = 0; } /** Create group */ diff --git a/tasks_required/remote_queue/src/remote_queue.cc b/tasks_required/remote_queue/src/remote_queue.cc index 6ae81d883..b0718a7c7 100644 --- a/tasks_required/remote_queue/src/remote_queue.cc +++ b/tasks_required/remote_queue/src/remote_queue.cc @@ -15,39 +15,6 @@ SERIALIZE_ENUM(labstor::IoType); namespace labstor::remote_queue { -/** Parameters for spawning async thread for thallium */ -struct ThalliumTask { - int replica_; - PushTask *task_; - DomainId domain_id_; - IoType io_type_; - char *data_; - size_t data_size_; - ABT_thread thread_; - bool done_; - - /** Default constructor */ - ThalliumTask() : done_(false) {}; - - /** Emplace constructor Small */ - ThalliumTask(int replica, PushTask *task, DomainId domain_id) : - replica_(replica), task_(task), domain_id_(domain_id), done_(false) {} - - /** Emplace constructor I/O */ - ThalliumTask(int replica, PushTask *task, DomainId domain_id, - IoType io_type, void *data, size_t data_size) : - replica_(replica), task_(task), domain_id_(domain_id), - io_type_(io_type), data_((char*)data), data_size_(data_size), done_(false) {} - - /** Check if the thread is finished */ - bool IsDone() { - if (done_) { - ABT_thread_join(thread_); - } - return done_; - } -}; - class Server : public TaskLib { public: labstor::remote_queue::Client client_; @@ -56,7 +23,9 @@ class Server : public TaskLib { Server() = default; /** Construct remote queue */ - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { + HILOG(kInfo, "(node {}) Constructing remote queue (task_node={}, task_state={}, method={})", + LABSTOR_CLIENT->node_id_, task->task_node_, task->task_state_, task->method_); LABSTOR_THALLIUM->RegisterRpc("RpcPushSmall", [this](const tl::request &req, TaskStateId state_id, u32 method, @@ -76,30 +45,22 @@ class Server : public TaskLib { } /** Destroy remote queue */ - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } /** Handle output from replica PUSH */ static void HandlePushReplicaOutput(int replica, std::string &ret, PushTask *task) { - try { - std::vector xfer(1); - xfer[0].data_ = ret.data(); - xfer[0].data_size_ = ret.size(); - HILOG(kDebug, "Wait got {} bytes of data (task_node={}, task_state={}, method={})", - xfer[0].data_size_, - task->orig_task_->task_node_, - task->orig_task_->task_state_, - task->orig_task_->method_); - BinaryInputArchive ar(xfer); - task->exec_->LoadEnd(replica, task->exec_method_, ar, task->orig_task_); - } catch (std::exception &e) { - HILOG(kFatal, "Error LoadEnd (task_node={}, task_state={}, method={}): {}", - task->orig_task_->task_node_, - task->orig_task_->task_state_, - task->orig_task_->method_, - e.what()); - } + std::vector xfer(1); + xfer[0].data_ = ret.data(); + xfer[0].data_size_ = ret.size(); + HILOG(kDebug, "Wait got {} bytes of data (task_node={}, task_state={}, method={})", + xfer[0].data_size_, + task->orig_task_->task_node_, + task->orig_task_->task_state_, + task->orig_task_->method_); + BinaryInputArchive ar(xfer); + task->exec_->LoadEnd(replica, task->exec_method_, ar, task->orig_task_); } /** Handle finalization of PUSH replicate */ @@ -118,36 +79,26 @@ class Server : public TaskLib { task->params_ = std::string((char *) xfer[0].data_, xfer[0].data_size_); for (int replica = 0; replica < task->domain_ids_.size(); ++replica) { DomainId domain_id = task->domain_ids_[replica]; - ThalliumTask *tl_task = new ThalliumTask(replica, task, domain_id); - tl_task->thread_ = LABSTOR_WORK_ORCHESTRATOR->SpawnAsyncThread([](void *data) { - ThalliumTask *tl_task = (ThalliumTask *) data; - DomainId &domain_id = tl_task->domain_id_; - PushTask *task = tl_task->task_; - int replica = tl_task->replica_; - HILOG(kDebug, "(SM) Transferring {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={})", - task->params_.size(), - task->orig_task_->task_node_, - task->orig_task_->task_state_, - task->orig_task_->method_, - LABSTOR_CLIENT->node_id_, - domain_id.id_); - std::string ret = LABSTOR_THALLIUM->SyncCall(domain_id.id_, - "RpcPushSmall", - task->exec_->id_, - task->exec_method_, - task->params_); - HandlePushReplicaOutput(replica, ret, task); - tl_task->done_ = true; - }, tl_task); - task->tl_future_.emplace_back(tl_task); - - -// tl::async_response future = LABSTOR_THALLIUM->AsyncCall(domain_id.id_, -// "RpcPushSmall", -// task->exec_->id_, -// task->exec_method_, -// params); -// task->tl_future_.emplace_back(std::move(future)); + HILOG(kDebug, "(SM) Transferring {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={})", + task->params_.size(), + task->orig_task_->task_node_, + task->orig_task_->task_state_, + task->orig_task_->method_, + LABSTOR_CLIENT->node_id_, + domain_id.id_); + std::string ret = LABSTOR_THALLIUM->SyncCall(domain_id.id_, + "RpcPushSmall", + task->exec_->id_, + task->exec_method_, + task->params_); + HILOG(kDebug, "(SM) Finished {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={})", + task->params_.size(), + task->orig_task_->task_node_, + task->orig_task_->task_state_, + task->orig_task_->method_, + LABSTOR_CLIENT->node_id_, + domain_id.id_); + HandlePushReplicaOutput(replica, ret, task); } } @@ -160,95 +111,55 @@ class Server : public TaskLib { } for (int replica = 0; replica < task->domain_ids_.size(); ++replica) { DomainId domain_id = task->domain_ids_[replica]; - ThalliumTask *tl_task = new ThalliumTask( - replica, task, domain_id, io_type, - xfer[0].data_, xfer[0].data_size_); - tl_task->thread_ = LABSTOR_WORK_ORCHESTRATOR->SpawnAsyncThread([](void *data) { - ThalliumTask *tl_task = (ThalliumTask *) data; - DomainId &domain_id = tl_task->domain_id_; - PushTask *task = tl_task->task_; - int replica = tl_task->replica_; - IoType &io_type = tl_task->io_type_; - HILOG(kDebug, "(IO) Transferring {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={}, type={})", - tl_task->data_size_, - task->orig_task_->task_node_, - task->orig_task_->task_state_, - task->orig_task_->method_, - LABSTOR_CLIENT->node_id_, - domain_id.id_, - static_cast(io_type)); - std::string ret = LABSTOR_THALLIUM->SyncIoCall(domain_id.id_, - "RpcPushBulk", - io_type, - tl_task->data_, - tl_task->data_size_, - task->exec_->id_, - task->exec_method_, - task->params_, - tl_task->data_size_, - io_type); - HandlePushReplicaOutput(replica, ret, task); - tl_task->done_ = true; - }, tl_task); - task->tl_future_.emplace_back(tl_task); - -// tl::async_response future = LABSTOR_THALLIUM->AsyncIoCall(domain_id.id_, -// "RpcPushBulk", -// io_type, -// (char *) xfer[0].data_, -// xfer[0].data_size_, -// task->exec_->id_, -// task->exec_method_, -// params, -// xfer[0].data_size_, -// io_type); -// task->tl_future_.emplace_back(std::move(future)); - } - } - - /** Wait for client to finish message */ - void ClientWaitForMessage(PushTask *task) { - for (; task->replica_ < task->tl_future_.size(); ++task->replica_) { -// tl::async_response &future = task->tl_future_[task->replica_]; -// if (!LABSTOR_THALLIUM->IsDone(future)) { -// return; -// } -// std::string ret = LABSTOR_THALLIUM->Wait(future); -// HandlePushReplicaOutput(task->replica_, ret, task); - ThalliumTask *tl_task = (ThalliumTask *) task->tl_future_[task->replica_]; - if (!tl_task->IsDone()) { - return; - } - free(tl_task); + char *data = (char*)xfer[0].data_; + size_t data_size = xfer[0].data_size_; + HILOG(kDebug, "(IO) Transferring {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={}, type={})", + data_size, + task->orig_task_->task_node_, + task->orig_task_->task_state_, + task->orig_task_->method_, + LABSTOR_CLIENT->node_id_, + domain_id.id_, + static_cast(io_type)); + std::string ret = LABSTOR_THALLIUM->SyncIoCall(domain_id.id_, + "RpcPushBulk", + io_type, + data, + data_size, + task->exec_->id_, + task->exec_method_, + task->params_, + data_size, + io_type); + HILOG(kDebug, "(IO) Finished transferring {} bytes of data (task_node={}, task_state={}, method={}, from={}, to={}, type={})", + data_size, + task->orig_task_->task_node_, + task->orig_task_->task_state_, + task->orig_task_->method_, + LABSTOR_CLIENT->node_id_, + domain_id.id_, + static_cast(io_type)); + HandlePushReplicaOutput(replica, ret, task); } - HandlePushReplicaEnd(task); } /** Push operation called on client */ - void Push(PushTask *task) { - switch (task->phase_) { - case PushPhase::kStart: { - std::vector &xfer = task->xfer_; - task->tl_future_.reserve(task->domain_ids_.size()); - switch (task->xfer_.size()) { - case 1: { - ClientSmallPush(xfer, task); - break; - } - case 2: { - ClientIoPush(xfer, task); - break; - } - default: { - HELOG(kFatal, "The task {}/{} does not support remote calls", task->task_state_, task->method_); - } - } - task->phase_ = PushPhase::kWait; + void Push(PushTask *task, RunContext &ctx) { + std::vector &xfer = task->xfer_; + switch (xfer.size()) { + case 1: { + ClientSmallPush(xfer, task); + break; + } + case 2: { + ClientIoPush(xfer, task); + break; } - case PushPhase::kWait: { - ClientWaitForMessage(task); + default: { + HELOG(kFatal, "The task {}/{} does not support remote calls", task->task_state_, task->method_); } } + HandlePushReplicaEnd(task); } private: @@ -340,6 +251,7 @@ class Server : public TaskLib { orig_task->UnsetStarted(); orig_task->UnsetMarked(); orig_task->UnsetDataOwner(); + orig_task->UnsetLongRunning(); queue->Emplace(orig_task->prio_, orig_task->lane_hash_, p); HILOG(kDebug, "(node {}) Executing task (task_node={}, task_state={}/{}, state_name={}, method={}, size={}, lane_hash={})", @@ -351,7 +263,7 @@ class Server : public TaskLib { method, data_size, orig_task->lane_hash_); - orig_task->Wait<1>(); + orig_task->Wait(); } void RpcComplete(const tl::request &req, @@ -359,7 +271,6 @@ class Server : public TaskLib { TaskState *exec, TaskStateId state_id) { BinaryOutputArchive ar(DomainId::GetNode(LABSTOR_CLIENT->node_id_)); std::vector out_xfer = exec->SaveEnd(method, ar, orig_task); - LABSTOR_CLIENT->DelTask(orig_task); HILOG(kDebug, "(node {}) Returning {} bytes of data (task_node={}, task_state={}/{}, method={})", LABSTOR_CLIENT->node_id_, out_xfer[0].data_size_, @@ -367,6 +278,7 @@ class Server : public TaskLib { orig_task->task_state_, state_id, method); + LABSTOR_CLIENT->DelTask(orig_task); req.respond(std::string((char *) out_xfer[0].data_, out_xfer[0].data_size_)); } diff --git a/tasks_required/small_message/include/small_message/small_message.h b/tasks_required/small_message/include/small_message/small_message.h index 6953a076e..bb5f8c1a2 100644 --- a/tasks_required/small_message/include/small_message/small_message.h +++ b/tasks_required/small_message/include/small_message/small_message.h @@ -70,7 +70,7 @@ class Client : public TaskLibClient { LPointer> push_task = AsyncMdPushRoot(domain_id); push_task->Wait(); - MdPushTask *task = push_task->subtask_ptr_; + MdPushTask *task = push_task->get(); int ret = task->ret_[0]; LABSTOR_CLIENT->DelTask(push_task); return ret; @@ -85,8 +85,8 @@ class Client : public TaskLibClient { } int IoRoot(const DomainId &domain_id) { LPointer> push_task = AsyncIoRoot(domain_id); - push_task.ptr_->Wait(); - IoTask *task = push_task.ptr_->subtask_ptr_; + push_task->Wait(); + IoTask *task = push_task->get(); int ret = task->ret_; LABSTOR_CLIENT->DelTask(push_task); return ret; diff --git a/tasks_required/small_message/include/small_message/small_message_lib_exec.h b/tasks_required/small_message/include/small_message/small_message_lib_exec.h index 2f217b7ba..68aab730b 100644 --- a/tasks_required/small_message/include/small_message/small_message_lib_exec.h +++ b/tasks_required/small_message/include/small_message/small_message_lib_exec.h @@ -2,26 +2,26 @@ #define LABSTOR_SMALL_MESSAGE_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kMd: { - Md(reinterpret_cast(task)); + Md(reinterpret_cast(task), ctx); break; } case Method::kIo: { - Io(reinterpret_cast(task)); + Io(reinterpret_cast(task), ctx); break; } case Method::kMdPush: { - MdPush(reinterpret_cast(task)); + MdPush(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/small_message/src/small_message.cc b/tasks_required/small_message/src/small_message.cc index 25eec506d..16282873d 100644 --- a/tasks_required/small_message/src/small_message.cc +++ b/tasks_required/small_message/src/small_message.cc @@ -13,25 +13,25 @@ class Server : public TaskLib { int count_ = 0; public: - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Md(MdTask *task) { + void Md(MdTask *task, RunContext &ctx) { task->ret_[0] = 1; task->SetModuleComplete(); } - void MdPush(MdPushTask *task) { + void MdPush(MdPushTask *task, RunContext &ctx) { task->ret_[0] = 1; task->SetModuleComplete(); } - void Io(IoTask *task) { + void Io(IoTask *task, RunContext &ctx) { task->ret_ = 1; for (int i = 0; i < 256; ++i) { if (task->data_[i] != 10) { diff --git a/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_lib_exec.h b/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_lib_exec.h index 10565c416..21d3493ee 100644 --- a/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_lib_exec.h +++ b/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_lib_exec.h @@ -2,18 +2,18 @@ #define LABSTOR_WORCH_PROC_ROUND_ROBIN_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kSchedule: { - Schedule(reinterpret_cast(task)); + Schedule(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_tasks.h b/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_tasks.h index d0926a34b..e9e6a27af 100644 --- a/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_tasks.h +++ b/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin_tasks.h @@ -39,12 +39,6 @@ struct ConstructTask : public CreateTaskStateTask { : CreateTaskStateTask(alloc, task_node, domain_id, state_name, "worch_proc_round_robin", id, queue_info) { } - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy worch_proc_round_robin */ diff --git a/tasks_required/worch_proc_round_robin/src/worch_proc_round_robin.cc b/tasks_required/worch_proc_round_robin/src/worch_proc_round_robin.cc index c51a0eba5..238143a27 100644 --- a/tasks_required/worch_proc_round_robin/src/worch_proc_round_robin.cc +++ b/tasks_required/worch_proc_round_robin/src/worch_proc_round_robin.cc @@ -10,15 +10,15 @@ namespace labstor::worch_proc_round_robin { class Server : public TaskLib { public: - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Schedule(ScheduleTask *task) { + void Schedule(ScheduleTask *task, RunContext &ctx) { int rr = 0; for (Worker &worker : LABSTOR_WORK_ORCHESTRATOR->workers_) { worker.SetCpuAffinity(rr % HERMES_SYSTEM_INFO->ncpu_); diff --git a/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_lib_exec.h b/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_lib_exec.h index 1321d5488..9223e7f1e 100644 --- a/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_lib_exec.h +++ b/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_lib_exec.h @@ -2,18 +2,18 @@ #define LABSTOR_WORCH_QUEUE_ROUND_ROBIN_LIB_EXEC_H_ /** Execute a task */ -void Run(u32 method, Task *task) override { +void Run(u32 method, Task *task, RunContext &ctx) override { switch (method) { case Method::kConstruct: { - Construct(reinterpret_cast(task)); + Construct(reinterpret_cast(task), ctx); break; } case Method::kDestruct: { - Destruct(reinterpret_cast(task)); + Destruct(reinterpret_cast(task), ctx); break; } case Method::kSchedule: { - Schedule(reinterpret_cast(task)); + Schedule(reinterpret_cast(task), ctx); break; } } diff --git a/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_tasks.h b/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_tasks.h index a5acbbc01..68ebda34b 100644 --- a/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_tasks.h +++ b/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin_tasks.h @@ -43,12 +43,6 @@ struct ConstructTask : public CreateTaskStateTask { /** Destructor */ HSHM_ALWAYS_INLINE ~ConstructTask() {} - - /** Create group */ - HSHM_ALWAYS_INLINE - u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; - } }; /** A task to destroy worch_queue_round_robin */ diff --git a/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc b/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc index 1ea856dcb..10f53ed33 100644 --- a/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc +++ b/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc @@ -13,16 +13,16 @@ class Server : public TaskLib { u32 count_; public: - void Construct(ConstructTask *task) { + void Construct(ConstructTask *task, RunContext &ctx) { count_ = 0; task->SetModuleComplete(); } - void Destruct(DestructTask *task) { + void Destruct(DestructTask *task, RunContext &ctx) { task->SetModuleComplete(); } - void Schedule(ScheduleTask *task) { + void Schedule(ScheduleTask *task, RunContext &ctx) { // Check if any new queues need to be scheduled for (MultiQueue &queue : *LABSTOR_QM_RUNTIME->queue_map_) { if (queue.id_.IsNull()) { diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index b8b63529d..dbfd08a04 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -7,4 +7,5 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${CMAKE_SOURCE_DIR}/tasks/labstor_admin/include) add_subdirectory(ipc) add_subdirectory(hermes) -add_subdirectory(hermes_adapters) \ No newline at end of file +add_subdirectory(hermes_adapters) +add_subdirectory(boost) \ No newline at end of file diff --git a/test/unit/asan.supp b/test/unit/asan.supp new file mode 100644 index 000000000..c17008e89 --- /dev/null +++ b/test/unit/asan.supp @@ -0,0 +1,10 @@ +# Ignore leaks from external libraries +leak:libfabric.so +leak:libabt.so +leak:libmargo.so +leak:libmpi.so +leak:librdmacm.so +leak:libhwloc.so +leak:libmpich.so +leak:aiori-HDF5.c +leak:ior.c \ No newline at end of file diff --git a/test/unit/boost/CMakeLists.txt b/test/unit/boost/CMakeLists.txt new file mode 100644 index 000000000..81746e03f --- /dev/null +++ b/test/unit/boost/CMakeLists.txt @@ -0,0 +1,43 @@ +cmake_minimum_required(VERSION 3.10) +project(labstor) + +set(CMAKE_CXX_STANDARD 17) + +#------------------------------------------------------------------------------ +# Build Tests +#------------------------------------------------------------------------------ + +add_executable(test_boost_exec + ${TEST_MAIN}/main.cc + test_init.cc + test_boost.cc +) +add_dependencies(test_boost_exec + ${Labstor_RUNTIME_DEPS} hermes) +target_link_libraries(test_boost_exec + ${Labstor_RUNTIME_LIBRARIES} Catch2::Catch2 MPI::MPI_CXX) + +#------------------------------------------------------------------------------ +# Test Cases +#------------------------------------------------------------------------------ + +add_test(NAME test_boost COMMAND + ${CMAKE_BINARY_DIR}/bin/test_messages "TestBoost") + +#------------------------------------------------------------------------------ +# Install Targets +#------------------------------------------------------------------------------ +install(TARGETS + test_boost_exec + EXPORT + ${LABSTOR_EXPORTED_TARGETS} + LIBRARY DESTINATION ${LABSTOR_INSTALL_LIB_DIR} + ARCHIVE DESTINATION ${LABSTOR_INSTALL_LIB_DIR} + RUNTIME DESTINATION ${LABSTOR_INSTALL_BIN_DIR}) + +#----------------------------------------------------------------------------- +# Coverage +#----------------------------------------------------------------------------- +if(LABSTOR_ENABLE_COVERAGE) + set_coverage_flags(test_boost_exec) +endif() diff --git a/test/unit/boost/test_boost.cc b/test/unit/boost/test_boost.cc new file mode 100644 index 000000000..84c517341 --- /dev/null +++ b/test/unit/boost/test_boost.cc @@ -0,0 +1,127 @@ +// +// Created by llogan on 7/1/23. +// + +#include "basic_test.h" +#include +#include "hermes_shm/util/timer.h" +#include "hermes_shm/util/logging.h" +#include + + +void function() { +} + +TEST_CASE("TestBoostFiber") { + hshm::Timer t; + t.Resume(); + size_t ops = (1 << 20); + + for (size_t i = 0; i < ops; ++i) { + int a; + boost::context::fiber source([&a](boost::context::fiber &&sink) { + function(); + return std::move(sink); + }); + } + + t.Pause(); + HILOG(kInfo, "Latency: {} MOps", ops / t.GetUsec()); +} + +template< std::size_t Max, std::size_t Default, std::size_t Min > +class simple_stack_allocator +{ + public: + static std::size_t maximum_stacksize() + { return Max; } + + static std::size_t default_stacksize() + { return Default; } + + static std::size_t minimum_stacksize() + { return Min; } + + void * allocate( std::size_t size) const + { + BOOST_ASSERT( minimum_stacksize() <= size); + BOOST_ASSERT( maximum_stacksize() >= size); + + void * limit = malloc( size); + if ( ! limit) throw std::bad_alloc(); + + return static_cast< char * >( limit) + size; + } + + void deallocate( void * vp, std::size_t size) const + { + BOOST_ASSERT( vp); + BOOST_ASSERT( minimum_stacksize() <= size); + BOOST_ASSERT( maximum_stacksize() >= size); + + void * limit = static_cast< char * >( vp) - size; + free( limit); + } +}; + +typedef simple_stack_allocator< + 8 * 1024 * 1024, + 64 * 1024, + 32> stack_allocator; + +int value1; +namespace bctx = boost::context::detail; + +bctx::transfer_t shared_xfer; + +void f3( bctx::transfer_t t) { + ++value1; + shared_xfer = t; + shared_xfer = bctx::jump_fcontext(shared_xfer.fctx, 0); + ++value1; + shared_xfer = bctx::jump_fcontext( shared_xfer.fctx, shared_xfer.data); +} + + +TEST_CASE("TestBoostFcontext") { + value1 = 0; + stack_allocator alloc; + int size = KILOBYTES(64); + + hshm::Timer t; + t.Resume(); + size_t ops = (1 << 20); + + for (size_t i = 0; i < ops; ++i) { + void *sp = alloc.allocate(size); + shared_xfer.fctx = bctx::make_fcontext(sp, size, f3); + shared_xfer = bctx::jump_fcontext(shared_xfer.fctx, 0); + shared_xfer = bctx::jump_fcontext(shared_xfer.fctx, 0); + alloc.deallocate(sp, size); + } + + t.Pause(); + HILOG(kInfo, "Latency: {} MOps", ops / t.GetUsec()); +} + +using namespace boost::coroutines2; + +void myCoroutine(coroutine::push_type& yield) { + for (int i = 1; i <= 5; ++i) { + yield(); + } +} + +TEST_CASE("TestBoostCoroutine") { + hshm::Timer t; + t.Resume(); + size_t ops = (1 << 20); + + for (size_t i = 0; i < ops; ++i) { + coroutine::pull_type myCoroutineInstance(myCoroutine); + myCoroutineInstance(); + } + + t.Pause(); + HILOG(kInfo, "Latency: {} MOps", ops / t.GetUsec()); +} \ No newline at end of file diff --git a/test/unit/boost/test_init.cc b/test/unit/boost/test_init.cc new file mode 100644 index 000000000..e101758d3 --- /dev/null +++ b/test/unit/boost/test_init.cc @@ -0,0 +1,22 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +#include "labstor/api/labstor_client.h" +#include "basic_test.h" +#include "test_init.h" + +void MainPretest() { +} + +void MainPosttest() { +} diff --git a/test/unit/boost/test_init.h b/test/unit/boost/test_init.h new file mode 100644 index 000000000..a6c71f3ec --- /dev/null +++ b/test/unit/boost/test_init.h @@ -0,0 +1,19 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + +#ifndef LABSTOR_TEST_UNIT_IPC_TEST_INIT_H_ +#define LABSTOR_TEST_UNIT_IPC_TEST_INIT_H_ + +#include "labstor/labstor_types.h" + +#endif // LABSTOR_TEST_UNIT_IPC_TEST_INIT_H_ diff --git a/test/unit/hermes/test_bucket.cc b/test/unit/hermes/test_bucket.cc index e9d131e96..b084edb29 100644 --- a/test/unit/hermes/test_bucket.cc +++ b/test/unit/hermes/test_bucket.cc @@ -9,6 +9,15 @@ #include "hermes/bucket.h" #include +TEST_CASE("TestHermesConnect") { + int rank, nprocs; + MPI_Barrier(MPI_COMM_WORLD); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + HERMES->ClientInit(); + MPI_Barrier(MPI_COMM_WORLD); +} + TEST_CASE("TestHermesPut1n") { int rank, nprocs; MPI_Barrier(MPI_COMM_WORLD); @@ -100,7 +109,6 @@ TEST_CASE("TestHermesPutGet") { memset(blob.data(), i % 256, blob.size()); hermes::BlobId blob_id = bkt.Put(std::to_string(i), blob, ctx); HILOG(kInfo, "(iteration {}) Using BlobID: {}", i, blob_id); - // Get a blob hermes::Blob blob2; bkt.Get(blob_id, blob2, ctx);