#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <string.h>#include <stdarg.h>#include <errno.h>#include "portability.h"#include "utility.h"#include "comm_basics.h"#include "comm_encode.h"#include "comm_data.h"#include "grpc.h"#include "gs_seq_dsi.h"#include "gs_seq_data_handle.h"
Go to the source code of this file.
Functions | |
| static int | gs_send_data_transfer_request (char *data_handle, gs_argument_t *argptr, int my_dsig) |
| int | gs_send_tag (SOCKET sock, int tag) |
| int | gs_recv_tag (SOCKET sock, int *tag) |
| int | gs_send_int (SOCKET sock, int tosend) |
| int | gs_recv_int (SOCKET sock, int *torecv) |
| int | gs_send_string (SOCKET sock, char *tosend) |
| int | gs_recv_string (SOCKET sock, char **torecv) |
| int | gs_get_element_size (enum datatype data_type, int dsig) |
| int | gs_recv_arg_into_file (SOCKET sock, char *fname) |
| int | gs_recv_file_scalar (SOCKET sock, gs_argument_t *arg, gs_side_t side) |
| int | gs_recv_file_vector (SOCKET sock, gs_argument_t *arg, gs_side_t side) |
| int | gs_recv_arg (SOCKET sock, gs_argument_t *arg, int sender_major, int sender_dsig, int my_dsig, gs_side_t side) |
| int | gs_send_arg_from_file (SOCKET sock, char *filename) |
| int | gs_send_dsi_input_arg (SOCKET sock, gs_argument_t *arg, int my_dsig) |
| int | gs_send_dsi_output_arg (SOCKET sock, gs_argument_t *arg, int my_dsig) |
| int | gs_recv_dsi_input_arg (SOCKET sock, gs_argument_t *arg, int data_size) |
| int | gs_recv_dsi_output_arg (SOCKET sock, gs_argument_t *arg, int data_size) |
| int | gs_send_arg (SOCKET sock, gs_argument_t *arg, int my_dsig) |
| int | gs_convert_arg (gs_argument_t *arg, char *data, int sender_dsig, int my_dsig) |
| int | gs_set_dsi_flags (gs_problem_t *prob, char *callsig) |
| int | gs_set_pass_back_flags (gs_problem_t *prob, char *callsig) |
| int | gs_set_call_signature (gs_problem_t *prob_desc) |
| int | gs_send_input_scalar_args (gs_va_list *args, void **argstack, SOCKET sock, gs_problem_t *problem, int my_dsig, int lang, int major) |
| int | gs_send_input_nonscalar_args (SOCKET sock, gs_problem_t *problem, int my_dsig) |
| int | gs_send_input_args (gs_va_list *args, void **argstack, SOCKET sock, gs_problem_t *problem, int my_dsig, int lang, int major) |
| int | gs_wait_for_output (SOCKET sock) |
| int | gs_recv_output_args (SOCKET sock, gs_problem_t *problem, int sender_dsig, int my_dsig) |
| int | gs_send_output_args (SOCKET sock, gs_problem_t *problem, int my_dsig) |
| int | gs_recv_input_scalar_args (SOCKET sock, gs_problem_t *problem, int sender_dsig, int my_dsig, int *sender_major_p) |
| int | gs_recv_input_args (SOCKET sock, gs_problem_t *problem, int sender_dsig, int my_dsig) |
| int | gs_dump_args (FILE *out, gs_problem_t *problem) |
| int | gs_construct_scalar_hashtable (icl_hash_t **new_hash, gs_problem_t *prob_desc, enum inout cond) |
| int | gs_receiver_compute_arg_sizes (gs_problem_t *prob_desc, enum inout cond) |
| int | gs_sender_compute_arg_sizes (gs_va_list *ap, void **argstack, gs_problem_t *prob_desc, int language, int major) |
| int | gs_transpose_matrix (gs_argument_t *arg, char *data, gs_side_t side) |
| int | gs_save_input_args_to_file (char *name, gs_problem_t *problem, int my_dsig, int lang, int major) |
| int | gs_restore_input_args_from_file (char *name, gs_problem_t *problem, int sender_dsig, int my_dsig) |
| int | gs_save_output_args_to_file (int fd, gs_problem_t *problem, int my_dsig) |
| int | gs_restore_output_args_from_file (int fd, gs_problem_t *problem, int my_dsig) |
| int | gs_setup_workspace (gs_problem_t *prob_desc, icl_hash_t *symtab) |
Variables | |
| static char * | client_callsig = NULL |
| static char * | server_callsig = NULL |
This file contains functions to transfer arguments between different components.
Definition in file comm_data.c.
| int gs_construct_scalar_hashtable | ( | icl_hash_t ** | new_hash, | |
| gs_problem_t * | prob_desc, | |||
| enum inout | cond | |||
| ) |
Creates and fills in a hash table with the scalars from the given problem struct.
| new_hash | -- the new hash table to be created (set upon return) | |
| prob_desc | -- the problem descriptor for the remote procedure being called. | |
| cond | -- should be GS_IN when called before the service is called and GS_OUT when called after the service is called |
Definition at line 2002 of file comm_data.c.
{
gs_argument_t *argptr;
icl_hash_t *symtab;
if(!prob_desc)
return -1;
symtab = icl_hash_create(11, NULL);
if(!symtab)
return -1;
for(argptr = prob_desc->arglist; argptr != NULL; argptr=argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == cond) ||
(argptr->inout == GS_INOUT)) && (argptr->objecttype == GS_SCALAR))
{
if(!argptr->data) {
icl_hash_destroy(symtab, NULL, NULL);
return -1;
}
switch(argptr->datatype) {
case GS_INT:
argptr->expr_val = (double) *((int *)(argptr->data));
break;
case GS_CHAR:
argptr->expr_val = (double) *((char *)(argptr->data));
break;
case GS_FLOAT:
argptr->expr_val = (double) *((float *)(argptr->data));
break;
case GS_DOUBLE:
argptr->expr_val = (double) *((double *)(argptr->data));
break;
case GS_SCOMPLEX:
argptr->expr_val = (double) ((gs_scomplex *)(argptr->data))->r;
break;
case GS_DCOMPLEX:
argptr->expr_val = (double) ((gs_dcomplex *)(argptr->data))->r;
break;
default:
ERRPRINTF("Bad data type\n");
icl_hash_destroy(symtab, NULL, NULL);
return -1;
}
}
else
argptr->expr_val = 0.0;
icl_hash_insert(symtab, argptr->name, &(argptr->expr_val));
}
*new_hash = symtab;
return 0;
}


| int gs_convert_arg | ( | gs_argument_t * | arg, | |
| char * | data, | |||
| int | sender_dsig, | |||
| int | my_dsig | |||
| ) |
Convert an argument from the sender's representation to this machine's representation.
| arg | -- pointer to the argument struct to be converted. | |
| data | -- pointer to the actual data to be converted. | |
| sender_dsig | -- the sender's data signature. | |
| my_dsig | -- this machine's data signature. |
Definition at line 1036 of file comm_data.c.
{
int i;
if(!arg || !arg->data)
return -1;
switch(arg->datatype) {
case GS_INT:
if(DSIG_INT_SIZE(sender_dsig) == DSIG_INT_SIZE(my_dsig)) {
for(i=0; i< arg->rows * arg->cols; i++)
gs_int_swap_func[DSIG_INT_ORDER(sender_dsig)][DSIG_INT_ORDER(my_dsig)](
((int *)data)+i);
}
else {
ERRPRINTF("Error: different int sizes not supported yet\n");
return -1;
}
break;
case GS_FLOAT:
if(DSIG_FLOAT_SIZE(sender_dsig) == DSIG_FLOAT_SIZE(my_dsig)) {
for(i=0; i< arg->rows * arg->cols; i++)
gs_float_swap_func[DSIG_FLOAT_ORDER(sender_dsig)][DSIG_FLOAT_ORDER(my_dsig)](((float *)data)+i);
}
else {
ERRPRINTF("Error: different float sizes not supported yet\n");
return -1;
}
break;
case GS_DOUBLE:
if(DSIG_DOUBLE_SIZE(sender_dsig) == DSIG_DOUBLE_SIZE(my_dsig)) {
for(i=0; i< arg->rows * arg->cols; i++)
gs_double_swap_func[DSIG_DOUBLE_ORDER(sender_dsig)][DSIG_DOUBLE_ORDER(my_dsig)](((double *)data)+i);
}
else {
ERRPRINTF("Error: different double sizes not supported yet\n");
return -1;
}
break;
case GS_SCOMPLEX:
if(DSIG_FLOAT_SIZE(sender_dsig) == DSIG_FLOAT_SIZE(my_dsig)) {
gs_scomplex *iptr;
for(i=0; i< arg->rows * arg->cols; i++) {
iptr = ((gs_scomplex *)data) + i;
gs_float_swap_func[DSIG_FLOAT_ORDER(sender_dsig)][DSIG_FLOAT_ORDER(my_dsig)](&(iptr->r));
gs_float_swap_func[DSIG_FLOAT_ORDER(sender_dsig)][DSIG_FLOAT_ORDER(my_dsig)](&(iptr->i));
}
}
else {
ERRPRINTF("Error: different scomplex sizes not supported yet\n");
return -1;
}
break;
case GS_DCOMPLEX:
if(DSIG_DOUBLE_SIZE(sender_dsig) == DSIG_DOUBLE_SIZE(my_dsig)) {
gs_dcomplex *iptr;
for(i=0; i< arg->rows * arg->cols; i++) {
iptr = ((gs_dcomplex *)data) + i;
gs_double_swap_func[DSIG_DOUBLE_ORDER(sender_dsig)][DSIG_DOUBLE_ORDER(my_dsig)](&(iptr->r));
gs_double_swap_func[DSIG_DOUBLE_ORDER(sender_dsig)][DSIG_DOUBLE_ORDER(my_dsig)](&(iptr->i));
}
}
else {
ERRPRINTF("Error: different dcomplex sizes not supported yet\n");
return -1;
}
break;
case GS_CHAR:
/* no conversion necessary for char */
break;
case GS_BAD_DTYPE:
ERRPRINTF("Error: argument has invalid data type.\n");
return -1;
break;
}
return 0;
}

