Skip to content

Commit

Permalink
Add support for flux
Browse files Browse the repository at this point in the history
Add configure check X_AC_FLUX based on X_AC_LSF.

When the user does not specify a location, use pkg-config to determine
whether flux-core is installed and where.  Otherwise look for
flux-core.h and attempt to link to flux_open().

At runtime, look in the environment for FLUX_JOB_ID.

Determine whether to query the current flux instance or the parent
for the expiration time of the allocation.  Note that this
currently works by checking the environment for FLUX_KVS_NAMESPACE,
but flux will provide a more explicit mechanism in the future.
See flux-framework/flux-core#3817
for details and status.

Fetch the expiration time and calculate remaining time based on that.

Support get_rank() by looking in the environment for FLUX_TASK_RANK.
  • Loading branch information
ofaaland committed Jan 23, 2022
1 parent 75f3f44 commit d00b393
Show file tree
Hide file tree
Showing 8 changed files with 280 additions and 3 deletions.
83 changes: 83 additions & 0 deletions config/x_ac_flux.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
##*****************************************************************************
# SYNOPSIS:
# X_AC_FLUX()
#
# DESCRIPTION:
# Check pkg-configfor a FLUX installation,
# updating CPPFLAGS and LDFLAGS as necessary.
#
# WARNINGS:
# This macro must be placed after AC_PROG_CC and before AC_PROG_LIBTOOL.
##*****************************************************************************

# --with-flux=no no test for flux
# --with-flux=check look in default location
# --with-flux look in default location; error on fail
# --with-flux=yes look in default location; error on fail
# --with-flux=<path> look under <path>; error on fail

