From 5e0694d2cafa22bcbdec5c842e955490bea05778 Mon Sep 17 00:00:00 2001 From: Jason Riedy Date: Sat, 26 Aug 2006 13:06:37 -0700 Subject: [PATCH 1/3] New files for the Fortran->C bridge. Calling C from Fortran is relatively straight-forward when no arguments are strings or logicals. We simply need to mangle the names appropriately. The current "system" handles two variations: symbol case: Some compilers use all upper-case, and some use all lower-case. Thankfully, the C bindings are mixed-case, so there are no name collisions. underscores: Three variations exist. Some compilers simply force the case as above. Others append a single underscore to all Fortran symbols. And yet others append a double underscore to all symbols that already contain an underscore and a single underscore otherwise. The name-mangling options are encapsulated in FC_FUNC and FC_FUNC_ cpp macros in src/f2c-bridge.h . These are the same names as the autoconf-generated manging macros, so it should be easy to replace f2c-bridge.h should we ever adopt autoconf. f2c-bridge.h also includes a typedef for returning REAL values from functions. The XBLAS are all subroutines, so that isn't currently used. It will be needed for SLAMCH someday. The next trick is generating an appropriate function body that takes its arguments as Fortran references / C pointers and passes them to C as values. That's the job of m4/f2c-bridge.m4. That file redefines enum, s_scalar, blas_*_type, etc. appropriately and then invokes ROUTINE_NAME, ROUTINE_ARGS, and ROUTINE_HEAD. The end result is a little C file that defines the bridge function. The BLAS_fpinfo_x routine is not automatically generated, so its bridge function is included (and marked in .gitignore). Signed-off-by: Jason Riedy --- .gitignore | 1 + m4/f2c-bridge.m4 | 61 ++++++++++++++++++++++++++++++++++++++++ src/common/BLAS_fpinfo_x-f2c.c | 10 +++++++ src/f2c-bridge.h | 40 ++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 0 deletions(-) diff --git a/.gitignore b/.gitignore index fa0ca55..e9f4fe2 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ src/blas_extended_proto.h src/*/*.c !src/common/BLAS_error.c !src/common/BLAS_fpinfo_x.c +!src/common/BLAS_fpinfo_x-f2c.c !src/common/blas_malloc.c testing/*/*.c !testing/test-dot/testgen_BLAS_cdot.c diff --git a/m4/f2c-bridge.m4 b/m4/f2c-bridge.m4 new file mode 100644 index 0000000..51203a6 --- /dev/null +++ b/m4/f2c-bridge.m4 @@ -0,0 +1,61 @@ +include(../cblas.m4) +include(routine-common.m4) +#include "f2c-bridge.h" +#include "blas_enum.h" +ROUTINE_HEAD(RARG); + +define(`enum',`int')dnl +define(`s_scalar', `float*')dnl +define(`d_scalar', `double*')dnl +define(`blas_order_type',`')dnl +define(`blas_trans_type',`')dnl +define(`blas_uplo_type',`')dnl +define(`blas_diag_type',`')dnl +define(`blas_side_type',`')dnl +define(`blas_cmach_type',`')dnl +define(`blas_norm_type',`')dnl +define(`blas_sort_type',`')dnl +define(`blas_conj_type',`')dnl +define(`blas_jrot_type',`')dnl +define(`blas_prec_type',`')dnl +define(`blas_base_type',`')dnl +define(`blas_symmetry_type',`')dnl +define(`blas_field_type',`')dnl +define(`blas_size_type',`')dnl +define(`blas_handle_type',`')dnl +define(`blas_sparsity_optimization_type',`')dnl +define(`int',`in`'t*')dnl +extern void FC_FUNC_(translit(ROUTINE_NAME(RARG),'A-Z','a-z'),translit(ROUTINE_NAME(RARG),'a-z','A-Z')) + (ROUTINE_PARAMS(RARG)) +{ +define(`void',`')dnl +define(`const',`')dnl +define(`enum',`')dnl +define(`blas_order_type',`(en`'um blas_order`'_type)*')dnl +define(`blas_trans_type',`(en`'um blas_trans`'_type)*')dnl +define(`blas_uplo_type',`(en`'um blas_uplo`'_type)*')dnl +define(`blas_diag_type',`(en`'um blas_diag`'_type)*')dnl +define(`blas_side_type',`(en`'um blas_side`'_type)*')dnl +define(`blas_cmach_type',`(en`'um blas_cmach`'_type)*')dnl +define(`blas_norm_type',`(en`'um blas_norm`'_type)*')dnl +define(`blas_sort_type',`(en`'um blas_sort`'_type)*')dnl +define(`blas_conj_type',`(en`'um blas_conj`'_type)*')dnl +define(`blas_jrot_type',`(en`'um blas_jrot`'_type)*')dnl +define(`blas_prec_type',`(en`'um blas_prec`'_type)*')dnl +define(`blas_base_type',`(en`'um blas_base`'_type)*')dnl +define(`blas_symmetry_type',`(en`'um blas_symmetry`'_type)*')dnl +define(`blas_field_type',`(en`'um blas_field`'_type)*')dnl +define(`blas_size_type',`(en`'um blas_size`'_type)*')dnl +define(`blas_handle_type',`(en`'um blas_handle`'_type)*')dnl +define(`blas_sparsity_optimization_type',`(en`'um blas_sparsity_optimization`'_type)*')dnl +define(`int',`*')dnl +define(`s_scalar',`*')dnl +define(`d_scalar',`*')dnl +define(`c_scalar',`')dnl +define(`z_scalar',`')dnl +define(`s_array',`')dnl +define(`d_array',`')dnl +define(`c_array',`')dnl +define(`z_array',`')dnl + ROUTINE_HEAD(RARG); +} \ No newline at end of file diff --git a/src/common/BLAS_fpinfo_x-f2c.c b/src/common/BLAS_fpinfo_x-f2c.c new file mode 100644 index 0000000..3d1fbb1 --- /dev/null +++ b/src/common/BLAS_fpinfo_x-f2c.c @@ -0,0 +1,10 @@ +#include "blas_enum.h" +#include "f2c-bridge.h" + +extern int BLAS_fpinfo_x(enum blas_cmach_type, enum blas_prec_type); + +int FC_FUNC_(blas_fpinfo_x,BLAS_FPINFO_X)(int *cmach, int *prec) +{ + return BLAS_fpinfo_x((enum blas_cmach_type)*cmach, + (enum blas_prec_type)*prec); +} diff --git a/src/f2c-bridge.h b/src/f2c-bridge.h new file mode 100644 index 0000000..3450e57 --- /dev/null +++ b/src/f2c-bridge.h @@ -0,0 +1,40 @@ +#if !defined(XBLAS_F2C_BRIDGE_H_) +#define XBLAS_F2C_BRIDGE_H_ + +#if defined(CONFIG_FC_UNDERSCORE) +#define FC_UNDER(x) x##_ +#define FC_UNDER2(x) x##_ +#elif defined(CONFIG_FC_DBL_UNDERSCORE) +#define FC_UNDER(x) x##_ +#define FC_UNDER2(x) x##__ +#else +#define FC_UNDER(x) x +#define FC_UNDER2(x) x +#endif + +#if defined(CONFIG_FC_UCASE) +#define FC_FUNC(x,X) FC_UNDER(X) +#define FC_FUNC_(x,X) FC_UNDER2(X) +#else +#define FC_FUNC(x,X) FC_UNDER(x) +#define FC_FUNC_(x,X) FC_UNDER2(x) +#endif + +#if defined(CONFIG_FC_RETURNS_DBL_REAL) +typedef double fc_real_result_t; +#else +typedef float fc_real_result_t; +#endif + +/* + Possible future config options: + + CONFIG_FC_RETURNS_DBL_REAL + The f2c ABI returns Fortan REALs in C doubles. + + CONFIG_FC_STUPID_TYPES + When the Fortran compiler defines 64-bit REALs and INTEGERs + as the default KIND. +*/ + +#endif /* XBLAS_F2C_BRIDGE_H_ */ -- 1.4.2.g6580-dirty