| int gs_dump_args | ( | FILE * | out, | |
| gs_problem_t * | problem | |||
| ) |
Print information about the specified problem descriptor. Used for debugging.
| out | -- the file to which the information should be printed. | |
| problem | -- the problem descriptor to be dumped. |
Definition at line 1933 of file comm_data.c.
{
gs_argument_t *args;
int i=0;
if(!out || !problem)
return -1;
fprintf(out, "Arguments:\n");
for(args = problem->arglist; args != NULL; args = args->next)
{
fprintf(out, "arg %d: name='%s', rowexp='%s', ",
i, args->name, args->rowexp);
fprintf(out, "colexp='%s', rows=%d, cols=%d, major=%c\n",
args->colexp, args->rows, args->cols, args->prob->major);
if(!args->data) continue;
switch(args->datatype) {
case GS_INT:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%d\n", ((int*)args->data)[i]);
break;
case GS_FLOAT:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%f\n", ((float*)args->data)[i]);
break;
case GS_DOUBLE:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%g\n", ((double*)args->data)[i]);
break;
case GS_SCOMPLEX:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%g + %gi\n", ((gs_scomplex*)args->data)[i].r,
((gs_scomplex*)args->data)[i].i);
break;
case GS_DCOMPLEX:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%g + %gi\n", ((gs_dcomplex*)args->data)[i].r,
((gs_dcomplex*)args->data)[i].i);
break;
case GS_CHAR:
for(i=0;i<args->rows*args->cols;i++)
fprintf(out,"%c\n", ((char*)args->data)[i]);
break;
case GS_BAD_DTYPE:
fprintf(out,"[INVALID DATA TYPE]\n");
break;
}
}
return 0;
}

| int gs_get_element_size | ( | enum datatype | data_type, | |
| int | dsig | |||
| ) |
Get the size of an element of the specified type for this architecture.
| data_type | -- the data type of the element | |
| dsig | -- the data signature of this architecture |
Definition at line 394 of file comm_data.c.
{
switch(data_type) {
case GS_INT:
return DSIG_INT_SIZE(dsig);
case GS_FLOAT:
return DSIG_FLOAT_SIZE(dsig);
case GS_DOUBLE:
return DSIG_DOUBLE_SIZE(dsig);
case GS_SCOMPLEX:
return 2 * DSIG_FLOAT_SIZE(dsig);
case GS_DCOMPLEX:
return 2 * DSIG_DOUBLE_SIZE(dsig);
case GS_CHAR:
return sizeof(char);
default:
ERRPRINTF("gs_get_element_size: bad data type\n");
return 1;
}
}

| int gs_receiver_compute_arg_sizes | ( | gs_problem_t * | prob_desc, | |
| enum inout | cond | |||
| ) |
Computes the sizes of the non-scalar arguments that we will be receiving. Before calling this function, we should have received the scalar arguments already.
| prob_desc | -- the problem descriptor for the remote procedure being called. | |
| cond | -- should be GS_IN when called before the service is called and GS_OUT when called after the service is called |
Definition at line 2076 of file comm_data.c.
{
icl_hash_t *symtab;
if(!prob_desc)
return -1;
if(gs_construct_scalar_hashtable(&symtab, prob_desc, cond) < 0) {
ERRPRINTF("error setting up hash table.\n");
return -1;
}
if(gs_setup_workspace(prob_desc, symtab) < 0) {
ERRPRINTF("error setting up workspace for matrix transpose.\n");
return -1;
}
icl_hash_destroy(symtab, NULL, NULL);
return 0;
}


| int gs_recv_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | sender_major, | |||
| int | sender_dsig, | |||
| int | my_dsig, | |||
| gs_side_t | side | |||
| ) |
Receive an argument on the socket.
| sock | -- the socket from which the argument will be received | |
| arg | -- pointer to the argument struct containing information like object type and data type. This function allocates space for the argument data. | |
| sender_major | -- specifies how the sender stores matrices. 'r' represents row-major and 'c' represents column-major. | |
| sender_dsig | -- the sender's data signature. | |
| my_dsig | -- this machine's data signature. | |
| side | -- which side of the transaction we are (GS_CLIENT_SIDE if we are the client, GS_SERVER_SIDE if we are the server) |
Definition at line 598 of file comm_data.c.
{
int sender_elsize, data_size;
char *data;
if(!arg || !arg->prob)
return -1;
if(arg->objecttype == GS_FILE)
return gs_recv_file_scalar(sock, arg, side);
else if(arg->objecttype == GS_PACKEDFILE)
return gs_recv_file_vector(sock, arg, side);
/* size expressions must have been evaluated first before calling this! */
sender_elsize = gs_get_element_size(arg->datatype, sender_dsig);
data_size = arg->rows * arg->cols * sender_elsize;
data = arg->data;
DBGPRINTF("receiving arg %s, type=%s, rows=%d, cols=%d, bytes=%d\n",
arg->name, gs_c_datatype[arg->datatype], arg->rows, arg->cols, data_size);
if(arg->dsi) {
if(side == GS_SERVER_SIDE) {
if(gs_recv_dsi_input_arg(sock, arg, data_size) < 0) {
ERRPRINTF("Error receiving DSI input arg\n");
return -1;
}
data = arg->data;
}
else {
if(gs_recv_dsi_output_arg(sock, arg, data_size) < 0) {
ERRPRINTF("Error receiving DSI output arg\n");
return -1;
}
/* currently output from DSI is not supported, so don't
* fall through to the transpose & byte swapping stuff below.
*/
return 0;
}
}
else {
/* if this is a variable-length output arg, the user has passed in
* a double pointer. first receive the length, malloc space for the
* argument, and set the data pointer to the dereferenced data
* pointer (which is a pointer to the actual data).
*/
if(arg->inout == GS_VAROUT) {
char **dptr;
int srv_data_size;
if(!arg->data) {
arg->data = (char **) malloc(sizeof(char *));
if(!arg->data) {
ERRPRINTF("malloc\n");
return -1;
}
}
dptr = arg->data;
if(gs_recv_int(sock, &srv_data_size) < 0) {
ERRPRINTF("Error reading arg size\n");
return -1;
}
data_size = srv_data_size;
*dptr = (char *)malloc(data_size);
data = *dptr;
if(!data) {
ERRPRINTF("error allocating space for arg\n");
return -1;
}
}
if(!arg->data) {
arg->data = (char *)malloc(data_size);
if(!arg->data) {
ERRPRINTF("error allocating space for argument ");
ERRPRINTF("%s (rows %s (%d) cols %s (%d))(%d bytes)\n",
arg->name, arg->rowexp, arg->rows, arg->colexp, arg->cols, data_size);
return -1;
}
data = arg->data;
}
if(gs_tread(sock, data, data_size) == -1) {
ERRPRINTF("error in receiving argument ");
ERRPRINTF("%s (rows %s (%d) cols %s (%d))(%d bytes)\n",
arg->name, arg->rowexp, arg->rows, arg->colexp, arg->cols, data_size);
return -1;
}
}
if((arg->objecttype == GS_MATRIX) && (sender_major != arg->prob->major))
gs_transpose_matrix(arg, data, side);
if(sender_dsig != my_dsig)
if(gs_convert_arg(arg, data, sender_dsig, my_dsig) < 0)
return -1;
return 0;
}


| int gs_recv_arg_into_file | ( | SOCKET | sock, | |
| char * | fname | |||
| ) |
Receive the argument on the socket and write it to a file.
| sock | -- the socket on which the argument will be received. | |
| fname | -- the name of the file to write the argument data to. |
Definition at line 425 of file comm_data.c.
{
char fxbuf[FILE_XFER_BUFSZ];
int n, nleft, len, fd;
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if(fd < 0) {
ERRPRINTF("File '%s' could not be opened\n", fname);
return -1;
}
/* should probably change this at some point to recv_long to
* support large file sizes.
*/
if(gs_recv_int(sock, &len) < 0) {
ERRPRINTF("error in receiving file len\n");
close(fd);
return -1;
}
nleft = len;
while(nleft > 0) {
n = gs_tread(sock, fxbuf, MIN(FILE_XFER_BUFSZ, nleft));
if(n < 0) {
if(errno_socket() == EINTR)
continue;
else {
ERRPRINTF("error in reading argument data from sock\n");
close(fd);
return -1;
}
} else if (n == 0)
break;
if(write(fd, fxbuf, n) != n) {
ERRPRINTF("error in writing argument data to file\n");
close(fd);
return -1;
}
nleft -= n;
}
close(fd);
if(nleft == 0)
return 0;
else
return -1;
}


