2015-10-17 11:56:19 +02:00
|
|
|
//
|
|
|
|
// Copyright 2010 Intel Corporation
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
//
|
|
|
|
// [2010-10-25] added support for non-blocking send/recv operations
|
|
|
|
// - iRCCE_isend(), ..._test(), ..._wait(), ..._push()
|
|
|
|
// - iRCCE_irecv(), ..._test(), ..._wait(), ..._push()
|
|
|
|
// by Carsten Clauss, Chair for Operating Systems,
|
|
|
|
// RWTH Aachen University
|
|
|
|
//
|
|
|
|
// [2010-11-12] extracted non-blocking code into separate library
|
|
|
|
// by Carsten Scholtes, University of Bayreuth
|
|
|
|
//
|
|
|
|
// [2010-12-09] added functions for a convenient handling of multiple
|
|
|
|
// pending non-blocking requests
|
|
|
|
// by Jacek Galowicz, Chair for Operating Systems
|
|
|
|
// RWTH Aachen University
|
|
|
|
//
|
|
|
|
// [2011-04-19] added wildcard mechanism (iRCCE_ANY_SOURCE) for receiving
|
|
|
|
// a message from an arbitrary remote rank
|
|
|
|
// by Simon Pickartz, Chair for Operating Systems,
|
|
|
|
// RWTH Aachen University
|
|
|
|
//
|
|
|
|
// [2011-06-16] iRCCE_ANY_LENGTH wildcard mechanism can only be used in
|
|
|
|
// the SINGLEBITFLAGS=0 case (-> bigflags must be enabled!)
|
|
|
|
//
|
|
|
|
// [2011-06-27] merged iRCCE_ANY_SOURCE branch with trunk (iRCCE_ANY_LENGTH)
|
|
|
|
//
|
|
|
|
// [2011-11-03] - renamed blocking (pipelined) send/recv functions to
|
|
|
|
// iRCCE_ssend() / iRCCE_srecv() (strictly synchronous!)
|
|
|
|
// - added non-blocking by synchronous send/recv functions:
|
|
|
|
// iRCCE_issend() / iRCCE_isrecv()
|
|
|
|
// by Carsten Clauss, Chair for Operating Systems,
|
|
|
|
// RWTH Aachen University
|
|
|
|
//
|
|
|
|
// [2012-10-29] - added functions for handling "Tagged Flags"
|
|
|
|
// iRCCE_flag_read/write_tagged(), iRCCE_test/wait_tagged()
|
|
|
|
// by Carsten Clauss, Chair for Operating Systems,
|
|
|
|
// RWTH Aachen University
|
|
|
|
//
|
2015-10-18 12:42:20 +02:00
|
|
|
// [2015-10-18] port (i)RCCE to "HermitCore"
|
|
|
|
// by Stefan Lankes, Institute for Automation of Complex Power Systems
|
|
|
|
// RWTH Aachen University
|
2015-10-17 11:56:19 +02:00
|
|
|
|
|
|
|
#ifndef IRCCE_H
|
|
|
|
#define IRCCE_H
|
|
|
|
|
|
|
|
#include "RCCE.h"
|
|
|
|
|
|
|
|
#define iRCCE_VERSION "2.0"
|
|
|
|
#define iRCCE_FLAIR
|
|
|
|
|
|
|
|
#define iRCCE_SUCCESS RCCE_SUCCESS
|
|
|
|
#define iRCCE_ERROR -1
|
|
|
|
#define iRCCE_PENDING -2
|
|
|
|
#define iRCCE_RESERVED -3
|
|
|
|
#define iRCCE_NOT_ENQUEUED -4
|
|
|
|
|
|
|
|
#if !defined(SINGLEBITFLAGS) && !defined(RCCE_VERSION)
|
|
|
|
#define _iRCCE_ANY_LENGTH_
|
|
|
|
extern const int iRCCE_ANY_LENGTH;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if !defined(SINGLEBITFLAGS)
|
2015-10-18 12:42:20 +02:00
|
|
|
#if defined(_OPENMP) && !defined(__hermit__)
|
2015-10-17 11:56:19 +02:00
|
|
|
#define iRCCE_MAX_TAGGED_LEN (RCCE_LINE_SIZE - 2 * sizeof(int))
|
|
|
|
#else
|
|
|
|
#define iRCCE_MAX_TAGGED_LEN (RCCE_LINE_SIZE - sizeof(int))
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
extern const int iRCCE_ANY_SOURCE;
|
|
|
|
|
|
|
|
typedef struct _iRCCE_SEND_REQUEST {
|
|
|
|
char *privbuf; // source buffer in local private memory (send buffer)
|
|
|
|
t_vcharp combuf; // intermediate buffer in MPB
|
|
|
|
size_t chunk; // size of MPB available for this message (bytes)
|
|
|
|
size_t subchunk1; // sub-chunks for the pipelined message transfe
|
|
|
|
size_t subchunk2;
|
|
|
|
RCCE_FLAG *ready; // flag indicating whether receiver is ready
|
|
|
|
RCCE_FLAG *sent; // flag indicating whether message has been sent by source
|
|
|
|
RCCE_FLAG_STATUS flag_set_value; // used for iRCCE_ANY_LENGTH wildcard
|
|
|
|
size_t size; // size of message (bytes)
|
|
|
|
int dest; // UE that will receive the message
|
|
|
|
int sync; // flag indicating whether send is synchronous or not
|
|
|
|
|
|
|
|
size_t wsize; // offset within send buffer when putting in "chunk" bytes
|
|
|
|
size_t remainder; // bytes remaining to be sent
|
|
|
|
size_t nbytes; // number of bytes to be sent in single RCCE_put call
|
|
|
|
char *bufptr; // running pointer inside privbuf for current location
|
|
|
|
|
|
|
|
int label; // jump/goto label for the reentrance of the respective poll function
|
|
|
|
int finished; // flag that indicates whether the request has already been finished
|
|
|
|
|
|
|
|
struct _iRCCE_SEND_REQUEST *next;
|
|
|
|
} iRCCE_SEND_REQUEST;
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct _iRCCE_RECV_REQUEST {
|
|
|
|
char *privbuf; // source buffer in local private memory (send buffer)
|
|
|
|
t_vcharp combuf; // intermediate buffer in MPB
|
|
|
|
size_t chunk; // size of MPB available for this message (bytes)
|
|
|
|
size_t subchunk1; // sub-chunks for the pipelined message transfe
|
|
|
|
size_t subchunk2;
|
|
|
|
RCCE_FLAG *ready; // flag indicating whether receiver is ready
|
|
|
|
RCCE_FLAG *sent; // flag indicating whether message has been sent by source
|
|
|
|
RCCE_FLAG_STATUS flag_set_value; // used for iRCCE_ANY_LENGTH wildcard
|
|
|
|
size_t size; // size of message (bytes)
|
|
|
|
int source; // UE that will send the message
|
|
|
|
int sync; // flag indicating whether recv is synchronous or not
|
|
|
|
|
|
|
|
size_t wsize; // offset within send buffer when putting in "chunk" bytes
|
|
|
|
size_t remainder; // bytes remaining to be sent
|
|
|
|
size_t nbytes; // number of bytes to be sent in single RCCE_put call
|
|
|
|
char *bufptr; // running pointer inside privbuf for current location
|
|
|
|
|
|
|
|
int label; // jump/goto label for the reentrance of the respective poll function
|
|
|
|
int finished; // flag that indicates whether the request has already been finished
|
|
|
|
int started; // flag that indicates whether message parts have already been received
|
|
|
|
|
|
|
|
struct _iRCCE_RECV_REQUEST *next;
|
|
|
|
} iRCCE_RECV_REQUEST;
|
|
|
|
|
|
|
|
#define iRCCE_WAIT_LIST_RECV_TYPE 0
|
|
|
|
#define iRCCE_WAIT_LIST_SEND_TYPE 1
|
|
|
|
|
|
|
|
typedef struct _iRCCE_WAIT_LISTELEM {
|
|
|
|
int type;
|
|
|
|
struct _iRCCE_WAIT_LISTELEM * next;
|
|
|
|
void * req;
|
|
|
|
} iRCCE_WAIT_LISTELEM;
|
|
|
|
|
|
|
|
typedef struct _iRCCE_WAIT_LIST {
|
|
|
|
iRCCE_WAIT_LISTELEM * first;
|
|
|
|
iRCCE_WAIT_LISTELEM * last;
|
|
|
|
} iRCCE_WAIT_LIST;
|
|
|
|
|
|
|
|
#ifdef AIR
|
|
|
|
typedef volatile struct _iRCCE_AIR {
|
2015-10-18 12:42:20 +02:00
|
|
|
#if !defined(_OPENMP) || defined(__hermit__)
|
2015-10-17 11:56:19 +02:00
|
|
|
int * counter;
|
|
|
|
int * init;
|
|
|
|
#else
|
|
|
|
int counter;
|
|
|
|
int init;
|
|
|
|
#endif
|
|
|
|
} iRCCE_AIR;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// THE iRCCE API:
|
|
|
|
//
|
|
|
|
// Initialize function:
|
|
|
|
int iRCCE_init(void);
|
|
|
|
//
|
|
|
|
// Non-blocking send/recv functions:
|
|
|
|
int iRCCE_isend(char *, ssize_t, int, iRCCE_SEND_REQUEST *);
|
|
|
|
int iRCCE_isend_test(iRCCE_SEND_REQUEST *, int *);
|
|
|
|
int iRCCE_isend_wait(iRCCE_SEND_REQUEST *);
|
|
|
|
int iRCCE_isend_push(void);
|
|
|
|
int iRCCE_irecv(char *, ssize_t, int, iRCCE_RECV_REQUEST *);
|
|
|
|
int iRCCE_irecv_test(iRCCE_RECV_REQUEST *, int *);
|
|
|
|
int iRCCE_irecv_wait(iRCCE_RECV_REQUEST *);
|
|
|
|
int iRCCE_irecv_push(void);
|
|
|
|
//
|
|
|
|
// Pipelined send/recv functions: (syncronous and blocking)
|
|
|
|
int iRCCE_ssend(char *, ssize_t, int);
|
|
|
|
int iRCCE_srecv(char *, ssize_t, int);
|
|
|
|
int iRCCE_srecv_test(char *, ssize_t, int, int*);
|
|
|
|
//
|
|
|
|
// Non-blocking pipelined send/recv functions:
|
|
|
|
int iRCCE_issend(char *, ssize_t, int, iRCCE_SEND_REQUEST *);
|
|
|
|
int iRCCE_isrecv(char *, ssize_t, int, iRCCE_RECV_REQUEST *);
|
|
|
|
//
|
|
|
|
// SCC-customized put/get and memcpy functions:
|
|
|
|
int iRCCE_put(t_vcharp, t_vcharp, int, int);
|
|
|
|
int iRCCE_get(t_vcharp, t_vcharp, int, int);
|
|
|
|
void* iRCCE_memcpy_put(void*, const void*, size_t);
|
|
|
|
void* iRCCE_memcpy_get(void*, const void*, size_t);
|
|
|
|
t_vcharp iRCCE_malloc(size_t);
|
|
|
|
#define iRCCE_memcpy iRCCE_memcpy_put
|
|
|
|
//
|
|
|
|
// Blocking and non-blocking 'probe' functions for incommimg messages:
|
|
|
|
int iRCCE_probe(int, int*);
|
|
|
|
int iRCCE_iprobe(int, int*, int*);
|
|
|
|
//
|
|
|
|
// Wait/test-all/any functions:
|
|
|
|
void iRCCE_init_wait_list(iRCCE_WAIT_LIST*);
|
|
|
|
void iRCCE_add_to_wait_list(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST *, iRCCE_RECV_REQUEST *);
|
|
|
|
int iRCCE_test_all(iRCCE_WAIT_LIST*, int *);
|
|
|
|
int iRCCE_wait_all(iRCCE_WAIT_LIST*);
|
|
|
|
int iRCCE_test_any(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST **, iRCCE_RECV_REQUEST **);
|
|
|
|
int iRCCE_wait_any(iRCCE_WAIT_LIST*, iRCCE_SEND_REQUEST **, iRCCE_RECV_REQUEST **);
|
|
|
|
//
|
|
|
|
// Query functions for request handle parameters:
|
|
|
|
int iRCCE_get_dest(iRCCE_SEND_REQUEST*);
|
|
|
|
int iRCCE_get_source(iRCCE_RECV_REQUEST*);
|
|
|
|
int iRCCE_get_size(iRCCE_SEND_REQUEST*, iRCCE_RECV_REQUEST*);
|
|
|
|
int iRCCE_get_length(void);
|
|
|
|
//
|
|
|
|
// Cancel functions for yet not started non-blocking requests:
|
|
|
|
int iRCCE_isend_cancel(iRCCE_SEND_REQUEST *, int *);
|
|
|
|
int iRCCE_irecv_cancel(iRCCE_RECV_REQUEST *, int *);
|
|
|
|
//
|
|
|
|
// Functions for handling tagged flags: (need whole cache line per flag)
|
|
|
|
#ifndef SINGLEBITFLAGS
|
|
|
|
int iRCCE_flag_alloc_tagged(RCCE_FLAG *);
|
|
|
|
int iRCCE_flag_write_tagged(RCCE_FLAG *, RCCE_FLAG_STATUS, int, void *, int);
|
|
|
|
int iRCCE_flag_read_tagged(RCCE_FLAG, RCCE_FLAG_STATUS *, int, void *, int);
|
|
|
|
int iRCCE_wait_tagged(RCCE_FLAG, RCCE_FLAG_STATUS, void *, int);
|
|
|
|
int iRCCE_test_tagged(RCCE_FLAG, RCCE_FLAG_STATUS, int *, void *, int);
|
|
|
|
int iRCCE_get_max_tagged_len(void);
|
|
|
|
#endif
|
|
|
|
//
|
|
|
|
// Functions for handling Atomic Increment Registers (AIR):
|
|
|
|
#ifdef AIR
|
|
|
|
int iRCCE_atomic_alloc(iRCCE_AIR **);
|
|
|
|
int iRCCE_atomic_inc(iRCCE_AIR*, int*);
|
|
|
|
int iRCCE_atomic_read(iRCCE_AIR*, int*);
|
|
|
|
int iRCCE_atomic_write(iRCCE_AIR*, int);
|
|
|
|
#endif
|
|
|
|
//
|
|
|
|
// Improved Collectives:
|
|
|
|
int iRCCE_barrier(RCCE_COMM*);
|
|
|
|
int iRCCE_bcast(char *, size_t, int, RCCE_COMM);
|
|
|
|
int iRCCE_mcast(char *, size_t, int);
|
|
|
|
int iRCCE_msend(char *, ssize_t);
|
|
|
|
int iRCCE_mrecv(char *, ssize_t, int);
|
|
|
|
//
|
|
|
|
// Functions form the GORY RCCE interface mapped to iRCCE:
|
|
|
|
t_vcharp iRCCE_malloc(size_t);
|
|
|
|
int iRCCE_flag_alloc(RCCE_FLAG *);
|
|
|
|
int iRCCE_flag_write(RCCE_FLAG *, RCCE_FLAG_STATUS, int);
|
|
|
|
int iRCCE_flag_read(RCCE_FLAG, RCCE_FLAG_STATUS *, int);
|
|
|
|
int iRCCE_wait_until(RCCE_FLAG, RCCE_FLAG_STATUS);
|
|
|
|
//
|
|
|
|
// Please Note: Since we're running in NON-GORY mode, there are no "free()" functions!
|
|
|
|
//
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Just for convenience:
|
|
|
|
#if 1
|
|
|
|
#define RCCE_isend iRCCE_isend
|
|
|
|
#define RCCE_isend_test iRCCE_isend_test
|
|
|
|
#define RCCE_isend_wait iRCCE_isend_wait
|
|
|
|
#define RCCE_isend_push iRCCE_isend_push
|
|
|
|
#define RCCE_irecv iRCCE_irecv
|
|
|
|
#define RCCE_irecv_test iRCCE_irecv_test
|
|
|
|
#define RCCE_irecv_wait iRCCE_irecv_wait
|
|
|
|
#define RCCE_irecv_push iRCCE_irecv_push
|
|
|
|
#define RCCE_SEND_REQUEST iRCCE_SEND_REQUEST
|
|
|
|
#define RCCE_RECV_REQUEST iRCCE_RECV_REQUEST
|
|
|
|
#ifdef _iRCCE_TAGGED_FLAGS_
|
|
|
|
#define RCCE_flag_write_tagged iRCCE_flag_write_tagged
|
|
|
|
#define RCCE_flag_read_tagged iRCCE_flag_read_tagged
|
|
|
|
#define RCCE_wait_tagged iRCCE_wait_tagged
|
|
|
|
#define RCCE_test_tagged iRCCE_test_tagged
|
|
|
|
#define RCCE_flag_alloc_tagged iRCCE_flag_alloc_tagged
|
|
|
|
#define RCCE_flag_free_tagged iRCCE_flag_free_tagged
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
//
|
|
|
|
#if 1
|
|
|
|
#define iRCCE_send iRCCE_ssend
|
|
|
|
#define iRCCE_recv iRCCE_srecv
|
|
|
|
#define iRCCE_recv_test iRCCE_srecv_test
|
|
|
|
#endif
|
|
|
|
//
|
|
|
|
#if 1
|
|
|
|
#define iRCCE_issend_test iRCCE_isend_test
|
|
|
|
#define iRCCE_issend_wait iRCCE_isend_wait
|
|
|
|
#define iRCCE_issend_push iRCCE_isend_push
|
|
|
|
#define iRCCE_isrecv_test iRCCE_irecv_test
|
|
|
|
#define iRCCE_isrecv_wait iRCCE_irecv_wait
|
|
|
|
#define iRCCE_isrecv_push iRCCE_irecv_push
|
|
|
|
#endif
|
|
|
|
//
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|