Problem installing gmxapi on Ubuntu

GROMACS version: GROMACS - gmx, 2023.3-Ubuntu_2023.3_1ubuntu3
GROMACS modification: No

Hi Dears, hope this finds you well,

apologize for yet another installation question.

My set up : Ubuntu 24.04.04 LTS

I got GROMACS as gmx, 2023.3-Ubuntu_2023.3_1ubuntu3 from ubuntu repo (apt install gromacs)

I guess it came already compiled.

which gmx reports /usr/bin/gmx

I am trying to install gmxapi but get the orrible/terrible :

Failed to build gmxapi
error: failed-wheel-build-for-install

× Failed to build installable wheels for some pyproject.toml based projects
╰─> gmxapi

somewhere up in the log:

The gmxapi package requires an existing GROMACS installation, version 2020 or higher.
If the usual GROMACS environment variables are detected (such as from sourcing GMXRC),
the corresponding GROMACS installation will be used. Otherwise, provide CMake options
to the Python package installer.
Define gmxapi_ROOT to the GROMACS installation directory (-Dgmxapi_ROOT=/path/to/gromacs).
Help CMake find the GROMACS compiler toolchain with -C /path/to/gromacs/share/cmake/gromacs/gromacs-hints.cmake.

tried with :

gmxapi_ROOT=usr/bin/gmx pip install --no-cache-dir gmxapi==0.4.0

(0.4.0 seemed the one same age of Gromacs 2023, but gget same results with latest versioN)

but no luck.

I dont understand a lot of this, but question is :

is there any way to solve it or have I to build/install gromacs from scratch ?

in the latter case what should I do to be sure to be able to install gmxapi afterward ?

ANd moreover ( feel really dumb for this) what is GMXRC cited above ?

Cheers

P.

Hello, P.

I have not used the gromacs ubuntu package before, but it doesn’t look like it provides a sufficient installation. I also tried installing the libgromacs-dev package, but it did not provide libgmxapi or the cmake infrastructure, as best I can tell. (It also does not provide a GMXRC file.)

gromacs has to be configured with -DGMXAPI=ON when it is built to support gmxapi. This option is normally ON by default, but was apparently disabled in the ubuntu package, and I don’t see an ubuntu package option that has the missing pieces.

The gmxapi installation instructions (Full installation instructions - GROMACS 2026.1 documentation) include links to other documentation about configuring, building, and installing gromacs appropriately.

I think if you install gromacs from source code, it will go more smoothly. You can download the source code from Downloads - GROMACS 2026.1 documentation

For more information on the GMXRC file, see Installation guide - GROMACS 2026.1 documentation

Sorry for the trouble! Good luck!

had to build/install latest cmake and gromacs as per instructions,

needed to install openmpi-bin libopenmpi-dev

used

gmxapi_ROOT=/usr/local/gromacs/ pip install --no-cache-dir gmxapi

and everything seems fine.

gmx

returns

