1
1

First cut of op handling -- now link-compatible. Still have work to

be done:
- need to define internal op_create function (that MPI_OP_CREATE will
  call)
- need to fill in all the handler functions that are the back-ends to the
  intrinsic MPI operations (e.g., MPI_SUM, MPI_MAX, etc.)

This commit was SVN r1061.
Этот коммит содержится в:
Jeff Squyres 2004-04-20 22:37:46 +00:00
родитель 7177358f23
Коммит 585aab46b7
5 изменённых файлов: 736 добавлений и 3 удалений

Просмотреть файл

@ -5,10 +5,18 @@
include $(top_srcdir)/config/Makefile.options
noinst_LTLIBRARIES = libop.la
# Source code files
headers = \
op.h
op.h \
op_predefined.h
libop_la_SOURCES = \
$(headers) \
op.c \
op_predefined.c
# Conditionally install the header files

358
src/op/op.c Обычный файл
Просмотреть файл

@ -0,0 +1,358 @@
/*
* $HEADER$
*/
/** @file **/
#include "lam_config.h"
#include "include/constants.h"
#include "op/op.h"
#include "op/op_predefined.h"
#include "lfc/lam_pointer_array.h"
/*
* Table for Fortran <-> C op handle conversion
*/
lam_pointer_array_t *lam_op_f_to_c_table;
/*
* Create intrinsic op
*/
static int add_intrinsic(lam_op_t *op, int fort_handle);
/*
* Class information
*/
static void lam_op_construct(lam_op_t *eh);
static void lam_op_destruct(lam_op_t *eh);
/*
* Class instance
*/
OBJ_CLASS_INSTANCE(lam_op_t, lam_object_t, lam_op_construct, lam_op_destruct);
/*
* MPI_OP_NULL
*/
lam_op_t lam_mpi_op_null = {
{ NULL, 0 },
"MPI_OP_NULL",
true, false, true, true,
{ NULL }
};
/*
* MPI_OP_MAX
*/
lam_op_t lam_mpi_op_max = {
{ NULL, 0 },
"MPI_OP_MAX",
true, false, true, true,
{ lam_mpi_op_max_func }
};
/*
* MPI_OP_MIN
*/
lam_op_t lam_mpi_op_min = {
{ NULL, 0 },
"MPI_OP_MIN",
true, false, true, true,
{ lam_mpi_op_min_func }
};
/*
* MPI_OP_SUM
*/
lam_op_t lam_mpi_op_sum = {
{ NULL, 0 },
"MPI_OP_SUM",
true, false, true, true,
{ lam_mpi_op_sum_func }
};
/*
* MPI_OP_PROD
*/
lam_op_t lam_mpi_op_prod = {
{ NULL, 0 },
"MPI_OP_PROD",
true, false, true, true,
{ lam_mpi_op_prod_func }
};
/*
* MPI_OP_LAND
*/
lam_op_t lam_mpi_op_land = {
{ NULL, 0 },
"MPI_OP_LAND",
true, false, true, true,
{ lam_mpi_op_land_func }
};
/*
* MPI_OP_BAND
*/
lam_op_t lam_mpi_op_band = {
{ NULL, 0 },
"MPI_OP_BAND",
true, false, true, true,
{ lam_mpi_op_band_func }
};
/*
* MPI_OP_LOR
*/
lam_op_t lam_mpi_op_lor = {
{ NULL, 0 },
"MPI_OP_LOR",
true, false, true, true,
{ lam_mpi_op_lor_func }
};
/*
* MPI_OP_BOR
*/
lam_op_t lam_mpi_op_bor = {
{ NULL, 0 },
"MPI_OP_BOR",
true, false, true, true,
{ lam_mpi_op_bor_func }
};
/*
* MPI_OP_LXOR
*/
lam_op_t lam_mpi_op_lxor = {
{ NULL, 0 },
"MPI_OP_LXOR",
true, false, true, true,
{ lam_mpi_op_lxor_func }
};
/*
* MPI_OP_BXOR
*/
lam_op_t lam_mpi_op_bxor = {
{ NULL, 0 },
"MPI_OP_BXOR",
true, false, true, true,
{ lam_mpi_op_bxor_func }
};
/*
* MPI_OP_MAXLOC
*/
lam_op_t lam_mpi_op_maxloc = {
{ NULL, 0 },
"MPI_OP_MAXLOC",
true, false, true, true,
{ lam_mpi_op_maxloc_func }
};
/*
* MPI_OP_MINLOC
*/
lam_op_t lam_mpi_op_minloc = {
{ NULL, 0 },
"MPI_OP_MINLOC",
true, false, true, true,
{ lam_mpi_op_minloc_func }
};
/*
* MPI_OP_REPLACE
*/
lam_op_t lam_mpi_op_replace = {
{ NULL, 0 },
"MPI_OP_REPLACE",
true, false, true, true,
{ lam_mpi_op_replace_func }
};
/*
* Initialize LAM op infrastructure
*/
int lam_op_init(void)
{
/* initialize lam_op_f_to_c_table */
lam_op_f_to_c_table = OBJ_NEW(lam_pointer_array_t);
if (NULL == lam_op_f_to_c_table){
return LAM_ERROR;
}
/* Create the intrinsic ops */
if (add_intrinsic(&lam_mpi_op_null, LAM_OP_NULL_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_max, LAM_OP_MAX_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_min, LAM_OP_MIN_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_sum, LAM_OP_SUM_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_prod, LAM_OP_PROD_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_land, LAM_OP_LAND_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_band, LAM_OP_BAND_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_lor, LAM_OP_LOR_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_bor, LAM_OP_BOR_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_lxor, LAM_OP_LXOR_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_bxor, LAM_OP_BXOR_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_maxloc,
LAM_OP_MAXLOC_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_minloc,
LAM_OP_MINLOC_FORTRAN) != LAM_SUCCESS ||
add_intrinsic(&lam_mpi_op_replace,
LAM_OP_REPLACE_FORTRAN) != LAM_SUCCESS) {
return LAM_ERROR;
}
/* All done */
return LAM_SUCCESS;
}
/*
* Clean up the op resources
*/
int lam_op_finalize(void)
{
/* Remove op F2C table */
OBJ_RELEASE(lam_op_f_to_c_table);
/* All done */
return LAM_SUCCESS;
}
#if 0
/* JMS Need to fill in -- template off lam_errhandler_create() */
lam_op_t *lam_op_create(lam_op_type_t object_type,
lam_op_fortran_handler_fn_t *func)
{
lam_op_t *new_op;
/* Create a new object and ensure that it's valid */
new_op = OBJ_NEW(lam_op_t);
if (NULL == new_op) {
if (LAM_ERROR == new_op->o_f_to_c_index) {
OBJ_RELEASE(new_op);
new_op = NULL;
} else {
/* The new object is valid -- initialize it. If this is being
created from fortran, the fortran MPI API wrapper function
will override the o_fortran_field directly. We cast the
function pointer type to the fortran type arbitrarily -- it
only has to be a function pointer in order to store properly,
it doesn't matter what type it is (we'll cast it to the Right
type when we *use* it). */
new_op->o_mpi_object_type = object_type;
new_op->o_fortran_function = false;
new_op->o_func.fort_fn = func;
}
}
/* All done */
return LAM_SUCCESS;
}
#endif
/**************************************************************************
*
* Static functions
*
**************************************************************************/
static int add_intrinsic(lam_op_t *op, int fort_handle)
{
int ret_val;
/* Add the op to the table */
ret_val = lam_pointer_array_add(lam_op_f_to_c_table, op);
if (-1 == ret_val){
return LAM_ERROR;
}
/* Make sure that the op is in the right location in the table */
if (fort_handle != ret_val) {
return LAM_ERROR;
};
op->o_f_to_c_index = ret_val;
/* All done */
return LAM_SUCCESS;
}
/*
* Op constructor
*/
static void lam_op_construct(lam_op_t *new_op)
{
int ret_val;
/* assign entry in fortran <-> c translation array */
ret_val = lam_pointer_array_add(lam_op_f_to_c_table,
new_op);
new_op->o_f_to_c_index = ret_val;
}
/*
* Op destructor
*/
static void lam_op_destruct(lam_op_t *op)
{
/* reset the lam_op_f_to_c_table entry - make sure that the
entry is in the table */
if (NULL!= lam_pointer_array_get_item(lam_op_f_to_c_table,
op->o_f_to_c_index)) {
lam_pointer_array_set_item(lam_op_f_to_c_table,
op->o_f_to_c_index, NULL);
}
}