| int gs_recv_dsi_input_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | data_size | |||
| ) |
Receive a DSI argument from the socket.
| sock | -- the socket on which the argument will be received. | |
| arg | -- pointer to the argument struct to be received. |
Definition at line 864 of file comm_data.c.
{
DSI_OBJECT *obj;
int bytes_read;
char *encoding;
void *data = NULL;
data = (void *)malloc(data_size);
if(!data) {
ERRPRINTF("failed to allocate data\n");
return -1;
}
obj = (DSI_OBJECT *)calloc(1, sizeof(DSI_OBJECT));
if(!obj) {
ERRPRINTF("malloc failed\n");
return -1;
}
if(gs_recv_string(sock, &encoding) < 0) {
ERRPRINTF("error in receiving DSI object encoding\n");
return -1;
}
if(gs_decode_dsi_object(encoding, obj) < 0) {
ERRPRINTF("error decoding DSI object\n");
free(encoding);
free(data);
free(obj);
return -1;
}
arg->dsi_obj = obj;
if(grpc_dsi_read_vector(obj, data, arg->rows * arg->cols,
arg->datatype, &bytes_read) != GRPC_NO_ERROR)
{
ERRPRINTF("error reading DSI object\n");
free(encoding);
free(data);
free(obj);
return -1;
}
if(!data) {
ERRPRINTF("Empty data after reading DSI object\n");
free(encoding);
free(data);
free(obj);
return -1;
}
arg->data = (char *)data;
free(encoding);
return 0;
}


| int gs_recv_dsi_output_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | data_size | |||
| ) |
Receive a DSI output argument from the socket.
| sock | -- the socket on which the argument will be received. | |
| arg | -- pointer to the argument struct to be received. |
Definition at line 935 of file comm_data.c.
{
char *encoding;
if(gs_recv_string(sock, &encoding) < 0) {
ERRPRINTF("error in receiving DSI object encoding\n");
return -1;
}
/* currently the returned DSI object is ignored since we
* expect it to be the same, but later if we want to
* support having the server create the DSI object and
* return it to the client, we can add code here.
*/
free(encoding);
return 0;
}


| int gs_recv_file_scalar | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| gs_side_t | side | |||
| ) |
Receive one file argument.
| sock | -- the socket from which the argument will be received | |
| arg | -- pointer to the argument struct containing information like object type and data type. | |
| side | -- which side of the transaction we are (GS_CLIENT_SIDE if we are the client, GS_SERVER_SIDE if we are the server) |
Definition at line 490 of file comm_data.c.
{
if(side == GS_SERVER_SIDE) {
if(gs_recv_arg_into_file(sock, arg->name) < 0) {
ERRPRINTF("error receiving arg data into file\n");
return -1;
}
arg->data = strdup(arg->name);
if(!arg->data) {
ERRPRINTF("error allocating string for arg.\n");
return -1;
}
}
else if(side == GS_CLIENT_SIDE) {
if(gs_recv_arg_into_file(sock, arg->data) < 0) {
ERRPRINTF("error receiving arg data into file\n");
return -1;
}
}
else {
ERRPRINTF("Bad 'side' argument.\n");
return -1;
}
return 0;
}


| int gs_recv_file_vector | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| gs_side_t | side | |||
| ) |
Receive an array of files.
| sock | -- the socket from which the argument will be received | |
| arg | -- pointer to the argument struct containing information like object type and data type. | |
| side | -- which side of the transaction we are (GS_CLIENT_SIDE if we are the client, GS_SERVER_SIDE if we are the server) |
Definition at line 532 of file comm_data.c.
{
char **data;
int i;
if(!arg) return -1;
if(side == GS_SERVER_SIDE) {
arg->data = malloc(arg->rows * sizeof(char *));
if(!arg->data) {
ERRPRINTF("error allocating memory for filenames.\n");
return -1;
}
data = (char **)arg->data;
for(i = 0; i < arg->rows; i++) {
data[i] = dstring_sprintf("%s_%d", arg->name, i);
if(!data[i]) {
ERRPRINTF("error allocating string for arg.\n");
return -1;
}
if(gs_recv_arg_into_file(sock, data[i]) < 0) {
ERRPRINTF("error receiving arg data into file\n");
return -1;
}
}
}
else if(side == GS_CLIENT_SIDE) {
data = (char **)arg->data;
for(i = 0; i < arg->rows; i++) {
if(gs_recv_arg_into_file(sock, data[i]) < 0) {
ERRPRINTF("error receiving arg data into file\n");
return -1;
}
}
}
else {
ERRPRINTF("Bad 'side' argument.\n");
return -1;
}
return 0;
}


| int gs_recv_input_args | ( | SOCKET | sock, | |
| gs_problem_t * | problem, | |||
| int | sender_dsig, | |||
| int | my_dsig | |||
| ) |
Receives all of the input arguments.
| sock | -- the socket from which the arguments will be received. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| sender_dsig | -- the sender's data signature. | |
| my_dsig | -- this machine's data signature. |
Definition at line 1799 of file comm_data.c.
{
gs_argument_t *argptr;
int sender_major;
char *data_handle;
if(!problem)
return -1;
/* Receive scalar input args */
if (gs_recv_input_scalar_args(sock, problem, sender_dsig,
my_dsig, &sender_major) < 0)
{
ERRPRINTF("Error in receiving input scalar args\n");
return -1;
}
/* once the scalar arguments have been received, compute the sizes
* of the other args so we'll know how many bytes to receive.
*/
if(gs_receiver_compute_arg_sizes(problem, GS_IN) < 0)
{
ERRPRINTF("error computing argument sizes.\n");
return -1;
}
/* now receive all the non-scalar arguments */
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT)) &&
(argptr->objecttype != GS_SCALAR))
{
/*argptr->data = NULL;*/
/* if the data to be received is a data handle */
/* modified for GRidSolve request sequencing */
if (argptr->data_handle) {
/* receive data handle from the client - string */
if (gs_recv_string(sock, &data_handle) < 0) {
ERRPRINTF("error receiving data handle - server side\n");
return -1;
}
if (!data_handle) {
ERRPRINTF("bad data handle\n");
return -1;
}
/* requrst a data transfer from the server that stores
the actual data represented by the data handle */
if (gs_send_data_transfer_request(data_handle, argptr, my_dsig) < 0) {
return -1;
}
}
else {
if(gs_recv_arg(sock, argptr, sender_major, sender_dsig, my_dsig,
GS_SERVER_SIDE) < 0)
{
ERRPRINTF("error receiving input non-scalar arguments\n");
return -1;
}
}
}
if((argptr->objecttype == GS_FILE) && (argptr->inout == GS_OUT)) {
argptr->data = strdup(argptr->name);
/* since this is an output-only file, then set the filename to be
* the arg name here.
*/
if(!argptr->data) {
ERRPRINTF("error allocating space for output arg\n");
return -1;
}
}
else if((argptr->objecttype == GS_PACKEDFILE) && (argptr->inout == GS_OUT)) {
char **data;
int i;
argptr->data = malloc(argptr->rows * sizeof(char *));
if(!argptr->data) {
ERRPRINTF("error allocating memory for filenames.\n");
return -1;
}
data = (char **)argptr->data;
for(i = 0; i < argptr->rows; i++) {
data[i] = dstring_sprintf("%s_%d", argptr->name, i);
if(!data[i]) {
ERRPRINTF("error allocating memory for filename.\n");
return -1;
}
}
}
else if((argptr->inout == GS_OUT) || (argptr->inout == GS_WORKSPACE)) {
int elsize;
/* since this is an output-only or workspace arg, allocate memory for
* it now since nothing would have been sent from the client.
*/
elsize = gs_get_element_size(argptr->datatype, my_dsig);
argptr->data = (char *)CALLOC(argptr->rows * argptr->cols, elsize);
if(!argptr->data) {
ERRPRINTF("error allocating space for output arg\n");
return -1;
}
}
else if(argptr->inout == GS_VAROUT)
{
char **foo = (char **)malloc(sizeof(char*));
argptr->data = foo;
}
}
return 0;
}


| int gs_recv_input_scalar_args | ( | SOCKET | sock, | |
| gs_problem_t * | problem, | |||
| int | sender_dsig, | |||
| int | my_dsig, | |||
| int * | sender_major_p | |||
| ) |
Receives only the scalar input arguments. This allows the receiving side to know the sizes of the non-scalar args before attempting to receive them.
| sock | -- the socket on which the arguments will be sent. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| sender_dsig | -- the sender's data signature. | |
| my_dsig | -- this machine's data signature. | |
| sender_major_p | -- on return, contains the sender's major. this specifies how the sender (client) stores matrices. 'r' represents row-major and 'c' represents column-major. |
Definition at line 1735 of file comm_data.c.
{
gs_argument_t *argptr;
char *sender_callsig;
int sender_major;
if(!problem)
return -1;
if(gs_recv_tag(sock, &sender_major) < 0) {
ERRPRINTF("error in receiving major\n");
return -1;
}
*sender_major_p = sender_major;
if(gs_recv_string(sock, &sender_callsig) < 0) {
ERRPRINTF("error in receiving sender's call signature\n");
return -1;
}
gs_set_dsi_flags(problem, sender_callsig);
gs_set_pass_back_flags(problem, sender_callsig);
server_callsig = strdup(sender_callsig);
/* first we receive all the scalar arguments so that the we
* can compute the size expressions for the vector/matrix args.
*/
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT)) &&
(argptr->objecttype == GS_SCALAR))
{
argptr->rows = argptr->cols = 1;
argptr->data = NULL;
if(gs_recv_arg(sock, argptr, sender_major, sender_dsig, my_dsig,
GS_SERVER_SIDE) < 0)
{
ERRPRINTF("error in receiving input scalar argument\n");
return -1;
}
}
}
return 0;
}


