Update the RAS and PLM components for Windows.
These won't suffer another platforms but only windows. This commit was SVN r17686.
Этот коммит содержится в:
родитель
55c727cea4
Коммит
ae41b5418b
56
orte/mca/plm/ccp/Makefile.am
Обычный файл
56
orte/mca/plm/ccp/Makefile.am
Обычный файл
@ -0,0 +1,56 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
AM_CPPFLAGS = $(plm_ccp_CPPFLAGS)
|
||||||
|
|
||||||
|
dist_pkgdata_DATA = help-plm-ccp.txt
|
||||||
|
|
||||||
|
sources = \
|
||||||
|
plm_ccp.h \
|
||||||
|
plm_ccp_component.c \
|
||||||
|
plm_ccp_module.c
|
||||||
|
|
||||||
|
# Make the output library in this directory, and name it either
|
||||||
|
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
|
||||||
|
# (for static builds).
|
||||||
|
|
||||||
|
if OMPI_BUILD_plm_ccp_DSO
|
||||||
|
lib =
|
||||||
|
lib_sources =
|
||||||
|
component = mca_plm_ccp.la
|
||||||
|
component_sources = $(sources)
|
||||||
|
else
|
||||||
|
lib = libmca_plm_ccp.la
|
||||||
|
lib_sources = $(sources)
|
||||||
|
component =
|
||||||
|
component_sources =
|
||||||
|
endif
|
||||||
|
|
||||||
|
mcacomponentdir = $(pkglibdir)
|
||||||
|
mcacomponent_LTLIBRARIES = $(component)
|
||||||
|
mca_plm_ccp_la_SOURCES = $(component_sources)
|
||||||
|
mca_plm_ccp_la_LDFLAGS = -module -avoid-version $(plm_ccp_LDFLAGS)
|
||||||
|
mca_plm_ccp_la_LIBADD = \
|
||||||
|
$(plm_ccp_LIBS) \
|
||||||
|
$(top_ompi_builddir)/orte/libopen-rte.la \
|
||||||
|
$(top_ompi_builddir)/opal/libopen-pal.la
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = $(lib)
|
||||||
|
libmca_plm_ccp_la_SOURCES = $(lib_sources)
|
||||||
|
libmca_plm_ccp_la_LDFLAGS = -module -avoid-version $(plm_ccp_LDFLAGS)
|
||||||
|
libmca_plm_ccp_la_LIBADD = $(plm_ccp_LIBS)
|
Двоичные данные
orte/mca/plm/ccp/ccpapi.tlb
Обычный файл
Двоичные данные
orte/mca/plm/ccp/ccpapi.tlb
Обычный файл
Двоичный файл не отображается.
26
orte/mca/plm/ccp/configure.m4
Обычный файл
26
orte/mca/plm/ccp/configure.m4
Обычный файл
@ -0,0 +1,26 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
# MCA_plm_ccp_CONFIG([action-if-found], [action-if-not-found])
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
AC_DEFUN([MCA_plm_ccp_CONFIG],[
|
||||||
|
plm_ccp_good=0
|
||||||
|
# CCP does never exist under Unix
|
||||||
|
[$2]
|
||||||
|
])dnl
|
22
orte/mca/plm/ccp/configure.params
Обычный файл
22
orte/mca/plm/ccp/configure.params
Обычный файл
@ -0,0 +1,22 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# Copyright (c) 2007 Los Alamos National Security, LLC. All rights
|
||||||
|
# reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
PARAM_CONFIG_FILES="Makefile"
|
57
orte/mca/plm/ccp/help-pls-ccp.txt
Обычный файл
57
orte/mca/plm/ccp/help-pls-ccp.txt
Обычный файл
@ -0,0 +1,57 @@
|
|||||||
|
# -*- text -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
[ccp-bad-launchid]
|
||||||
|
The CCP process starter cannot spawn the specified
|
||||||
|
application on a remote node due to an invalid launch_id.
|
||||||
|
|
||||||
|
Node name: %s
|
||||||
|
Launch id: %d
|
||||||
|
|
||||||
|
This is most likely due to use of the "--hostfile" option to the
|
||||||
|
command line. At this time, Open MPI/OpenRTE do not support this
|
||||||
|
method of operation. Instead, the system expects to directly read
|
||||||
|
information regarding the nodes to be used from the environment.
|
||||||
|
|
||||||
|
Removing "--hostfile" from the command line will likely allow the
|
||||||
|
application to be launched. This will be fixed in a future release
|
||||||
|
to support the use of "--hostfile" on the command line.
|
||||||
|
#
|
||||||
|
[multiple-prefixes]
|
||||||
|
Multiple different --prefix options were specified to mpirun for the
|
||||||
|
same node. This is a fatal error for the ccp process
|
||||||
|
starter in Open MPI.
|
||||||
|
|
||||||
|
The first two prefix values supplied for node %s were:
|
||||||
|
%s
|
||||||
|
and %s
|
||||||
|
#
|
||||||
|
[ccp-spawn-failed]
|
||||||
|
The CCP process starter failed to spawn a daemon (orted)
|
||||||
|
on a remote node.
|
||||||
|
|
||||||
|
Command line: %s
|
||||||
|
Node name: %s
|
||||||
|
Launch id: %d
|
||||||
|
|
||||||
|
If you do not understand this error mesage, please try the following:
|
||||||
|
|
||||||
|
1. Ensure that the executable "orted" is in your PATH
|
||||||
|
2. Use the --prefix option to indicate where we can
|
||||||
|
find that executable
|
||||||
|
3. Talk to your local system administrator
|
45
orte/mca/plm/ccp/plm_ccp.h
Обычный файл
45
orte/mca/plm/ccp/plm_ccp.h
Обычный файл
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ORTE_plm_CCP_EXPORT_H
|
||||||
|
#define ORTE_plm_CCP_EXPORT_H
|
||||||
|
|
||||||
|
#include "orte_config.h"
|
||||||
|
|
||||||
|
#include "opal/mca/mca.h"
|
||||||
|
#include "orte/mca/plm/plm.h"
|
||||||
|
|
||||||
|
#if defined(c_plusplus) || defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct orte_plm_ccp_component_t {
|
||||||
|
orte_plm_base_component_t super;
|
||||||
|
int priority;
|
||||||
|
int debug;
|
||||||
|
int verbose;
|
||||||
|
bool want_path_check;
|
||||||
|
char *orted;
|
||||||
|
char **checked_paths;
|
||||||
|
bool timing;
|
||||||
|
};
|
||||||
|
typedef struct orte_plm_ccp_component_t orte_plm_ccp_component_t;
|
||||||
|
/* Globally exported variables */
|
||||||
|
ORTE_DECLSPEC extern orte_plm_ccp_component_t mca_plm_ccp_component;
|
||||||
|
extern orte_plm_base_module_t orte_plm_ccp_module;
|
||||||
|
|
||||||
|
#if defined(c_plusplus) || defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ORTE_plm_CCP_EXPORT_H */
|
139
orte/mca/plm/ccp/plm_ccp_component.c
Обычный файл
139
orte/mca/plm/ccp/plm_ccp_component.c
Обычный файл
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "orte_config.h"
|
||||||
|
|
||||||
|
#include "opal/mca/base/mca_base_param.h"
|
||||||
|
#include "opal/util/output.h"
|
||||||
|
#include "opal/util/argv.h"
|
||||||
|
#include "orte/constants.h"
|
||||||
|
|
||||||
|
#include "orte/util/proc_info.h"
|
||||||
|
#include "orte/mca/errmgr/errmgr.h"
|
||||||
|
|
||||||
|
#include "orte/mca/plm/plm.h"
|
||||||
|
#include "orte/mca/plm/base/base.h"
|
||||||
|
#include "orte/mca/plm/base/plm_private.h"
|
||||||
|
#include "plm_ccp.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public string showing the plm ompi_ccp component version number
|
||||||
|
*/
|
||||||
|
const char *mca_plm_ccp_component_version_string =
|
||||||
|
"Open MPI ccp plm MCA component version " ORTE_VERSION;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local function
|
||||||
|
*/
|
||||||
|
static int plm_ccp_open(void);
|
||||||
|
static int plm_ccp_close(void);
|
||||||
|
static orte_plm_base_module_t *plm_ccp_init(int *priority);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instantiate the public struct with all of our public information
|
||||||
|
* and pointers to our public functions in it
|
||||||
|
*/
|
||||||
|
|
||||||
|
orte_plm_ccp_component_t mca_plm_ccp_component = {
|
||||||
|
{
|
||||||
|
/* First, the mca_component_t struct containing meta information
|
||||||
|
about the component itself */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Indicate that we are a plm v1.3.0 component (which also
|
||||||
|
implies a specific MCA version) */
|
||||||
|
ORTE_PLM_BASE_VERSION_1_0_0,
|
||||||
|
|
||||||
|
/* Component name and version */
|
||||||
|
"ccp",
|
||||||
|
ORTE_MAJOR_VERSION,
|
||||||
|
ORTE_MINOR_VERSION,
|
||||||
|
ORTE_RELEASE_VERSION,
|
||||||
|
|
||||||
|
/* Component open and close functions */
|
||||||
|
plm_ccp_open,
|
||||||
|
plm_ccp_close,
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Next the MCA v1.0.0 component meta data */
|
||||||
|
{
|
||||||
|
/* The component is checkpoint ready */
|
||||||
|
MCA_BASE_METADATA_PARAM_CHECKPOINT
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Initialization / querying functions */
|
||||||
|
plm_ccp_init
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_open(void)
|
||||||
|
{
|
||||||
|
int tmp, value;
|
||||||
|
mca_base_component_t *comp = &mca_plm_ccp_component.super.plm_version;
|
||||||
|
|
||||||
|
mca_base_param_reg_int(comp, "debug", "Enable debugging of the CCP plm",
|
||||||
|
false, false, 0, &mca_plm_ccp_component.debug);
|
||||||
|
mca_base_param_reg_int(comp, "verbose", "Enable verbose output of the ccp plm",
|
||||||
|
false, false, 0, &mca_plm_ccp_component.verbose);
|
||||||
|
|
||||||
|
mca_base_param_reg_int(comp, "priority", "Default selection priority",
|
||||||
|
false, false, 75, &mca_plm_ccp_component.priority);
|
||||||
|
|
||||||
|
mca_base_param_reg_string(comp, "orted",
|
||||||
|
"Command to use to start proxy orted",
|
||||||
|
false, false, "orted",
|
||||||
|
&mca_plm_ccp_component.orted);
|
||||||
|
mca_base_param_reg_int(comp, "want_path_check",
|
||||||
|
"Whether the launching process should check for the plm_ccp_orted executable in the PATH before launching (the CCP API does not give an indication of failure; this is a somewhat-lame workaround; non-zero values enable this check)",
|
||||||
|
false, false, (int) true, &tmp);
|
||||||
|
mca_plm_ccp_component.want_path_check = OPAL_INT_TO_BOOL(tmp);
|
||||||
|
|
||||||
|
tmp = mca_base_param_reg_int_name("orte", "timing",
|
||||||
|
"Request that critical timing loops be measured",
|
||||||
|
false, false, 0, &value);
|
||||||
|
if (value != 0) {
|
||||||
|
mca_plm_ccp_component.timing = true;
|
||||||
|
} else {
|
||||||
|
mca_plm_ccp_component.timing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
mca_plm_ccp_component.checked_paths = NULL;
|
||||||
|
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_close(void)
|
||||||
|
{
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static orte_plm_base_module_t *plm_ccp_init(int *priority)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* if we are NOT an HNP, then don't select us */
|
||||||
|
if (!orte_process_info.hnp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*priority = mca_plm_ccp_component.priority;
|
||||||
|
return &orte_plm_ccp_module;
|
||||||
|
}
|
739
orte/mca/plm/ccp/plm_ccp_module.c
Обычный файл
739
orte/mca/plm/ccp/plm_ccp_module.c
Обычный файл
@ -0,0 +1,739 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2007 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "orte_config.h"
|
||||||
|
#include "orte/constants.h"
|
||||||
|
#include "orte/types.h"
|
||||||
|
|
||||||
|
#if HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#include <signal.h>
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_STAT_H
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_WAIT_H
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SCHED_H
|
||||||
|
#include <sched.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_TIME_H
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
#include <errno.h>
|
||||||
|
#include <comutil.h>
|
||||||
|
|
||||||
|
#include "opal/mca/installdirs/installdirs.h"
|
||||||
|
#include "opal/threads/condition.h"
|
||||||
|
#include "opal/event/event.h"
|
||||||
|
#include "opal/util/argv.h"
|
||||||
|
#include "opal/util/output.h"
|
||||||
|
#include "opal/util/opal_environ.h"
|
||||||
|
#include "opal/util/show_help.h"
|
||||||
|
#include "opal/util/path.h"
|
||||||
|
#include "opal/util/basename.h"
|
||||||
|
#include "opal/mca/base/mca_base_param.h"
|
||||||
|
#include "opal/runtime/opal_progress.h"
|
||||||
|
|
||||||
|
#include "orte/util/name_fns.h"
|
||||||
|
#include "orte/runtime/orte_globals.h"
|
||||||
|
#include "orte/runtime/orte_wait.h"
|
||||||
|
#include "orte/mca/errmgr/errmgr.h"
|
||||||
|
#include "orte/mca/rmaps/rmaps.h"
|
||||||
|
|
||||||
|
#include "orte/mca/plm/plm.h"
|
||||||
|
#include "orte/mca/plm/base/plm_private.h"
|
||||||
|
#include "plm_ccp.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Import the Windows CCP API. */
|
||||||
|
#import "ccpapi.tlb" named_guids no_namespace raw_interfaces_only \
|
||||||
|
rename("SetEnvironmentVariable","SetEnvVar") \
|
||||||
|
rename("GetJob", "GetSingleJob") \
|
||||||
|
rename("AddJob", "AddSingleJob")
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions
|
||||||
|
*/
|
||||||
|
static int plm_ccp_init(void);
|
||||||
|
static int plm_ccp_launch_job(orte_job_t *jdata);
|
||||||
|
static int plm_ccp_terminate_job(orte_jobid_t jobid);
|
||||||
|
static int plm_ccp_terminate_orteds();
|
||||||
|
static int plm_ccp_signal_job(orte_jobid_t jobid, int32_t signal);
|
||||||
|
static int plm_ccp_finalize(void);
|
||||||
|
|
||||||
|
static int plm_ccp_connect(ICluster* pCluster);
|
||||||
|
static int plm_ccp_disconnect(void);
|
||||||
|
|
||||||
|
void get_cluster_message(ICluster* pCluster);
|
||||||
|
static char *plm_ccp_commandline(char *node_name, int argc, char **argv);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global variable
|
||||||
|
*/
|
||||||
|
orte_plm_base_module_t orte_plm_ccp_module = {
|
||||||
|
plm_ccp_init,
|
||||||
|
orte_plm_base_set_hnp_name,
|
||||||
|
plm_ccp_launch_job,
|
||||||
|
plm_ccp_terminate_job,
|
||||||
|
plm_ccp_terminate_orteds,
|
||||||
|
plm_ccp_signal_job,
|
||||||
|
plm_ccp_finalize
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init the module
|
||||||
|
*/
|
||||||
|
static int plm_ccp_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_comm_start())) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* When working in this function, ALWAYS jump to "cleanup" if
|
||||||
|
* you encounter an error so that orterun will be woken up and
|
||||||
|
* the job can cleanly terminate
|
||||||
|
*/
|
||||||
|
static int plm_ccp_launch_job(orte_job_t *jdata)
|
||||||
|
{
|
||||||
|
orte_app_context_t **apps;
|
||||||
|
orte_node_t **nodes;
|
||||||
|
orte_std_cntr_t launched = 0, i;
|
||||||
|
int local_err;
|
||||||
|
|
||||||
|
orte_job_map_t *map = NULL;
|
||||||
|
opal_list_item_t *item;
|
||||||
|
size_t num_nodes;
|
||||||
|
int argc, rc, node_name_index, proc_vpid_index, proc_name_index;
|
||||||
|
char *param, **env = NULL, *var, **argv = NULL;
|
||||||
|
bool connected = false;
|
||||||
|
char *bin_base = NULL, *lib_base = NULL, command_line[300];
|
||||||
|
|
||||||
|
struct timeval completionstart, completionstop, launchstart, launchstop;
|
||||||
|
struct timeval jobstart, jobstop;
|
||||||
|
int maxtime=0, mintime=99999999, maxiter = 0, miniter = 0, deltat;
|
||||||
|
float avgtime=0.0;
|
||||||
|
bool failed_launch = true;
|
||||||
|
mode_t current_umask;
|
||||||
|
IClusterEnumerable* pNodesCollection = NULL;
|
||||||
|
IEnumVARIANT* pNodes = NULL;
|
||||||
|
VARIANT v;
|
||||||
|
|
||||||
|
INode* pNode = NULL;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
ICluster* pCluster = NULL;
|
||||||
|
IJob* pJob = NULL;
|
||||||
|
long job_id, num_processors = 0, idle_processors = 0;
|
||||||
|
IClusterCounter* pClusterCounter = NULL;
|
||||||
|
ITask* pTask = NULL;
|
||||||
|
JobPriority job_priority = JobPriority_Normal;
|
||||||
|
|
||||||
|
/* check for timing request - get start time if so */
|
||||||
|
if (orte_timing) {
|
||||||
|
if (0 != gettimeofday(&jobstart, NULL)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: could not obtain job start time"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if this jobid isn't invalid, then it already
|
||||||
|
* has been setup, so skip the setup actions
|
||||||
|
*/
|
||||||
|
if (ORTE_JOBID_INVALID != jdata->jobid) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: launching job %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
ORTE_JOBID_PRINT(jdata->jobid)));
|
||||||
|
goto GETMAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* create a jobid for this job */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_create_jobid(&jdata->jobid))) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: launching job %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
ORTE_JOBID_PRINT(jdata->jobid)));
|
||||||
|
|
||||||
|
/* setup the job */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_setup_job(jdata))) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
GETMAP:
|
||||||
|
/* Get the map for this job */
|
||||||
|
if (NULL == (map = orte_rmaps.get_job_map(jdata->jobid))) {
|
||||||
|
ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND);
|
||||||
|
rc = ORTE_ERR_NOT_FOUND;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
apps = (orte_app_context_t**)jdata->apps->addr;
|
||||||
|
nodes = (orte_node_t**)map->nodes->addr;
|
||||||
|
|
||||||
|
if (0 == map->num_new_daemons) {
|
||||||
|
/* have all the daemons we need - launch app */
|
||||||
|
goto launch_apps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the daemon command (as specified by user) */
|
||||||
|
argv = opal_argv_split(mca_plm_ccp_component.orted, ' ');
|
||||||
|
argc = opal_argv_count(argv);
|
||||||
|
|
||||||
|
opal_argv_append(&argc, &argv, "--no-daemonize");
|
||||||
|
|
||||||
|
/* Add basic orted command line options */
|
||||||
|
orte_plm_base_orted_append_basic_args(&argc, &argv, "env",
|
||||||
|
&proc_vpid_index,
|
||||||
|
&node_name_index);
|
||||||
|
|
||||||
|
if (0 < opal_output_get_verbosity(orte_plm_globals.output)) {
|
||||||
|
param = opal_argv_join(argv, ' ');
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: final top-level argv:\n\t%s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
(NULL == param) ? "NULL" : param));
|
||||||
|
if (NULL != param) free(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CCP is not thread safe. Use the apartment model. */
|
||||||
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
/* Create the Cluster object. */
|
||||||
|
hr = CoCreateInstance( __uuidof(Cluster),
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
__uuidof(ICluster),
|
||||||
|
reinterpret_cast<void **> (&pCluster) );
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
opal_output(orte_plm_globals.output,
|
||||||
|
"plm:ccp: failed to create cluster object!");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the head node. */
|
||||||
|
rc = plm_ccp_connect(pCluster);
|
||||||
|
if (ORTE_SUCCESS != rc) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
connected = true;
|
||||||
|
|
||||||
|
hr = pCluster->CreateJob(&pJob);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
opal_output(orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to create cluster object!");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
/* Figure out the basenames for the libdir and bindir. There is a
|
||||||
|
lengthy comment about this in plm_rsh_module.c explaining all
|
||||||
|
the rationale for how / why we're doing this. */
|
||||||
|
lib_base = opal_basename(opal_install_dirs.libdir);
|
||||||
|
bin_base = opal_basename(opal_install_dirs.bindir);
|
||||||
|
|
||||||
|
/* setup environment */
|
||||||
|
env = opal_argv_copy(environ);
|
||||||
|
|
||||||
|
/* add our umask -- see big note in orted.c */
|
||||||
|
current_umask = umask(0);
|
||||||
|
umask(current_umask);
|
||||||
|
asprintf(&var, "0%o", current_umask);
|
||||||
|
opal_setenv("ORTE_DAEMON_UMASK_VALUE", var, true, &env);
|
||||||
|
free(var);
|
||||||
|
|
||||||
|
/* If we have a prefix, then modify the PATH and
|
||||||
|
LD_LIBRARY_PATH environment variables. We only allow
|
||||||
|
a single prefix to be specified. Since there will
|
||||||
|
always be at least one app_context, we take it from
|
||||||
|
there
|
||||||
|
*/
|
||||||
|
if (NULL != apps[0]->prefix_dir) {
|
||||||
|
char *newenv;
|
||||||
|
|
||||||
|
for (i = 0; NULL != env && NULL != env[i]; ++i) {
|
||||||
|
/* Reset PATH */
|
||||||
|
if (0 == strncmp("PATH=", env[i], 5)) {
|
||||||
|
asprintf(&newenv, "%s/%s:%s",
|
||||||
|
apps[0]->prefix_dir, bin_base, env[i] + 5);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: resetting PATH: %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
newenv));
|
||||||
|
opal_setenv("PATH", newenv, true, &env);
|
||||||
|
free(newenv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset LD_LIBRARY_PATH */
|
||||||
|
else if (0 == strncmp("LD_LIBRARY_PATH=", env[i], 16)) {
|
||||||
|
asprintf(&newenv, "%s/%s:%s",
|
||||||
|
apps[0]->prefix_dir, lib_base, env[i] + 16);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: resetting LD_LIBRARY_PATH: %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
newenv));
|
||||||
|
opal_setenv("LD_LIBRARY_PATH", newenv, true, &env);
|
||||||
|
free(newenv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This has already been done in RAS, but I have to do it again here.
|
||||||
|
* Because the node structure doesn't have num_processor member. */
|
||||||
|
|
||||||
|
/* Get the collection of nodes. */
|
||||||
|
hr = pCluster->get_ComputeNodes(&pNodesCollection);
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the enumerator used to iterate through the collection. */
|
||||||
|
hr = pNodesCollection->GetEnumerator(&pNodes);
|
||||||
|
|
||||||
|
VariantInit(&v);
|
||||||
|
|
||||||
|
/* Loop through the collection. */
|
||||||
|
while (hr = pNodes->Next(1, &v, NULL) == S_OK) {
|
||||||
|
v.pdispVal->QueryInterface(IID_INode, reinterpret_cast<void **> (&pNode));
|
||||||
|
|
||||||
|
/* Iterate through each of the nodes and check to sum up all the processors. */
|
||||||
|
for (i = 0; i < map->num_nodes; i++) {
|
||||||
|
orte_node_t* node = nodes[i];
|
||||||
|
char* vpid_string;
|
||||||
|
|
||||||
|
BSTR node_name;
|
||||||
|
hr = pNode->get_Name(&node_name);
|
||||||
|
|
||||||
|
if( 0 == strcmp(_com_util::ConvertBSTRToString(node_name), node->name)) {
|
||||||
|
/* Get available number of processors on required node. */
|
||||||
|
hr = pNode->get_NumberOfIdleProcessors(&idle_processors);
|
||||||
|
num_processors += idle_processors;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pJob->put_MinimumNumberOfProcessors(num_processors);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to put min num of processors!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pJob->put_MaximumNumberOfProcessors(num_processors);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to put max num of processors!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pJob->put_Priority(job_priority);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to set proiority!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pJob->SetExtendedJobTerm(_bstr_t(L"extended terms"), _bstr_t(L"TermValue"));
|
||||||
|
|
||||||
|
/* Iterate through each of the nodes and spin
|
||||||
|
* up a daemon.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < map->num_nodes; i++) {
|
||||||
|
orte_node_t* node = nodes[i];
|
||||||
|
char* vpid_string;
|
||||||
|
|
||||||
|
/* if this daemon already exists, don't launch it! */
|
||||||
|
if (node->daemon_launched) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setup node name */
|
||||||
|
free(argv[node_name_index]);
|
||||||
|
argv[node_name_index] = strdup(node->name);
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: launching on node %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
node->name));
|
||||||
|
|
||||||
|
/* setup process name */
|
||||||
|
rc = orte_util_convert_vpid_to_string(&vpid_string, nodes[i]->daemon->name.vpid);
|
||||||
|
if (ORTE_SUCCESS != rc) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp: unable to get daemon vpid as string"));
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
free(argv[proc_vpid_index]);
|
||||||
|
argv[proc_vpid_index] = strdup(vpid_string);
|
||||||
|
free(vpid_string);
|
||||||
|
|
||||||
|
/* exec the daemon */
|
||||||
|
if (0 < opal_output_get_verbosity(orte_plm_globals.output)) {
|
||||||
|
param = opal_argv_join(argv, ' ');
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: executing:\n\t%s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
(NULL == param) ? "NULL" : param));
|
||||||
|
if (NULL != param) free(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for timing request - get start time if so */
|
||||||
|
if (orte_timing) {
|
||||||
|
if (0 != gettimeofday(&launchstart, NULL)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: could not obtain start time"));
|
||||||
|
launchstart.tv_sec = 0;
|
||||||
|
launchstart.tv_usec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Set terms for task. */
|
||||||
|
hr = pCluster->CreateTask(&pTask);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to create task object!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTask->put_MinimumNumberOfProcessors(node->num_procs);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to create task object!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTask->put_MaximumNumberOfProcessors(node->num_procs);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to create task object!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTask->put_RequiredNodes(_bstr_t(node->name));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to set required nodes!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare the command a little bit. */
|
||||||
|
strcpy_s(command_line, apps[0]->prefix_dir);
|
||||||
|
strcat(command_line,"\\");
|
||||||
|
{
|
||||||
|
char* ccp_cmdline = plm_ccp_commandline(node->name, argc, argv);
|
||||||
|
strcat(command_line, ccp_cmdline);
|
||||||
|
free(ccp_cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pTask->put_CommandLine(_bstr_t(command_line));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to put command line!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pTask->put_Stdout(_bstr_t(L"ompi_ccp_output.txt"));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to set stdout!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pTask->put_Stderr(_bstr_t(L"ompi_ccp_error.txt"));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to set stderr!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = pJob->AddTask(pTask);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:failed to add task!"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Allow some progress to occur */
|
||||||
|
opal_event_loop(OPAL_EVLOOP_NONBLOCK);
|
||||||
|
|
||||||
|
launched++;
|
||||||
|
|
||||||
|
pTask->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add job to the queue. */
|
||||||
|
hr = pCluster->QueueJob(pJob, NULL, NULL, VARIANT_TRUE, 0, &job_id);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"Added job %d to scheduling queue.\n", job_id));
|
||||||
|
}else {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp:launch: finished spawning orteds",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
||||||
|
|
||||||
|
/* wait for daemons to callback */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_daemon_callback(map->num_new_daemons))) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: daemon launch failed for job %s on error %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
ORTE_JOBID_PRINT(jdata->jobid), ORTE_ERROR_NAME(rc)));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
launch_apps:
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_launch_apps(jdata->jobid))) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp: launch of apps failed for job %s on error %s",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
|
||||||
|
ORTE_JOBID_PRINT(jdata->jobid), ORTE_ERROR_NAME(rc)));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we get here, then everything launched okay - record that fact */
|
||||||
|
failed_launch = false;
|
||||||
|
|
||||||
|
/* check for timing request - get stop time for launch completion and report */
|
||||||
|
if (orte_timing) {
|
||||||
|
if (0 != gettimeofday(&completionstop, NULL)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: could not obtain completion stop time"));
|
||||||
|
} else {
|
||||||
|
deltat = (launchstop.tv_sec - launchstart.tv_sec)*1000000 +
|
||||||
|
(launchstop.tv_usec - launchstart.tv_usec);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: launch completion required %d usec", deltat));
|
||||||
|
}
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: Launch statistics:"));
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: Average time to launch an orted: %f usec", avgtime));
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: Max time to launch an orted: %d usec at iter %d", maxtime, maxiter));
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: Min time to launch an orted: %d usec at iter %d", mintime, miniter));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (NULL != argv) {
|
||||||
|
opal_argv_free(argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != env) {
|
||||||
|
opal_argv_free(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connected) {
|
||||||
|
plm_ccp_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != lib_base) {
|
||||||
|
free(lib_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != bin_base) {
|
||||||
|
free(bin_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for failed launch - if so, force terminate */
|
||||||
|
if (failed_launch) {
|
||||||
|
orte_plm_base_launch_failed(jdata->jobid, false, -1, 0, ORTE_JOB_STATE_FAILED_TO_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for timing request - get stop time and process if so */
|
||||||
|
if (orte_timing) {
|
||||||
|
if (0 != gettimeofday(&jobstop, NULL)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: could not obtain stop time"));
|
||||||
|
} else {
|
||||||
|
deltat = (jobstop.tv_sec - jobstart.tv_sec)*1000000 +
|
||||||
|
(jobstop.tv_usec - jobstart.tv_usec);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm_ccp: launch of entire job required %d usec", deltat));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"%s plm:ccp:launch: finished",
|
||||||
|
ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_terminate_job(orte_jobid_t jobid)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* order all of the daemons to kill their local procs for this job */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_orted_kill_local_procs(jobid))) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terminate the orteds for a given job
|
||||||
|
*/
|
||||||
|
int plm_ccp_terminate_orteds()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* now tell them to die! */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_orted_exit())) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_signal_job(orte_jobid_t jobid, int32_t signal)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* order them to pass this signal to their local procs */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_orted_signal_local_procs(jobid, signal))) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free stuff
|
||||||
|
*/
|
||||||
|
static int plm_ccp_finalize(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* cleanup any pending recvs */
|
||||||
|
if (ORTE_SUCCESS != (rc = orte_plm_base_comm_stop())) {
|
||||||
|
ORTE_ERROR_LOG(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_connect(ICluster* pCluster)
|
||||||
|
{
|
||||||
|
size_t i, len;
|
||||||
|
char *cluster_head = NULL;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
/* Get the cluster head nodes name */
|
||||||
|
_dupenv_s(&cluster_head, &len, "LOGONSERVER");
|
||||||
|
|
||||||
|
if(cluster_head == NULL) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:allocate: connot find cluster head node!"));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of the beginning '//'. */
|
||||||
|
for( i = 0; i < len; i++){
|
||||||
|
cluster_head[i] = cluster_head[i+2];
|
||||||
|
cluster_head[i+2] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the cluster's head node */
|
||||||
|
hr = pCluster->Connect(_bstr_t(cluster_head));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"plm:ccp:allocate: connection failed!"));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"Connected to Cluster: %s. \n", cluster_head));
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int plm_ccp_disconnect(void)
|
||||||
|
{
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Generate the proper command line according to the env. */
|
||||||
|
static char *plm_ccp_commandline(char *node_name, int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *commandline;
|
||||||
|
int i, len = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < argc; i++ ) {
|
||||||
|
len += strlen(argv[i]) + 1;
|
||||||
|
}
|
||||||
|
commandline = (char*)malloc( len + 1);
|
||||||
|
memset(commandline, '\0', len+1);
|
||||||
|
|
||||||
|
for(i=0;i<argc;i++) {
|
||||||
|
|
||||||
|
/* Don't know why we use these -mca args, I have to ignore them
|
||||||
|
* otherwise the command line will be too long for CCP. */
|
||||||
|
if( 0 == strcmp("-mca", argv[i]) &&
|
||||||
|
(0 == strcmp("mca_base_param_file_path", argv[i+1]) ||
|
||||||
|
0 == strcmp("mca_base_param_file_path_force", argv[i+1])) ) {
|
||||||
|
i += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unknown option "--no-daemonize" for Windows? */
|
||||||
|
if ( 0 == strcmp("--no-daemonize", argv[i]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Append command args, and separate them with spaces. */
|
||||||
|
strcat(commandline, argv[i]);
|
||||||
|
|
||||||
|
commandline[strlen(commandline)]=' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
return commandline;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void get_cluster_message(ICluster* pCluster)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
BSTR message = NULL;
|
||||||
|
|
||||||
|
hr = pCluster->get_ErrorMessage(&message);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
_com_util::ConvertBSTRToString(message)));
|
||||||
|
SysFreeString(message);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_plm_globals.output,
|
||||||
|
"pCluster->get_ErrorMessage failed.\n"));
|
||||||
|
}
|
||||||
|
}
|
59
orte/mca/ras/ccp/Makefile.am
Обычный файл
59
orte/mca/ras/ccp/Makefile.am
Обычный файл
@ -0,0 +1,59 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
# Use the top-level Makefile.options
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AM_CPPFLAGS = $(ras_ccp_CPPFLAGS)
|
||||||
|
|
||||||
|
sources = \
|
||||||
|
ras_ccp.h \
|
||||||
|
ras_ccp_component.c \
|
||||||
|
ras_ccp_module.c
|
||||||
|
|
||||||
|
|
||||||
|
# Make the output library in this directory, and name it either
|
||||||
|
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
|
||||||
|
# (for static builds).
|
||||||
|
|
||||||
|
if OMPI_BUILD_ras_ccp_DSO
|
||||||
|
lib =
|
||||||
|
lib_sources =
|
||||||
|
component = mca_ras_ccp.la
|
||||||
|
component_sources = $(sources)
|
||||||
|
else
|
||||||
|
lib = libmca_ras_ccp.la
|
||||||
|
lib_sources = $(sources)
|
||||||
|
component =
|
||||||
|
component_sources =
|
||||||
|
endif
|
||||||
|
|
||||||
|
mcacomponentdir = $(pkglibdir)
|
||||||
|
mcacomponent_LTLIBRARIES = $(component)
|
||||||
|
mca_ras_ccp_la_SOURCES = $(component_sources)
|
||||||
|
mca_ras_ccp_la_LDFLAGS = -module -avoid-version $(ras_ccp_LDFLAGS)
|
||||||
|
mca_ras_ccp_la_LIBADD = \
|
||||||
|
$(ras_ccp_LIBS) \
|
||||||
|
$(top_ompi_builddir)/orte/libopen-rte.la \
|
||||||
|
$(top_ompi_builddir)/opal/libopen-pal.la
|
||||||
|
|
||||||
|
noinst_LTLIBRARIES = $(lib)
|
||||||
|
libmca_ras_ccp_la_SOURCES = $(lib_sources)
|
||||||
|
libmca_ras_ccp_la_LDFLAGS = -module -avoid-version $(ras_ccp_LDFLAGS)
|
||||||
|
libmca_ras_ccp_la_LIBADD = $(ras_ccp_LIBS)
|
Двоичные данные
orte/mca/ras/ccp/ccpapi.tlb
Обычный файл
Двоичные данные
orte/mca/ras/ccp/ccpapi.tlb
Обычный файл
Двоичный файл не отображается.
26
orte/mca/ras/ccp/configure.m4
Обычный файл
26
orte/mca/ras/ccp/configure.m4
Обычный файл
@ -0,0 +1,26 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
# MCA_ras_ccp_CONFIG([action-if-found], [action-if-not-found])
|
||||||
|
# -----------------------------------------------------------
|
||||||
|
AC_DEFUN([MCA_ras_ccp_CONFIG],[
|
||||||
|
ras_ccp_good=0
|
||||||
|
# CCP does never exist under Unix
|
||||||
|
[$2]
|
||||||
|
])dnl
|
22
orte/mca/ras/ccp/configure.params
Обычный файл
22
orte/mca/ras/ccp/configure.params
Обычный файл
@ -0,0 +1,22 @@
|
|||||||
|
# -*- shell-script -*-
|
||||||
|
#
|
||||||
|
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||||
|
# University Research and Technology
|
||||||
|
# Corporation. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
# of Tennessee Research Foundation. All rights
|
||||||
|
# reserved.
|
||||||
|
# Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
|
||||||
|
# University of Stuttgart. All rights reserved.
|
||||||
|
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||||
|
# All rights reserved.
|
||||||
|
# Copyright (c) 2007 Los Alamos National Security, LLC. All rights
|
||||||
|
# reserved.
|
||||||
|
# $COPYRIGHT$
|
||||||
|
#
|
||||||
|
# Additional copyrights may follow
|
||||||
|
#
|
||||||
|
# $HEADER$
|
||||||
|
#
|
||||||
|
|
||||||
|
PARAM_CONFIG_FILES="Makefile"
|
48
orte/mca/ras/ccp/ras_ccp.h
Обычный файл
48
orte/mca/ras/ccp/ras_ccp.h
Обычный файл
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* Resource Allocation (CCP)
|
||||||
|
*/
|
||||||
|
#ifndef ORTE_RAS_ccp_H
|
||||||
|
#define ORTE_RAS_ccp_H
|
||||||
|
|
||||||
|
#include "orte/mca/ras/ras.h"
|
||||||
|
#include "orte/mca/ras/base/base.h"
|
||||||
|
|
||||||
|
#if defined(c_plusplus) || defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct orte_ras_ccp_component_t {
|
||||||
|
/** Base RAS component */
|
||||||
|
orte_ras_base_component_t super;
|
||||||
|
/** What's the priority of this component */
|
||||||
|
int priority;
|
||||||
|
};
|
||||||
|
typedef struct orte_ras_ccp_component_t orte_ras_ccp_component_t;
|
||||||
|
|
||||||
|
ORTE_DECLSPEC extern orte_ras_ccp_component_t mca_ras_ccp_component;
|
||||||
|
ORTE_DECLSPEC extern orte_ras_base_module_t orte_ras_ccp_module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module init function
|
||||||
|
*/
|
||||||
|
orte_ras_base_module_t *orte_ras_ccp_init(int* priority);
|
||||||
|
|
||||||
|
#if defined(c_plusplus) || defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
93
orte/mca/ras/ccp/ras_ccp_component.c
Обычный файл
93
orte/mca/ras/ccp/ras_ccp_component.c
Обычный файл
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "orte_config.h"
|
||||||
|
|
||||||
|
#include "opal/mca/base/base.h"
|
||||||
|
#include "opal/mca/base/mca_base_param.h"
|
||||||
|
#include "opal/util/output.h"
|
||||||
|
#include "opal/util/basename.h"
|
||||||
|
#include "orte/constants.h"
|
||||||
|
#include "orte/util/proc_info.h"
|
||||||
|
#include "ras_ccp.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables
|
||||||
|
*/
|
||||||
|
static int param_priority;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions
|
||||||
|
*/
|
||||||
|
static int ras_ccp_open(void);
|
||||||
|
static orte_ras_base_module_t *ras_ccp_init(int*);
|
||||||
|
|
||||||
|
|
||||||
|
orte_ras_ccp_component_t mca_ras_ccp_component = {
|
||||||
|
{
|
||||||
|
/* First, the mca_base_component_t struct containing meta
|
||||||
|
information about the component itself */
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Indicate that we are a ras v1.3.0 component (which also
|
||||||
|
implies a specific MCA version) */
|
||||||
|
|
||||||
|
ORTE_RAS_BASE_VERSION_2_0_0,
|
||||||
|
|
||||||
|
/* Component name and version */
|
||||||
|
|
||||||
|
"ccp",
|
||||||
|
ORTE_MAJOR_VERSION,
|
||||||
|
ORTE_MINOR_VERSION,
|
||||||
|
ORTE_RELEASE_VERSION,
|
||||||
|
|
||||||
|
/* Component open and close functions */
|
||||||
|
|
||||||
|
ras_ccp_open,
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Next the MCA v1.0.0 component meta data */
|
||||||
|
{
|
||||||
|
/* The component is checkpoint ready */
|
||||||
|
MCA_BASE_METADATA_PARAM_CHECKPOINT
|
||||||
|
},
|
||||||
|
ras_ccp_init
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int ras_ccp_open(void)
|
||||||
|
{
|
||||||
|
mca_base_param_reg_int(&mca_ras_ccp_component.super.ras_version,
|
||||||
|
"priority",
|
||||||
|
"Priority of the ccp ras component",
|
||||||
|
false, false, 13,
|
||||||
|
&mca_ras_ccp_component.priority);
|
||||||
|
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static orte_ras_base_module_t *ras_ccp_init(int* priority)
|
||||||
|
{
|
||||||
|
/* if we are not an HNP, then we must not be selected */
|
||||||
|
if (!orte_process_info.hnp) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*priority = mca_ras_ccp_component.priority;
|
||||||
|
return &orte_ras_ccp_module;
|
||||||
|
}
|
326
orte/mca/ras/ccp/ras_ccp_module.c
Обычный файл
326
orte/mca/ras/ccp/ras_ccp_module.c
Обычный файл
@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004-2007 The University of Tennessee and The University
|
||||||
|
* of Tennessee Research Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
|
||||||
|
* University of Stuttgart. All rights reserved.
|
||||||
|
* $COPYRIGHT$
|
||||||
|
*
|
||||||
|
* Additional copyrights may follow
|
||||||
|
*
|
||||||
|
* $HEADER$
|
||||||
|
*/
|
||||||
|
#include "orte_config.h"
|
||||||
|
#include "orte/constants.h"
|
||||||
|
#include "orte/types.h"
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x0500
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <comutil.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "opal/util/argv.h"
|
||||||
|
#include "opal/util/output.h"
|
||||||
|
#include "opal/util/os_path.h"
|
||||||
|
#include "opal/util/show_help.h"
|
||||||
|
|
||||||
|
#include "orte/mca/errmgr/errmgr.h"
|
||||||
|
#include "orte/runtime/orte_globals.h"
|
||||||
|
#include "orte/util/name_fns.h"
|
||||||
|
|
||||||
|
#include "orte/mca/ras/base/ras_private.h"
|
||||||
|
#include "ras_ccp.h"
|
||||||
|
|
||||||
|
/* Import the Windows CCP API. */
|
||||||
|
#import "ccpapi.tlb" named_guids no_namespace raw_interfaces_only \
|
||||||
|
rename("SetEnvironmentVariable","SetEnvVar") \
|
||||||
|
rename("GetJob", "GetSingleJob") \
|
||||||
|
rename("AddJob", "AddSingleJob")
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local functions
|
||||||
|
*/
|
||||||
|
static int orte_ras_ccp_allocate(opal_list_t *nodes);
|
||||||
|
static int orte_ras_ccp_finalize(void);
|
||||||
|
static int discover(opal_list_t* nodelist, ICluster* pCluster);
|
||||||
|
void get_cluster_message(ICluster* pCluster);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables
|
||||||
|
*/
|
||||||
|
orte_ras_base_module_t orte_ras_ccp_module = {
|
||||||
|
orte_ras_ccp_allocate,
|
||||||
|
orte_ras_ccp_finalize
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover available (pre-allocated) nodes. Allocate the
|
||||||
|
* requested number of nodes/process slots to the job.
|
||||||
|
*/
|
||||||
|
static int orte_ras_ccp_allocate(opal_list_t *nodes)
|
||||||
|
{
|
||||||
|
int ret, i;
|
||||||
|
size_t len;
|
||||||
|
char *cluster_head = NULL;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
ICluster* pCluster = NULL;
|
||||||
|
|
||||||
|
/* CCP is not thread safe. Use the apartment model. */
|
||||||
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||||
|
|
||||||
|
/* Create the Cluster object. */
|
||||||
|
hr = CoCreateInstance( __uuidof(Cluster),
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
__uuidof(ICluster),
|
||||||
|
reinterpret_cast<void **> (&pCluster) );
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate: failed to create cluster object!"));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the cluster head nodes name */
|
||||||
|
_dupenv_s(&cluster_head, &len, "LOGONSERVER");
|
||||||
|
|
||||||
|
if(cluster_head == NULL) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate: connot find cluster head node!"));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get rid of the beginning '//'. */
|
||||||
|
for( i = 0; i < sizeof(cluster_head) * 2 - 2; i++){
|
||||||
|
cluster_head[i] = cluster_head[i+2];
|
||||||
|
cluster_head[i+2] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the cluster's head node */
|
||||||
|
hr = pCluster->Connect(_bstr_t(cluster_head));
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate: connection failed!"));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ORTE_SUCCESS != (ret = discover(nodes, pCluster))) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate: discover failed!"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in the CCP world, if we didn't find anything, then this
|
||||||
|
* is an unrecoverable error - report it
|
||||||
|
*/
|
||||||
|
if (opal_list_is_empty(nodes)) {
|
||||||
|
opal_show_help("help-ras-ccp.txt", "no-nodes-found", true);
|
||||||
|
return ORTE_ERR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All finished, release cluster object*/
|
||||||
|
pCluster->Release();
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There's really nothing to do here
|
||||||
|
*/
|
||||||
|
static int orte_ras_ccp_finalize(void)
|
||||||
|
{
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:finalize: success (nothing to do)"));
|
||||||
|
return ORTE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discover the available resources. Obtain directly from head node
|
||||||
|
*
|
||||||
|
* - validate any Windows Cluster nodes
|
||||||
|
* - check for additional nodes that have already been allocated
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int discover(opal_list_t* nodelist, ICluster* pCluster)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int32_t nodeid;
|
||||||
|
orte_node_t *node;
|
||||||
|
opal_list_item_t* item;
|
||||||
|
opal_list_t new_nodes;
|
||||||
|
struct timeval start, stop;
|
||||||
|
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
long idle_processors = 0;
|
||||||
|
IClusterEnumerable* pNodesCollection = NULL;
|
||||||
|
IEnumVARIANT* pNodes = NULL;
|
||||||
|
INode* pNode = NULL;
|
||||||
|
BSTR node_name = NULL, node_arch = NULL;
|
||||||
|
VARIANT var;
|
||||||
|
NodeStatus Status;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* check for timing request - get start time if so */
|
||||||
|
if (orte_timing) {
|
||||||
|
gettimeofday(&start, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the collection of nodes. */
|
||||||
|
hr = pCluster->get_ComputeNodes(&pNodesCollection);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pCluster->get_ComputeNodes failed."));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the enumerator used to iterate through the collection. */
|
||||||
|
hr = pNodesCollection->GetEnumerator(&pNodes);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
get_cluster_message(pCluster);
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pNodesCollection->GetEnumerator failed."));
|
||||||
|
return ORTE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantInit(&var);
|
||||||
|
|
||||||
|
/* Construct new node list. */
|
||||||
|
OBJ_CONSTRUCT(&new_nodes, opal_list_t);
|
||||||
|
nodeid=0;
|
||||||
|
|
||||||
|
/* Loop through the collection. */
|
||||||
|
while (hr = pNodes->Next(1, &var, NULL) == S_OK) {
|
||||||
|
var.pdispVal->QueryInterface(IID_INode, reinterpret_cast<void **> (&pNode));
|
||||||
|
|
||||||
|
/* Check wether the node is ready.
|
||||||
|
* There are four states:
|
||||||
|
* NodeStatus_Ready = 0,
|
||||||
|
* NodeStatus_Paused = 1,
|
||||||
|
* NodeStatus_Unreachable = 2, probably not a windows cluster node.
|
||||||
|
* NodeStatus_PendingApproval = 3
|
||||||
|
*/
|
||||||
|
hr = pNode->get_Status(&Status);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pNode->get_Status failed."));
|
||||||
|
ret = ORTE_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get available number of processors on each node. */
|
||||||
|
hr = pNode->get_NumberOfIdleProcessors(&idle_processors);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pNode->get_NumberOfIdleProcessors failed."));
|
||||||
|
ret = ORTE_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we have enough processors on the available nodes?
|
||||||
|
* Question: How do we get the required number of processors?
|
||||||
|
*/
|
||||||
|
if ( (Status != NodeStatus_Unreachable) && (idle_processors > 0) ) {
|
||||||
|
|
||||||
|
/* Get node name. */
|
||||||
|
hr = pNode->get_Name(&node_name);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pNode->get_Name failed."));
|
||||||
|
ret = ORTE_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get node processor architecture. */
|
||||||
|
hr = pNode->get_ProcessorArchitecture(&node_arch);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:pNode->get_ProcessorArchitecture failed."));
|
||||||
|
ret = ORTE_ERROR;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent duplicated nodes in the list*/
|
||||||
|
for (item = opal_list_get_first(&new_nodes);
|
||||||
|
opal_list_get_end(&new_nodes) != item;
|
||||||
|
item = opal_list_get_next(item)) {
|
||||||
|
|
||||||
|
node = (orte_node_t*) item;
|
||||||
|
if (0 == strcmp(node->name, (char *)node_name)) {
|
||||||
|
++node->slots;
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate:discover: found -- bumped slots to %d",
|
||||||
|
node->slots));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Did we find it? */
|
||||||
|
|
||||||
|
if (opal_list_get_end(&new_nodes) == item) {
|
||||||
|
|
||||||
|
/* Nope -- didn't find it, so add a new item to the list */
|
||||||
|
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate:discover: not found -- added to list"));
|
||||||
|
|
||||||
|
node = OBJ_NEW(orte_node_t);
|
||||||
|
|
||||||
|
/* The function _dupenv_s is much safer than getenv on Windows. */
|
||||||
|
_dupenv_s(&node->username, &len, "username");
|
||||||
|
|
||||||
|
node->name = _com_util::ConvertBSTRToString(node_name);
|
||||||
|
node->launch_id = nodeid;
|
||||||
|
node->slots_inuse = 0;
|
||||||
|
node->slots_max = 0;
|
||||||
|
node->slots = 1;
|
||||||
|
opal_list_append(nodelist, &node->super);
|
||||||
|
}
|
||||||
|
/* up the nodeid */
|
||||||
|
nodeid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
pNode->Release();
|
||||||
|
VariantClear(&var);
|
||||||
|
}
|
||||||
|
|
||||||
|
pNodes->Release();
|
||||||
|
|
||||||
|
if (nodeid > 0) ret = ORTE_SUCCESS;
|
||||||
|
|
||||||
|
/* All done */
|
||||||
|
cleanup:
|
||||||
|
|
||||||
|
if (ORTE_SUCCESS == ret) {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate:discover: success"));
|
||||||
|
} else {
|
||||||
|
OPAL_OUTPUT_VERBOSE((1, orte_ras_base.ras_output,
|
||||||
|
"ras:ccp:allocate:discover: failed (rc=%d)", ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJ_DESTRUCT(&new_nodes);
|
||||||
|
SysFreeString(node_name);
|
||||||
|
SysFreeString(node_arch);
|
||||||
|
|
||||||
|
/* check for timing request - get stop time and report elapsed time if so */
|
||||||
|
if (orte_timing) {
|
||||||
|
gettimeofday(&stop, NULL);
|
||||||
|
opal_output(0, "ras_ccp: time to allocate is %ld usec",
|
||||||
|
(long int)((stop.tv_sec - start.tv_sec)*1000000 +
|
||||||
|
(stop.tv_usec - start.tv_usec)));
|
||||||
|
gettimeofday(&start, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user