Commit 899615a0 authored by Philip Carns's avatar Philip Carns

initial commit of code copied from CODES repo

parents
#
# Output dist version
#
.phony: distversion
distversion:
@echo $(VERSION)
#
# Easy way to build unit tests without running them
#
.phony: tests
tests: $(check_PROGRAMS)
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS =
bin_SCRIPTS =
noinst_LIBRARIES =
noinst_PROGRAMS =
lib_LIBRARIES =
noinst_HEADERS =
TESTS =
check_PROGRAMS =
EXTRA_PROGRAMS =
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST =
BUILT_SOURCES =
EXTRA_DIST += prepare.sh
AM_CPPFLAGS = -I$(top_srcdir)/src ${CODES_BASE_CFLAGS}
AM_CFLAGS = ${CODES_BASE_CFLAGS}
AM_LIBS = ${CODES_BASE_LIBS}
AM_CXXFLAGS = $(AM_CFLAGS)
include Make.rules
include $(top_srcdir)/src/models/Makefile.subdir
0 - Checkout, build, and install codes-base
git clone git@git.mcs.anl.gov:radix/codes-base
<see codes-base/README.txt>
1 - If this is the first time you are building codes-net, run
./prepare.sh
2- Configure codes-net. This can be done in the source directory or in a
dedicated build directory if you prefer out-of-tree builds. The CC
environment variable must refer to an MPI compiler.
./configure --with-codes-base=/path/to/codes-base/install --prefix=/path/to/codes-net/install CC=mpicc
3 - Build codes-net
make clean && make
/*
* Copyright (C) 2013, University of Chicago
*
* See COPYRIGHT notice in top-level directory.
*/
#ifndef MODELNET_H
#define MODELNET_H
#include "ross.h"
#include "lp-type-lookup.h"
typedef struct simplenet_param simplenet_param;
typedef struct dragonfly_param dragonfly_param;
typedef struct torus_param torus_param;
enum NETWORKS
{
SIMPLENET,
DRAGONFLY,
TORUS
};
/* structs for initializing a network/ specifying network parameters */
struct simplenet_param
{
double net_startup_ns; /*simplenet startup cost*/
double net_bw_mbps; /*Link bandwidth per byte*/
int num_nics;
};
struct dragonfly_param
{
char* name;
int num_routers; /*Number of routers in a group*/
int num_nodes; /*Number of compute nodes connected to a router*/
int num_chans; /*Number of global channels connected to each router*/
};
struct torus_param
{
char* name;
int n_dim; /*Dimension of the torus network, 5-D, 7-D or any other*/
int* dim_length; /*Length of each torus dimension*/
};
/* NOTE: the following auxilliary functions are probably wrong; just leaving
* these examples from simplenet for reference purposes.
*
* In general we need to figure out how to pass configuration information to
* the methods and we need to be able to calculate ross event message size.
*/
#if 0
/* returns a pointer to the lptype struct to use for simplenet LPs */
const tw_lptype* sn_get_lp_type(void);
/* set model parameters:
*
* - net_startup_ns: network startup cost in ns.
* - net_bs_mbs: network bandwidth in MiB/s (megabytes per second).
*/
void sn_set_params(double net_startup_ns, double net_bw_mbs);
/* retrieve the size of the portion of the event struct that is consumed by
* the simplenet module. The caller should add this value to the size of
* its own event structure to get the maximum total size of a message.
*/
int sn_get_msg_sz(void);
/* retrieve the minimum timestamp offset that simplenet will use */
tw_stime sn_get_min_ts(void);
#endif
/*Initialize the network by specifying the network parameters. The
* underlying model-net.c function call will set the network parameters
* according to the network name specified*/
// return an integer being the identifier for the type of network
// call modelnet setup 1 time for a torus and retur value is 0 for e.g.
// call modelnet setup second time for a simplenet
int model_net_setup(char* net_name, int packet_size, const void* net_params);
/* allocate and transmit a new event that will pass through model_net to
* arrive at its destination:
*
* - category: category name to associate with this communication
* - OPTIONAL: callers can set this to NULL if they don't want to use it,
* and model_net methods can ignore it if they don't support it
* - final_dest_lp: the LP that the message should be delivered to.
* - NOTE: this is _not_ the LP of an underlying network method (for
* example, it is not a torus or dragonfly LP), but rather the LP of an
* MPI process or storage server that you are transmitting to.
* - message_size: this is the size of the message (in bytes) that modelnet
* will simulate transmitting to the final_dest_lp. It can be any size
* (i.e. it is not constrained by transport packet size).
* - remote_event_size: this is the size of the ROSS event structure that
* will be delivered to the final_dest_lp.
* - remote_event: pointer ot data to be used as the remove event message
* - self_event_size: this is the size of the ROSS event structure that will
* be delivered to the calling LP once local completion has occurred for
* the network transmission.
* - NOTE: "local completion" in this sense means that model_net has
* transmitted the data off of the local node, but it does not mean that
* the data has been (or even will be) delivered. Once this event is
* delivered the caller is free to re-use its buffer.
* - self_event: pionter to data to be used as the self event message
* - sender: pointer to the tw_lp structure of the API caller. This is
* identical to the sender argument to tw_event_new().
*/
// first argument becomes the network ID
void model_net_event(
int net_id,
char* category,
tw_lpid final_dest_lp,
int message_size,
int remote_event_size,
const void* remote_event,
int self_event_size,
const void* self_event,
tw_lp *sender);
/* model_net_event_rc()
*
* This function does reverse computation for the model_net_event_new()
* function.
* - sender: pointer to the tw_lp structure of the API caller. This is
* identical to the sender argument to tw_event_new().
*/
/* NOTE: we may end up needing additoinal arguments here to track state for
* reverse computation; add as needed
*/
void model_net_event_rc(
int net_id,
tw_lp *sender,
int message_size);
const int model_net_get_msg_sz(int net_id);
/* returns pointer to LP information for simplenet module */
const tw_lptype* model_net_get_lp_type(int net_id);
const int model_net_get_packet_size(int net_id);
void model_net_add_lp_type(int net_id);
#endif /* MODELNET_H */
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.67])
AC_INIT([codes-net], [0.2], [http://trac.mcs.anl.gov/projects/codes/newticket],[],[http://trac.mcs.anl.gov/projects/codes/wiki])
AC_CANONICAL_TARGET
AC_CANONICAL_SYSTEM
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_CONFIG_SRCDIR([README.txt])
AC_CONFIG_HEADERS([codes_net_config.h])
# Checks for programs.
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AC_PROG_CXXCPP
AC_PROG_RANLIB
AC_REQUIRE_CPP
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h unistd.h execinfo.h pthread.h malloc.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
# Checks for library functions.
AC_CHECK_FUNCS([memset])
AC_CHECK_LIB([pthread],[pthread_create],,[AC_MSG_ERROR([Could not find pthread_create!])])
AC_CHECK_LIB([m],[sqrt],,[AC_MSG_ERROR([Could not find sqrt!])])
USE_CODES_BASE=UNKNOWN
AC_ARG_WITH(codes-base,
[ --with-codes-base=<dir> Location of codes-base installation],
[
AC_CHECK_FILE(${withval}/lib/pkgconfig/codes-base.pc)
USE_CODES_BASE=${withval}
],
[
AC_MSG_ERROR([Requires --with-codes-base])
])
CODES_BASE_LIBS=`PKG_CONFIG_PATH=${withval}/lib/pkgconfig pkg-config codes-base --libs`
CODES_BASE_CFLAGS=`PKG_CONFIG_PATH=${withval}/lib/pkgconfig pkg-config codes-base --cflags`
AC_SUBST(CODES_BASE_LIBS)
AC_SUBST(CODES_BASE_CFLAGS)
# put include files in a codes/ subdir
includedir="${includedir}/codes"
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
#!/bin/sh
echo "Regenerating build files..."
autoreconf -fi
lib_LIBRARIES += src/libcodes-net.a
nobase_include_HEADERS = \
codes/model-net.h
src_libcodes_net_a_SOURCES = \
src/models/networks/model-net/model-net-method.h \
src/models/networks/model-net/model-net.c \
src/models/networks/model-net/simplenet-upd.c
Design notes for model_net network abstraction.
Overview:
model_net is an abstraction layer that will allow models to send messages
across components using different network transports. This is a
consistent API that can send messages across either torus, dragonfly, or
simplenet network models without changing the higher level model code.
model_net assumes that the caller already knows what LP it wants to
deliver the message to and how large the simulated message is.
Implementation note:
The network abstraction works at the ROSS event level by managing three
event structures internally:
a) the internal event used by the network method for routing etc.
b) the remote event to be delivered to a higher level model LP
c) the local event to be delivered the caller once a message has been
transmitted from the node
The model_net caller gets to specify b) and c). a) is defined by the
underlying network method being used to transmit the message.
Components:
model-net.h: API that higher level models (such as an MPI application
model, a triton storage model, or a BG/P storage model) will use to send
*messages* over the network to other model entities
model-net.c: implements the model-net.h API. It also packetizes messages
for underlying network methods that operate in terms of packets. This code
is responsible for calling the correct underlying network model depending
on configuration values.
model-net-method.h: this is the API that underlying network methods will
implement in order to interface with the model-net framework.
Simplenet
---------
Model overview:
---------------
Simplenet is a module that implements a network module for use as a
component within model net.
The simplenet model is a basic cost model based on the startup cost
(latency) of the network and the bandwidth (cost per byte transferred)
of the network. Each NIC is assumed to have full-duplex transmit and
receive capability. Messages begin transmission when the sender's output
queue is available. From the sender's perspective, the transmission is
complete as soon as enough virtual time has elapsed to account for the
startup and bandwidth costs of the message. However, the message is
not delivered for processing on the receiver until the receiver's input
queue is also available. The network fabric itself is not modeled and is
instead treated as if it has infinite buffering ability and no internal
routing overhead.
Simplenet supports optimistic mode and reverse computation.
Modularization concepts:
------------------------
The simplenet LPs are intended to be used in conjunction with other LPs that
implement a higher level protocol. For examples, they may be used in
conjunction with LPs that model file servers in a parallel file system.
Each simplenet LP represents a NIC. In terms of LP mapping, each simplenet
LP should also use an LP ID that is a fixed offset from the "node" that it
belongs to. Note that the offset is specified to the simplenet module at
event creation time, which means that multiple "node" LPs can share the same
simplenet LP by using different offsets.
In terms of event transmission, simplenet can be thought of as a wrapper
around other events. It tunnels the upper level events through the network
and delivers them to a remote LP, consuming some amount of virtual time
along the way according to the modeled network characteristics. The upper
level model does not have access to the simplenet LPs, the simplenet message
struct, or any other internal parameters. It is intended to abstract away
network details from some higher level model.
- The test.conf file has the mapping of model-net and server LPs (currently 16 server LPs and 16 modelnet LPs)
- To run the program :
./modelnettest --sync=1 test.conf
mpirun -np 4 ./modelnettest --sync=2 test.conf (The synchronization protocol is specified before the file name)
/*
* Copyright (C) 2013, University of Chicago
*
* See COPYRIGHT notice in top-level directory.
*/
#include <string.h>
#include <assert.h>
#include "model-net.h"
#include "model-net-method.h"
#define STR_SIZE 16
#define PROC_TIME 10.0
#define NUM_NETS 1
extern struct model_net_method simplenet_method;
//extern struct dragonfly_method dragonfly_method;
//extern struct torus_method torus_method;
/* Global array initialization, terminated with a NULL entry */
static struct model_net_method* method_array[] =
{&simplenet_method, NULL};
int model_net_setup(char* name,
int packet_size,
const void* net_params)
{
int i;
/* find struct for underlying method (according to configuration file) */
for(i=0; method_array[i] != NULL; i++)
{
if(strcmp(method_array[i]->method_name, name) == 0)
{
method_array[i]->mn_setup(net_params);
method_array[i]->packet_size = packet_size;
return(i);
}
}
fprintf(stderr, "Error: undefined network name %s (Available options dragonfly, torus, simplenet) \n", name);
return -1; // indicating error
}
void model_net_event(
int net_id,
char* category,
tw_lpid final_dest_lp,
int message_size,
int remote_event_size,
const void* remote_event,
int self_event_size,
const void* self_event,
tw_lp *sender)
{
/* determine packet size for underlying method */
int packet_size = model_net_get_packet_size(net_id);
int num_packets = message_size/packet_size; /* Number of packets to be issued by the API */
int i;
int last = 0;
if(message_size % packet_size)
num_packets++; /* Handle the left out data if message size is not exactly divisible by packet size */
/*Determine the network name*/
if(net_id < 0 || net_id > NUM_NETS)
{
fprintf(stderr, "Error: undefined network ID %d (Available options 0 (simplenet), 1 (dragonfly) 2 (torus) ) \n", net_id);
exit(-1);
}
/* issue N packets using method API */
/* somehow mark the final packet as the one responsible for delivering
* the self event and remote event
*
* local event is delivered to caller of this function, remote event is
* passed along through network hops and delivered to final_dest_lp
*/
for( i = 0; i < num_packets; i++ )
{
/*Mark the last packet to the net method API*/
if(i == num_packets - 1)
{
last = 1;
/* also calculate the last packet's size */
packet_size = message_size - ((num_packets-1)*packet_size);
}
/* Number of packets and packet ID is passed to the underlying network to mark the final packet for local event completion*/
method_array[net_id]->model_net_method_packet_event(category, final_dest_lp, packet_size, remote_event_size, remote_event, self_event_size, self_event, sender, last);
}
return;
}
void model_net_event_rc(
int net_id,
tw_lp *sender,
int message_size)
{
/* this will be used for reverse computation of anything calculated
* within th model_net_event() function call itself (not reverse
* handling for the underlying methods, which will have their own events
* and reverse handlers
*/
int packet_size = model_net_get_packet_size(net_id);
int num_packets = message_size/packet_size; /* For rolling back */
int i;
if(message_size % packet_size)
num_packets++;
for( i = 0; i < num_packets; i++ )
{
/* Number of packets and packet ID is passed to the underlying network to mark the final packet for local event completion*/
method_array[net_id]->model_net_method_packet_event_rc(sender);
}
return;
}
/* returns the message size, can be either simplenet, dragonfly or torus message size*/
const int model_net_get_msg_sz(int net_id)
{
// TODO: Add checks on network name
// TODO: Add dragonfly and torus network models
if(net_id < 0 || net_id > NUM_NETS)
{
printf("%s Error: Uninitializied modelnet network, call modelnet_init first\n", __FUNCTION__);
exit(-1);
}
return method_array[net_id]->mn_get_msg_sz();
}
/* returns the packet size in the modelnet struct */
const int model_net_get_packet_size(int net_id)
{
if(net_id < 0 || net_id > NUM_NETS)
{
fprintf(stderr, "%s Error: Uninitializied modelnet network, call modelnet_init first\n", __FUNCTION__);
exit(-1);
}
return method_array[net_id]->packet_size; // TODO: where to set the packet size?
}
/* returns lp type for modelnet */
const tw_lptype* model_net_get_lp_type(int net_id)
{
if(net_id < 0 || net_id > NUM_NETS)
{
fprintf(stderr, "%s Error: Uninitializied modelnet network, call modelnet_init first\n", __FUNCTION__);
exit(-1);
}
// TODO: ADd checks by network names
// Add dragonfly and torus network models
return method_array[net_id]->mn_get_lp_type();
}
/* registers the lp type */
void model_net_add_lp_type(int net_id)
{
switch(net_id)
{
case SIMPLENET:
lp_type_register("modelnet_simplenet", model_net_get_lp_type(net_id));
break;
DEFAULT:
{
printf("\n Invalid net_id specified ");
exit(-1);
}
}
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* End:
*
* vim: ft=c ts=8 sts=4 sw=4 expandtab
*/
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment