Skip to content

Commit 34acfb4

Browse files
authored
Merge pull request #81 from gvallee/issue_79
Fix non-MPI applications not being able to run
2 parents 787e7d7 + e59d994 commit 34acfb4

File tree

6 files changed

+73
-21
lines changed

6 files changed

+73
-21
lines changed

pkg/container/container.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,13 @@ func GetMetadata(imgPath string, sysCfg *sys.Config) (Config, implem.Info, error
384384
}
385385

386386
func getDefaultExecArgs() []string {
387-
return strings.Split(defaultExecArgs, " ")
387+
args := []string{"exec"}
388+
args = append(args, strings.Split(defaultExecArgs, " ")...)
389+
390+
return args
388391
}
389392

390-
func getBindArguments(hostMPI *implem.Info, hostBuildenv *buildenv.Info, c *Config) []string {
393+
func getMPIBindArguments(hostMPI *implem.Info, hostBuildenv *buildenv.Info, c *Config) []string {
391394
var bindArgs []string
392395

393396
if c.Model == BindModel {
@@ -401,20 +404,24 @@ func getBindArguments(hostMPI *implem.Info, hostBuildenv *buildenv.Info, c *Conf
401404
return bindArgs
402405
}
403406

404-
// GetExecArgs figures out the singularity exec arguments to be used for executing a container
405-
func GetExecArgs(myHostMPICfg *implem.Info, hostBuildEnv *buildenv.Info, syContainer *Config, sysCfg *sys.Config) []string {
407+
// GetMPIExecCfg figures out the singularity exec arguments to be used for executing a container
408+
func GetMPIExecCfg(myHostMPICfg *implem.Info, hostBuildEnv *buildenv.Info, syContainer *Config, sysCfg *sys.Config) []string {
406409
args := getDefaultExecArgs()
407410
if sysCfg.Nopriv {
408411
args = append(args, "-u")
409412
}
410-
411-
bindArgs := getBindArguments(myHostMPICfg, hostBuildEnv, syContainer)
413+
bindArgs := getMPIBindArguments(myHostMPICfg, hostBuildEnv, syContainer)
412414
if len(bindArgs) > 0 {
413415
args = append(args, "--bind")
414416
args = append(args, bindArgs...)
415417
}
416-
417418
log.Printf("-> Exec args to use: %s\n", strings.Join(args, " "))
419+
return args
420+
}
418421

422+
// GetDefaultExecCfg returns the default way to run a container
423+
func GetDefaultExecCfg() []string {
424+
args := getDefaultExecArgs()
425+
log.Printf("-> Exec args to use: %s\n", strings.Join(args, " "))
419426
return args
420427
}

pkg/implem/implem.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,12 @@ type Info struct {
3333
// Tarball is the name of the tarball of the MPI implementation
3434
Tarball string
3535
}
36+
37+
// IsMPI checks if information passed in is an MPI implementation
38+
func IsMPI(i *Info) bool {
39+
if i != nil && (i.ID == OMPI || i.ID == MPICH || i.ID == IMPI) {
40+
return true
41+
}
42+
43+
return false
44+
}

pkg/jm/jobmgr_native.go

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/sylabs/singularity-mpi/internal/pkg/impi"
1616
"github.com/sylabs/singularity-mpi/internal/pkg/job"
1717
"github.com/sylabs/singularity-mpi/pkg/buildenv"
18+
"github.com/sylabs/singularity-mpi/pkg/container"
1819
"github.com/sylabs/singularity-mpi/pkg/implem"
1920
"github.com/sylabs/singularity-mpi/pkg/mpi"
2021
"github.com/sylabs/singularity-mpi/pkg/syexec"
@@ -63,18 +64,11 @@ func NativeGetError(j *job.Job, sysCfg *sys.Config) string {
6364
return j.ErrBuffer.String()
6465
}
6566

66-
// NativeSubmit is the function to call to submit a job through the native job manager
67-
func NativeSubmit(j *job.Job, env *buildenv.Info, sysCfg *sys.Config) (syexec.SyCmd, error) {
68-
var sycmd syexec.SyCmd
69-
70-
if j.App.BinPath == "" {
71-
return sycmd, fmt.Errorf("application binary is undefined")
72-
}
73-
67+
func prepareMPISubmit(sycmd *syexec.SyCmd, j *job.Job, env *buildenv.Info, sysCfg *sys.Config) error {
7468
var err error
7569
sycmd.BinPath, err = mpi.GetPathToMpirun(j.HostCfg, env)
7670
if err != nil {
77-
return sycmd, err
71+
return err
7872
}
7973
if j.NP > 0 {
8074
sycmd.CmdArgs = append(sycmd.CmdArgs, "-np")
@@ -83,7 +77,7 @@ func NativeSubmit(j *job.Job, env *buildenv.Info, sysCfg *sys.Config) (syexec.Sy
8377

8478
mpirunArgs, err := mpi.GetMpirunArgs(j.HostCfg, env, &j.App, j.Container, sysCfg)
8579
if err != nil {
86-
return sycmd, fmt.Errorf("unable to get mpirun arguments: %s", err)
80+
return fmt.Errorf("unable to get mpirun arguments: %s", err)
8781
}
8882
if len(mpirunArgs) > 0 {
8983
sycmd.CmdArgs = append(sycmd.CmdArgs, mpirunArgs...)
@@ -98,6 +92,37 @@ func NativeSubmit(j *job.Job, env *buildenv.Info, sysCfg *sys.Config) (syexec.Sy
9892
sycmd.Env = append([]string{"LD_LIBRARY_PATH=" + newLDPath}, os.Environ()...)
9993
sycmd.Env = append([]string{"PATH=" + newPath}, os.Environ()...)
10094

95+
return nil
96+
}
97+
98+
func prepareStdSubmit(sycmd *syexec.SyCmd, j *job.Job, env *buildenv.Info, sysCfg *sys.Config) error {
99+
sycmd.BinPath = sysCfg.SingularityBin
100+
sycmd.CmdArgs = container.GetDefaultExecCfg()
101+
sycmd.CmdArgs = append(sycmd.CmdArgs, j.Container.Path, j.App.BinPath)
102+
103+
return nil
104+
}
105+
106+
// NativeSubmit is the function to call to submit a job through the native job manager
107+
func NativeSubmit(j *job.Job, env *buildenv.Info, sysCfg *sys.Config) (syexec.SyCmd, error) {
108+
var sycmd syexec.SyCmd
109+
110+
if j.App.BinPath == "" {
111+
return sycmd, fmt.Errorf("application binary is undefined")
112+
}
113+
114+
if implem.IsMPI(j.HostCfg) {
115+
err := prepareMPISubmit(&sycmd, j, env, sysCfg)
116+
if err != nil {
117+
return sycmd, fmt.Errorf("unable to prepare MPI job: %s", err)
118+
}
119+
} else {
120+
err := prepareStdSubmit(&sycmd, j, env, sysCfg)
121+
if err != nil {
122+
return sycmd, fmt.Errorf("unable to prepare MPI job: %s", err)
123+
}
124+
}
125+
101126
j.GetOutput = NativeGetOutput
102127
j.GetError = NativeGetError
103128

pkg/jm/jobmgr_prun.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func PrunSubmit(j *job.Job, env *buildenv.Info, sysCfg *sys.Config) (syexec.SyCm
6868
sycmd.CmdArgs = append(sycmd.CmdArgs, j.Container.AppExe)
6969

7070
// Get the exec arguments and set the env var
71-
execArgs := container.GetExecArgs(j.HostCfg, env, j.Container, sysCfg)
71+
execArgs := container.GetMPIExecCfg(j.HostCfg, env, j.Container, sysCfg)
7272
syExecArgsEnv := "SY_EXEC_ARGS=\"" + strings.Join(execArgs, " ") + "\""
7373
log.Printf("Command to be executed: %s %s", sycmd.BinPath, strings.Join(sycmd.CmdArgs, " "))
7474
log.Printf("SY_EXEC_ARGS to be used: %s", strings.Join(execArgs, " "))

pkg/launcher/launcher.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ type Info struct {
4444
func prepareLaunchCmd(j *job.Job, jobmgr *jm.JM, hostEnv *buildenv.Info, sysCfg *sys.Config) (syexec.SyCmd, error) {
4545
var cmd syexec.SyCmd
4646

47+
// Sanity checks
48+
if j == nil || jobmgr == nil || hostEnv == nil || sysCfg == nil {
49+
return cmd, fmt.Errorf("invalid parameter(s)")
50+
}
51+
4752
launchCmd, err := jobmgr.Submit(j, hostEnv, sysCfg)
4853
if err != nil {
4954
return cmd, fmt.Errorf("failed to create a launcher object: %s", err)

pkg/mpi/mpi.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package mpi
77

88
import (
9+
"fmt"
910
"log"
1011
"path/filepath"
1112

@@ -35,6 +36,11 @@ type Config struct {
3536

3637
// GetPathToMpirun returns the path to mpirun based a configuration of MPI
3738
func GetPathToMpirun(mpiCfg *implem.Info, env *buildenv.Info) (string, error) {
39+
// Sanity checks
40+
if mpiCfg == nil || env == nil {
41+
return "", fmt.Errorf("invalid parameter(s)")
42+
}
43+
3844
path := filepath.Join(env.InstallDir, "bin", "mpirun")
3945
// Intel MPI is installing the binaries and libraries in a quite complex setup
4046
if mpiCfg.ID == implem.IMPI {
@@ -54,10 +60,10 @@ func GetPathToMpirun(mpiCfg *implem.Info, env *buildenv.Info) (string, error) {
5460

5561
// GetMpirunArgs returns the arguments required by a mpirun
5662
func GetMpirunArgs(myHostMPICfg *implem.Info, hostBuildEnv *buildenv.Info, app *app.Info, syContainer *container.Config, sysCfg *sys.Config) ([]string, error) {
57-
args := []string{"singularity", "exec"}
58-
args = append(args, container.GetExecArgs(myHostMPICfg, hostBuildEnv, syContainer, sysCfg)...)
59-
args = append(args, syContainer.Path, app.BinPath)
6063
var extraArgs []string
64+
args := []string{"singularity"}
65+
args = append(args, container.GetMPIExecCfg(myHostMPICfg, hostBuildEnv, syContainer, sysCfg)...)
66+
args = append(args, syContainer.Path, app.BinPath)
6167

6268
// We really do not want to do this but MPICH is being picky about args so for now, it will do the job.
6369
switch myHostMPICfg.ID {

0 commit comments

Comments
 (0)