| int gs_recv_int | ( | SOCKET | sock, | |
| int * | torecv | |||
| ) |
Receive an unsigned integer from the network. The integer is converted to host format after being received.
| sock | -- the socket on which to read the integer | |
| torecv | -- on return, contains the integer received |
Definition at line 281 of file comm_data.c.
{
uint32_t uint2;
if (gs_tread(sock, (char *)&uint2, sizeof(uint32_t)) == -1) {
ERRPRINTF("Error receiving int \n");
return(-1);
}
*torecv = (int)ntohl(uint2);
return 0;
}


| int gs_recv_output_args | ( | SOCKET | sock, | |
| gs_problem_t * | problem, | |||
| int | sender_dsig, | |||
| int | my_dsig | |||
| ) |
Receive all of the output arguments from the server.
| sock | -- the socket from which the arguments will be received. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| sender_dsig | -- the server's data signature. | |
| my_dsig | -- this machine's data signature. |
Definition at line 1517 of file comm_data.c.
{
gs_argument_t *argptr;
char *data_handle;
int sender_major;
int i;
if(!problem)
return -1;
if(gs_wait_for_output(sock) < 0) {
ERRPRINTF("error waiting for output to be ready\n");
return -1;
}
if(gs_recv_tag(sock, &sender_major) < 0) {
ERRPRINTF("error in receiving major\n");
return -1;
}
/* reconstruct the pass_back flags on the client
side for nonblocking sequencing calls */
/* modified for GridSolve request sequencing */
gs_set_pass_back_flags(problem, client_callsig);
i = 0;
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next, i++)
{
argptr->index = i;
if((argptr->inout == GS_INOUT) || (argptr->inout == GS_OUT) ||
(argptr->inout == GS_VAROUT))
{
/* if the argument won't be passed back,
expect to receive the data handle instead */
/* modified for GridSolve request sequencing */
if (!argptr->pass_back) {
/* receive data handle from the server - string */
if (gs_recv_string(sock, &data_handle) < 0) {
ERRPRINTF("error in receiving data handle - client side\n");
return -1;
}
/* save the data handle so that the depending job can get it */
if (insert_data_handle(problem->name, problem->seq_id,
argptr->index, argptr->data, data_handle) < 0) {
return -1;
}
}
else {
if(gs_recv_arg(sock, argptr, sender_major, sender_dsig, my_dsig,
GS_CLIENT_SIDE) < 0)
{
ERRPRINTF("error in receiving output arguments\n");
return -1;
}
}
}
}
return 0;
}


| int gs_recv_string | ( | SOCKET | sock, | |
| char ** | torecv | |||
| ) |
Receive a string from a socket. The string length is received first. Then space is allocated for the string and the string is received. The caller is responsible for deallocating the space.
| sock | -- the socket on which to read the string | |
| torecv | -- on return, contains the string received |
Definition at line 349 of file comm_data.c.
{
int len = -1;
if(gs_recv_int(sock, &len) < 0) {
ERRPRINTF("Error receiving string length\n");
return -1;
}
if((*torecv = (char *)CALLOC(len+1, sizeof(char))) == NULL) {
ERRPRINTF("Error allocating memory for string\n");
return -1;
}
if(gs_tread(sock, *torecv, len*sizeof(char)) < 0) {
free(*torecv);
ERRPRINTF("Error reading string\n");
return -1;
}
#ifdef GS_DEBUG
{
char *tmps = strdup(*torecv);
if (strlen(tmps) > 50) tmps[51]='\0';
DBGPRINTF("recvd string of len %d: '%s...'\n", len, tmps);
FREE(tmps);
}
#else
DBGPRINTF("recvd string of len %d\n", len); fflush(NULL);
#endif
return 0;
}


| int gs_recv_tag | ( | SOCKET | sock, | |
| int * | tag | |||
| ) |
Get a tag value from a socket. A byte is received and then converted to an int which is returned.
| sock | -- socket to read the tag from | |
| tag | -- on return, this parameter will contain the tag that was read from the socket |
Definition at line 229 of file comm_data.c.
{
char bytetag = -1;
if (gs_tread(sock, &bytetag, sizeof(bytetag)) == -1) {
ERRPRINTF("Error in reading tag \n");
return(-1);
}
*tag = bytetag;
return 0;
}


| int gs_restore_input_args_from_file | ( | char * | name, | |
| gs_problem_t * | problem, | |||
| int | sender_dsig, | |||
| int | my_dsig | |||
| ) |
Restores previously saved input arguments.
| name | -- the name of the file from which the arguments will be read. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| sender_dsig | -- the sender's data signature. | |
| my_dsig | -- this machine's data signature. |
Definition at line 2460 of file comm_data.c.
{
int fd;
char *c;
fd = open(name, O_RDONLY, 0666);
if(fd < 0) {
ERRPRINTF("File '%s' could not be opened\n", name);
return -1;
}
/* remove all DSI flags from callsig */
c = problem->callsig;
while(*c) {
if(*c == 'D')
*c = 'P';
c++;
}
if(gs_recv_input_args(fd, problem, sender_dsig, my_dsig) < 0) {
ERRPRINTF("Error reading input args from file\n");
return -1;
}
return 0;
}


| int gs_restore_output_args_from_file | ( | int | fd, | |
| gs_problem_t * | problem, | |||
| int | my_dsig | |||
| ) |
Reads all the output args from a file. This is used by the server to retrieve results that were computed and saved earlier using gs_save_output_args_to_file().
| fd | -- the file descriptor to which the arguments will be read. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. |
Definition at line 2589 of file comm_data.c.
{
gs_argument_t *argptr;
int sender_major;
if(!problem)
return -1;
if(gs_recv_tag(fd, &sender_major) < 0) {
ERRPRINTF("error in receiving major\n");
return -1;
}
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT) ||
(argptr->inout == GS_OUT)) && (argptr->objecttype == GS_SCALAR))
{
argptr->rows = argptr->cols = 1;
argptr->data = NULL;
if(gs_recv_arg(fd, argptr, sender_major, my_dsig, my_dsig,
GS_CLIENT_SIDE) < 0)
{
ERRPRINTF("error in reading input argument\n");
return -1;
}
}
}
if(gs_receiver_compute_arg_sizes(problem, GS_OUT) < 0)
{
ERRPRINTF("could not compute argument sizes.\n");
return -1;
}
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if((argptr->inout == GS_INOUT) || (argptr->inout == GS_OUT) ||
(argptr->inout == GS_VAROUT))
{
if(argptr->objecttype == GS_FILE) {
char *fname;
if(gs_recv_string(fd, &fname) < 0) {
ERRPRINTF("error in reading file name\n");
return -1;
}
argptr->data = fname;
}
else if(argptr->objecttype == GS_PACKEDFILE) {
char *fname;
int i, n;
if(gs_recv_int(fd, &n) < 0) {
ERRPRINTF("error in reading number of packed files\n");
return -1;
}
argptr->data = malloc(n * sizeof(char *));
for(i = 0; i < n; i++) {
if(gs_recv_string(fd, &fname) < 0) {
ERRPRINTF("error in reading file name\n");
return -1;
}
((char **)(argptr->data))[i] = fname;
}
}
else {
if(gs_recv_arg(fd, argptr, sender_major, my_dsig, my_dsig,
GS_CLIENT_SIDE) < 0)
{
ERRPRINTF("error in reading input argument\n");
return -1;
}
}
}
}
return 0;
}


| int gs_save_input_args_to_file | ( | char * | name, | |
| gs_problem_t * | problem, | |||
| int | my_dsig, | |||
| int | lang, | |||
| int | major | |||
| ) |
Writes all the input args to a file. This is used by the server to store the input data before submitting to some sort of queue or other back-end system.
| name | -- the file name to which the arguments will be written. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. | |
| lang | -- language being used on the client side (either GS_CALL_FROM_C or GS_CALL_FROM_FORTRAN). | |
| major | -- specifies how this client stores matrices. 'r' represents row-major and 'c' represents column-major. |
Definition at line 2402 of file comm_data.c.
{
gs_argument_t *argptr;
gs_problem_t *pcopy;
int fd;
fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if(fd < 0) {
ERRPRINTF("File '%s' could not be opened\n", name);
return -1;
}
pcopy = (gs_problem_t *) malloc(sizeof(gs_problem_t));
if(!pcopy) {
close(fd);
return -1;
}
if(gs_dup_problem(pcopy, problem) < 0) {
ERRPRINTF("Failed to duplicate problem\n");
close(fd);
free(pcopy);
return -1;
}
/* set the dsi flags to 0 here since this is the server side and
* we would have already downloaded the args from dsi.
*/
for(argptr=pcopy->arglist; argptr != NULL; argptr=argptr->next)
argptr->dsi = 0;
if(gs_send_input_args(NULL, NULL, fd, pcopy, my_dsig, lang, major) < 0) {
ERRPRINTF("Failed to save input args to file\n");
gs_free_problem(pcopy);
close(fd);
return -1;
}
gs_free_problem(pcopy);
close(fd);
return 0;
}


| int gs_save_output_args_to_file | ( | int | fd, | |
| gs_problem_t * | problem, | |||
| int | my_dsig | |||
| ) |
Writes all the output args to a file. This is used by the server to store the computed results so that a client may connect later to pick them up.
| fd | -- the file descriptor to which the arguments will be written. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. |
Definition at line 2503 of file comm_data.c.
{
gs_argument_t *argptr;
if(!problem)
return -1;
if(gs_send_tag(fd, problem->major) < 0) {
ERRPRINTF("failed to send major\n");
return -1;
}
/* first save the scalars so we'll know the sizes of the other
* args when we process the file later.
*/
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT) ||
(argptr->inout == GS_OUT)) && (argptr->objecttype == GS_SCALAR))
{
if(gs_send_arg(fd, argptr, my_dsig) < 0) {
ERRPRINTF("error in writing input argument\n");
return -1;
}
}
}
if(gs_receiver_compute_arg_sizes(problem, GS_OUT) < 0)
{
ERRPRINTF("could not compute argument sizes.\n");
return -1;
}
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if((argptr->inout == GS_INOUT) || (argptr->inout == GS_OUT) ||
(argptr->inout == GS_VAROUT))
{
if(argptr->objecttype == GS_FILE) {
if(gs_send_string(fd, argptr->data) < 0) {
ERRPRINTF("error in writing file name\n");
return -1;
}
}
else if(argptr->objecttype == GS_PACKEDFILE) {
int i;
if(gs_send_int(fd, argptr->rows) < 0) {
ERRPRINTF("Error sending string length\n");
return -1;
}
for(i = 0; i < argptr->rows; i++) {
if(gs_send_string(fd, ((char **)(argptr->data))[i]) < 0) {
ERRPRINTF("error in writing file name\n");
return -1;
}
}
}
else {
if(gs_send_arg(fd, argptr, my_dsig) < 0) {
ERRPRINTF("error in writing input argument\n");
return -1;
}
}
}
}
return 0;
}


| int gs_send_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | my_dsig | |||
| ) |
Send an argument on the socket.
| sock | -- the socket on which the argument will be sent. | |
| arg | -- pointer to the argument struct to be sent. | |
| my_dsig | -- this machine's data signature. |
Definition at line 966 of file comm_data.c.
{
int data_size;
char *data;
if(!arg || !arg->data)
return -1;
data_size = gs_get_element_size(arg->datatype, my_dsig) *
arg->rows * arg->cols;
data = arg->data;
DBGPRINTF("sending arg %s, type=%s, rows=%d, cols=%d, bytes=%d\n",
arg->name, gs_c_datatype[arg->datatype], arg->rows, arg->cols, data_size);
if(arg->objecttype == GS_FILE) {
if(gs_send_arg_from_file(sock, data) < 0) {
ERRPRINTF("error arg data from file '%s'\n", data);
return -1;
}
return 0;
}
else if(arg->objecttype == GS_PACKEDFILE) {
char **filenames;
int i;
filenames = (char **)arg->data;
for(i=0; i < arg->rows; i++)
if(gs_send_arg_from_file(sock, filenames[i]) < 0) {
ERRPRINTF("error arg data from file '%s'\n", filenames[i]);
return -1;
}
return 0;
}
if(arg->inout == GS_VAROUT) {
if(gs_send_int(sock, data_size) < 0) {
ERRPRINTF("error in sending arg len\n");
return -1;
}
if(arg->objecttype != GS_SCALAR)
data = *((char **)(arg->data));
}
if(gs_twrite(sock, data, data_size) != data_size) {
ERRPRINTF("error in sending argument data\n");
return -1;
}
return 0;
}


| int gs_send_arg_from_file | ( | SOCKET | sock, | |
| char * | filename | |||
| ) |
Send an argument on the socket.
| sock | -- the socket on which the argument will be sent. | |
| filename | -- the name of the file containing the argument data. |
Definition at line 719 of file comm_data.c.
{
struct stat st;
char fxbuf[FILE_XFER_BUFSZ];
int n, fd;
if(stat(filename, &st) == -1) {
ERRPRINTF("Could not stat file '%s'\n", filename);
return -1;
}
fd = open(filename, O_RDONLY, 0666);
if(fd < 0) {
ERRPRINTF("File '%s' could not be opened\n", filename);
return -1;
}
/* should probably change this at some point to send_long to
* support large file sizes.
*/
if(gs_send_int(sock, (int)st.st_size) < 0) {
ERRPRINTF("error in sending file len\n");
close(fd);
return -1;
}
while((n=read(fd, fxbuf, FILE_XFER_BUFSZ)) > 0) {
if(gs_twrite(sock, fxbuf, n) != n) {
ERRPRINTF("error in sending argument data\n");
close(fd);
return -1;
}
}
close(fd);
if(n < 0) {
ERRPRINTF("Error reading from file\n");
return -1;
}
return 0;
}


| static int gs_send_data_transfer_request | ( | char * | data_handle, | |
| gs_argument_t * | argptr, | |||
| int | my_dsig | |||
| ) | [static] |
Send and process a request of direct data transfer between two servers without the interference of the client used by GridSolve request sequencing
Definition at line 42 of file comm_data.c.
{
LFS_DSI_OBJECT *obj;
char *server_name, *path, *file_name, *full_name;
int server_sock, tag, port;
int len, sender_major, sender_dsig;
struct hostent *hp;
char cid[CID_LEN];
ipaddr_t ipaddr;
if (!data_handle || !argptr) {
fprintf(stderr, "bad data handle or argument pointer \
in gs_send_data_transfer_request\n");
return -1;
}
/* decode the data handle */
if ((obj = gs_seq_decode_lfs_dsi_object(data_handle)) == NULL) {
fprintf(stderr, "error decoding data handle\n");
return -1;
}
if (!DATA_RECV_FILE_PATH) {
gs_seq_set_lfs_dsi_data_storage_path();
}
/* construct the full path name */
path = DATA_RECV_FILE_PATH;
file_name = obj->file_name;
full_name = (char *) malloc(sizeof(char)
* (strlen(path) + strlen(file_name) + 1));
if (!full_name) {
perror("malloc");
return -1;
}
strcpy(full_name, path);
full_name[strlen(path)] = '\0';
strcat(full_name, file_name);
full_name[strlen(path) + strlen(file_name)] = '\0';
/* get the name of the server to send data transfer request */
server_name = obj->source;
memset(cid, 0xFF, CID_LEN);
/* default port */
port = GRIDSOLVE_SERVER_PORT_DEFAULT;
/* get server host by its name */
if ((hp = gethostbyname(server_name)) == NULL) {
errno = errno_socket();
fprintf(stderr,
"could not gethostbyname for %s (errno %d) \n", server_name, errno);
return INVALID_SOCKET;
}
memcpy((void *) &ipaddr, hp->h_addr_list[0], sizeof(ipaddr));
/* all ones will match any component ID */
memset(cid, 0xFF, CID_LEN);
/* connect to the server */
server_sock = gs_connect_to_host(cid, ipaddr, port, 0, 0);
if(server_sock < 0) {
ERRPRINTF("unsuccessful (connecting server)\n");
return -1;
}
/* send tag and GridSolve version */
if((gs_send_tag(server_sock, GS_PROT_DATA_TRANSFER) < 0) ||
(gs_send_string(server_sock, VERSION) < 0)) {
ERRPRINTF("unsuccessful (sending tag to Server)\n");
return -1;
}
/* receive the replied tag */
if(gs_recv_tag(server_sock, &tag) < 0) {
ERRPRINTF("error communicating with server.\n");
return -1;
}
if(tag != GS_PROT_OK) {
if(tag == GS_PROT_VERSION_MISMATCH)
ERRPRINTF("error: server is an incompatible version\n");
else
ERRPRINTF("error: server refused\n");
return -1;
}
/* send the data handle */
if (gs_send_string(server_sock, data_handle) < 0) {
ERRPRINTF("unsuccessful (sending data handle)\n");
return -1;
}
/*
if (gs_recv_arg_into_file(server_sock, full_name) < 0) {
ERRPRINTF("error receiving data into file\n");
return -1;
}
if (gs_seq_restore_data_from_file(full_name, argptr, my_dsig) < 0) {
ERRPRINTF("error reading data from file\n");
return -1;
}
if (remove(full_name) < 0) {
ERRPRINTF("error removing file: %s\n", full_name);
return -1;
}
*/
if (gs_recv_int(server_sock, &len) < 0) {
fprintf(stderr, "error receiving file length\n");
return -1;
}
if (gs_recv_tag(server_sock, &sender_major) < 0) {
fprintf(stderr, "error receiving sender major\n");
return -1;
}
if (gs_recv_int(server_sock, &sender_dsig) < 0) {
fprintf(stderr, "error receiving sender data signature\n");
return -1;
}
if (gs_recv_arg(server_sock, argptr, sender_major,
sender_dsig, my_dsig, GS_SERVER_SIDE) < 0) {
fprintf(stderr, "error receiving argument\n");
return -1;
}
return 0;
}