Просмотреть файл

@ -5,13 +5,201 @@
#ifndef LAM_OP_H
#define LAM_OP_H
#include "lam_config.h"
#include "mpi.h"
#include "lfc/lam_object.h"
#include "lfc/lam_pointer_array.h"
/*
* These must correspond to the fortran handle indices
*/
#define MPI_MAX 0
#define MPI_MIN 1
#define MPI_SUM 2
#define MPI_PROD 3
#define MPI_LAND 4
#define MPI_BAND 5
#define MPI_LOR 6
#define MPI_BOR 7
#define MPI_LXOR 8
#define MPI_BXOR 9
#define MPI_MAXLOC 10
#define MPI_MINLOC 11
#define MPI_REPLACE 12
/**
* Typedef for C op functions. We don't use MPI_User_function because
* this would create a confusing dependency loop between this file and
* mpi.h.
*/
typedef void (lam_op_c_handler_fn_t)(void *, void *, int *, MPI_Datatype *);
/**
* Typedef for fortran op functions
*/
typedef void (lam_op_fortran_handler_fn_t)(void *, void *, int *, MPI_Fint *);
/**
* Back-end type of MPI_Op
*/
struct lam_op_t {
char o_name[MPI_MAX_OBJECT_NAME];
lam_object_t super;
/* ...more stuff... */
char o_name[MPI_MAX_OBJECT_NAME];
/* Flags about the op */
bool o_is_intrinsic;
bool o_fortran_function;
bool o_is_assoc;
bool o_is_commun;
/* Function pointers */
union {
lam_op_c_handler_fn_t *c_fn;
lam_op_fortran_handler_fn_t *fort_fn;
} o_func;
/* index in Fortran <-> C translation array */
int o_f_to_c_index;
};
typedef struct lam_op_t lam_op_t;
/**
* Global variable for MPI_NULL
*/
extern lam_op_t lam_mpi_op_null;
#define LAM_OP_NULL_FORTRAN 0
/**
* Global variable for MPI_MAX
*/
extern lam_op_t lam_mpi_op_max;
#define LAM_OP_MAX_FORTRAN 1
/**
* Global variable for MPI_MIN
*/
extern lam_op_t lam_mpi_op_min;
#define LAM_OP_MIN_FORTRAN 2
/**
* Global variable for MPI_SUM
*/
extern lam_op_t lam_mpi_op_sum;
#define LAM_OP_SUM_FORTRAN 3
/**
* Global variable for MPI_PROD
*/
extern lam_op_t lam_mpi_op_prod;
#define LAM_OP_PROD_FORTRAN 4
/**
* Global variable for MPI_LAND
*/
extern lam_op_t lam_mpi_op_land;
#define LAM_OP_LAND_FORTRAN 5
/**
* Global variable for MPI_BAND
*/
extern lam_op_t lam_mpi_op_band;
#define LAM_OP_BAND_FORTRAN 6
/**
* Global variable for MPI_LOR
*/
extern lam_op_t lam_mpi_op_lor;
#define LAM_OP_LOR_FORTRAN 7
/**
* Global variable for MPI_BOR
*/
extern lam_op_t lam_mpi_op_bor;
#define LAM_OP_BOR_FORTRAN 8
/**
* Global variable for MPI_LXOR
*/
extern lam_op_t lam_mpi_op_lxor;
#define LAM_OP_LXOR_FORTRAN 9
/**
* Global variable for MPI_BXOR
*/
extern lam_op_t lam_mpi_op_bxor;
#define LAM_OP_BXOR_FORTRAN 10
/**
* Global variable for MPI_MAXLOC
*/
extern lam_op_t lam_mpi_op_maxloc;
#define LAM_OP_MAXLOC_FORTRAN 11
/**
* Global variable for MPI_MINLOC
*/
extern lam_op_t lam_mpi_op_minloc;
#define LAM_OP_MINLOC_FORTRAN 12
/**
* Global variable for MPI_REPLACE
*/
extern lam_op_t lam_mpi_op_replace;
#define LAM_OP_REPLACE_FORTRAN 13
/**
* Table for Fortran <-> C op handle conversion
*/
extern lam_pointer_array_t *lam_op_f_to_c_table;
#if defined(c_plusplus) || defined(__cplusplus)
extern "C" {
#endif
/**
* Initialize the op interface.
*
* @returns LAM_SUCCESS Upon success
* @returns LAM_ERROR Otherwise
*
* Invoked from lam_mpi_init(); sets up the op interface, creates
* the predefined MPI operations, and creates the corresopnding F2C
* translation table.
*/
int lam_op_init(void);
/**
* Finalize the op interface.
*
* @returns LAM_SUCCESS Always
*
* Invokes from lam_mpi_finalize(); tears down the op interface, and
* destroys the F2C translation table.
*/
int lam_op_finalize(void);
#if 0
/**
* Create a lam_op_t
*
* JMS Need to fill in -- template off lam_errhandler_create().
*/
lam_op_t *lam_op_create(lam_op_fortran_handler_fn_t *func);
#endif
#if defined(c_plusplus) || defined(__cplusplus)
}
#endif
#endif /* LAM_OP_H */

