Commit ef6e46e3 authored by Jakob Luettgau's avatar Jakob Luettgau
Browse files

Darshan C++ module minimal example.

parent 7aeeaeee
CC=mpicc
CLFAGS=-g
all: abcxyz
all: abcxyz
libabcxyz:
${CC} ${CLFAGS} -fPIC -c -Wall $@.c
${CC} -shared -Wl,-soname,$@.so.1 -o $@.so.1.0.1 $@.o
ln -s $@.so.1.0.1 $@.so
ln -s $@.so.1.0.1 $@.so.1
mycpplib:
g++ -fPIC -shared -o lib$@.so $@.cpp
abcxyz: libabcxyz
${CC} ${CFLAGS} -o $@ $@.c -L. -l$@
abcxyz: mycpplib
# NOTE: mpic++!
mpic++ $(CFLAGS) abcxyz.cpp -o $@ -L. -lmycpplib
run:
./run.sh
clean:
rm -f *.darshan
rm -rf *.o
rm -f *.so*
rm -f abcxyz
......@@ -24,7 +24,7 @@ using the parser.sh file:
By default darshan-runtime will not include instrumentation for the new mod.
Therefor when configuring darshan-runtime build as follows:
./configure CC=mpicc --with-mem-align=8 \
./configure CC=mpicc CXX=mpic++ --with-mem-align=8 \
--with-log-path-by-env=DARSHAN_LOG_DIR_PATH \
--with-jobid-env=NONE --enable-abcxyz
make -j
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <mpi.h>
#include "libabcxyz.h"
int main(int argc, char const* argv[])
{
MPI_Init(NULL, NULL);
// have some calls which are captured by the new instrumentation module
foo("hello", 21);
foo("hello", 42);
foo("hello", 84);
// have some posix I/O, too
int fd = open("testfile", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH);
write(fd, "abc", 3);
close(fd);
MPI_Finalize();
return 0;
}
#include <mpi.h>
#include <stdio.h>
#include "mycpplib.hpp"
int main(int argc, char const* argv[])
{
MPI_Init(NULL, NULL);
X x;
x.fn1("abc", 42);
x.fn2();
MPI_Finalize();
return 0;
}
#include <stdio.h>
void foo(const char *name, int arg1)
{
printf("Hello from foo() of libabcxyz.c!\n");
}
#ifndef LIBABCXYZ_H
#define LIBABCXYZ_H
#ifdef __cplusplus
extern "C" {
#endif
void foo(const char *name, int arg1);
#ifdef __cplusplus
}
#endif
#endif /* !LIBABCXYZ_H */
#include <iostream>
#include "mycpplib.hpp"
void X::fn1(const char* name, int arg1) { std::cout << "X::fn1(" << "name=" << name << ", arg1=" << arg1 << ")\n"; }
void X::fn2() { std::cout << "X::fn2()\n"; }
void X::fn3() { std::cout << "X::fn3()\n"; }
#ifndef MYCPPLIB_df789dg8j3
#define MYCPPLIB_df789dg8j3
class X
{
public:
void fn1(const char* name, int arg1);
void fn2();
void fn3();
};
#endif
......@@ -103,10 +103,10 @@ lib/darshan-null.po: lib/darshan-null.c darshan.h darshan-dynamic.h darshan-comm
$(CC) $(CFLAGS_SHARED) -c $< -o $@
lib/darshan-abcxyz.o: lib/darshan-abcxyz.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-abcxyz-log-format.h | lib
$(CC) $(CFLAGS) -c $< -o $@
$(CXX) $(CFLAGS) -fpermissive -c $< -o $@
lib/darshan-abcxyz.po: lib/darshan-abcxyz.c darshan.h darshan-dynamic.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-abcxyz-log-format.h | lib
$(CC) $(CFLAGS_SHARED) -c $< -o $@
$(CXX) $(CFLAGS_SHARED) -fpermissive -c $< -o $@
lib/darshan-posix.o: lib/darshan-posix.c darshan.h darshan-common.h $(DARSHAN_LOG_FORMAT) $(srcdir)/../darshan-posix-log-format.h | lib
$(CC) $(CFLAGS) -DDARSHAN_WRAP_MMAP -c $< -o $@
......@@ -185,7 +185,7 @@ lib/libdarshan.a: lib/darshan-core-init-finalize.o lib/darshan-core.o lib/darsha
ar rcs $@ $^
lib/libdarshan.so: lib/darshan-core-init-finalize.po lib/darshan-core.po lib/darshan-common.po $(DARSHAN_DYNAMIC_MOD_OBJS) lib/lookup3.po lib/lookup8.po
$(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ -lpthread -lrt -lz -ldl
$(CC) $(CFLAGS_SHARED) $(LDFLAGS) -o $@ $^ -lpthread -lrt -lz -ldl -lstdc++
ifdef BUILD_HDF5_MODULE
lib/libdarshan-stubs.a: lib/darshan-hdf5-stubs.o lib/darshan-pnetcdf-stubs.o
......
......@@ -667,7 +667,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
......@@ -706,6 +705,7 @@ with_mod_mem
enable_HDF5_post_1_10
enable_HDF5_pre_1_10
enable_mdhim
enable_abcxyz
'
ac_precious_vars='build_alias
host_alias
......@@ -754,7 +754,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
......@@ -1007,15 +1006,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
......@@ -1153,7 +1143,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
......@@ -1306,7 +1296,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
......@@ -1348,6 +1337,7 @@ Optional Features:
--enable-HDF5-pre-1.10
Enable HDF5 module for HDF5 versions earlier than 1.10
--enable-mdhim Enable mdhim module
--enable-abcxyz Enable abcxyz module
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
......@@ -4266,6 +4256,24 @@ done
fi
# ABCYXZ Module:
BUILD_ABCXYZ_MODULE=
DARSHAN_ABCXYZ_LD_OPTS=
# Check whether --enable-abcxyz was given.
if test "${enable_abcxyz+set}" = set; then :
enableval=$enable_abcxyz;
fi
if test "x$enable_abcxyz" = "xyes"; then :
BUILD_ABCXYZ_MODULE=1
DARSHAN_ABCXYZ_LD_OPTS="@${darshan_share_path}/ld-opts/darshan-abcxyz-ld-opts"
#AC_CHECK_HEADERS([abcxyz.h],
# [],
# AC_MSG_ERROR([abcxyz requested but headers cannot be found]) ),
fi
# determine if the MPI library includes MPI-IO functions or not
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MPI-IO support in MPI" >&5
......
......@@ -156,6 +156,10 @@ struct darshan_variance_dt
* darshan-common functions for darshan modules *
***********************************************/
#ifdef __cplusplus
extern "C" {
#endif
/* darshan_lookup_record_ref()
*
* Lookup a record reference pointer using the given 'handle'.
......@@ -280,4 +284,8 @@ void darshan_variance_reduce(
int *len,
MPI_Datatype *dt);
#ifdef __cplusplus
}
#endif
#endif /* __DARSHAN_COMMON_H */
......@@ -120,6 +120,10 @@ void darshan_instrument_fs_data(
* darshan-core functions exported to darshan modules *
*****************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/* darshan_core_register_module()
*
* Register module identifier 'mod_id' with the darshan-core runtime
......@@ -219,4 +223,8 @@ int darshan_core_excluded_path(
*/
int darshan_core_disabled_instrumentation(void);
#ifdef __cplusplus
}
#endif
#endif /* __DARSHAN_H */
......@@ -7,6 +7,8 @@
#define _XOPEN_SOURCE 500
#define _GNU_SOURCE
#define OMPI_SKIP_MPICXX
#include "darshan-runtime-config.h"
#include <stdio.h>
#include <unistd.h>
......@@ -15,9 +17,16 @@
#include <string.h>
#include <assert.h>
#include <dlfcn.h>
#include "darshan.h"
#include "darshan-dynamic.h"
#ifdef __cplusplus
#include <iostream>
#include <typeinfo>
#endif
/* The "ABCXYZ" module is an example instrumentation module implementation provided
* with Darshan, primarily to indicate how arbitrary modules may be integrated
* into Darshan. In particular, this module demonstrates how to develop wrapper
......@@ -28,11 +37,24 @@
* that may be reused and expanded on by developers adding new instrumentation modules.
*/
/* The DARSHAN_FORWARD_DECL macro (defined in darshan.h) is used to provide forward
* declarations for wrapped funcions, regardless of whether Darshan is used with
* statically or dynamically linked executables.
*
* NOTE: Unfortuntely, this level of convienience can not be offered using standard
* C++ mechanisms, but requires to include a dependency to perform name mangling.
*/
DARSHAN_FORWARD_DECL(foo, int, (const char *name, int arg1));
//DARSHAN_FORWARD_DECL(foo, int, (const char *name, int arg1));
class X
{
public:
void fn1(const char* name, int arg1);
void fn2();
void fn3();
};
/* The abcxyz_record_ref structure maintains necessary runtime metadata
* for the ABCXYZ module record (darshan_abcxyz_record structure, defined in
......@@ -163,34 +185,77 @@ static int my_rank = -1;
/* The DARSHAN_DECL macro provides the appropriate wrapper function names,
* depending on whether the Darshan library is statically or dynamically linked.
*
* NOTE: Unfortuntely, this level of convienience can not be offered using standard
* C++ mechanisms. It could be provided by including an implmentation of e.g.
* the commonly used itanium ABI mangler which seems consistent to GCC/LLVM.
*/
int DARSHAN_DECL(foo)(const char* name, int arg1)
// Kept for comparison ;)
//int DARSHAN_DECL(foo)(const char* name, int arg1)
//{
// ssize_t ret;
// double tm1, tm2;
//
// /* The MAP_OR_FAIL macro attempts to obtain the address of the actual
// * underlying foo function call (__real_foo), in the case of LD_PRELOADing
// * the Darshan library. For statically linked executables, this macro is
// * just a NOP.
// */
// MAP_OR_FAIL(foo);
//
// /* In general, Darshan wrappers begin by calling the real version of the
// * given wrapper function. Timers are used to record the duration of this
// * operation. */
// tm1 = darshan_core_wtime();
// ret = __real_foo(name, arg1);
// tm2 = darshan_core_wtime();
//
// ABCXYZ_PRE_RECORD();
// /* Call macro for instrumenting data for foo function calls. */
// ABCXYZ_RECORD_FOO(ret, name, arg1, tm1, tm2);
// ABCXYZ_POST_RECORD();
//
// return(ret);
//}
/* Use/nest namespaces as required to match original.
*/
//namespace mynamespace {
void X::fn1(const char* name, int arg1)
{
ssize_t ret;
// void X::fn1(const char* name, int arg1);
// _ZN1X3fn1EPKci
bool ret;
double tm1, tm2;
/* The MAP_OR_FAIL macro attempts to obtain the address of the actual
* underlying foo function call (__real_foo), in the case of LD_PRELOADing
* the Darshan library. For statically linked executables, this macro is
* just a NOP.
*/
MAP_OR_FAIL(foo);
// REMAP: compare to Darshan's MAP_OR_FAIL(name)
typedef bool (X::*fn1)(const char* name, int arg1);
static fn1 _realMethod = NULL;
if (_realMethod == NULL) {
void *tmpPtr = dlsym(RTLD_NEXT, "_ZN1X3fn1EPKci");
memcpy(&_realMethod, &tmpPtr, sizeof(void *));
}
/* In general, Darshan wrappers begin by calling the real version of the
* given wrapper function. Timers are used to record the duration of this
* operation. */
tm1 = darshan_core_wtime();
ret = __real_foo(name, arg1);
ret = (this->*_realMethod)(name, arg1);
tm2 = darshan_core_wtime();
// LOG
ABCXYZ_PRE_RECORD();
/* Call macro for instrumenting data for foo function calls. */
ABCXYZ_RECORD_FOO(ret, name, arg1, tm1, tm2);
ABCXYZ_RECORD_FOO(ret, name, -1, tm1, tm2);
ABCXYZ_POST_RECORD();
return(ret);
//return(ret);
}
//} // mynamespace end
/**********************************************************
* Internal functions for manipulating ABCXYZ module state *
**********************************************************/
......@@ -267,7 +332,7 @@ static struct abcxyz_record_ref *abcxyz_track_new_record(
NULL);
if(!record_p)
{
{
/* if registration fails, delete record reference and return */
darshan_delete_record_ref(&(abcxyz_runtime->rec_id_hash),
&rec_id, sizeof(darshan_record_id));
......
......@@ -661,7 +661,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
......@@ -735,7 +734,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
......@@ -988,15 +986,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
......@@ -1134,7 +1123,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
......@@ -1287,7 +1276,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment