Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
467 lines (396 sloc) 18.2 KB
/*
* Copyright 2013 University of Chicago and Argonne National Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
#ifndef ADLB_H
#define ADLB_H
#include "adlb-defs.h"
#include "version.h"
#define XLB
#define XLB_VERSION 0
/*
These are the functions available to ADLB application code
*/
adlb_code ADLBP_Init(int nservers, int ntypes, int type_vect[],
int *am_server, MPI_Comm adlb_comm,
MPI_Comm *worker_comm);
adlb_code ADLB_Init(int nservers, int ntypes, int type_vect[],
int *am_server, MPI_Comm adlb_comm,
MPI_Comm *worker_comm);
adlb_code ADLB_Server(long max_memory);
adlb_status ADLB_Status(void);
adlb_code ADLB_Version(version* output);
MPI_Comm ADLB_GetComm(void);
MPI_Comm ADLB_GetComm_workers(void);
MPI_Comm ADLB_GetComm_leaders(void);
void ADLB_Leaders(int* leaders, int* count);
adlb_code ADLB_Hostmap_stats(unsigned int* count,
unsigned int* name_max);
adlb_code ADLB_Hostmap_lookup(const char* name, int count,
int* output, int* actual);
/**
Obtain RS-separated buffer of host names
@param output: OUT Buffer into which to write result
@param max: Maximal number of characters to write
@param offset: start with this hostname
@param actual: out number of hostnames written
*/
adlb_code ADLB_Hostmap_list(char* output, unsigned int max,
unsigned int offset, int* actual);
/*
Put a task into the global task queue.
@param payload: data buffer containing task data
@param length: length of the payload in bytes
@param target: target rank for task, adlb_rank_any if any target
@param answer: answer rank passed to receiver of task
@param type: task type
@param priority: priority of task
@param parallelism: number of ranks to execute task
(1 for serial tasks, > 1 for parallel tasks)
@param opts: additional options
*/
adlb_code ADLBP_Put(const void* payload, int length, int target, int answer,
int type, adlb_put_opts opts);
adlb_code ADLB_Put(const void* payload, int length, int target, int answer,
int type, adlb_put_opts opts);
/*
Put a data-dependent task into the global task queue. The task will
be released and eligible to be matched to an ADLB_Get call once all
specified ids reach write refcount 0, and all specified id/subscript
pairs are assigned. Most parameters are identical to adlb_put, except:
@param wait_ids: array of ids to wait for
@param wait_id_count: length of wait_ids array
@param wait_id_subs: array of id/subscript pairs to wait for
@param wait_id_sub_count: length of wait_id_subs array
*/
adlb_code ADLBP_Dput(const void* payload, int length, int target,
int answer, int type, adlb_put_opts opts, const char *name,
const adlb_datum_id *wait_ids, int wait_id_count,
const adlb_datum_id_sub *wait_id_subs, int wait_id_sub_count);
adlb_code ADLB_Dput(const void* payload, int length, int target,
int answer, int type, adlb_put_opts opts, const char *name,
const adlb_datum_id *wait_ids, int wait_id_count,
const adlb_datum_id_sub *wait_id_subs, int wait_id_sub_count);
/*
Get a task from the global task queue.
@param type_requested: the type of work requested
@param payload IN/OUT Pointer into which to receive task
May be changed if too small, in which case
caller must free the new value
Caller should compare payload before and after
@param length IN/OUT original initial/actual length of payload
@param length IN Limit for allocating new payload
@param answer OUT parameter for answer rank specified in ADLB_Put
for task
@param type_recvd OUT parameter for actual type of task
@param comm OUT parameter for MPI communicator to use for
executing parallel task
*/
adlb_code ADLBP_Get(int type_requested, void** payload,
int* length, int max_length,
int* answer, int* type_recvd, MPI_Comm* comm);
adlb_code ADLB_Get(int type_requested, void** payload,
int* length, int max_length,
int* answer, int* type_recvd, MPI_Comm* comm);
/*
Polling equivalent of ADLB_Get. Returns ADLB_NOTHING if no
matching task are available. Other return codes are same as
ADLB_Get
NOTE: Iget does not currently support parallel tasks
*/
adlb_code ADLBP_Iget(int type_requested, void* payload, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
adlb_code ADLB_Iget(int type_requested, void* payload, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
/*
Non-blocking equivalent of ADLB_Get. Matching requests should be
filled in in the order that they are posted (i.e. if work matches two
requests from a client, the first request that was posted will be
filled first.
If a work unit doesn't fit in the posted buffer, a runtime error
will occur.
TODO: currently we assume that only requests for the same type
will be issues concurrently
payload: will be retained by ADLB until request is completed.
req: handle used to check for completion, filled in by function
*/
adlb_code ADLBP_Aget(int type_requested, adlb_payload_buf payload,
adlb_get_req *req);
adlb_code ADLB_Aget(int type_requested, adlb_payload_buf payload,
adlb_get_req *req);
/*
Same as ADLB_Aget except initiates multiple requests at once.
nreqs: number of requests to initiate
wait: wait for first request to be filled (or shutdown to occur),
Return immediately if 0 requests.
After returns, ADLB_Aget_wait will immediately succeed
on first request returned.
payloads: array of nreqs payload buffers
reqs: array of nreqs requests, filled in with request handles
*/
adlb_code ADLBP_Amget(int type_requested, int nreqs, bool wait,
const adlb_payload_buf* payloads,
adlb_get_req *reqs);
adlb_code ADLB_Amget(int type_requested, int nreqs, bool wait,
const adlb_payload_buf* payloads,
adlb_get_req *reqs);
/*
Test if a get request completed without blocking.
Return codes match ADLB_Get
*/
adlb_code ADLBP_Aget_test(adlb_get_req *req, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
adlb_code ADLB_Aget_test(adlb_get_req *req, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
/*
Wait until a get request completes.
Return codes match ADLB_Get
*/
adlb_code ADLBP_Aget_wait(adlb_get_req *req, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
adlb_code ADLB_Aget_wait(adlb_get_req *req, int* length,
int* answer, int* type_recvd, MPI_Comm* comm);
/**
Obtain server rank responsible for data id
*/
int ADLB_Locate(adlb_datum_id id);
// Applications should not call these directly but
// should use the typed forms defined below
// Can be called locally on server where data resides
adlb_code ADLBP_Create(adlb_datum_id id, adlb_data_type type,
adlb_type_extra type_extra,
adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create(adlb_datum_id id, adlb_data_type type,
adlb_type_extra type_extra,
adlb_create_props props, adlb_datum_id *new_id);
// Create multiple variables.
// Currently we assume that spec[i].id is ADLB_DATA_ID_NULL and
// will be filled in with a new id
// Can be called locally on server where data resides
adlb_code ADLB_Multicreate(ADLB_create_spec *specs, int count);
adlb_code ADLBP_Multicreate(ADLB_create_spec *specs, int count);
adlb_code ADLB_Create_integer(adlb_datum_id id, adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create_float(adlb_datum_id id, adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create_string(adlb_datum_id id, adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create_blob(adlb_datum_id id, adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create_ref(adlb_datum_id id, adlb_create_props props,
adlb_datum_id *new_id);
/**
* Struct type: specify struct type, or leave as ADLB_STRUCT_TYPE_NULL to
* resolve upon assigning typed struct value
*/
adlb_code ADLB_Create_struct(adlb_datum_id id, adlb_create_props props,
adlb_struct_type struct_type, adlb_datum_id *new_id);
adlb_code ADLB_Create_container(adlb_datum_id id,
adlb_data_type key_type,
adlb_data_type val_type,
adlb_create_props props,
adlb_datum_id *new_id);
adlb_code ADLB_Create_multiset(adlb_datum_id id,
adlb_data_type val_type,
adlb_create_props props,
adlb_datum_id *new_id);
/*
Add debug symbol entry, overwriting any existing entry.
Only adds to local table (not on other ranks).
symbol: debug symbol identifier, should not be ADLB_DSYM_NULL
data: associated null-terminated data string, will be copied.
*/
adlb_code ADLBP_Add_dsym(adlb_dsym symbol, adlb_dsym_data data);
adlb_code ADLB_Add_dsym(adlb_dsym symbol, adlb_dsym_data data);
/*
Retrieve debug symbol entry from local debug symbol table.
symbol: a debug symbol identifier
return: entry previous added for symbol, or NULL values if not present
*/
adlb_dsym_data ADLBP_Dsym(adlb_dsym symbol);
adlb_dsym_data ADLB_Dsym(adlb_dsym symbol);
adlb_code ADLBP_Exists(adlb_datum_id id, adlb_subscript subscript, bool* result,
adlb_refc decr);
adlb_code ADLB_Exists(adlb_datum_id id, adlb_subscript subscript, bool* result,
adlb_refc decr);
/**
* Find out the current reference counts for a datum.
*
* E.g. if you want to find out that the datum is closed with refcount 0
* This will succeed with zero refcounts if datum isn't found.
*
* result: refcounts of id after decr applied
* decr: amount to decrement refcounts
*/
adlb_code ADLBP_Refcount_get(adlb_datum_id id, adlb_refc *result,
adlb_refc decr);
adlb_code ADLB_Refcount_get(adlb_datum_id id, adlb_refc *result,
adlb_refc decr);
/*
Store value into datum
data: binary representation
length: length of binary representation
refcount_decr: refcounts to to decrement on this id
store_refcounts: refcounts to include for any refs in this data
returns: ADLB_SUCCESS if store succeeded
ADLB_REJECTED if id/subscript already assigned and cannot be
overwritten
ADLB_ERROR for other errors
*/
adlb_code ADLBP_Store(adlb_datum_id id, adlb_subscript subscript,
adlb_data_type type, const void *data, size_t length,
adlb_refc refcount_decr, adlb_refc store_refcounts);
adlb_code ADLB_Store(adlb_datum_id id, adlb_subscript subscript,
adlb_data_type type, const void *data, size_t length,
adlb_refc refcount_decr, adlb_refc store_refcounts);
/*
Retrieve contents of datum.
refcounts: specify how reference counts should be changed
read_refcount: decrease read refcount of this datum
incr_read_referand: increase read refcount of referands,
to ensure they aren't cleaned up prematurely
type: output arg for the type of the datum
data: a buffer of at least size ADLB_DATA_MAX
length: output arg for data size in bytes
*/
adlb_code ADLBP_Retrieve(adlb_datum_id id, adlb_subscript subscript,
adlb_retrieve_refc refcounts,
adlb_data_type* type, void* data, size_t* length);
adlb_code ADLB_Retrieve(adlb_datum_id id, adlb_subscript subscript,
adlb_retrieve_refc refcounts, adlb_data_type* type,
void* data, size_t* length);
/*
List contents of container
data: binary encoded keys and values (if requested), with each member
encoded as follows:
- key length encoded with vint_encode()
- key data without null terminator
- value length encoded with vint_encode()
- value data encoded with ADLB_Pack
length: number of bytes of data
records: number of elements returned
*/
adlb_code ADLBP_Enumerate(adlb_datum_id container_id,
int count, int offset, adlb_refc decr,
bool include_keys, bool include_vals,
void** data, size_t* length, int* records,
adlb_type_extra *kv_type);
adlb_code ADLB_Enumerate(adlb_datum_id container_id,
int count, int offset, adlb_refc decr,
bool include_keys, bool include_vals,
void** data, size_t* length, int* records,
adlb_type_extra *kv_type);
// Switch on read refcounting and memory management, which is off by default
adlb_code ADLBP_Read_refcount_enable(void);
adlb_code ADLB_Read_refcount_enable(void);
adlb_code ADLBP_Refcount_incr(adlb_datum_id id, adlb_refc change);
adlb_code ADLB_Refcount_incr(adlb_datum_id id, adlb_refc change);
/*
Try to reserve an insert position in container
result: true if could be created, false if already present/reserved
value_present: true if value was present (not just reserved)
data: optionally, if this is not NULL, return the existing value in
this buffer of at least size ADLB_DATA_MAX
length: length of existing value if found
type: type of existing value
refcounts: refcounts to apply.
if data exists, apply all refcounts
if placeholder exists, don't apply
if nothing exists, don't apply
*/
adlb_code ADLBP_Insert_atomic(adlb_datum_id id, adlb_subscript subscript,
adlb_retrieve_refc refcounts,
bool *result, bool *value_present,
void *data, size_t *length, adlb_data_type *type);
adlb_code ADLB_Insert_atomic(adlb_datum_id id, adlb_subscript subscript,
adlb_retrieve_refc refcounts,
bool *result, bool *value_present,
void *data, size_t *length, adlb_data_type *type);
/*
returns: ADLB_SUCCESS if datum found
ADLB_NOTHING if datum not found (can indicate it was gced)
*/
adlb_code ADLBP_Subscribe(adlb_datum_id id, adlb_subscript subscript,
int work_type, int* subscribed);
adlb_code ADLB_Subscribe(adlb_datum_id id, adlb_subscript subscript,
int work_type, int* subscribed);
adlb_code ADLBP_Container_reference(adlb_datum_id id, adlb_subscript subscript,
adlb_datum_id ref_id, adlb_subscript ref_subscript,
adlb_data_type ref_type, adlb_refc transfer_refs,
int ref_write_decr);
adlb_code ADLB_Container_reference(adlb_datum_id id, adlb_subscript subscript,
adlb_datum_id ref_id, adlb_subscript ref_subscript,
adlb_data_type ref_type, adlb_refc transfer_refs,
int ref_write_decr);
/*
* Allocate a unique data ID
*/
adlb_code ADLBP_Unique(adlb_datum_id *result);
adlb_code ADLB_Unique(adlb_datum_id *result);
/*
* Allocates a range of count data IDs ADLB ranks. This is useful for
* implementing, for example, globally shared variables. The allocated
* range is inclusive of start and end and will have count members, i.e.
* is [start, start + count).
*
* Must be called collectively by all ranks of the ADLB communicator.
* The same range will be returned on all ranks. This will return
* once all globals have been correctly set up.
*
* Start and end are arbitrarily selected by the function.
* The allocated IDs will be negative, so will not conflict with any
* user-defined IDs in the positive range or IDs allocated by ADLB_Unique
* or a ADLB_Create or related call. If the allocated range conflicts
* with any IDs already created, this will return an error.
*/
adlb_code ADLBP_Alloc_global(int count, adlb_datum_id *start);
adlb_code ADLB_Alloc_global(int count, adlb_datum_id *start);
adlb_code ADLBP_Typeof(adlb_datum_id id, adlb_data_type* type);
adlb_code ADLB_Typeof(adlb_datum_id id, adlb_data_type* type);
adlb_code ADLBP_Container_typeof(adlb_datum_id id, adlb_data_type* key_type,
adlb_data_type* val_type);
adlb_code ADLB_Container_typeof(adlb_datum_id id, adlb_data_type* key_type,
adlb_data_type* val_type);
adlb_code ADLBP_Container_size(adlb_datum_id container_id, int* size,
adlb_refc decr);
adlb_code ADLB_Container_size(adlb_datum_id container_id, int* size,
adlb_refc decr);
adlb_code ADLBP_Lock(adlb_datum_id id, bool* result);
adlb_code ADLB_Lock(adlb_datum_id id, bool* result);
adlb_code ADLBP_Unlock(adlb_datum_id id);
adlb_code ADLB_Unlock(adlb_datum_id id);
/**
Get information about a type based on name.
Returns error if not found
*/
adlb_code ADLB_Data_string_totype(const char* type_string,
adlb_data_type* type, adlb_type_extra *extra);
const char *ADLB_Data_type_tostring(adlb_data_type type);
/*
Convert string to placement enum value.
Case insensitive.
*/
adlb_code ADLB_string_to_placement(const char *string,
adlb_placement *placement);
adlb_code ADLB_Server_idle(int rank, int64_t check_attempt, bool* result,
int *request_counts, int *untargeted_work_counts);
adlb_code ADLBP_Finalize(void);
adlb_code ADLB_Finalize(void);
/**
Tell server to fail.
*/
adlb_code ADLB_Fail(int code);
void ADLB_Abort(int code);
#endif