| int gs_send_dsi_input_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | my_dsig | |||
| ) |
Send a DSI argument on the socket.
| sock | -- the socket on which the argument will be sent. | |
| arg | -- pointer to the argument struct to be sent. | |
| my_dsig | -- this machine's data signature. |
Definition at line 774 of file comm_data.c.
{
int data_size;
char *data_encoding;
if(!arg || !arg->data)
return -1;
data_size = gs_get_element_size(arg->datatype, my_dsig) *
arg->rows * arg->cols;
DBGPRINTF("sending DSI arg %s, type=%s, rows=%d, cols=%d, bytes=%d\n",
arg->name, gs_c_datatype[arg->datatype], arg->rows, arg->cols, data_size);
if(gs_encode_dsi_object(&data_encoding, arg->data) < 0) {
ERRPRINTF("Failed to encode DSI object\n");
return -1;
}
if(gs_send_string(sock, data_encoding) < 0) {
ERRPRINTF("failed to send encoded DSI object\n");
free(data_encoding);
return -1;
}
free(data_encoding);
return 0;
}


| int gs_send_dsi_output_arg | ( | SOCKET | sock, | |
| gs_argument_t * | arg, | |||
| int | my_dsig | |||
| ) |
Send an argument on the socket back to the DSI location.
| sock | -- the socket on which the argument will be sent. | |
| arg | -- pointer to the argument struct to be sent. | |
| my_dsig | -- this machine's data signature. |
to be added later for supporting output DSI objects
if(grpc_dsi_store(arg->dsi_obj->dsi_file, arg->data, data_size) < 0) { ERRPRINTF("Failed to write results back to DSI object\n"); return -1; }
Definition at line 815 of file comm_data.c.
{
int data_size;
char *data_encoding;
if(!arg || !arg->data)
return -1;
data_size = gs_get_element_size(arg->datatype, my_dsig) *
arg->rows * arg->cols;
DBGPRINTF("sending DSI arg %s, type=%s, rows=%d, cols=%d, bytes=%d\n",
arg->name, gs_c_datatype[arg->datatype], arg->rows, arg->cols, data_size);
if(gs_encode_dsi_object(&data_encoding, arg->dsi_obj) < 0) {
ERRPRINTF("Failed to encode DSI object\n");
return -1;
}
if(gs_send_string(sock, data_encoding) < 0) {
ERRPRINTF("failed to send encoded DSI object\n");
free(data_encoding);
return -1;
}
free(data_encoding);
return 0;
}


| int gs_send_input_args | ( | gs_va_list * | args, | |
| void ** | argstack, | |||
| SOCKET | sock, | |||
| gs_problem_t * | problem, | |||
| int | my_dsig, | |||
| int | lang, | |||
| int | major | |||
| ) |
Sends all of the input arguments to the server.
| args | -- variable arg list. If using the argument stack calling sequence, then set this parameter to NULL. | |
| argstack | -- array of pointers to the arguments. If using the variable arg list, then set this parameter to NULL. | |
| sock | -- the socket on which the argument will be sent. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. | |
| lang | -- language being used on the client side (either GS_CALL_FROM_C or GS_CALL_FROM_FORTRAN). | |
| major | -- specifies how this client stores matrices. 'r' represents row-major and 'c' represents column-major. |
Definition at line 1465 of file comm_data.c.
{
if(!problem)
return -1;
/* First send the scalar arguments */
if(gs_send_input_scalar_args(args, argstack, sock, problem,
my_dsig, lang, major) < 0)
return -1;
/* now send all the non-scalar arguments */
if(gs_send_input_nonscalar_args(sock, problem, my_dsig) < 0)
return -1;
return 0;
}


| int gs_send_input_nonscalar_args | ( | SOCKET | sock, | |
| gs_problem_t * | problem, | |||
| int | my_dsig | |||
| ) |
Sends only the non-scalar input arguments. you must call gs_send_input_scalar_args() at some point before this because it computes the sizes of the non-scalars.
| sock | -- the socket on which the arguments will be sent. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. |
Definition at line 1397 of file comm_data.c.
{
gs_argument_t *argptr;
char *data_handle;
int i;
i = 0;
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next, i++)
{
argptr->index = i;
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT)) &&
(argptr->objecttype != GS_SCALAR))
{
if(argptr->dsi) {
if(gs_send_dsi_input_arg(sock, argptr, my_dsig) < 0) {
ERRPRINTF("error in sending input DSI argument\n");
return -1;
}
}
/* if the data to be sent is a data handle */
/* modified for GridSolve request sequencing */
else if (argptr->data_handle) {
data_handle = find_data_handle(
problem->name, problem->seq_id, argptr->index, argptr->data);
if (!data_handle) {
return -1;
}
/* send the data handle to the server - string */
if (gs_send_string(sock, data_handle) < 0) {
fprintf(stderr, "error in sending data handle - client side\n");
return -1;
}
}
/* the normal argument case */
else {
if(gs_send_arg(sock, argptr, my_dsig) < 0) {
fprintf(stderr, "error in sending input argument\n");
return -1;
}
}
}
}
return 0;
}


| int gs_send_input_scalar_args | ( | gs_va_list * | args, | |
| void ** | argstack, | |||
| SOCKET | sock, | |||
| gs_problem_t * | problem, | |||
| int | my_dsig, | |||
| int | lang, | |||
| int | major | |||
| ) |
Sends only the scalar input arguments. This allows the receiving side to know the sizes of the non-scalar args before attempting to receive them.
| args | -- variable arg list. If using the argument stack calling sequence, then set this parameter to NULL. | |
| argstack | -- array of pointers to the arguments. If using the variable arg list, then set this parameter to NULL. | |
| sock | -- the socket on which the arguments will be sent. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. | |
| lang | -- language being used on the client side (either GS_CALL_FROM_C or GS_CALL_FROM_FORTRAN). | |
| major | -- specifies how this client stores matrices. 'r' represents row-major and 'c' represents column-major. |
Definition at line 1331 of file comm_data.c.
{
gs_argument_t *argptr;
if(!problem)
return -1;
/* if args and argstack are both NULL, then skip computing the arg
* sizes since they would have been computed on the previous failed
* submission.
*/
if(args || argstack)
if(gs_sender_compute_arg_sizes(args, argstack, problem, lang, major) < 0)
return -1;
if(gs_send_tag(sock, major) < 0) {
ERRPRINTF("failed to send major %d\n", problem->major);
return -1;
}
/* determine call signature if not already set. */
if(!strcmp(problem->callsig, GS_NO_CALL_SIG))
if(gs_set_call_signature(problem) < 0)
return -1;
if(gs_send_string(sock, problem->callsig) < 0) {
ERRPRINTF("failed to send call signature '%s'\n", problem->callsig);
return -1;
}
/* first we send all the scalar arguments so that the receiver
* can compute the size expressions for the vector/matrix args.
*/
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next)
{
if(((argptr->inout == GS_IN) || (argptr->inout == GS_INOUT)) &&
(argptr->objecttype == GS_SCALAR))
{
if(gs_send_arg(sock, argptr, my_dsig) < 0) {
ERRPRINTF("error in sending input scalar argument\n");
return -1;
}
}
}
return 0;
}


| int gs_send_int | ( | SOCKET | sock, | |
| int | tosend | |||
| ) |
Send an unsigned integer over a socket. The integer is assumed to be unsigned; it is converted to network byte order and then sent.
| sock | -- the socket on which to send the integer | |
| tosend | -- the integer to be sent |
Definition at line 252 of file comm_data.c.
{
uint32_t uint1 = (uint32_t)tosend;
uint32_t uint2 = htonl(uint1);
if (tosend < 0) {
ERRPRINTF("The integer must be unsigned %d\n", tosend);
return -1;
}
if (gs_twrite(sock, &uint2, sizeof(uint32_t)) <= 0) {
ERRPRINTF("Could not send int %d\n", tosend);
return -1;
}
return 0;
}


| int gs_send_output_args | ( | SOCKET | sock, | |
| gs_problem_t * | problem, | |||
| int | my_dsig | |||
| ) |
Sends all of the output arguments back to the client.
| sock | -- the socket on which the argument will be sent. | |
| problem | -- the problem descriptor for the remote procedure being called. | |
| my_dsig | -- this machine's data signature. |
Definition at line 1593 of file comm_data.c.
{
gs_argument_t *argptr;
char *full_name, *path, *file_name, *data_handle;
LFS_DSI_OBJECT *obj;
int i;
if(!problem)
return -1;
if(gs_send_tag(sock, problem->major) < 0) {
ERRPRINTF("failed to send major\n");
return -1;
}
if(gs_receiver_compute_arg_sizes(problem, GS_OUT) < 0)
{
ERRPRINTF("could not compute argument sizes.\n");
return -1;
}
/* reconstruct the server-side pass-back flags */
/* modified for GridSolve request sequencing */
gs_set_pass_back_flags(problem, server_callsig);
i = 0;
for(argptr = problem->arglist; argptr != NULL; argptr = argptr->next, i++)
{
/* the index of the argument in argument list */
argptr->index = i;
if((argptr->inout == GS_INOUT) || (argptr->inout == GS_OUT) ||
(argptr->inout == GS_VAROUT))
{
if(argptr->dsi) {
if(gs_send_dsi_output_arg(sock, argptr, my_dsig) < 0) {
ERRPRINTF("error in sending output DSI argument\n");
return -1;
}
}
/* if the argument to be sent back is a data handle */
/* modified for GridSolve request sequencing */
if (!argptr->pass_back) {
struct sockaddr_in addr;
socklen_t addr_length;
/* get the ip address of this host */
if (getsockname(sock, (struct sockaddr *) &addr, &addr_length) < 0) {
fprintf(stderr, "error getting local host name\n");
return -1;
}
argptr->hostname = inet_ntoa(addr.sin_addr);
/* generate a unique file name */
file_name = gs_seq_create_unique_file_name(argptr);
if (!file_name) {
fprintf(stderr, "error generating unique data file name\n");
return -1;
}
if (!DATA_SEND_FILE_PATH) {
gs_seq_set_lfs_dsi_data_storage_path();
}
path = DATA_SEND_FILE_PATH;
/* construct the full path name */
full_name = (char *) malloc(sizeof(char)
* (strlen(path) + strlen(file_name) + 1));
if (!full_name) {
perror("malloc");
return -1;
}
strcpy(full_name, path);
full_name[strlen(path)] = '\0';
strcat(full_name, file_name);
full_name[strlen(path) + strlen(file_name)] = '\0';
/* save the data to the file */
if (gs_seq_save_data_into_file(
full_name, argptr, problem->major, my_dsig) < 0) {
fprintf(stderr, "error saving data to file\n");
return -1;
}
/* create a data handle for the file */
obj = gs_seq_create_data_handle(
argptr, path, file_name, problem->major);
if (!obj) {
fprintf(stderr, "error creating data handle\n");
return -1;
}
/* encode the data handle */
data_handle = gs_seq_encode_lfs_dsi_object(obj);
/* make sure the data handle is ok */
if (!data_handle) {
fprintf(stderr, "bad data handle - server side\n");
return -1;
}
/* send the data handle back to the client - string */
if (gs_send_string(sock, data_handle) < 0) {
fprintf(stderr, "error in sending data handle - server side\n");
return -1;
}
}
else {
if(gs_send_arg(sock, argptr, my_dsig) < 0) {
fprintf(stderr, "error in sending output arguments\n");
return -1;
}
}
}
}
return 0;
}


