2.4.6.2. - The Data-Pipe Facility
spec's
From spec, access to the data-pipe facility is through the
Prior to spec release 4.03.13, only one
The user C code can be complied and linked using the command
After linking
The subroutines available from the user C code portion of the data-pipe program are described below.
The skeleton user C-code part of the data-pipe program should contain the following:
The subroutine
The
Besides the
If
The following subroutines allow you to send group/array data back to spec when
There are two ways to send group/array data back to spec. The subroutine
You can set the value that the
data_pipe()
function allows integration of external code
with spec.
With the data-pipe facility, spec sends
information to the external program,
allows the external program to execute for a time, and
then receives information back from the external program.
The information can be in the form of a string or a number, and can
also include
the contents of
a spec data group or data array.
The handshaking and data transfer between spec and the data-pipe program
is done in an
overhead module included in the spec distribution that is linked
with the external code.
From spec, access to the data-pipe facility is through the
data_pipe()
function called from the user level.
Usage
is as follows.
data_pipe(program [, args [, grp_out|arr_out [, grp_in|arr_in ]]])
-
Initiates or resumes synchronous execution of the special process named
program
. Ifprogram
contains a/
character, then it contains the complete absolute or relative path name of the program to run. Otherwise the program must be in theSPECD
/data_pipe directory, whereSPECD
is the built-in spec variable containing the path name of spec's auxiliary file directory. You can use the string"."
forprogram
as an abbreviation for the same program name as used in the last call todata_pipe()
.
The string value ofargs
is made available to the user code in the program as described in the next section.
The optional argumentsgrp_out
andgrp_in
are data group numbers. Ifgrp_out
is present, the contents of that group are sent to the data-pipe program. Ifgrp_in
is present, it is the number of the data group that will receive values from the data-pipe program. The data-pipe program configures the size ofgrp_in
for an implicit call todata_grp()
withindata_pipe()
. If thegrp_in
argument is absent, spec will not receive data-group data from the data-pipe program. Ifgrp_out
is also absent, group data won't be sent to the data-pipe program. Even without group arguments, the data-pipe program can still return values to spec in the form of assigning a number or string return value todata_pipe()
.
Either or both of the data group arguments can be replaced with the array argumentsarr_out
andarr_in
. The arrays referred to by these arguments must be the data arrays declared explicitly with thearray
keyword. When sending array data to the data-pipe program, the array data is first converted to double precision floating point format. The received data is always double, but is converted to fit the declared data type ofarr_in
. Only as much data as will fit into the array will be assigned. The number of columns inarr_in
should match the width of the data sent over by the data-pipe program. If not, the data will still be assigned to the array, but will be misaligned.
Prior to spec release 4.03.13, only one
data_pipe()
function could be active at a time.
The user C code can be complied and linked using the command
dpmake program [UOBJ=...] [LIBS=...] [optional_make_args]The command
dpmake
is a short shell script which invokes the
make
utility using the makefile
data_pipe.mak
in the
SPECD
/data_pipe
directory.
The file
program
.c
will be compiled and linked with the data-pipe
overhead module, and the result
placed in an executable file named
program
.
If additional object modules or libraries need to be linked, they can
be specified with the
UOBJ=
or
LIBS=
parameters.
If the tools provided are not sufficient, you can create custom
makefiles based on the distributed
data_pipe.mak.
After linking
program
,
move it to the
SPECD
/data_pipe
directory for easy access by all users.
The subroutines available from the user C code portion of the data-pipe program are described below.
The skeleton user C-code part of the data-pipe program should contain the following:
#include <user_pipe.h> user_code(argc, argv) char **argv; { ... }The include file user_pipe.h contains declarations of the subroutines available in the C code. The file resides in the
SPECD
/data_pipe
directory.
The subroutine
user_code()
is called
by the overhead part of the data-pipe program each time
data_pipe()
is invoked in spec.
The parameter
argc
is set to the number of space-delimited words present in the
string value of the
args
parameter to
data_pipe()
. The parameter
argv
is an array of character pointers
that point to each of the
argc
space-delimited words in the
args
string.
Alternatively, the
get_input_string()
function (see below) returns the
args
string in its entirety.
The
user_code()
routine will be called every time the
data_pipe()
function is called from spec.
The data-pipe program does not exit between calls of
user_code()
, so you should be careful about
allocating memory or opening files
each time
user_code()
is called without
freeing the memory or closing the files each time
user_code()
returns.
Alternatively, you can make sure such things are only done
the first time
user_code()
is called.
Besides the
argc
, argv
technique for accessing the
args
typed in the
data_pipe()
call, the following function is available:
char * get_input_string()
-
Returns a pointer to memory holding a copy of the second argument
args
entered with the call todata_pipe()
.
If
data_pipe()
is sending a data group or array
to the user code, the following subroutines
provide access to the data parameters and values.
int get_group_number()
-
Returns the group number specified as the
data_pipe()
grp_out
argument. A -2 is returned if an array was specified. A -1 is returned if neither data group or array was specified. int get_group_npts()
-
Returns the number of points in the
data_pipe()
grp_out
or the number of rows inarr_out
. int get_group_width()
-
Returns the number of elements per point in the
data_pipe()
grp_out
or the number of columns inarr_out
. int get_input_data(double *x, int pts, int wid)
-
Transfers data from the
grp_out
orarr_out
specified in the call todata_pipe()
to the memory area indicated by the pointerx
. The pointerx
is treated as an array dimensioned as x[
pts][
wid]
. If the data group/array has more points/rows thanpts
or more elements/columns thanwid
, only as many points/rows or elements/columns as are available in the data group/array are copied. Data from only a single element/column may be retrieved using one or more calls ofget_input_elem()
below. If the data in the data group from spec is float rather than double (which depends on spec's installation configuration), float-to-double conversion is done within the call toget_input_data()
. The return value is the number of points/rows copied. int get_input_elem(double *x, int pts, int el)
-
Transfers one element of the data from the
grp_out
orarr_out
specified in the call todata_pipe()
to the memory area indicated by the pointerx
. No more thanpts
points are copied from element/columnel
of the the data group/array. If the data in the data group from spec is float rather than double (which depends on spec's installation configuration), float-to-double conversion is done within the call toget_input_data()
. The return value is the number of points/rows copied.
The following subroutines allow you to send group/array data back to spec when
data_pipe()
is invoked with a
grp_in
or
arr_in
argument.
For a data group, the call to
data_pipe()
will implicitly call
data_grp()
to configure the size of the
return group according to the parameters set in the following subroutines.
For an array, the array must already be declared and dimensioned.
There are two ways to send group/array data back to spec. The subroutine
set_return_data()
allows you to send the entire data group in one call that passes both
a pointer to the data and the data group size to the data-pipe program
overhead code.
Alternatively, you can use the
set_return_group()
subroutine to configure the data group/array size, followed by one or more
calls to
set_return_elem()
to set one element/column of the data group/array at a time.
int get_return_group_number()
-
Returns the group number specified as the
data_pipe()
grp_in
argument. A -2 is returned if an array was specified. A -1 is returned if neither data group or array was specified. void set_return_data(double *x, int pts, int wid, int last)
-
Configures the return data group and copies the data at the same time.
The pointer
x
is considered as an array of dimension x[
pts][
wid]
for the purpose of transferring data to the data group. The argumentlast
sets the index number of the last element added to the group, which is used by the various data analysis and plotting functions available in spec. void set_return_group(int pts, int wid)
-
Configures the size of the return data group without copying
data.
This subroutine must be called once before calling
set_return_elem()
below. void set_return_elem(double *x, int pts, int el, int last)
-
Copies one element to the return data group, which must have been
previously configured by a call of
set_return_group()
, above. If the parameterspts
orel
exceed the values configured, or if the return group hasn't been configured, the subroutine returns -1. Otherwise zero is returned.
You can set the value that the
data_pipe()
function returns in spec
from the user C code in your
data-pipe
process.
You can have
data_pipe()
return a number or a string or, if necessary, reset to command level.
If no explicit return value is assigned in the user C code,
data_pipe()
returns zero.
int set_return_string(char *s)
-
Sets the return value of
data_pipe()
to the strings
. This subroutine returns -1 if memory could not be obtained for the strings
, otherwise it returns zero. void set_return_value(double v)
-
Sets the return value of
data_pipe()
to the valuev
. void do_error_return()
-
Calling this subroutine from the user C code causes control to pass
back to spec without returning data group or array values,
if they have been
set.
The return value of
data_pipe()
will be the value set byset_return_value()
above, if such a value has been set, otherwise the return value ofdata_pipe()
will be -1. This subroutine does not return. void do_abort_return()
-
Calling this subroutine from the user C code causes control to pass
back to spec without returning data group or array values, if they has been
set.
In spec, there is no return from
data_pipe()
, rather spec resets to command level. This subroutine does not return. void do_quit_return()
-
Calling this subroutine from the user C code causes control to pass
back to spec normally as if
user_code()
returned normally, but the data-pipe program will then exit. This subroutine does not return.