100
src/op/op_predefined.c Обычный файл
Просмотреть файл

@ -0,0 +1,100 @@
/*
* $HEADER$
*/
#include "lam_config.h"
#include "op/op.h"
#include "op/op_predefined.h"
void lam_mpi_op_max_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_min_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_sum_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_prod_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_land_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_band_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_lor_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_bor_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_lxor_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_bxor_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_maxloc_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_minloc_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}
void lam_mpi_op_replace_func(void *in, void *out, int *count,
MPI_Datatype *type)
{
/* JMS Need to fill in */
}

79
src/op/op_predefined.h Обычный файл
Просмотреть файл

@ -0,0 +1,79 @@
/*
* $HEADER$
*/
#ifndef LAM_OP_PREDEFINED_H
#define LAM_OP_PREDEFINED_H
#include "op/op.h"
/**
* Handler function for MPI_MAX
*/
void lam_mpi_op_max_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_MIN
*/
void lam_mpi_op_min_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_SUM
*/
void lam_mpi_op_sum_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_PROD
*/
void lam_mpi_op_prod_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_LAND
*/
void lam_mpi_op_land_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_BAND
*/
void lam_mpi_op_band_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_LOR
*/
void lam_mpi_op_lor_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_BOR
*/
void lam_mpi_op_bor_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_LXOR
*/
void lam_mpi_op_lxor_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_BXOR
*/
void lam_mpi_op_bxor_func(void *in, void *out, int *count, MPI_Datatype *type);
/**
* Handler function for MPI_MAXLOC
*/
void lam_mpi_op_maxloc_func(void *in, void *out, int *count,
MPI_Datatype *type);
/**
* Handler function for MPI_MINLOC
*/
void lam_mpi_op_minloc_func(void *in, void *out, int *count,
MPI_Datatype *type);
/**
* Handler function for MPI_REPLACE
*/
void lam_mpi_op_replace_func(void *in, void *out, int *count,
MPI_Datatype *type);
#endif /* LAM_OP_PREDEFINED_H */