...
 
Commits (53)
......@@ -13,7 +13,13 @@ CLEANFILES = $(bin_SCRIPTS)
MAINTAINERCLEANFILES =
EXTRA_DIST =
BUILT_SOURCES =
include_HEADERS = include/bake.h include/bake-client.h include/bake-server.h
include_HEADERS = include/bake.h\
include/bake-client.h\
include/bake-server.h\
include/bake.hpp\
include/bake-client.hpp\
include/bake-server.hpp
TESTS_ENVIRONMENT =
EXTRA_DIST += \
......
......@@ -98,9 +98,6 @@ int main(int argc, char **argv)
bake_write(bph, rid, 0, buf, size);
/* Make all modifications persistent */
bake_persist(bph, rid);
/* Get size of region */
size_t check_size;
bake_get_size(bph, rid, &check_size);
/* Release provider handle */
bake_provider_handle_release(bph);
/* Release BAKE client */
......@@ -146,7 +143,7 @@ This makes the provider manage the given storage target.
Other functions are available to remove a storage target (or all storage
targets) from a provider.
## Benchmark execution example
## Latency benchmark execution example
* `./bake-latency-bench sm:///tmp/cci/sm/carns-x1/1/1 100000 4 8`
......@@ -164,6 +161,57 @@ The second argument is the number of benchmark iterations.
The third and fourth arguments specify the range of sizes to use for read and
write operations in the benchmark.
## Generic Bake benchmark
By using `--enable-benchmark` when compiling Bake (or `+benchmark` when using Spack),
you will build a `bake-benchmark` program that can be used as a configurable benchmark.
This benchmark requires an MPI compiler, hence you may need to configure Bake with
`CC=mpicc` and `CXX=mpicxx`.
The benchmark is an MPI program that can be run on 2 or more ranks. Rank 0 will act
as a server, while non-zero ranks act as clients. The server will not create
a Bake target. The Bake target needs to be created (with `bake-makepool`) beforehand.
The program takes as parameter the path to a JSON file containing the sequence
of benchmarks to execute. An example of such a file is located in `src/benchmark.json`.
Each entry in the `benchmarks` array corresponds to a benchmark. The `type` field indicates
the type of benchmark to execute. The `repetitions` field indicates how many times the
benchmark should be repeated.
The following table describes each type of benchmark and their parameters.
| type | parameter | default | description |
|----------------------|-------------------|---------|-------------------------------------------------------------------|
| | | | |
| create | num-entries | 1 | Number of regions to create |
| | region-sizes | - | Size of the regions, or range (e.g. [12, 24]) |
| | erase-on-teardown | true | Whether to erase the created regions after the benchmark executed |
| | | | |
| write | num-entries | 1 | Number of regions to write |
| | region-sizes | - | Size of the regions, or range (e.g. [12, 24]) |
| | reuse-buffer | false | Whether to reuse the input buffer for each write |
| | reuse-region | false | Whether to write to the same region |
| | preregister-bulk | false | Whether to preregister the input buffer for RDMA |
| | erase-on-teardown | true | Whether to erase the created regions after the benchmark executed |
| | | | |
| persist | num-entries | 1 | Number of region to persist |
| | region-sizes | - | Size of the regions, or range (e.g. [12, 24]) |
| | erase-on-teardown | true | Whether to erase the created regions after the benchmark executed |
| | | | |
| read | num-entries | 1 | Number of region to read |
| | region-sizes | - | Size of the regions, or range (e.g. [12, 24]) |
| | reuse-buffer | false | Whether to reuse the same buffer for each read |
| | reuse-region | false | Whether to access the same region for each read |
| | preregister-bulk | false | Whether to preregister the client's buffer for RDMA |
| | erase-on-teardown | true | Whether to remove the regions after the benchmark |
| | | | |
| create-write-persist | num-entries | 1 | Number of regions to create/write/persist |
| | region-sizes | - | Size of the regions, or range (e.g. [12, 24]) |
| | reuse-buffer | false | Whether to reuse the same buffer on clients for each operation |
| | preregister-bulk | false | Whether to preregister the client's buffer for RDMA |
| | erase-on-teardown | true | Whether to remove the regions after the benchmark |
## Misc tips
Memory allocation seems to account for a significant portion of
......
......@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([bake], [0.1], [],[],[])
AC_INIT([bake], [0.6], [],[],[])
AC_CONFIG_MACRO_DIR([m4])
LT_INIT
......@@ -66,6 +66,18 @@ LIBS="$MARGO_LIBS $LIBS"
CPPFLAGS="$MARGO_CFLAGS $CPPFLAGS"
CFLAGS="$MARGO_CFLAGS $CFLAGS"
PKG_CHECK_MODULES([ABTIO],[abt-io],[],
[AC_MSG_ERROR([Could not find working abt-io installation!])])
LIBS="$ABTIO_LIBS $LIBS"
CPPFLAGS="$ABTIO_CFLAGS $CPPFLAGS"
CFLAGS="$ABTIO_CFLAGS $CFLAGS"
PKG_CHECK_MODULES([MOCHICFG],[mochi-cfg],[],
[AC_MSG_ERROR([Could not find working mochi-cfg installation!])])
LIBS="$MOCHICFG_LIBS $LIBS"
CPPFLAGS="$MOCHICFG_CFLAGS $CPPFLAGS"
CFLAGS="$MOCHICFG_CFLAGS $CFLAGS"
# NOTE: See README.md if the following does not work for you; some versions of
# nvml/pmem install broken .pc files
PKG_CHECK_MODULES([LIBPMEMOBJ],[libpmemobj],[],
......@@ -80,11 +92,48 @@ LIBS="$UUID_LIBS $LIBS"
CPPFLAGS="$UUID_CFLAGS $CPPFLAGS"
CFLAGS="$UUID_CFLAGS $CFLAGS"
PKG_CHECK_MODULES([REMI],[remi],[],
[AC_MSG_ERROR([Could not find working remi installation!])])
LIBS="$REMI_LIBS $LIBS"
CPPFLAGS="$REMI_CFLAGS $CPPFLAGS"
CFLAGS="$REMI_CFLAGS $CFLAGS"
AC_ARG_ENABLE(remi,
[AS_HELP_STRING([--enable-remi],[Enable REMI (migration) support @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_remi="yes" ;;
no) enable_remi="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-remi) ;;
esac],
[enable_remi="no"]
)
AM_CONDITIONAL(ENABLE_REMI, test x$enable_remi = xyes)
if test "$enable_remi" = "yes"; then
PKG_CHECK_MODULES(REMI, remi)
AC_DEFINE(USE_REMI, 1, [REMI support enabled.])
USE_REMI=1
LIBS="$REMI_LIBS $LIBS"
CPPFLAGS="$REMI_CFLAGS $CPPFLAGS"
CFLAGS="$REMI_CFLAGS $CFLAGS"
REMI_PKG="remi"
else
USE_REMI=0
REMI_PKG=""
fi
AC_SUBST(USE_REMI)
AC_SUBST(REMI_PKG)
AC_ARG_ENABLE(benchmark,
[AS_HELP_STRING([--enable-benchmark],[Build Bake benchmark @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_benchmark="yes" ;;
no) enable_benchmark="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-benchmark) ;;
esac],
[enable_benchmark="no"]
)
AM_CONDITIONAL(BUILD_BENCHMARK, test x$enable_benchmark = xyes)
if [test "$enable_benchmark" = "yes"]; then
PKG_CHECK_MODULES(JSONCPP, jsoncpp)
LIBS="$JSONCPP_LIBS $LIBS"
CPPFLAGS="$JSONCPP_CFLAGS $CPPFLAGS"
CFLAGS="$JSONCPP_CFLAGS $CFLAGS"
fi
AC_ARG_ENABLE([sizecheck],
AS_HELP_STRING([--enable-sizecheck], [Adds a header in regions to keep track of region sizes (may degrade performance) @<:@default=no@:>@]),
......
......@@ -71,6 +71,23 @@ int bake_provider_handle_create(
*/
int bake_provider_handle_ref_incr(bake_provider_handle_t handle);
/**
* @brief Returns the address and provider id of a provider handle.
* The returned address should be freed by the caller using
* margo_addr_free.
*
* @param handle Provider handle
* @param client Returned bake client (ignored if NULL)
* @param addr Returned address (ignored if NULL)
* @param provider_id Returned provider id (ignored if NULL)
*
* @return BAKE_SUCCESS or corresponding error code.
*/
int bake_provider_handle_get_info(bake_provider_handle_t handle,
bake_client_t *client,
hg_addr_t *addr,
uint16_t *provider_id);
/**
* Get the limit (in bytes) bellow which this provider handle will use
* eager mode (i.e. packing data into the RPC instead of using RDMA).
......@@ -156,6 +173,7 @@ int bake_create(
*/
int bake_write(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
void const *buf,
......@@ -181,6 +199,7 @@ int bake_write(
*/
int bake_proxy_write(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
hg_bulk_t remote_bulk,
......@@ -200,6 +219,7 @@ int bake_proxy_write(
*/
int bake_persist(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
size_t offset,
size_t size);
......@@ -262,6 +282,7 @@ int bake_create_write_persist_proxy(
*/
int bake_get_size(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t *size);
......@@ -287,6 +308,7 @@ int bake_get_size(
*/
int bake_get_data(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
void** ptr);
......@@ -306,6 +328,7 @@ int bake_get_data(
*/
int bake_read(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
void *buf,
......@@ -333,6 +356,7 @@ int bake_read(
*/
int bake_proxy_read(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
hg_bulk_t remote_bulk,
......@@ -361,6 +385,7 @@ int bake_proxy_read(
*/
int bake_migrate_region(
bake_provider_handle_t source,
bake_target_id_t source_bti,
bake_region_id_t source_rid,
size_t region_size,
int remove_source,
......@@ -418,6 +443,7 @@ int bake_noop(bake_provider_handle_t provider);
*/
int bake_remove(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid);
#ifdef __cplusplus
......
This diff is collapsed.
......@@ -19,7 +19,7 @@ extern "C" {
#define BAKE_PROVIDER_ID_DEFAULT 0
#define BAKE_PROVIDER_IGNORE NULL
typedef struct bake_server_context_t* bake_provider_t;
typedef struct bake_provider* bake_provider_t;
/**
* Creates a BAKE pool to use for backend PMEM storage.
......@@ -43,7 +43,6 @@ int bake_makepool(
* @param[in] mid Margo instance identifier
* @param[in] provider_id provider id
* @param[in] pool Pool on which to run the RPC handlers
* @param[in] target_name path to PMEM backend file
* @param[out] provider resulting provider
* @returns 0 on success, -1 otherwise
*/
......@@ -53,6 +52,32 @@ int bake_provider_register(
ABT_pool pool,
bake_provider_t* provider);
/**
* Initializes a BAKE provider with json configuration.
*
* @param[in] mid Margo instance identifier
* @param[in] provider_id provider id
* @param[in] pool Pool on which to run the RPC handlers
* @param[out] provider resulting provider
* @returns 0 on success, -1 otherwise
*/
int bake_provider_register_json(
margo_instance_id mid,
uint16_t provider_id,
ABT_pool pool,
bake_provider_t* provider,
const char* json_cfg_string);
/**
* @brief Deregisters and destroys the provider.
*
* @param provider Provider to deregister and destroy.
*
* @return 0 on success, -1 otherwise.
*/
int bake_provider_destroy(
bake_provider_t provider);
/**
* Makes the provider start managing a target.
* The target must have been previously created with bake_makepool,
......@@ -120,38 +145,42 @@ int bake_provider_list_storage_targets(
bake_target_id_t* targets);
/**
* @brief Sets the size and number of intermediate buffers used for transfering data.
* The size is set to 0 by default. A size of 0 indicates that RDMA will be
* done all at once and target the backend device directly without using an
* intermediate buffer.
* Retrieves complete configuration for provider, encoded as json
*
* @param [in] provider
* @returns null terminated string that must be free'd by caller
*/
char* bake_provider_get_config(bake_provider_t provider);
/**
* @brief Set configuration parameters as string key/value pairs
*
* @param provider Bake provider
* @param target_id Target for which to change the buffer size.
* @param count Number of buffers to initialize.
* @param size Size of the buffer.
* @param key Configuration key
* @param value Configuratiion value
*
* @return 0 on success, -1 on failure
*/
int bake_provider_set_target_xfer_buffer(
int bake_provider_set_conf(
bake_provider_t provider,
bake_target_id_t target_id,
size_t count,
size_t size);
const char *key,
const char *value);
/**
* @brief Sets the maximum number of ULTs that will be used to concurrently
* transfer data.
* @brief Set configuration parameters for a target.
*
* @param provider Bake provider
* @param target_id Target for which to change the number of ULTs
* @param num_threads Number of ULTs
* @param tid Bake target id
* @param key Configuration key
* @param value Configuration value
*
* @return 0 on success, -1 on failure
*/
int bake_provider_set_target_xfer_concurrency(
int bake_target_set_conf(
bake_provider_t provider,
bake_target_id_t target_id,
uint32_t num_threads);
bake_target_id_t tid,
const char* key,
const char* value);
#ifdef __cplusplus
}
......
/*
* (C) 2019 The University of Chicago
*
* See COPYRIGHT in top-level directory.
*/
#ifndef __BAKE_SERVER_HPP
#define __BAKE_SERVER_HPP
#include <string>
#include <vector>
#include <bake.hpp>
#include <bake-server.h>
#define _CHECK_RET(__ret) \
if(__ret != BAKE_SUCCESS) throw exception(__ret)
namespace bake {
/**
* @brief Creates a pool at a given path, with a given size and mode.
*
* @param pool_name Pool name.
* @param pool_size Pool size.
* @param pool_mode Mode.
*/
inline void makepool(
const std::string& pool_name,
size_t pool_size,
mode_t pool_mode) {
int ret = bake_makepool(pool_name.c_str(), pool_size, pool_mode);
_CHECK_RET(ret);
}
/**
* @brief The provider class is the C++ equivalent to a bake_provider_t.
*/
class provider {
margo_instance_id m_mid = MARGO_INSTANCE_NULL;
bake_provider_t m_provider = NULL;
provider(
margo_instance_id mid,
uint16_t provider_id = 0,
ABT_pool pool = ABT_POOL_NULL)
: m_mid(mid) {
int ret = bake_provider_register(mid, provider_id, pool, &m_provider);
_CHECK_RET(ret);
}
static void finalize_callback(void* args) {
auto* p = static_cast<provider*>(args);
delete p;
}
public:
/**
* @brief Factory method to create an instance of provider.
*
* @param mid Margo instance id.
* @param provider_id Provider id.
* @param pool Argobots pool.
*
* @return Pointer to newly created provider.
*/
static provider* create(margo_instance_id mid,
uint16_t provider_id = 0,
ABT_pool pool = BAKE_ABT_POOL_DEFAULT) {
auto p = new provider(mid, provider_id, pool);
margo_provider_push_finalize_callback(mid, p, &finalize_callback, p);
return p;
}
/**
* @brief Deleted copy constructor.
*/
provider(const provider&) = delete;
/**
* @brief Deleted move constructor.
*/
provider(provider&& other) = delete;
/**
* @brief Deleted copy-assignment operator.
*/
provider& operator=(const provider&) = delete;
/**
* @brief Deleted move-assignment operator.
*/
provider& operator=(provider&& other) = delete;
/**
* @brief Destructor.
*/
~provider() {
margo_provider_pop_finalize_callback(m_mid, this);
bake_provider_destroy(m_provider);
}
/**
* @brief Adds a storage target to the provider.
* The target must have been created beforehand.
*
* @param target_name Path to the target.
*
* @return a target object.
*/
target add_storage_target(const std::string& target_name) {
target t;
int ret = bake_provider_add_storage_target(
m_provider,
target_name.c_str(),
&(t.m_tid));
_CHECK_RET(ret);
return t;
}
/**
* @brief Removes the storage target from the provider.
* This does not removes the storage target from the device, it
* simply makes it unaccessible through this provider.
*
* @param t target to remove.
*/
void remove_storage_target(const target& t) {
int ret = bake_provider_remove_storage_target(m_provider, t.m_tid);
_CHECK_RET(ret);
}
/**
* @brief Removes all the storage targets managed by the provider.
*/
void remove_all_storage_targets() {
int ret = bake_provider_remove_all_storage_targets(m_provider);
_CHECK_RET(ret);
}
/**
* @brief Count the number of storage targets managed by the provider.
*
* @return number of storage targets.
*/
uint64_t count_storage_targets() const {
uint64_t count;
int ret = bake_provider_count_storage_targets(m_provider, &count);
_CHECK_RET(ret);
return count;
}
/**
* @brief Lists all the storage targets managed by the provider.
*
* @return Vector of targets.
*/
std::vector<target> list_storage_targets() const {
uint64_t count = count_storage_targets();
std::vector<target> result(count);
std::vector<bake_target_id_t> tgts(count);
int ret = bake_provider_list_storage_targets(m_provider, tgts.data());
_CHECK_RET(ret);
for(unsigned i=0; i < count; i++) {
result[i].m_tid = tgts[i];
}
return result;
}
void set_config(const std::string& key, const std::string& value) {
int ret = bake_provider_set_conf(m_provider, key.c_str(), value.c_str());
_CHECK_RET(ret);
}
};
}
#undef _CHECK_RET
#endif
......@@ -38,6 +38,72 @@ typedef struct {
#define BAKE_ERR_OUT_OF_BOUNDS (-9) /* Attempting an out of bound access */
#define BAKE_ERR_REMI (-10) /* Error related to REMI */
#define BAKE_ERR_OP_UNSUPPORTED (-11) /* Operation not supported */
#define BAKE_ERR_FORBIDDEN (-12) /* Forbidden operation */
#define BAKE_ERR_BACKEND_TYPE (-13) /* Unknown backend type */
#define BAKE_ERR_IO (-14) /* Back-end I/O error */
#define BAKE_ERR_END (-15) /* End of valid bake error codes */
/**
* Print bake errors in human-friendly form
*
* @param a string to print out before the error
* @param ret error code from a bake routine
*/
void bake_perror(const char *s, int ret);
/**
* @brief Converts a target id into an ASCII readable string.
*
* @param tid Target id to convert into a string.
* @param str Resulting string (must be allocated to at least 37 bytes)
* @param size size of the allocated string.
*
* @return error code.
*/
int bake_target_id_to_string(bake_target_id_t tid, char* str, size_t size);
/**
* @brief Converts an ASCI readable representation of the target id into
* and actual target id.
*
* @param str Null-terminated string to read from.
* @param tid Resulting target id.
*
* @return error code.
*/
int bake_target_id_from_string(const char* str, bake_target_id_t* tid);
/**
* @brief Converts the region id into an ASCII readable representation.
*
* @param rid Region id.
* @param str Resulting string, should be preallocated wirg sufficient size.
* @param size size of the preallocated string.
*
* @return error code.
*/
int bake_region_id_to_string(bake_region_id_t rid, char* str, size_t size);
/**
* @brief Converts a string back into a region id.
*
* @param str String to convert.
* @param rid Resulting region id.
*
* @return error code.
*/
int bake_region_id_from_string(const char* str, bake_region_id_t* rid);
/**
* Convert region id into printable string for debugging purposes
*
* @param[in] str string to fill in
* @param[in] size length of string, not including terminator. If rid
* string is longer than this it will be truncated.
* @param[in] rid region_id
*/
void bake_print_dbg_region_id_t(char *str, size_t size, bake_region_id_t rid)
__attribute__((deprecated("use bake_region_id_to_string instead")));
#ifdef __cplusplus
}
......
/*
* (C) 2019 The University of Chicago
*
* See COPYRIGHT in top-level directory.
*/
#ifndef __BAKE_HPP
#define __BAKE_HPP
#include <exception>
#include <string>
#include <bake.h>
namespace bake {
/**
* @brief Array of error messages for bake::exception.
*/
const char* const bake_error_messages[] = {
"",
"Allocation error",
"Invalid argument",
"Mercury error",
"Argobots error",
"PMEM error",
"Unknown target",
"Unknown provider",
"Unknown region",
"Access out of bound",
"REMI error",
"Operation not supported",
"Forbidden operation"
};
class client;
class provider;
/**
* @brief target instances are equivalent to bake_target_id_t.
*/
class target {
friend class client;
friend class provider;
bake_target_id_t m_tid;
public:
/**
* @brief Constructor.
*/
target() = default;
/**
* @brief Constructor from a human-readable string.
* The string must have been obtained using target's
* std::string cast operator.
*
* @param str String representation of the target.
*/
target(const std::string& str) {
bake_target_id_from_string(str.c_str(), &m_tid);
}
/**
* @brief Copy constructor.
*/
target(const target&) = default;
/**
* @brief Move constructor.
*/
target(target&&) = default;
/**
* @brief Copy-assignment operator.
*/
target& operator=(const target&) = default;
/**
* @brief Move-assignment operator.
*/
target& operator=(target&&) = default;
/**
* @brief Destructor.
*/
~target() = default;
/**
* @brief Converts the target to a human-readable string.
*/
operator std::string() const {
char str[37];
bake_target_id_to_string(m_tid, str, 37);
return std::string(str);
}
/**
* @brief Serialization function (useful when using Thallium).
*
* @tparam A Archive type.
* @param ar Archive object.
*/
template<typename A>
void save(A& ar) const {
ar.write(&m_tid);
}
/**
* @brief Deserialization function (useful when using Thallium).
*
* @tparam A Archive type.
* @param ar Archive object.
*/
template<typename A>
void load(A& ar) {
ar.read(&m_tid);
}
};
/**
* @brief The region class is the C++ equivalent to bake_region_id_t.
*/
class region {
friend class client;
bake_region_id_t m_rid;
public:
/**
* @brief Default constructor.
*/
region() = default;
/**
* @brief Builds a region from a human-readable string representation.
*
* @param str String representation of the region.
*/
region(const std::string& str) {
bake_region_id_from_string(str.c_str(), &m_rid);
}
/**
* @brief Copy constructor.
*/
region(const region&) = default;
/**
* @brief Move constructor.
*/
region(region&&) = default;
/**
* @brief Copy-assignment operator.
*/
region& operator=(const region&) = default;
/**
* @brief Move-assignment operator.
*/
region& operator=(region&&) = default;
/**
* @brief Destructor.
*/
~region() = default;
/**
* @brief Converts the region into a human-readable string.
*
* @return Human-readable representation of the region.
*/
operator std::string() const {
char str[128];
bake_region_id_to_string(m_rid, str, 128);
return std::string(str);
}
/**
* @brief Serialization function (useful when using Thallium).
*
* @tparam A Archive type.
* @param ar Archive object.
*/
template<typename A>
void save(A& ar) const {
ar.write(&m_rid);
}
/**
* @brief Deserialization function (useful when using Thallium).
*
* @tparam A Archive type.
* @param ar Archive object.
*/
template<typename A>
void load(A& ar) {
ar.read(&m_rid);
}
};
/**
* @brief Exception thrown by Bake methods.
*/
class exception : public std::exception {
int m_error;
std::string m_msg;
public:
exception(int error)
: m_error(error) {
if(error < 0 && error > BAKE_ERR_END) {
m_msg = std::string("[BAKE] ") + bake_error_messages[-error];
} else {
m_msg = std::string("[BAKE] Unknown error code "+std::to_string(error));
}
}
const char* what() const noexcept override {
return m_msg.c_str();
}
int error() const {
return m_error;
}
};
}
#endif
......@@ -5,7 +5,7 @@ includedir=@includedir@
Name: bake-client
Description: bulk data access service, client side
Version: 0.1
Version: 0.3.4
URL: https://xgitlab.cels.anl.gov/sds/bake
Requires: margo
Libs: -L${libdir} -lbake-client
......
......@@ -5,8 +5,8 @@ includedir=@includedir@
Name: bake-server
Description: bulk data access service, server side
Version: 0.1
Version: 0.3.4
URL: https://xgitlab.cels.anl.gov/sds/bake
Requires: margo uuid libpmemobj remi
Requires: margo uuid libpmemobj @REMI_PKG@
Libs: -L${libdir} -lbake-server
Cflags: -I${includedir}
#!/bin/bash
CLIENT=(include/bake-client.h include/bake.h src/bake-client.c src/bake-mkpool.c src/util.c)
SERVER=(include/bake-server.h src/bake-rpc.h src/bake-server.c src/bake-timing.h)
echo "************** CLIENT ***************"
sloccount "${CLIENT[@]}"
echo "************** SERVER ***************"
sloccount "${SERVER[@]}"
noinst_LTLIBRARIES = \
src/libutil.la
src_libutil_la_SOURCES = \
src/util.c \
src/base64/encode.c \
src/base64/decode.c
src_libbake_client_la_SOURCES += \
src/bake-client.c
src_libbake_client_la_LIBADD = src/libutil.la
src_libbake_server_la_SOURCES += \
src/bake-server.c
src/bake-server.c \
src/bake-pmem-backend.c \
src/bake-file-backend.c
src_libbake_server_la_LIBADD = src/libutil.la
src_bake_server_daemon_LDADD = src/libbake-server.la
src_bake_mkpool_LDADD = src/libbake-server.la
......@@ -12,5 +26,13 @@ bin_PROGRAMS += \
src/bake-mkpool \
src/bake-shutdown \
src/bake-copy-to \
src/bake-copy-from \
src/bake-latency-bench
src/bake-copy-from
if BUILD_BENCHMARK
src_bake_benchmark_SOURCES = src/bake-benchmark.cc
src_bake_benchmark_LDADD = src/libbake-server.la src/libbake-client.la
bin_PROGRAMS += src/bake-benchmark
#src_bake_benchmark_LDADD = ${LIBS} -lbake-client -lbake-server
endif
#ifndef __BAKE_BACKEND_H
#define __BAKE_BACKEND_H
#include "bake-server.h"
#include "bake.h"
typedef struct bake_provider* bake_provider_t;
typedef void* backend_context_t;
typedef int (*bake_backend_initialize_fn)(bake_provider_t provider,
const char* path,
bake_target_id_t *target,
backend_context_t *context);
typedef int (*bake_backend_finalize_fn)(backend_context_t context);
typedef int (*bake_create_fn)(backend_context_t context,
size_t size,
bake_region_id_t *rid);
typedef int (*bake_write_raw_fn)(backend_context_t context,
bake_region_id_t rid,
size_t offset,
size_t size,
const void* data);
typedef int (*bake_write_bulk_fn)(backend_context_t context,
bake_region_id_t rid,
size_t region_offset,
size_t size,
hg_bulk_t bulk,
hg_addr_t source,
size_t bulk_offset);
typedef void (*free_fn)(void*);
typedef int (*bake_read_raw_fn)(backend_context_t context,
bake_region_id_t rid,
size_t offset,
size_t size,
void** data,
uint64_t* bytes_available,
free_fn* free_data);
typedef int (*bake_read_bulk_fn)(backend_context_t context,
bake_region_id_t rid,
size_t region_offset,
size_t size,
hg_bulk_t bulk,
hg_addr_t source,
size_t bulk_offset,
size_t* bytes_read);
typedef int (*bake_persist_fn)(backend_context_t context,
bake_region_id_t rid,
size_t offset,
size_t size);
typedef int (*bake_create_write_persist_raw_fn)(backend_context_t context,
const void* data,
size_t size,
bake_region_id_t *rid);
typedef int (*bake_create_write_persist_bulk_fn)(backend_context_t context,
hg_bulk_t bulk,
hg_addr_t source,
size_t bulk_offset,
size_t size,
bake_region_id_t *rid);
typedef int (*bake_get_region_size_fn)(backend_context_t context,
bake_region_id_t rid,
size_t* size);
typedef int (*bake_get_region_data_fn)(backend_context_t context,
bake_region_id_t rid,
void** data);
typedef int (*bake_remove_fn)(backend_context_t context,
bake_region_id_t rid);
typedef int (*bake_migrate_region_fn)(backend_context_t context,
bake_region_id_t source_rid,
size_t region_size,
int remove_source,
const char* dest_addr,
uint16_t dest_provider_id,
bake_target_id_t dest_target_id,
bake_region_id_t *dest_rid);
#ifdef USE_REMI
typedef int (*bake_create_fileset_fn)(backend_context_t context,
remi_fileset_t* fileset);
#endif
typedef struct bake_backend {
const char* name;
bake_backend_initialize_fn _initialize;
bake_backend_finalize_fn _finalize;
bake_create_fn _create;
bake_write_raw_fn _write_raw;
bake_write_bulk_fn _write_bulk;
bake_read_raw_fn _read_raw;
bake_read_bulk_fn _read_bulk;
bake_persist_fn _persist;
bake_create_write_persist_raw_fn _create_write_persist_raw;
bake_create_write_persist_bulk_fn _create_write_persist_bulk;
bake_get_region_size_fn _get_region_size;
bake_get_region_data_fn _get_region_data;
bake_remove_fn _remove;
bake_migrate_region_fn _migrate_region;
#ifdef USE_REMI
bake_create_fileset_fn _create_fileset;
#endif
} bake_backend;
typedef bake_backend* bake_backend_t;
#endif
This diff is collapsed.
......@@ -147,8 +147,8 @@ int bake_client_finalize(bake_client_t client)
{
if(client->num_provider_handles != 0) {
fprintf(stderr,
"[BAKE] Warning: %d provider handles not released before bake_client_finalize was called\n",
client->num_provider_handles);
"[BAKE] Warning: %llu provider handles not released before bake_client_finalize was called\n",
(long long unsigned int)client->num_provider_handles);
}
free(client);
return BAKE_SUCCESS;
......@@ -269,6 +269,22 @@ int bake_provider_handle_ref_incr(bake_provider_handle_t handle)
return BAKE_SUCCESS;
}
int bake_provider_handle_get_info(bake_provider_handle_t handle,
bake_client_t *client,
hg_addr_t *addr,
uint16_t *provider_id)
{
int ret = BAKE_SUCCESS;
hg_return_t hret = HG_SUCCESS;
if(handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
if(client) *client = handle->client;
if(addr) hret = margo_addr_dup(handle->client->mid, handle->addr, addr);
if(provider_id) *provider_id = handle->provider_id;
if(hret != HG_SUCCESS)
ret = BAKE_ERR_MERCURY;
return ret;
}
int bake_provider_handle_release(bake_provider_handle_t handle)
{
if(handle == BAKE_PROVIDER_HANDLE_NULL) return BAKE_ERR_INVALID_ARG;
......@@ -288,6 +304,7 @@ int bake_shutdown_service(bake_client_t client, hg_addr_t addr)
static int bake_eager_write(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid,
uint64_t region_offset,
void const *buf,
......@@ -300,6 +317,7 @@ static int bake_eager_write(
bake_eager_write_out_t out;
int ret;
in.bti = tid;
in.rid = rid;
in.region_offset = region_offset;
in.size = buf_size;
......@@ -345,6 +363,7 @@ finish:
int bake_write(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid,
uint64_t region_offset,
void const *buf,
......@@ -358,10 +377,11 @@ int bake_write(
int ret;
if(buf_size <= provider->eager_limit)
return(bake_eager_write(provider, rid, region_offset, buf, buf_size));
return(bake_eager_write(provider, tid, rid, region_offset, buf, buf_size));
TIMERS_INITIALIZE("bulk_create", "forward", "end");
in.bti = tid;
in.rid = rid;
in.region_offset = region_offset;
in.bulk_offset = 0;
......@@ -419,6 +439,7 @@ finish:
int bake_proxy_write(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid,
uint64_t region_offset,
hg_bulk_t remote_bulk,
......@@ -433,6 +454,7 @@ int bake_proxy_write(
bake_write_out_t out;
int ret;
in.bti = tid;
in.rid = rid;
in.region_offset = region_offset;
in.bulk_handle = remote_bulk;
......@@ -540,6 +562,7 @@ finish:
int bake_persist(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid,
size_t offset,
size_t size)
......@@ -551,6 +574,7 @@ int bake_persist(
bake_persist_out_t out;
int ret;
in.bti = tid;
in.rid = rid;
in.offset = offset;
in.size = size;
......@@ -675,6 +699,7 @@ int bake_create_write_persist(
in.bti = bti;
in.bulk_offset = 0;
in.bulk_size = buf_size;
in.region_size = buf_size;
in.remote_addr_str = NULL; /* set remote_addr to NULL to disable proxy write */
hret = margo_bulk_create(provider->client->mid, 1, (void**)(&buf), &buf_size,
......@@ -790,6 +815,7 @@ finish:
int bake_get_size(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t *region_size)
{
......@@ -800,6 +826,7 @@ int bake_get_size(
bake_get_size_out_t out;
int ret;
in.bti = bti;
in.rid = rid;
hret = margo_create(provider->client->mid, provider->addr,
......@@ -843,6 +870,7 @@ finish:
int bake_get_data(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
void** ptr)
{
......@@ -881,6 +909,7 @@ int bake_get_data(
}
margo_addr_free(provider->client->mid, self_addr);
in.bti = bti;
in.rid = rid;
hret = margo_create(provider->client->mid, provider->addr,
......@@ -923,6 +952,7 @@ finish:
int bake_migrate_region(
bake_provider_handle_t source,
bake_target_id_t bti,
bake_region_id_t source_rid,
size_t region_size,
int remove_source,
......@@ -938,6 +968,7 @@ int bake_migrate_region(
bake_migrate_region_out_t out;
int ret;
in.bti = bti;
in.source_rid = source_rid;
in.region_size = region_size;
in.remove_src = remove_source;
......@@ -1000,7 +1031,7 @@ int bake_migrate_target(
bake_migrate_target_out_t out;
int ret;
in.target_id = src_target_id;
in.bti = src_target_id;
in.remove_src = remove_source;
in.dest_remi_addr = dest_addr;
in.dest_remi_provider_id = dest_provider_id;
......@@ -1066,6 +1097,7 @@ int bake_noop(bake_provider_handle_t provider)
static int bake_eager_read(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
void *buf,
......@@ -1081,6 +1113,7 @@ static int bake_eager_read(
out.size = 0;
int ret;
in.bti = bti;
in.rid = rid;
in.region_offset = region_offset;
in.size = buf_size;
......@@ -1131,6 +1164,7 @@ finish:
int bake_read(
bake_provider_handle_t provider,
bake_target_id_t bti,
bake_region_id_t rid,
uint64_t region_offset,
void *buf,
......@@ -1145,10 +1179,11 @@ int bake_read(
int ret;
if(buf_size <= provider->eager_limit)
return(bake_eager_read(provider, rid, region_offset, buf, buf_size, bytes_read));
return(bake_eager_read(provider, bti, rid, region_offset, buf, buf_size, bytes_read));
TIMERS_INITIALIZE("bulk_create","forward","end");
in.bti = bti;
in.rid = rid;
in.region_offset = region_offset;
in.bulk_offset = 0;
......@@ -1204,6 +1239,7 @@ finish:
int bake_proxy_read(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid,
uint64_t region_offset,
hg_bulk_t remote_bulk,
......@@ -1219,6 +1255,7 @@ int bake_proxy_read(
bake_read_out_t out;
int ret;
in.bti = tid;
in.rid = rid;
in.region_offset = region_offset;
in.bulk_handle = remote_bulk;
......@@ -1267,6 +1304,7 @@ finish:
int bake_remove(
bake_provider_handle_t provider,
bake_target_id_t tid,
bake_region_id_t rid)
{
TIMERS_INITIALIZE("start","forward","end");
......@@ -1276,6 +1314,7 @@ int bake_remove(
bake_remove_out_t out;
int ret;
in.bti = tid;
in.rid = rid;
hret = margo_create(provider->client->mid, provider->addr,
......
......@@ -31,11 +31,13 @@ int main(int argc, char **argv)
uint8_t mplex_id;
hg_return_t hret;
int ret;
bake_target_id_t tid;
bake_region_id_t rid;
int fd;
char* local_region;
int region_fd;
uint64_t size;
char region_str[128];
if(argc != 6)
{
......@@ -63,7 +65,7 @@ int main(int argc, char **argv)
ret = bake_client_init(mid, &bcl);
if(ret != 0)
{
fprintf(stderr, "Error: bake_client_init()\n");
bake_perror( "Error: bake_client_init()", ret);
margo_finalize(mid);
return -1;
}
......@@ -80,7 +82,7 @@ int main(int argc, char **argv)
ret = bake_provider_handle_create(bcl, svr_addr, mplex_id, &bph);
if(ret < 0)
{
fprintf(stderr, "Error: bake_provider_handle_create()\n");
bake_perror("Error: bake_provider_handle_create()", ret);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
......@@ -98,6 +100,18 @@ int main(int argc, char **argv)
return(-1);
}
ret = read(region_fd, &tid, sizeof(tid));
if(ret != sizeof(tid))
{
perror("read");
close(region_fd);
bake_provider_handle_release(bph);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
return(-1);
}
ret = read(region_fd, &rid, sizeof(rid));
if(ret != sizeof(rid))
{
......@@ -111,12 +125,15 @@ int main(int argc, char **argv)
}
close(region_fd);
bake_region_id_to_string(rid, region_str, 128);
printf("# will read bake region %s\n", region_str);
#ifdef USE_SIZECHECK_HEADERS
uint64_t check_size;
ret = bake_get_size(bph, rid, &check_size);
ret = bake_get_size(bph, tid, rid, &check_size);
if(ret != 0)
{
fprintf(stderr, "Error: bake_get_size()\n");
bake_perror("Error: bake_get_size()", ret);
bake_provider_handle_release(bph);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
......@@ -172,6 +189,7 @@ int main(int argc, char **argv)
uint64_t bytes_read;
ret = bake_read(
bph,
tid,
rid,
0,
local_region,
......@@ -185,7 +203,7 @@ int main(int argc, char **argv)
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
fprintf(stderr, "Error: bake_read()\n");
bake_perror("Error: bake_read()", ret);
return(-1);
}
......
......@@ -38,11 +38,14 @@ int main(int argc, char **argv)
char* local_region;
int region_fd;
char region_file[128];
char region_str[128];
#ifdef USE_SIZECHECK_HEADERS
uint64_t check_size;
#endif
if(argc != 5)
{
fprintf(stderr, "Usage: bake-copy-to <local file> <server addr> <mplex id> <target number>\n");
fprintf(stderr, "Usage: bake-copy-to <local file> <server addr> <provider id> <target number>\n");
fprintf(stderr, " Example: ./bake-copy-to /tmp/foo.dat tcp://localhost:1234 1 3\n");
return(-1);
}
......@@ -93,7 +96,7 @@ int main(int argc, char **argv)
ret = bake_client_init(mid, &bcl);
if(ret != 0)
{
fprintf(stderr, "Error: bake_client_init()\n");
bake_perror("Error: bake_client_init()", ret);
margo_finalize(mid);
munmap(local_region, statbuf.st_size);
close(fd);
......@@ -119,7 +122,7 @@ int main(int argc, char **argv)
margo_finalize(mid);
munmap(local_region, statbuf.st_size);
close(fd);
fprintf(stderr, "Error: bake_provider_handle_create()\n");
bake_perror("Error: bake_provider_handle_create()", ret);
return(-1);
}
......@@ -132,12 +135,12 @@ int main(int argc, char **argv)
margo_finalize(mid);
munmap(local_region, statbuf.st_size);
close(fd);
fprintf(stderr, "Error: bake_probe()\n");
bake_perror( "Error: bake_probe()", ret);
return(-1);
}
if(num_targets < target_number) {
fprintf(stderr, "Error: provider has only %d storage targets\n", num_targets);
fprintf(stderr, "Error: provider has only %llu storage targets\n", (long long unsigned int)num_targets);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
......@@ -156,13 +159,17 @@ int main(int argc, char **argv)
margo_finalize(mid);
munmap(local_region, statbuf.st_size);
close(fd);
fprintf(stderr, "Error: bake_create()\n");
bake_perror("Error: bake_create()", ret);
return(-1);
}
bake_region_id_to_string(rid, region_str, 128);
printf("# created bake region %s\n", region_str);
/* transfer data */
ret = bake_write(
bph,
bti[target_number-1],
rid,
0,
local_region,
......@@ -175,34 +182,34 @@ int main(int argc, char **argv)
margo_finalize(mid);
munmap(local_region, statbuf.st_size);
close(fd);
fprintf(stderr, "Error: bake_write()\n");
bake_perror("bake_write():", ret);
return(-1);
}
munmap(local_region, statbuf.st_size);
close(fd);
ret = bake_persist(bph, rid, 0, statbuf.st_size);
ret = bake_persist(bph, bti[target_number-1], rid, 0, statbuf.st_size);
if(ret != 0)
{
bake_provider_handle_release(bph);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
fprintf(stderr, "Error: bake_persist()\n");
bake_perror("Error: bake_persist()", ret);
return(-1);
}
#ifdef USE_SIZECHECK_HEADERS
/* safety check size */
ret = bake_get_size(bph, rid, &check_size);
ret = bake_get_size(bph, bti[target_number-1], rid, &check_size);
if(ret != 0)
{
bake_provider_handle_release(bph);
margo_addr_free(mid, svr_addr);
bake_client_finalize(bcl);
margo_finalize(mid);
fprintf(stderr, "Error: bake_get_size()\n");
bake_perror("Error: bake_get_size()", ret);