AC_DEFUN([X_AC_FLUX], [
AC_ARG_WITH(
[flux],
AS_HELP_STRING(--with-flux=PATH,Specify path to flux installation),
[],
[with_flux=check])
AS_IF([test x$with_flux != xno],[
found_flux=no
# Check for FLUX library in the default location.
AS_IF([test x$with_flux = xyes -o x$with_flux = xcheck],[
PKG_CHECK_MODULES([FLUX], [flux-core], [found_flux=yes], [found_flux=no])
])
AS_IF([test x$with_flux != xyes -a x$with_flux != xcheck -a x$found_flux = xno ],[
AC_CACHE_CHECK([for FLUX include directory],
[x_ac_cv_flux_includedir],
[FLUX_INCLUDEDIR="$with_flux/include/"
AS_IF([test -f "$FLUX_INCLUDEDIR/flux/core.h"],
[x_ac_cv_flux_includedir="$FLUX_INCLUDEDIR"],
[x_ac_cv_flux_includedir=no])
])
AC_CACHE_CHECK([for FLUX library directory],
[x_ac_cv_flux_libdir],
[x_ac_cv_flux_libdir=no
_x_ac_flux_libs_save=$LIBS
FLUX_LIBDIR="$with_flux/lib/"
AS_IF([test -d "$FLUX_LIBDIR"],[
LIBS="-L$FLUX_LIBDIR -lflux-core $LIBS"
CFLAGS="-I $x_ac_cv_flux_includedir"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <flux/core.h>], [flux_open(NULL,0);])],
[x_ac_cv_flux_libdir=$FLUX_LIBDIR]
)
])
LIBS="$_x_ac_flux_libs_save"
])
AS_IF([test x$x_ac_cv_flux_includedir != xno -a x$x_ac_cv_flux_libdir != xno],[
found_flux=yes
FLUX_CFLAGS="-I$FLUX_INCLUDEDIR"
FLUX_LIBS="-L$FLUX_LIBDIR"
],[
found_flux=no
FLUX_CFLAGS=""
FLUX_LIBS=""
])
])
AS_IF([test x$found_flux != xyes],[
AS_IF([test x$with_flux != xcheck],
[AC_MSG_ERROR([FLUX not found!])],
[AC_MSG_WARN([not building support for FLUX])])
], [
FLUX_LIBADD="-lflux-core"
AC_SUBST(FLUX_LIBADD)
AC_SUBST(FLUX_CFLAGS)
AC_SUBST(FLUX_LIBS)
AC_DEFINE([HAVE_LIBFLUX], 1, [Define to 1 if you have the `flux-core' library (-lflux-core).])
])
])
AM_CONDITIONAL(WITH_FLUX, test "x$found_flux" = xyes)
])
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ AM_MAINTAINER_MODE
AC_PROG_CC
AC_PROG_LIBTOOL

# Check for pkg-config support
PKG_PROG_PKG_CONFIG

# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE

Expand All @@ -42,6 +45,7 @@ X_AC_SLURM
X_AC_LCRM
X_AC_MOAB
X_AC_LSF
X_AC_FLUX

aix_64bit_mode=no
using_aix=no
Expand All @@ -67,6 +71,7 @@ AC_CONFIG_FILES([libyogrt.spec
doc/man/Makefile
src/Makefile
src/none/Makefile
src/flux/Makefile
src/slurm/Makefile
src/lcrm/Makefile
src/moab/Makefile
Expand Down
2 changes: 1 addition & 1 deletion doc/man/libyogrt.7
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ libyogrt provides a simple API by which a parallel application can
determine the amount of time remaining before it will be terminated.
libyogrt is designed as a layer above the system scheduler, allowing an
application compiled against libyogrt to query its remaining time
with Moab, SLURM, LCRM, and possibly other systems in the future. The
with Flux, Moab, SLURM, LCRM, and possibly other systems in the future. The
system administrator installs the correct version of libyogrt on each
system to match that system's resource manager, so no effort on the part
of the application programmer is required to move between systems
Expand Down
5 changes: 5 additions & 0 deletions libyogrt.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# Declare rpmbuild --with/--without parameters
%bcond_without slurm
%bcond_without flux
%bcond_with lsf

Summary: @PACKAGE_NAME@
Expand All @@ -14,6 +15,10 @@ URL: @PACKAGE_URL@
Packager: Christopher J. Morrone <[email protected]>
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
%if %{with flux}
BuildRequires: flux-core
Requires: flux-core
%endif
%if %{with slurm}
BuildRequires: slurm slurm-devel
Requires: slurm
Expand Down
5 changes: 4 additions & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
if WITH_FLUX
FLUX_DIR = flux
endif
if WITH_SLURM
SLURM_DIR = slurm
endif
Expand All @@ -14,7 +17,7 @@ if WITH_LSF
LSF_DIR = lsf
endif

SUBDIRS = none $(SLURM_DIR) $(LCRM_DIR) $(MOAB_DIR) $(AIXSLURM_DIR) $(LSF_DIR)
SUBDIRS = none $(FLUX_DIR) $(SLURM_DIR) $(LCRM_DIR) $(MOAB_DIR) $(AIXSLURM_DIR) $(LSF_DIR)

lib_LTLIBRARIES = libyogrt.la
libyogrt_la_SOURCES = yogrt.c
Expand Down
11 changes: 11 additions & 0 deletions src/flux/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
AM_CPPFLAGS = -I$(top_srcdir)/src

sublibdir = $(libdir)/libyogrt
sublib_LTLIBRARIES = libyogrt-flux.la
libyogrt_flux_la_SOURCES = internal.c
libyogrt_flux_la_LIBADD = $(FLUX_LIBADD)
libyogrt_flux_la_CPPFLAGS = $(AM_CPPFLAGS) $(FLUX_CFLAGS)
libyogrt_flux_la_LDFLAGS = $(FLUX_LIBS) \
-no-undefined \
-export-symbols-regex "^internal_.*" \
-version-info $(LIBYOGRT_LT_CURRENT):$(LIBYOGRT_LT_REVISION):$(LIBYOGRT_LT_AGE)
170 changes: 170 additions & 0 deletions src/flux/internal.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/***************************************************************************
* Copyright (C) 2017, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Olaf Faaland <[email protected]>
* UCRL-CODE-235649. All rights reserved.
*
* This file is part of libyogrt.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
***************************************************************************/


#include <stdio.h>
#include <jansson.h>
#include <time.h>
#include <limits.h>
#include <flux/core.h>

#include "internal_yogrt.h"

#define BOGUS_TIME -1

int jobid_valid = 0;
int verbosity = 0;

static flux_jobid_t jobid = 0;

int internal_init(int verb)
{
char *jobid_str;

verbosity = verb;
jobid_valid = 0;

if ((jobid_str = getenv("FLUX_JOB_ID")) == NULL) {
error("ERROR: FLUX_JOB_ID is not set."
" Remaining time will be a bogus value.\n");
return jobid_valid;
}

if (flux_job_id_parse(jobid_str, &jobid) < 0) {
error("ERROR: Unable to parse FLUX_JOB_ID %s."
" Remaining time will be a bogus value.\n", jobid_str);
return jobid_valid;
}

jobid_valid = 1;

return jobid_valid;
}

char *internal_backend_name(void)
{
return "FLUX";
}

static int get_job_expiration(flux_jobid_t id, long int *expiration)
{
flux_t *h = NULL;
flux_t *child_handle = NULL;
flux_future_t *f;
json_t *job;
json_t *value;
double exp;
const char *uri = NULL;
int rc = -1;

if (!(h = flux_open(NULL, 0))) {
error("ERROR: flux_open() failed with errno %d\n", errno);
goto out;
}

/*
* Determine whether to ask our parent or not
* See https://github.com/flux-framework/flux-core/issues/3817
*/

if (!getenv("FLUX_KVS_NAMESPACE")) {
uri = flux_attr_get(h, "parent-uri");
if (!uri) {
error("ERROR: no FLUX_KVS_NAMESPACE and flux_attr_get failed with "
"errno %d\n", errno);
goto out;
}

child_handle = h;
h = flux_open(uri, 0);
if (!h) {
printf("flux_open with parent-uri %s failed with errno %d\n", uri,
errno);
goto out;
}
}

if (!(f = flux_job_list_id(h, jobid, "[\"expiration\"]"))) {
error("ERROR: flux_job_list failed with errno %d.\n", errno);
goto out;
}

if (flux_rpc_get_unpack (f, "{s:{s:f}}", "job", "expiration", &exp) < 0) {
error("ERROR: flux_rpc_get_unpack failed with errno %d.\n", errno);
goto out;
}

*expiration = (long int) exp;
rc = 0;

out:
flux_future_destroy(f);
flux_close(h);
flux_close(child_handle);

return rc;
}

int internal_get_rem_time(time_t now, time_t last_update, int cached)
{
long int expiration;
int remaining_sec = BOGUS_TIME;

if (! jobid_valid) {
error("FLUX: No valid jobid to lookup!\n");
return BOGUS_TIME;
}

if (get_job_expiration(jobid, &expiration)) {
error("FLUX: get_job_expiration failed\n");
goto out;
}

remaining_sec = (int) (expiration - time(NULL));
debug("flux remaining seconds is %ld\n", remaining_sec);

out:
return remaining_sec;
}

int internal_get_rank(void)
{
char *rank_str;

rank_str = getenv("FLUX_TASK_RANK");

if (rank_str) {
return atoi(rank_str);
} else {
return 0;
}
}

int internal_fudge(void)
{
return 0;
}

/*
* vim: tabstop=8 shiftwidth=8 smartindent:
*/
2 changes: 1 addition & 1 deletion yogrt.conf.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Configuration file for libyogrt
#
# Possible backend settings are: none, slurm, lcrm, moab
# Possible backend settings are: none, slurm, lcrm, moab, flux
#
backend=none

0 comments on commit d00b393

Please sign in to comment.