| int gs_send_string | ( | SOCKET | sock, | |
| char * | tosend | |||
| ) |
Send a string over a socket. First sends the string length, then sends the string.
| sock | -- the socket on which to send the string | |
| tosend | -- the string to be sent |
Definition at line 306 of file comm_data.c.
{
int len = -1;
ASSERT_EXPR((tosend != NULL), return(-1));
len = strlen(tosend);
#ifdef GS_DEBUG
{
char *tmps = strdup(tosend);
if (strlen(tmps) > 50) tmps[50]='\0';
DBGPRINTF("sending string of len %d to sock %d: '%s...'\n", len, sock, tmps);
FREE(tmps);
}
#else
DBGPRINTF("sending string of len %d to sock %d \n", len, sock);
#endif
if(gs_send_int(sock, len) < 0) {
ERRPRINTF("Error sending string length\n");
return -1;
}
if(gs_twrite(sock, tosend, len*sizeof(char)) < 0) {
ERRPRINTF("Error sending string\n");
return -1;
}
return 0;
}


| int gs_send_tag | ( | SOCKET | sock, | |
| int | tag | |||
| ) |
Send a tag to a socket.
A byte is used to send a numeric tag value, because it will be machine architecture independent (don't need htons, xdr, etc). The tag is limited to values from 0-127, so we need to make sure not to exceed these limits.
| sock | -- socket to write the tag to | |
| tag | -- tag to be written |
Definition at line 199 of file comm_data.c.
{
unsigned char bytetag;
DBGPRINTF("sock %d tag %d\n", sock, tag);
/* Check that the tag is in the correct range */
if (tag<0 || tag>127) {
ERRPRINTF("Tag value %d cannot be held in one byte!!!\n", tag);
return -1;
}
bytetag = tag;
if (gs_twrite(sock, &bytetag, sizeof(bytetag)) <= 0) {
ERRPRINTF("Could not write tag %d to the network\n", tag);
return -1;
}
return 0;
}


| int gs_sender_compute_arg_sizes | ( | gs_va_list * | ap, | |
| void ** | argstack, | |||
| gs_problem_t * | prob_desc, | |||
| int | language, | |||
| int | major | |||
| ) |
Computes the sizes of the non-scalar arguments that we will be sending.
| ap | -- variable arg list. If using the argument stack calling sequence, then set this parameter to NULL. | |
| argstack | -- array of pointers to the arguments. If using the variable arg list, then set this parameter to NULL. | |
| prob_desc | -- the problem descriptor for the remote procedure being called. | |
| language | -- language being used on the sending side (either GS_CALL_FROM_C or GS_CALL_FROM_FORTRAN). | |
| major | -- specifies how the sender stores matrices. 'r' represents row-major and 'c' represents column-major. |
Definition at line 2117 of file comm_data.c.
{
gs_argument_t *argptr;
icl_hash_t *symtab;
int i, j;
if (prob_desc->size_computed) return 0;
if(!prob_desc)
return -1;
symtab = icl_hash_create(11, NULL);
if(!symtab)
return -1;
prob_desc->major = major;
i = -1;
j = 0;
for(argptr=prob_desc->arglist; argptr != NULL; argptr=argptr->next)
{
argptr->prob = prob_desc;
/* if this is workspace, there will be no real argument passed in the
* calling sequence, so do nothing here.
*/
if(argptr->inout == GS_WORKSPACE) {
argptr->data = NULL;
continue;
}
/* this is a real arg, so increment the index and continue */
i++;
if((argptr->objecttype == GS_SCALAR) && (argptr->inout == GS_IN))
{
switch(argptr->datatype) {
case GS_INT:
if(ap) {
if(language == GS_CALL_FROM_C) {
argptr->scalar_val.int_val = (int)va_arg(ap->args, int);
} else
argptr->scalar_val.int_val = *((int*)va_arg(ap->args, int*));
}
else {
argptr->scalar_val.int_val = *((int *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.int_val);
argptr->expr_val = (double) argptr->scalar_val.int_val;
break;
case GS_CHAR:
if(ap) {
/* note promotion to int in va_arg() for pass by value scalar */
if(language == GS_CALL_FROM_C)
argptr->scalar_val.char_val = (char)va_arg(ap->args, int);
else
argptr->scalar_val.char_val = *((char*)va_arg(ap->args, char*));
}
else {
argptr->scalar_val.char_val = *((char *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.char_val);
argptr->expr_val = (double) argptr->scalar_val.char_val;
break;
case GS_FLOAT:
if(ap) {
/* note promotion to double in va_arg() for pass by value scalar */
if(language == GS_CALL_FROM_C)
argptr->scalar_val.float_val = (float)va_arg(ap->args, double);
else
argptr->scalar_val.float_val = *((float*)va_arg(ap->args, float*));
}
else {
argptr->scalar_val.float_val = *((float *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.float_val);
argptr->expr_val = (double) argptr->scalar_val.float_val;
break;
case GS_DOUBLE:
if(ap) {
if(language == GS_CALL_FROM_C)
argptr->scalar_val.double_val = (double)va_arg(ap->args, double);
else
argptr->scalar_val.double_val = *((double*)va_arg(ap->args, double*));
}
else {
argptr->scalar_val.double_val = *((double *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.double_val);
argptr->expr_val = argptr->scalar_val.double_val;
break;
case GS_SCOMPLEX:
if(ap) {
if(language == GS_CALL_FROM_C)
argptr->scalar_val.scomplex_val = va_arg(ap->args, gs_scomplex);
else
argptr->scalar_val.scomplex_val = *((gs_scomplex*)va_arg(ap->args, gs_scomplex*));
}
else {
argptr->scalar_val.scomplex_val = *((gs_scomplex *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.scomplex_val);
argptr->expr_val = argptr->scalar_val.scomplex_val.r;
break;
case GS_DCOMPLEX:
if(ap) {
if(language == GS_CALL_FROM_C)
argptr->scalar_val.dcomplex_val = va_arg(ap->args, gs_dcomplex);
else
argptr->scalar_val.dcomplex_val = *((gs_dcomplex*)va_arg(ap->args, gs_dcomplex*));
}
else {
argptr->scalar_val.dcomplex_val = *((gs_dcomplex *)argstack[i]);
}
argptr->data = &(argptr->scalar_val.dcomplex_val);
argptr->expr_val = argptr->scalar_val.dcomplex_val.r;
break;
default:
ERRPRINTF("Bad data type\n");
return -1;
}
icl_hash_insert(symtab, argptr->name, &(argptr->expr_val));
}
else {
if(argptr->datatype == GS_INT) {
if(ap)
argptr->data = (int*)va_arg(ap->args, int*);
else
argptr->data = (int*)argstack[i];
}
else if(argptr->datatype == GS_CHAR) {
if(ap)
argptr->data = (char*)va_arg(ap->args, char*);
else
argptr->data = (char*)argstack[i];
}
else if(argptr->datatype == GS_FLOAT) {
if(ap)
argptr->data = (float*)va_arg(ap->args, float*);
else
argptr->data = (float*)argstack[i];
}
else if(argptr->datatype == GS_DOUBLE) {
if(ap)
argptr->data = (double*)va_arg(ap->args, double*);
else
argptr->data = (double*)argstack[i];
}
else if(argptr->datatype == GS_SCOMPLEX) {
if(ap)
argptr->data = (gs_scomplex*)va_arg(ap->args, gs_scomplex*);
else
argptr->data = (gs_scomplex*)argstack[i];
}
else if(argptr->datatype == GS_DCOMPLEX) {
if(ap)
argptr->data = (gs_dcomplex*)va_arg(ap->args, gs_dcomplex*);
else
argptr->data = (gs_dcomplex*)argstack[i];
}
/* if this is an output only scalar, insert a 0 size in the
* symbol table so we will know not to allocate memory for any
* objects using this as its size.
*/
if((argptr->objecttype == GS_SCALAR) && (argptr->inout == GS_OUT)) {
argptr->expr_val = 0.0;
icl_hash_insert(symtab, argptr->name, &(argptr->expr_val));
}
}
}
if(ap)
va_end(ap->args);
if(gs_setup_workspace(prob_desc, symtab) < 0) {
ERRPRINTF("problem setting up workspace for matrix transpose.\n");
return -1;
}
icl_hash_destroy(symtab, NULL, NULL);
return 0;
}


| int gs_set_call_signature | ( | gs_problem_t * | prob_desc | ) |
Sets the call signature for this problem, depending on the arguments.
| prob | -- pointer to the problem descriptor |
Definition at line 1235 of file comm_data.c.
{
gs_argument_t *argptr;
char *callsig;
int i, count;
if(!prob_desc) return -1;
/* count args */
count = 0;
for(argptr=prob_desc->arglist; argptr != NULL; argptr=argptr->next)
count++;
callsig = (char *)malloc(count + 1);
if(!callsig)
return -1;
i = 0;
for(argptr=prob_desc->arglist; argptr != NULL; argptr=argptr->next, i++) {
argptr->dsi = 0;
if(argptr->data) {
if(gs_is_dsi_object(argptr->data)) {
callsig[i] = 'D';
argptr->dsi = 1;
if((argptr->objecttype == GS_FILE) ||
(argptr->objecttype == GS_PACKEDFILE) ||
(argptr->inout == GS_INOUT) ||
(argptr->inout == GS_OUT) ||
(argptr->inout == GS_VAROUT) ||
(argptr->inout == GS_WORKSPACE))
{
ERRPRINTF("DSI only supported for INPUT variables ");
ERRPRINTF("(offending variable = %s)\n", argptr->name);
free(callsig);
return -1;
}
}
/* indicating whether an argument should be passed
back to the client or not, and whether it is
replaced with data handle */
/* modified for GridSolve request sequencing */
if (!argptr->pass_back && !argptr->data_handle) {
callsig[i] = 'R';
}
else if (!argptr->pass_back && argptr->data_handle) {
callsig[i] = 'S';
}
else if (argptr->pass_back && argptr->data_handle) {
callsig[i] = 'T';
}
else
callsig[i] = 'P';
}
else
callsig[i] = 'N';
argptr->dsi_obj = NULL;
}
callsig[i] = 0;
if(prob_desc->callsig)
free(prob_desc->callsig);
prob_desc->callsig = callsig;
client_callsig = callsig;
return 0;
}


| int gs_set_dsi_flags | ( | gs_problem_t * | prob, | |
| char * | callsig | |||
| ) |
Based on the call signature, set the dsi flags in the arguments for this problem. This is called on the server side since all we have is the call signature sent by the client.
| prob | -- pointer to problem descriptor for this call | |
| callsig | -- the call signature |
Definition at line 1134 of file comm_data.c.
{
gs_argument_t *argptr;
int i;
if(!prob) return -1;
if(prob->callsig)
free(prob->callsig);
prob->callsig = callsig;
if(!strcmp(callsig, GS_NO_CALL_SIG)) {
for(argptr=prob->arglist; argptr != NULL; argptr=argptr->next) {
argptr->dsi = 0;
argptr->dsi_obj = NULL;
}
return 0;
}
i = 0;
for(argptr=prob->arglist; argptr != NULL; argptr=argptr->next, i++) {
if(prob->callsig) {
if(prob->callsig[i] == 'D')
argptr->dsi = 1;
}
else
argptr->dsi = 0;
argptr->dsi_obj = NULL;
}
return 0;
}

| int gs_set_pass_back_flags | ( | gs_problem_t * | prob, | |
| char * | callsig | |||
| ) |
set the flag indicating whether arguments need to be passed back used by GridSolve request sequencing
Definition at line 1174 of file comm_data.c.
{
gs_argument_t *argptr;
int i;
if (!prob) return -1;
/*
if (prob->callsig)
free(prob->callsig);
prob->callsig = callsig;
if (!prob->callsig) {
fprintf(stderr, "bad call signature\n");
return -1;
}
if (!strcmp(callsig, GS_NO_CALL_SIG)) {
for (argptr = prob->arglist; argptr != NULL; argptr = argptr->next) {
argptr->pass_back = 1;
argptr->data_handle = 0;
}
return 0;
}
*/
i = 0;
for (argptr = prob->arglist; argptr != NULL; argptr = argptr->next, i++) {
if (prob->callsig[i] == 'R') {
argptr->pass_back = 0;
argptr->data_handle = 0;
}
else if (prob->callsig[i] == 'S') {
argptr->pass_back = 0;
argptr->data_handle = 1;
}
else if (prob->callsig[i] == 'T') {
argptr->pass_back = 1;
argptr->data_handle = 1;
}
else {
argptr->pass_back = 1;
argptr->data_handle = 0;
}
}
return 0;
}

| int gs_setup_workspace | ( | gs_problem_t * | prob_desc, | |
| icl_hash_t * | symtab | |||
| ) |
Setup workspace (temporary storage required for the matrix transpose algorithm) and compute the non-scalar argument sizes.
| prob_desc | -- the problem descriptor for the remote procedure being called. | |
| symtab | -- symbol table containing the scalar variables/values used in computing the arg sizes. |
Definition at line 2688 of file comm_data.c.
{
int worksz, row_max = 0, col_max = 0;
gs_argument_t *argptr;
if(!prob_desc)
return -1;
for(argptr = prob_desc->arglist; argptr != NULL; argptr=argptr->next)
{
/* Evaluate the row/col values */
if((gs_expr_i(argptr->rowexp, &(argptr->rows), symtab) < 0) ||
(gs_expr_i(argptr->colexp, &(argptr->cols), symtab) < 0))
{
ERRPRINTF("Error parsing dimension expression\n");
return -1;
}
/* If sparse matrix, evaluate nnz, then save and overwrite row/col with that info */
if(argptr->objecttype == GS_SPARSEMATRIX) {
if((gs_expr_i(argptr->sparse_attr.nnzexp, &(argptr->sparse_attr.nnz), symtab) < 0)) {
ERRPRINTF("Error parsing NNZ expression\n");
return -1;
}
/* TODO Save the actual row/col values before overwriting with nnz */
argptr->sparse_attr.rows_val_saved = argptr->rows;
argptr->sparse_attr.cols_val_saved = argptr->cols;
argptr->rows = argptr->sparse_attr.nnz;
argptr->cols = 1;
}
if(argptr->rows > row_max)
row_max = argptr->rows;
if(argptr->cols > col_max)
col_max = argptr->cols;
}
worksz = (row_max+col_max)/2;
/* check if there was a previous request using this handle and
* malloc new memory or reuse the workspace if possible.
*/
if(!prob_desc->work) {
prob_desc->work = (int *)malloc(worksz *sizeof(int));
prob_desc->worksize = worksz;
}
else if(prob_desc->worksize < worksz) {
prob_desc->work = (int *)realloc(prob_desc->work, worksz *sizeof(int));
prob_desc->worksize = worksz;
}
if(!prob_desc->work)
prob_desc->worksize = 0;
return 0;
}

| int gs_transpose_matrix | ( | gs_argument_t * | arg, | |
| char * | data, | |||
| gs_side_t | side | |||
| ) |
Transpose the given matrix argument.
| arg | -- the matrix argument to transpose | |
| data | -- pointer to the actual matrix data to be transposed | |
| side | -- which side of the transaction we are (GS_CLIENT_SIDE if we are the client, GS_SERVER_SIDE if we are the server) |
Definition at line 2323 of file comm_data.c.
{
int *move,mn,iwrk,iok,rows,cols;
if(!arg)
return -1;
mn = arg->rows * arg->cols;
if(!arg->prob->work) {
iwrk = (arg->rows + arg->cols)/2;
move = (int*)malloc(iwrk*sizeof(int));
}
else {
move = arg->prob->work;
iwrk = arg->prob->worksize;
}
if(!move)
return -1;
if(side == GS_CLIENT_SIDE) {
rows = arg->rows;
cols = arg->cols;
}
else {
rows = arg->cols;
cols = arg->rows;
}
iok = -1;
switch(arg->datatype) {
case GS_INT:
itrans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
case GS_DOUBLE:
dtrans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
case GS_DCOMPLEX:
dctrans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
case GS_SCOMPLEX:
sctrans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
case GS_FLOAT:
strans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
case GS_CHAR:
ctrans_(data,&rows,&cols,&mn,move,&iwrk,&iok);
break;
default:
ERRPRINTF("gs_transpose_matrix: bad data type\n");
}
if(!arg->prob->work)
free(move);
return iok ? -1 : 0;
}


| int gs_wait_for_output | ( | SOCKET | sock | ) |
Waits for the output to be ready for reading.
| sock | -- the socket that we are going to read the output from |
Definition at line 1495 of file comm_data.c.
{
int nready;
nready = proxy_readable_timeout(sock, -1);
return (nready > 0) ? 0 : -1;
}


char* client_callsig = NULL [static] |
Definition at line 33 of file comm_data.c.
char* server_callsig = NULL [static] |
Definition at line 34 of file comm_data.c.
1.6.3-20100507