void SNetDistribZMQHostsInit(int argc, char **argv) { int i; node_location = -1; data_port = SNET_ZMQ_DPORT; sync_port = SNET_ZMQ_SPORT; net_size = 1; on_cloud = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-raddr") == 0) { //root node address (tcp://host:port/) strncpy(root_addr, argv[i+1], SNET_ZMQ_HOSTLN); } else if (strcmp(argv[i], "-hostn") == 0) { //force local hostname strncpy(host_name, argv[i+1], SNET_ZMQ_HOSTLN); } else if (strcmp(argv[i], "-sport") == 0) { //synchronization port sync_port = atoi(argv[i+1]); } else if (strcmp(argv[i], "-dport") == 0) { //data port data_port = atoi(argv[i+1]); } else if (strcmp(argv[i], "-node") == 0) { //try to set snet node id node_location = atoi(argv[i+1]); if (node_location == 0) { SNetUtilDebugFatal("ZMQDistrib: -node argument cannot be 0"); } } else if (strcmp(argv[i], "-root") == 0) { //be root node of network of size as param net_size = atoi(argv[i+1]); node_location = 0; } else if (strcmp(argv[i], "-cloud-static") == 0) { //use static cloud instantiation on_cloud = 1; } else if (strcmp(argv[i], "-cloud-dynamic") == 0) { //use dynamic cloud instantiation on_cloud = 2; } } if ((strcmp(root_addr, "") == 0) && (node_location != 0)) { SNetUtilDebugFatal("ZMQDistrib: <[-root <net_size>] | [-raddr <root_addr]>"); } SNetDistribZMQHTabInit(data_port, sync_port, node_location, root_addr, host_name, on_cloud); node_location = HTabNodeLocation(); if (on_cloud == 1 && node_location == 0) { sprintf(root_addr, "tcp://%s:%d/", HTabGetHostName(), sync_port); SNetCloudInit(argv[0], root_addr); SNetCloudInstantiateNetRaw(net_size - 1); } SNetDistribZMQHTabStart(); }
static FILE *SNetInOpenInputSocket(int port) { struct sockaddr_in addr; struct sockaddr_in in_addr; int fdesc; FILE *file; int yes = 1; unsigned int sin_size; int in_fdesc; if ((fdesc = socket(AF_INET, SOCK_STREAM, 0)) == -1) { SNetUtilDebugFatal("Could not create socket for input!\n"); } if(setsockopt(fdesc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { SNetUtilDebugFatal("Could not obtain socket for input!\n"); } addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; memset(addr.sin_zero, '\0', sizeof addr.sin_zero); if(bind(fdesc, (struct sockaddr *)&addr, sizeof addr) == -1) { SNetUtilDebugFatal("Could not bind to input port (%d)!\n", addr.sin_port); } /* Notice: This blocks the initialization of the SNet until the * first connection! (Listen in different thread?) */ listen(fdesc, 1); sin_size = sizeof(in_addr); in_fdesc = accept(fdesc, (struct sockaddr *)&in_addr, &sin_size); /* Currently only one connection accepted! * Note: it could be a nice feature to accept more? */ close(fdesc); file = fdopen(in_fdesc, "r"); if(file == NULL) { SNetUtilDebugFatal("Socket error!\n"); } return file; }
/* A record arriving via the loopback now leaves the feedback network. * Remove the detref structure and check for termination conditions. */ void SNetFeedbackLeave(snet_record_t *rec, landing_t *landing, fifo_t *detfifo) { snet_stack_t *stack; detref_t *detref, *first; trace(__func__); // record must have a stack of detrefs if ((stack = DATA_REC(rec, detref)) == NULL) { SNetUtilDebugFatal("[%s]: missing stack.", __func__); } // stack must have at least one detref if ((detref = SNetStackPop(stack)) == NULL) { SNetUtilDebugFatal("[%s]: empty stack.", __func__); } if (SNetStackIsEmpty(stack)) { SNetStackDestroy(stack); DATA_REC(rec, detref) = NULL; } // detref must refer to this DetLeave node if (detref->leave != landing) { SNetUtilDebugFatal("[%s]: leave %p != landing %p.", __func__, detref->leave, landing); } // reference counter must be at least two if (detref->refcount < 2) { SNetUtilDebugFatal("[%s]: refcnt %d < 1.", __func__, detref->refcount); } // decrease reference count if (DETREF_DECR(detref) == 1) { DETREF_DECR(detref); } assert(detref->refcount >= 0); // pop detrefs in sequence which have no more records in the loopback left. while ((first = SNetFifoPeekFirst(detfifo)) != NULL) { // stop processing if more records to come for this sequence counter if (first->refcount > 0) { break; } SNetFifoGet(detfifo); SNetFifoDone(&first->recfifo); SNetDelete(first); } }
/* Language interface initialization function. */ void C4SNetInit( int id, snet_distrib_t distImpl) { /* set call back function on data */ SNetReferenceSetDataFunc(AllocatedSpace); interface_id = id; snet_pack_fun_t packfun = NULL; snet_unpack_fun_t unpackfun = NULL; switch (distImpl) { case nodist: break; case mpi: #ifdef ENABLE_DIST_MPI packfun = (void (*)(void*, void*)) &MPIPackFun; unpackfun = (void *(*)(void*)) &MPIUnpackFun; #else SNetUtilDebugFatal("C4SNet supports MPI, but is not configured to use " "it.\n"); #endif break; case scc: #ifdef ENABLE_DIST_SCC MemAlloc = &SCCMalloc; MemFree = &SCCFreeWrapper; packfun = (void (*)(void*, void*)) &SCCPackFun; unpackfun = &SCCUnpackFun; #else SNetUtilDebugFatal("C4SNet supports SCC, but is not configured to use " "it.\n"); #endif break; default: SNetUtilDebugFatal("C4SNet doesn't support the selected distribution " "layer (%d).\n", distImpl); break; } SNetInterfaceRegister( id, (void (*)(void*)) &C4SNetFree, (void *(*)(void*)) &C4SNetShallowCopy, (size_t (*)(void*)) &AllocatedSpace, (void (*)(FILE*, void*)) &C4SNetSerialise, (void *(*)(FILE*)) &C4SNetDeserialise, (void (*)(FILE*, void*)) &C4SNetEncode, (void *(*)(FILE*)) &C4SNetDecode, packfun, unpackfun); }
/* Serializes data to a file using textual representation. */ static void C4SNetSerialise(FILE *file, c4snet_data_t *data) { switch (data->type) { case CTYPE_uchar: fprintf(file, "(unsigned char"); break; case CTYPE_char: fprintf(file, "(char"); break; case CTYPE_ushort: fprintf(file, "(unsigned short"); break; case CTYPE_short: fprintf(file, "(short"); break; case CTYPE_uint: fprintf(file, "(unsigned int"); break; case CTYPE_int: fprintf(file, "(int"); break; case CTYPE_ulong: fprintf(file, "(unsigned long"); break; case CTYPE_long: fprintf(file, "(long"); break; case CTYPE_float: fprintf(file, "(float"); break; case CTYPE_double: fprintf(file, "(double"); break; case CTYPE_ldouble: fprintf(file, "(long double"); break; case CTYPE_pointer: fprintf(file, "(pointer"); break; default: SNetUtilDebugFatal("[%s]: Unknown type %d in C4SNet.", __func__, data->type); } if (data->vtype == VTYPE_array) fprintf(file, "[%lu]", data->size); fprintf(file, ")"); if (data->vtype == VTYPE_array) { for (int i = 0; i < data->size; i++) { SerialiseData(file, data->type, (char*) data->data.ptr + i * C4SNetSizeof(data)); if (i < data->size - 1) fprintf(file, ","); } } else { SerialiseData(file, data->type, &data->data); } }
static void SerialiseData(FILE *file, c4snet_type_t type, void *data) { switch (type) { case CTYPE_uchar: case CTYPE_char: { char c = *(char*) data; /* '&' and '<' must be encoded to '&' and 'lt'; * as they are not legal characters in XML character data! */ if (c == '<') fprintf(file, "<"); else if (c == '&') fprintf(file, "&"); else fprintf(file, "%c", c); } break; case CTYPE_ushort: fprintf(file, "%hu", *(unsigned short *) data); break; case CTYPE_short: fprintf(file, "%hd", *(short *) data); break; case CTYPE_uint: fprintf(file, "%u", *(unsigned int *) data); break; case CTYPE_int: fprintf(file, "%d", *(int *) data); break; case CTYPE_ulong: fprintf(file, "%lu", *(unsigned long *) data); break; case CTYPE_long: fprintf(file, "%ld", *(long *) data); break; case CTYPE_float: fprintf(file, "%.32f", *(float *) data); break; case CTYPE_double: fprintf(file, "%.32le", *(double *) data); break; case CTYPE_ldouble: fprintf(file, "%.32Le", *(long double *) data); break; case CTYPE_pointer: fprintf(file, "%p", *(void **) data); break; default: SNetUtilDebugFatal("[%s]: Unknown type %d in C4SNet.", __func__, type); } }
void SAC4SNetInit( int id, snet_distrib_t distImpl) { my_interface_id = id; snet_pack_fun_t packfun = NULL; snet_unpack_fun_t unpackfun = NULL; switch (distImpl) { case nodist: break; case mpi: #ifdef ENABLE_DIST_MPI packfun = &SAC4SNetMPIPackFun; unpackfun = &SAC4SNetMPIUnpackFun; #else SNetUtilDebugFatal("SAC4SNet supports MPI, but is not configured to use " "it.\n"); #endif break; case scc: #ifdef ENABLE_DIST_SCC packfun = &SAC4SNetSCCPackFun; unpackfun = &SAC4SNetSCCUnpackFun; #else SNetUtilDebugFatal("SAC4SNet supports SCC, but is not configured to use " "it.\n"); #endif break; default: SNetUtilDebugFatal("SAC4SNet doesn't support the selected distribution " "layer (%d).\n", distImpl); break; } SNetInterfaceRegister( id, &SACARGfree, &SACARGcopy, &SAC4SNetAllocSize, &SAC4SNetDataSerialise, &SAC4SNetDataDeserialise, &SAC4SNetDataEncode, &SAC4SNetDataDecode, packfun, unpackfun); SAC_InitRuntimeSystem(); }
/* Deserializes textual data from a file. */ static c4snet_data_t *C4SNetDeserialise(FILE *file) { char buf[16]; c4snet_data_t *temp = SNetMemAlloc(sizeof(c4snet_data_t)); temp->size = 0; temp->ref_count = 1; if (fscanf(file, "(%15[^[)][%lu])", buf, &temp->size) == 2) { temp->vtype = VTYPE_array; } else { temp->vtype = VTYPE_simple; (void) fscanf(file, ")"); } int size = strlen(buf); if (strncmp(buf, "unsigned char", size) == 0) temp->type = CTYPE_uchar; else if(strncmp(buf, "char", size) == 0) temp->type = CTYPE_char; else if(strncmp(buf, "unsigned short", size) == 0) temp->type = CTYPE_ushort; else if(strncmp(buf, "short", size) == 0) temp->type = CTYPE_short; else if(strncmp(buf, "unsigned int", size) == 0) temp->type = CTYPE_uint; else if(strncmp(buf, "int", size) == 0) temp->type = CTYPE_int; else if(strncmp(buf, "unsigned long", size) == 0) temp->type = CTYPE_ulong; else if(strncmp(buf, "long", size) == 0) temp->type = CTYPE_long; else if(strncmp(buf, "float", size) == 0) temp->type = CTYPE_float; else if(strncmp(buf, "double", size) == 0) temp->type = CTYPE_double; else if(strncmp(buf, "long double", size) == 0) temp->type = CTYPE_ldouble; else if(strncmp(buf, "pointer", size) == 0) temp->type = CTYPE_pointer; else SNetUtilDebugFatal("[%s]: C4SNet interface encountered an unknown type.", __func__); if (temp->vtype == VTYPE_simple) { DeserialiseData(file, temp->type, &temp->data); } else { temp->data.ptr = MemAlloc(AllocatedSpace(temp)); for (int i = 0; i < temp->size; i++) { if (i > 0 && fgetc(file) != ',') { SNetUtilDebugFatal("[%s]: Parse error deserialising data.", __func__); } DeserialiseData(file, temp->type, (char*) temp->data.ptr + i * C4SNetSizeof(temp)); } } return temp; }
snet_record_t *SNetRecCreate( snet_record_descr_t descr, ...) { snet_record_t *rec; va_list args; rec = SNetMemAlloc( sizeof( snet_record_t)); REC_DESCR( rec) = descr; va_start( args, descr); switch (descr) { case REC_data: RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( rec, data_rec) = SNetMemAlloc( sizeof( data_rec_t)); DATA_REC( rec, btags) = SNetIntMapCreate(0); DATA_REC( rec, tags) = SNetIntMapCreate(0); DATA_REC( rec, fields) = SNetRefMapCreate(0); DATA_REC( rec, mode) = MODE_binary; GenerateRecId( &DATA_REC( rec, rid) ); DATA_REC( rec, parent_rids) = NULL; DATA_REC( rec, interface_id) = 0; break; case REC_trigger_initialiser: RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); break; case REC_sync: { RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( rec, sync_rec) = SNetMemAlloc( sizeof( sync_rec_t)); SYNC_REC( rec, input) = va_arg( args, snet_stream_t *); SYNC_REC( rec, outtype) = NULL; } break; case REC_collect: RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( rec, coll_rec) = SNetMemAlloc( sizeof( coll_rec_t)); COLL_REC( rec, output) = va_arg( args, snet_stream_t*); break; case REC_terminate: RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( rec, terminate_rec) = SNetMemAlloc( sizeof( terminate_rec_t)); TERM_REC( rec, local) = false; break; case REC_sort_end: RECPTR( rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( rec, sort_end_rec) = SNetMemAlloc( sizeof( sort_end_rec_t)); SORT_E_REC( rec, level) = va_arg( args, int); SORT_E_REC( rec, num) = va_arg( args, int); break; default: SNetUtilDebugFatal("Unknown control record description. [%d]", descr); break; } va_end( args); return rec; }
static FILE *SNetInOpenFile(const char *file, const char *args) { FILE *fileptr = fopen(file, args); if(fileptr == NULL) { SNetUtilDebugFatal("Could not open file \"%s\" with mode \"%s\"!\n", file, args); } return fileptr; }
snet_msg_t SNetDistribRecvMsg(void) { int count; snet_msg_t result; MPI_Status status; static mpi_buf_t recvBuf = {0, 0, NULL}; MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); MPI_Get_count(&status, MPI_PACKED, &count); MPI_Pack_size(count, MPI_PACKED, MPI_COMM_WORLD, &recvBuf.offset); if (recvBuf.offset > recvBuf.size) { recvBuf.data = SNetMemResize(recvBuf.data, recvBuf.offset); recvBuf.size = recvBuf.offset; } MPI_Recv(recvBuf.data, count, MPI_PACKED, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status); recvBuf.offset = 0; result.type = status.MPI_TAG; switch (status.MPI_TAG) { case snet_rec: result.rec = SNetRecDeserialise(&recvBuf); case snet_block: case snet_unblock: result.dest = SNetDestDeserialise(&recvBuf); result.dest.node = status.MPI_SOURCE; break; case snet_ref_set: result.ref = SNetRefDeserialise(&recvBuf); result.data = (uintptr_t) SNetInterfaceGet(SNetRefInterface(result.ref))->unpackfun(&recvBuf); break; case snet_ref_fetch: result.ref = SNetRefDeserialise(&recvBuf); result.data = status.MPI_SOURCE; break; case snet_ref_update: result.ref = SNetRefDeserialise(&recvBuf); SNetDistribUnpack(&recvBuf, &result.val, sizeof(result.val)); break; case snet_update: break; case snet_stop: break; default: SNetUtilDebugFatal("[%s]: Unexpected MPI TAG %d\n", __func__, result.type); break; } return result; }
static FILE *SNetInOpenOutputSocket(const char *address, int port) { struct hostent *host; struct sockaddr_in addr; int fdesc; FILE *file; if(inet_aton(address, &addr.sin_addr)) { SNetUtilDebugFatal("Could not parse output address (%s)!\n", address); } host = gethostbyname(address); if(!host) { SNetUtilDebugFatal("Unknown host for output (%s)!\n", address); } addr.sin_addr = *(struct in_addr*)host->h_addr; fdesc = socket(PF_INET, SOCK_STREAM, 0); if(fdesc == -1){ SNetUtilDebugFatal("Could not create socket for output!\n"); } addr.sin_port = htons(port); addr.sin_family = AF_INET; if(connect(fdesc, (struct sockaddr*)&addr, sizeof(addr)) == -1) { close(fdesc); SNetUtilDebugFatal("Could not connect to host (%s:%d)!\n", address, port); } file = fdopen(fdesc, "w"); if(file == NULL) { close(fdesc); SNetUtilDebugFatal("Socket error!\n"); } return file; }
/* Get a copy of an unterminated char array as a proper C string. */ char* C4SNetGetString(c4snet_data_t *data) { if (data->type != CTYPE_char && data->type != CTYPE_uchar) { SNetUtilDebugFatal("[%s]: Not a char array type %d.", __func__, data->type); return NULL; /* NOT REACHED */ } else { size_t size = C4SNetArraySize(data); char* str = SNetMemAlloc(size + 1); memcpy(str, C4SNetGetData(data), size); str[size] = '\0'; return str; } }
static size_t sizeOfType(SACbasetype_t type) { switch (type) { case T_int: return sizeof(int); case T_double: return sizeof(double); case T_float: return sizeof(float); default: SNetUtilDebugFatal("Unknown SAC type!\n"); break; } return -1; }
static void DeserialiseData(FILE *file, c4snet_type_t type, void *data) { char buf[6]; char *fmt = NULL; switch (type) { case CTYPE_char: case CTYPE_uchar: { /* '&' and '<' must be encoded to '&' and 'lt'; * as they are not legal characters in XML character data! */ int count = fscanf(file, "%c%4[^<,]", buf, buf+1); if (!strcmp(buf, "&")) *(char *) data = '&'; else if (!strcmp(buf, "<")) *(char *) data = '<'; else if (count == 1) *(char *) data = buf[0]; else SNetUtilDebugFatal("[%s]: FIXME invalid char '%s'.", __func__, buf); if (type == CTYPE_uchar) *(unsigned char*) data = (unsigned char) *(char*) data; return; } case CTYPE_ushort: fmt = "%hu"; break; case CTYPE_short: fmt = "%hd"; break; case CTYPE_uint: fmt = "%u"; break; case CTYPE_int: fmt = "%d"; break; case CTYPE_ulong: fmt = "%lu"; break; case CTYPE_long: fmt = "%ld"; break; case CTYPE_float: fmt = "%f"; break; case CTYPE_double: fmt = "%lf"; break; case CTYPE_ldouble: fmt = "%Lf"; break; case CTYPE_pointer: fmt = "%p"; break; default: SNetUtilDebugFatal("[%s]: FIXME invalid type %d.", __func__, type); } (void) fscanf(file, fmt, data); }
static MPI_Datatype TypeToMPIType(c4snet_type_t type) { switch (type) { case CTYPE_uchar: return MPI_UNSIGNED_CHAR; case CTYPE_char: return MPI_CHAR; case CTYPE_ushort: return MPI_UNSIGNED_SHORT; case CTYPE_short: return MPI_SHORT; case CTYPE_uint: return MPI_UNSIGNED; case CTYPE_int: return MPI_INT; case CTYPE_ulong: return MPI_UNSIGNED_LONG; case CTYPE_long: return MPI_LONG; case CTYPE_float: return MPI_FLOAT; case CTYPE_double: return MPI_DOUBLE; case CTYPE_ldouble: return MPI_LONG_DOUBLE; default: SNetUtilDebugFatal("Unknown MPI datatype!\n"); } return MPI_CHAR; }
static MPI_Datatype TypeToMPIType(c4snet_type_t type) { switch (type) { case CTYPE_uchar: return MPI_UNSIGNED_CHAR; case CTYPE_char: return MPI_CHAR; case CTYPE_ushort: return MPI_UNSIGNED_SHORT; case CTYPE_short: return MPI_SHORT; case CTYPE_uint: return MPI_UNSIGNED; case CTYPE_int: return MPI_INT; case CTYPE_ulong: return MPI_UNSIGNED_LONG; case CTYPE_long: return MPI_LONG; case CTYPE_float: return MPI_FLOAT; case CTYPE_double: return MPI_DOUBLE; case CTYPE_ldouble: return MPI_LONG_DOUBLE; case CTYPE_pointer: return MPI_VOID_POINTER; default: SNetUtilDebugFatal("[%s]: Unknown C4SNet datatype %d.\n", __func__, type); } return MPI_CHAR; }
static int sizeOfType(c4snet_type_t type) { switch (type) { case CTYPE_uchar: return sizeof(unsigned char); case CTYPE_char: return sizeof(signed char); case CTYPE_ushort: return sizeof(unsigned short); case CTYPE_short: return sizeof(signed short); case CTYPE_uint: return sizeof(unsigned int); case CTYPE_int: return sizeof(signed int); case CTYPE_ulong: return sizeof(unsigned long); case CTYPE_long: return sizeof(signed long); case CTYPE_float: return sizeof(float); case CTYPE_double: return sizeof(double); case CTYPE_ldouble: return sizeof(long double); default: SNetUtilDebugFatal("Unknown type in C4SNet language interface!"); } return 0; }
void SNetDistribZMQSend(zframe_t *payload, int type, int destination) { int rc; zframe_t *source_f = NULL; zframe_t *type_f = NULL; zmsg_t *msg = zmsg_new(); zmsg_push(msg, payload); SNetDistribPack(&type_f, &type, sizeof(int)); zmsg_push(msg, type_f); SNetDistribPack(&source_f, &node_location, sizeof(int)); zmsg_push(msg, source_f); rc = HTabSend(msg, destination); if (rc != 0) { SNetUtilDebugFatal("ZMQDistrib: Cannot send message to %d (%s): zmsg_send (%d)", destination, SNetDistribZMQHTabLookUp(destination)->host, rc); } }
void SNetRecDestroy( snet_record_t *rec) { int name; snet_ref_t *field; switch (REC_DESCR( rec)) { case REC_data: RECORD_FOR_EACH_FIELD(rec, name, field) { SNetRefDestroy(field); } SNetRefMapDestroy( DATA_REC( rec, fields)); SNetIntMapDestroy( DATA_REC( rec, tags)); SNetIntMapDestroy( DATA_REC( rec, btags)); if (DATA_REC( rec, parent_rids) != NULL) SNetRecIdListDestroy( DATA_REC( rec, parent_rids)); SNetMemFree( RECORD( rec, data_rec)); break; case REC_sync: { snet_variant_t *var = SYNC_REC( rec, outtype); if (var != NULL) { SNetVariantDestroy(var); } SNetMemFree( RECORD( rec, sync_rec)); } break; case REC_collect: SNetMemFree( RECORD( rec, coll_rec)); break; case REC_sort_end: SNetMemFree( RECORD( rec, sort_end_rec)); break; case REC_terminate: SNetMemFree( RECORD( rec, terminate_rec)); break; case REC_trigger_initialiser: break; default: SNetUtilDebugFatal("Unknown record description, in SNetRecDestroy"); break; }
snet_record_t *SNetRecCopy( snet_record_t *rec) { snet_record_t *new_rec; switch (REC_DESCR( rec)) { case REC_data: new_rec = SNetMemAlloc( sizeof( snet_record_t)); REC_DESCR( new_rec) = REC_data; RECPTR( new_rec) = SNetMemAlloc( sizeof( snet_record_types_t)); RECORD( new_rec, data_rec) = SNetMemAlloc( sizeof( data_rec_t)); DATA_REC( new_rec, fields) = SNetRefMapCopy(DATA_REC(rec, fields)); DATA_REC( new_rec, tags) = SNetIntMapCopy( DATA_REC( rec, tags)); DATA_REC( new_rec, btags) = SNetIntMapCopy( DATA_REC( rec, btags)); SNetRecSetInterfaceId( new_rec, SNetRecGetInterfaceId( rec)); SNetRecSetDataMode( new_rec, SNetRecGetDataMode( rec)); DATA_REC( new_rec, parent_rids) = NULL; /* (DATA_REC( rec, parent_rids)==NULL) ? NULL : SNetRecIdListCopy(DATA_REC( rec, parent_rids)); */ break; case REC_sort_end: new_rec = SNetRecCreate( REC_DESCR( rec), SORT_E_REC( rec, level), SORT_E_REC( rec, num)); break; case REC_terminate: new_rec = SNetRecCreate( REC_terminate); TERM_REC(new_rec, local) = TERM_REC(rec, local); break; default: new_rec = NULL; SNetUtilDebugFatal("Can't copy record of type %d", REC_DESCR( rec)); break; } return new_rec; }
int SNetThreadingInit(int argc, char **argv) { /* init map from file */ SNetLocvecMapInit(argc, argv); #ifdef USE_LOGGING char *mon_elts = NULL; #endif lpel_config_t config; int i; memset(&config, 0, sizeof(lpel_config_t)); config.type = DECEN_LPEL; config.flags = LPEL_FLAG_PINNED; // pinned by default /* task migration configure */ lpel_tm_config_t tm_conf; memset(&tm_conf, 0, sizeof(lpel_tm_config_t)); int tm_mech = 0; double tm_threshold = 0.0; for (i=0; i<argc; i++) { if(strcmp(argv[i], "-m") == 0 && i + 1 <= argc) { /* Monitoring level */ i = i + 1; #ifdef USE_LOGGING mon_elts = argv[i]; #endif } else if(strcmp(argv[i], "-excl") == 0 ) { /* Assign realtime priority to workers*/ config.flags |= LPEL_FLAG_EXCLUSIVE; } else if(strcmp(argv[i], "-dloc") == 0 ) { /* Use distributed s-net location placement */ dloc_placement = true; } else if(strcmp(argv[i], "-co") == 0 && i + 1 <= argc) { /* Number of cores for others */ i = i + 1; proc_others = atoi(argv[i]); } else if(strcmp(argv[i], "-cw") == 0 && i + 1 <= argc) { /* Number of cores for others */ i = i + 1; proc_workers = atoi(argv[i]); } else if(strcmp(argv[i], "-w") == 0 && i + 1 <= argc) { /* Number of workers */ i = i + 1; num_workers = atoi(argv[i]); } else if(strcmp(argv[i], "-sosi") == 0) { sosi_placement = true; } else if (strcmp(argv[i], "-np") == 0) { // no pinned config.flags ^= LPEL_FLAG_PINNED; } else if (strcmp(argv[i], "-tm") == 0) { i = i + 1; tm_mech = atoi(argv[i]); } else if (strcmp(argv[i], "-threshold") == 0) { i = i +1; tm_threshold = atof(argv[i]); } } /* set up task migration configuration */ switch (tm_mech) { case 1: tm_conf.mechanism = LPEL_MIG_RAND; if (tm_threshold <= 0) tm_threshold = 0.5; tm_conf.threshold = tm_threshold; break; case 2: tm_conf.mechanism = LPEL_MIG_WAIT_PROP; break; default: tm_conf.mechanism = LPEL_MIG_NONE; break; } #ifdef USE_LOGGING char fname[20+1]; if (mon_elts != NULL) { if (strchr(mon_elts, MON_ALL_FLAG) != NULL) { mon_flags = (1<<7) - 1; } else { if (strchr(mon_elts, MON_MAP_FLAG) != NULL) mon_flags |= SNET_MON_MAP; if (strchr(mon_elts, MON_TIME_FLAG) != NULL) mon_flags |= SNET_MON_TIME; if (strchr(mon_elts, MON_WORKER_FLAG) != NULL) mon_flags |= SNET_MON_WORKER; if (strchr(mon_elts, MON_TASK_FLAG) != NULL) mon_flags |= SNET_MON_TASK; if (strchr(mon_elts, MON_STREAM_FLAG) != NULL) mon_flags |= SNET_MON_STREAM; if (strchr(mon_elts, MON_MESSAGE_FLAG) != NULL) mon_flags |= SNET_MON_MESSAGE; if (strchr(mon_elts, MON_LOAD_FLAG) != NULL) mon_flags |= SNET_MON_LOAD; } /* set monitoring framework for task migration */ if (tm_conf.mechanism == LPEL_MIG_WAIT_PROP) mon_flags |= SNET_MON_WAIT_PROP; if ( mon_flags & SNET_MON_MAP) { snprintf(fname, 20, "n%02d_tasks.map", SNetDistribGetNodeId() ); /* create a map file */ mapfile = fopen(fname, "w"); assert( mapfile != NULL); (void) fprintf(mapfile, "%s%c", LOG_FORMAT_VERSION, END_LOG_ENTRY); } } #endif /* determine number of cpus */ if ( 0 != LpelGetNumCores( &num_cpus) ) { SNetUtilDebugFatal("Could not determine number of cores!\n"); assert(0); } if (num_workers == -1) config.num_workers = num_cpus; else config.num_workers = num_workers; if (proc_workers == -1) config.proc_workers = num_cpus; else config.proc_workers = proc_workers; config.proc_others = proc_others; #ifdef USE_LOGGING /* initialise monitoring module */ config.mon.num_workers = config.num_workers; SNetThreadingMonInit(&config.mon, SNetDistribGetNodeId(), mon_flags); #endif /* assin non-sosi task to non-sosi workers */ SNetAssignInit(config.num_workers); LpelInit(&config); /* init task migration */ tm_conf.num_workers = config.num_workers; LpelTaskMigrationInit(&tm_conf); /* start Lpel */ if (LpelStart(&config)) SNetUtilDebugFatal("Could not initialize LPEL!"); return 0; }
int SNetThreadingInit(int argc, char **argv) { lpel_config_t config; char fname[20+1]; int num_others = 0; char *mon_elts = NULL; LpelInit(&config); config.flags = LPEL_FLAG_PINNED; config.threshold = 0; for (int i = 0; i < argc; i++) { if(strcmp(argv[i], "-m") == 0 && i + 1 <= argc) { /* Monitoring level */ i = i + 1; mon_elts = argv[i]; } else if(strcmp(argv[i], "-excl") == 0 ) { /* Assign realtime priority to workers*/ config.flags |= LPEL_FLAG_EXCLUSIVE; } else if(strcmp(argv[i], "-dloc") == 0 ) { /* Use distributed s-net location placement */ dloc_placement = true; } else if(strcmp(argv[i], "-wo") == 0 && i + 1 <= argc) { /* Number of cores for others */ i = i + 1; num_others = atoi(argv[i]); } else if(strcmp(argv[i], "-w") == 0 && i + 1 <= argc) { /* Number of workers */ i = i + 1; num_workers = atoi(argv[i]); } else if(strcmp(argv[i], "-threshold") == 0 && i + 1 <= argc) { /* Threshold for placement scheduler */ i = i + 1; config.threshold = atof(argv[i]); } else if(strcmp(argv[i], "-sockets") == 0 && i + 1 <= argc) { i = i + 1; config.sockets = atoi(argv[i]); } else if(strcmp(argv[i], "-cores") == 0 && i + 1 <= argc) { i = i + 1; config.cores = atoi(argv[i]); } else if(strcmp(argv[i], "-threads") == 0 && i + 1 <= argc) { i = i + 1; config.threads = atoi(argv[i]); } else if(strcmp(argv[i], "-gather") == 0) { config.gather = 1; } } #ifdef USE_LOGGING if (mon_elts != NULL) { if (strchr(mon_elts, MON_ALL_FLAG) != NULL) { mon_flags = (1<<7) - 1; } else { if (strchr(mon_elts, MON_MAP_FLAG) != NULL) mon_flags |= SNET_MON_MAP; if (strchr(mon_elts, MON_TIME_FLAG) != NULL) mon_flags |= SNET_MON_TIME; if (strchr(mon_elts, MON_WORKER_FLAG) != NULL) mon_flags |= SNET_MON_WORKER; if (strchr(mon_elts, MON_TASK_FLAG) != NULL) mon_flags |= SNET_MON_TASK; if (strchr(mon_elts, MON_STREAM_FLAG) != NULL) mon_flags |= SNET_MON_STREAM; if (strchr(mon_elts, MON_MESSAGE_FLAG) != NULL) mon_flags |= SNET_MON_MESSAGE; if (strchr(mon_elts, MON_LOAD_FLAG) != NULL) mon_flags |= SNET_MON_LOAD; } if ( mon_flags & SNET_MON_MAP) { snprintf(fname, 20, "n%02d_tasks.map", SNetDistribGetNodeId() ); /* create a map file */ mapfile = fopen(fname, "w"); assert( mapfile != NULL); (void) fprintf(mapfile, "%s%c", LOG_FORMAT_VERSION, END_LOG_ENTRY); } } #endif config.proc_others = num_others; if (num_workers) { config.proc_workers = num_workers; config.num_workers = config.proc_others + config.proc_workers; } else { config.proc_workers = config.num_workers - config.proc_others; num_workers = config.proc_workers; } #ifdef USE_LOGGING /* initialise monitoring module */ SNetThreadingMonInit(&config.mon, SNetDistribGetNodeId(), mon_flags); #endif SNetAssignInit(config.num_workers); if (LpelStart(&config)) SNetUtilDebugFatal("Could not initialize LPEL!"); return 0; }
/** * Process commandline options. */ static int SNetInParseOptions(int argc, char **argv, FILE **input_ptr, FILE **output_ptr) { FILE *input = stdin; FILE *output = stdout; int i = 0; char *brk; char addr[256]; int len; int port; /* Parse argv: */ for(i = 1; i < argc; i++) { if(strcmp(argv[i], "-h") == 0) { /* Help */ SNetRuntimeHelpText(); if(input != stdin && input != NULL) { SNetInClose(input); } if(output != stdout && output != NULL) { SNetInClose(output); } return false; } else if (strcmp(argv[i], "-V") == 0) { SNetRuntimeVersion(); if (input != stdin && input != NULL) { SNetInClose(input); } if (output != stdout && output != NULL) { SNetInClose(output); } return false; } else if(strcmp(argv[i], "-i") == 0 && input == stdin && i + 1 <= argc) { /* Input from file */ i = i + 1; input = SNetInOpenFile(argv[i], "r"); } else if(strcmp(argv[i], "-I") == 0 && input == stdin && i + 1 <= argc) { /* Input from socket */ i = i + 1; input = SNetInOpenInputSocket(atoi(argv[i])); } else if(strcmp(argv[i], "-o") == 0 && output == stdout && i + 1 <= argc) { /* Output to file */ i = i + 1; output = SNetInOpenFile(argv[i], "w"); } else if(strcmp(argv[i], "-O") == 0 && output == stdout && i + 1 <= argc) { /* Output to socket */ i = i + 1; brk = strchr(argv[i], ':'); if(brk == NULL) { output = NULL; SNetUtilDebugFatal("Could not parse URL!\n"); } len = brk - argv[i]; strncpy((char *)addr, (const char *)argv[i], len); addr[len] = '\0'; port = atoi(brk + 1); output = SNetInOpenOutputSocket(addr, port); } } *input_ptr = input; *output_ptr = output; if(input == NULL) { if(output != stdout && output != NULL) { SNetInClose(output); } SNetUtilDebugFatal("Could not open input"); } if(output == NULL) { if(input != stdin && input != NULL) { SNetInClose(input); } SNetUtilDebugFatal("Could not open output"); } return true; }
/** * Star component task */ static void StarBoxTask(void *arg) { star_arg_t *sarg = arg; snet_record_t *rec; /* read from input stream */ rec = SNetStreamRead( sarg->instream); switch( SNetRecGetDescriptor( rec)) { case REC_data: if( MatchesExitPattern( rec, sarg->exit_patterns, sarg->guards)) { assert(!sarg->sync_cleanup); #ifdef DEBUG_PRINT_GC SNetUtilDebugNoticeEnt( ent, "[STAR] Notice: Data leaves replication network."); #endif /* send rec to collector */ SNetStreamWrite( sarg->outstream, rec); } else { /* if instance has not been created yet, create it */ if( sarg->nextstream == NULL) { CreateOperandNetwork(&sarg->nextstream, sarg, sarg->outstream); } /* send the record to the instance */ SNetStreamWrite( sarg->nextstream, rec); } /* end if not matches exit pattern */ /* deterministic non-incarnate has to append control records */ if (sarg->is_det && !sarg->is_incarnate) { /* send new sort record to collector level=0, counter=0*/ SNetStreamWrite( sarg->outstream, SNetRecCreate( REC_sort_end, 0, sarg->counter) ); /* if has next instance, send new sort record */ if (sarg->nextstream != NULL) { SNetStreamWrite( sarg->nextstream, SNetRecCreate( REC_sort_end, 0, sarg->counter) ); } /* increment counter */ sarg->counter++; } #ifdef ENABLE_GC else if (sarg->sync_cleanup) { snet_record_t *term_rec; /* * If sync_cleanup is set, we decided to postpone termination * due to garbage collection triggered by a sync record until now. * Postponing was done in order not to create the operand network unnecessarily * only to be able to forward the sync record. */ assert( sarg->nextstream != NULL); /* first send a sync record to the next instance */ SNetStreamWrite( sarg->nextstream, SNetRecCreate( REC_sync, SNetStreamGet(sarg->instream)) ); /* send a terminate record to collector, it will close and destroy the stream */ term_rec = SNetRecCreate(REC_terminate); SNetRecSetFlag(term_rec); SNetStreamWrite( sarg->outstream, term_rec); #ifdef DEBUG_PRINT_GC /* terminating due to GC */ SNetUtilDebugNoticeEnt( ent, "[STAR] Notice: Destroying star dispatcher due to GC, " "delayed until new data record!" ); #endif SNetStreamClose(sarg->nextstream, false); SNetStreamClose(sarg->instream, false); TerminateStarBoxTask(sarg->outstream,sarg); return; } #endif /* ENABLE_GC */ break; case REC_sync: { snet_stream_t *newstream = SNetRecGetStream( rec); #ifdef ENABLE_GC snet_locvec_t *loc = SNetStreamGetSource( newstream); #ifdef DEBUG_PRINT_GC if (loc != NULL) { int size = SNetLocvecPrintSize(loc) + 1; char srecloc[size]; srecloc[size - 1] = '\0'; SNetLocvecPrint(srecloc, loc); SNetUtilDebugNoticeTask( "[STAR] Notice: Received sync record with a stream with source %s.", srecloc ); } #endif /* TODO * It is not necessary to carry the whole location vector in the * next stream of a star-entity, only a flag. As a prerequisite, * non_incarnates must not clean themselves up! */ /* * Only incarnates are eligible for cleanup! * check if the source (location) of the stream and the own location are * (subsequent) star dispatcher entities of the same star combinator network * -> if so, we can clean-up ourselves */ if ( sarg->is_incarnate && loc != NULL ) { assert( true == SNetLocvecEqualParent(loc, SNetLocvecGet(sarg->info)) ); /* If the next instance is already created, we can forward the sync-record * immediately and terminate. * Otherwise we postpone termination to the point when a next data record * is received, as we create the operand network then. */ if (sarg->nextstream != NULL) { snet_record_t *term_rec; /* forward the sync record */ SNetStreamWrite( sarg->nextstream, rec); /* send a terminate record to collector, it will close and destroy the stream */ term_rec = SNetRecCreate(REC_terminate); SNetRecSetFlag(term_rec); SNetStreamWrite( sarg->outstream, term_rec); #ifdef DEBUG_PRINT_GC /* terminating due to GC */ SNetUtilDebugNoticeEnt( ent, "[STAR] Notice: Destroying star dispatcher due to GC, " "immediately on sync!" ); #endif SNetStreamClose(sarg->nextstream, false); SNetStreamClose(sarg->instream, true); TerminateStarBoxTask(sarg->outstream,sarg); return; } else { sarg->sync_cleanup = true; #ifdef DEBUG_PRINT_GC SNetUtilDebugNoticeEnt( ent, "[STAR] Notice: Remembering delayed destruction."); #endif /* handle sync record as usual */ SNetStreamReplace( sarg->instream, newstream); SNetRecDestroy( rec); } } else #endif /* ENABLE_GC */ { /* handle sync record as usual */ SNetStreamReplace( sarg->instream, newstream); SNetRecDestroy( rec); } } break; case REC_sort_end: { int rec_lvl = SNetRecGetLevel(rec); /* send a copy to the box, if exists */ if( sarg->nextstream != NULL) { SNetStreamWrite( sarg->nextstream, SNetRecCreate( REC_sort_end, (!sarg->is_incarnate)? rec_lvl+1 : rec_lvl, SNetRecGetNum(rec) ) ); } /* send the original one to the collector */ if (!sarg->is_incarnate) { /* if non-incarnate, we have to increase level */ SNetRecSetLevel( rec, rec_lvl+1); } SNetStreamWrite( sarg->outstream, rec); } break; case REC_terminate: if( sarg->nextstream != NULL) { SNetStreamWrite( sarg->nextstream, SNetRecCopy( rec)); SNetStreamClose( sarg->nextstream, false); } SNetStreamWrite( sarg->outstream, rec); /* note that no sort record has to be appended */ SNetStreamClose(sarg->instream, true); TerminateStarBoxTask(sarg->outstream,sarg); return; case REC_collect: default: SNetUtilDebugFatal("Unknown record type!"); /* if ignore, at least destroy ... */ SNetRecDestroy( rec); } SNetThreadingRespawn(NULL); }
/** * Main starting entry point of the SNet program */ int SNetInRun(int argc, char **argv, char *static_labels[], int number_of_labels, char *static_interfaces[], int number_of_interfaces, snet_startup_fun_t fun) { FILE *input = stdin; FILE *output = stdout; snet_stream_t *input_stream = NULL; snet_stream_t *output_stream = NULL; int i = 0; snet_info_t *info = NULL; snet_locvec_t *locvec; snetin_label_t *labels = NULL; snetin_interface_t *interfaces = NULL; char *brk; char addr[256]; int len; int port; /* Parse argv: */ for(i = 1; i < argc; i++) { if(strcmp(argv[i], "-h") == 0) { /* Help */ SNetRuntimeHelpText(); if(input != stdin && input != NULL) { SNetInClose(input); } if(output != stdout && output != NULL) { SNetInClose(output); } return 0; } else if(strcmp(argv[i], "-i") == 0 && input == stdin && i + 1 <= argc) { /* Input from file */ i = i + 1; input = SNetInOpenFile(argv[i], "r"); } else if(strcmp(argv[i], "-I") == 0 && input == stdin && i + 1 <= argc) { /* Input from socket */ i = i + 1; input = SNetInOpenInputSocket(atoi(argv[i])); } else if(strcmp(argv[i], "-o") == 0 && output == stdout && i + 1 <= argc) { /* Output to file */ i = i + 1; output = SNetInOpenFile(argv[i], "w"); } else if(strcmp(argv[i], "-O") == 0 && output == stdout && i + 1 <= argc) { /* Output to socket */ i = i + 1; brk = strchr(argv[i], ':'); if(brk == NULL) { output = NULL; SNetUtilDebugFatal("Could not parse URL!\n"); } len = brk - argv[i]; strncpy((char *)addr, (const char *)argv[i], len); addr[len] = '\0'; port = atoi(brk + 1); output = SNetInOpenOutputSocket(addr, port); } } if(input == NULL) { if(output != stdout && output != NULL) { SNetInClose(output); } SNetUtilDebugFatal(""); } if(output == NULL) { if(input != stdin && input != NULL) { SNetInClose(input); } SNetUtilDebugFatal(""); } /* Actual SNet network interface main: */ /* check for number of interfaces */ if (0 == number_of_interfaces) { SNetUtilDebugNotice("No language interfaces were specified by the source program!"); exit(1); } labels = SNetInLabelInit(static_labels, number_of_labels); interfaces = SNetInInterfaceInit(static_interfaces, number_of_interfaces); info = SNetInfoInit(); SNetDistribInit(argc, argv, info); (void) SNetThreadingInit(argc, argv); //SNetObserverInit(labels, interfaces); locvec = SNetLocvecCreate(); SNetLocvecSet(info, locvec); SNetDistribStart(); if (SNetDistribIsRootNode()) { input_stream = SNetStreamCreate(0); output_stream = fun(input_stream, info, 0); output_stream = SNetRouteUpdate(info, output_stream, 0); /* create output thread */ SNetInOutputInit(output, labels, interfaces, output_stream); /* create input thread */ SNetInInputInit(input, labels, interfaces, input_stream); SNetRuntimeStartWait(input_stream, info, output_stream); /* tell the threading layer that it is ok to shutdown, and wait until it has stopped such that it can be cleaned up */ (void) SNetThreadingStop(); } (void) SNetThreadingCleanup(); SNetInfoDestroy(info); SNetLocvecDestroy(locvec); /* destroy observers */ //SNetObserverDestroy(); SNetInLabelDestroy(labels); SNetInInterfaceDestroy(interfaces); if(input != stdin) { SNetInClose(input); } if(output != stdout) { SNetInClose(output); } return 0; }
/* This function prints records to stdout */ static void printRec(snet_record_t *rec, handle_t *hnd) { snet_ref_t *field; int name, val; char *label = NULL; char *interface = NULL; snet_record_mode_t mode; /* Change this to redirect the output! */ if (rec != NULL) { fprintf(hnd->file, "<?xml version=\"1.0\" ?>\n"); switch( SNetRecGetDescriptor( rec)) { case REC_data: mode = SNetRecGetDataMode(rec); if (mode == MODE_textual) { fprintf(hnd->file, "<record xmlns=\"snet-home.org\" type=\"data\" mode=\"textual\" >\n"); } else { fprintf(hnd->file, "<record xmlns=\"snet-home.org\" type=\"data\" mode=\"binary\" >\n"); } /* Fields */ RECORD_FOR_EACH_FIELD(rec, name, field) { int id = SNetRecGetInterfaceId(rec); if((label = SNetInIdToLabel(hnd->labels, name)) != NULL){ if((interface = SNetInIdToInterface(hnd->interfaces, id)) != NULL) { fprintf(hnd->file, "<field label=\"%s\" interface=\"%s\">", label, interface); if(mode == MODE_textual) { SNetInterfaceGet(id)->serialisefun(hnd->file, SNetRefGetData(field)); } else { SNetInterfaceGet(id)->encodefun(hnd->file, SNetRefGetData(field)); } fprintf(hnd->file, "</field>\n"); SNetMemFree(interface); } SNetMemFree(label); } else{ SNetUtilDebugFatal("Unknown field %d at output!", name); } } /* Tags */ RECORD_FOR_EACH_TAG(rec, name, val) { if ((label = SNetInIdToLabel(hnd->labels, name)) != NULL) { fprintf(hnd->file, "<tag label=\"%s\">%d</tag>\n", label, val); } else{ SNetUtilDebugFatal("Unknown tag %d at output!", name); } SNetMemFree(label); } /* BTags */ RECORD_FOR_EACH_BTAG(rec, name, val) { if ((label = SNetInIdToLabel(hnd->labels, name)) != NULL){ fprintf(hnd->file, "<btag label=\"%s\">%d</btag>\n", label, val); } else{ SNetUtilDebugFatal("Unknown binding tag %d at output!", name); } SNetMemFree(label); } fprintf(hnd->file, "</record>\n"); break; case REC_sync: SNetUtilDebugFatal("REC_sync in output! This should not happen."); break; case REC_collect: SNetUtilDebugFatal("REC_collect in output! This should not happen."); break; case REC_sort_end: SNetUtilDebugFatal("REC_sort_end in output! This should not happen."); break; case REC_trigger_initialiser: SNetUtilDebugFatal("REC_trigger_initializer in output! This should not happen."); break; case REC_terminate: fprintf(hnd->file, "<record type=\"terminate\" />"); break; default: break; }