:-) GROMACS - gmx, 2026.1 (-:

import gmxapi

print('gmxapi version : ', gmxapi.version)

prints gmxapi version : 0.4.2

but trying to run pytest:

cd python_packaging/gmxapi
pip install -r requirements.txt
pytest test

gives : ImportError: Error importing plugin “gmxapi.testsupport”: No module named ‘gmxapi’

while in python :

from gmxapi import testsupport

print('gmxapi.testsupport : ', gmxapi.testsupport)

gives: gmxapi.testsupport : <module ‘gmxapi.testsupport’ from ‘/xxx/xxx/xxx/xx/myenv/GMXAPI_spyder/lib/python3.12/site-packages/gmxapi/testsupport.py’>

can run it from inside python with

python

>>>> import pytest

>>>> pytest.main([“test”])

and unfortunately got:

platform linux – Python 3.12.3, pytest-9.0.2, pluggy-1.6.0
rootdir: /xx/xxx/xxx/GROMACS/gromacs-2026.1/python_packaging/gmxapi/test
configfile: pytest.ini
collected 41 items

test/test_commandline.py …F… [ 29%]
test/test_exceptions.py . [ 31%]
test/test_feature_check.py .ss [ 39%]
test/test_fileio.py … [ 46%]
test/test_fileio_low_level.py … [ 53%]
test/test_mdrun.py …s.s.. [ 73%]
test/test_operation.py … [ 82%]
test/test_runtime.py … [ 92%]
test/test_subgraph.py … [100%]

================================================================================= FAILURES =================================================================================
__ test_command_with_input_files ___

cleandir = PosixPath(‘/tmp/pytest-of-opw/pytest-1/test_command_with_input_files0’)

def test_command_with_input_files(cleandir):
    """Test handling of *input_file* arguments.
    
        Generate a file and provide it as a relative path to a simple command line tool.
        Confirm that the relative path (valid for the script working directory but not
        for the Task working directory) is correctly normalized to an absolute path.
    
        Check for #4827 regression.
        """
        with tempfile.NamedTemporaryFile(mode="w", delete=False) as fh:
            fh.write("hi\nthere\n")
            fh.flush()
        assert fh.closed
        actual_path = Path(fh.name).resolve()
        try:
            with open(actual_path, "r") as fh:
                num_lines = len(fh.readlines())
            relative_path = os.path.relpath(actual_path, start=cleandir)
            # Overload the input files facility to trigger path normalization.
            # `wc` implementations are fairly consistent as far as providing a
            # `-l` option and accepting a positional file argument.
            cmd = commandline.commandline_operation(
                executable="wc", input_files={"-l": relative_path}
            )
            # We want to find a relative path from the current directory that would
            # not resolve correctly from the generated Task directory. We will now
            # double-check that the relative path _would have_ caused the test to fail
            # if the absolute path conversion (#4827) were not working correctly.
            workdir = cmd.output.directory.result()
            assert not Path(workdir).joinpath(relative_path).exists()
            # Uncomment the following for additional debugging.
            # actual_relative_path = os.path.relpath(actual_path, start=workdir)
            # returncode = cmd.output.returncode.result()
            # error = cmd.output.stderr.result()
    
            # Check that the file whose lines we counted has the expected number of lines.
            output = cmd.output.stdout.result()
            # For `wc -l filename` on a 2-line file, we expect output
            # similar to "      2 filename\n".
            # Check the first non-whitespace field.
>           assert output.split()[0] == str(num_lines)
                   ^^^^^^^^^^^^^^^^^
E           IndexError: list index out of range

/xxx/xxx/xxx/GROMACS/gromacs-2026.1/python_packaging/gmxapi/test/test_commandline.py:172: IndexError

looks llike is failing where it could be of help (running gromacs from python using files as args of commands !!??)

Any help here too ? Or should I create a new question

Thanks a lot

PS

trying to understand more it’s like after

cmd = commandline.commandline_operation(
executable=“wc”, input_files={“-l”: relative_path}
)

there is no cmd.run() line in test_commandline.py , but even adding it the test keeps failing

blabbing about some non existent file

error : /usr/bin/wc: pippo.txt: No such file or directory

Glad you made progress!

For the pytest test command line, my guess is that the pytest command is probably in a different environment or virtual environment than your pip command. You can try doing pip install –upgrade pytest to make sure that the pytest entry point is in the same environment that you installed gmxapi into, or you could invoke pytest as python -m pytest instead of just pytest.

As far as the failing test, the main difference I see from https://gitlab.com/gromacs/gromacs/-/jobs/13459460957 is that you are using a newer version of Python. It is possible that the main project testing needs to be updated to catch behavior changes in newer versions of Python.

I’m surprised that the temporary filename that was generated would be “pippo.txt” instead of something more random-looking, but it seems like something might be going wrong in the path handling or file staging. I’ll try to take a look soon, but you can look at the working directories and “task directories” if you want to try to figure out what is going on.

The output should have been generated at the time that result() was called. (No explicit call to run() should be necessary.)

However, the relative path should have been normalized to an absolute path when commandline.commandline_operation() was called, but it seems like that might not have happened.

For more information about the intended behavior, see gmxapi.commandline_operation has potentially confusing behavior with relative paths in *input_files* parameter (#4827) · Issues · GROMACS / GROMACS · GitLab and Clarify `gmxapi.commandline_operation()` behavior re: *input_files* (!3704) · Merge requests · GROMACS / GROMACS · GitLab

This does not sound like an installation problem. It could warrant a bug report (see Change Management - GROMACS 2026.1 documentation). At the very least, more recent Python versions should be added to the automated testing jobs.

yep pytest was installed systemwide added to virtualenv too

temp file was “pippo.txt” because was trying to figure out if something was wrong with File.NamedTemporaryFile

got test working with changing :

cmd = commandline.commandline_operation(
executable=“wc”, input_files={“-l”: relative_path}
)

to

    cmd = commandline.commandline_operation(
        executable="wc", input_files={"-l": actual_path}
    )

results gives (output = cmd.output.stdout.result()):

output : 2 /tmp/pytest-of-opw/pytest-78/test_command_with_input_files0/pippo.txt

NOT SURE IF IT DEFIES THE GOAL OF THE TEST THOUGH !!!

[could try to change relative_path = os.path.relpath(actual_path, start=cleandir) with

relative_path = os.path.relpath(actual_path, start=os.curdir)) to save the logic ???]

I noticed that using:

cmd = commandline.commandline_operation(
executable=“wc”, arguments=[‘-l’], input_files={“”: actual_path}
)

I get:

output : 2 /tmp/pytest-of-opw/pytest-79/test_command_with_input_files0/pippo.txt
2 total

looks like using:

wc -l “” pippo.txt

Now I understand gmxapi.commandline_operation better than reading :

input_files – mapping of command-line flags to input file paths

No clues about:

The output should have been generated at the time that result() was called. (No explicit call to run() should be necessary.)

Thanks for your help (time and patience)

Is there any way to mark the discussion as solved ? like stack overflow ?

It’s good to know that it works when you use an absolute path.

The test is supposed to confirm that a relative path is properly handled, too. Since it fails with a relative path, it sounds like there is a bug that needs to be fixed to restore the intended behavior in more recent versions of Python.

Thank you for reporting and taking the time to track it down!