Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conda installation fails on Mac M1 architectures #48

Open
adonath opened this issue Oct 3, 2024 · 10 comments
Open

Conda installation fails on Mac M1 architectures #48

adonath opened this issue Oct 3, 2024 · 10 comments
Assignees

Comments

@adonath
Copy link
Contributor

adonath commented Oct 3, 2024

I tried to install neost on a MacBook Pro M1 (2021) using conda and the provided environment.yml file. However it fails with:

Could not solve for environment specs
The following package could not be installed
└─ pymultinest is not installable because it requires
   └─ multinest, which does not exist (perhaps a missing channel).

And indeed there are no arm-64 coda builds for multinest (https://anaconda.org/conda-forge/multinest) available. The README.md mentions specific (limited) instructions for Mac (https://github.com/xpsi-group/neost?tab=readme-ov-file#installation-and-testing), however I cannot find those in the actual documentation (https://xpsi-group.github.io/neost/install.html).

Given that Mac users are very common in the scientific community I think it would be good to address installation on Mac specifically and also mentioned the support (or non-support) for ARM architectures.

@adonath
Copy link
Contributor Author

adonath commented Oct 3, 2024

Just a few more updates:

  • Removing pymultinest from the environment.yml and installing it via pip instead works fine.
  • However when trying to install neost using python -m pip install -e . it fails with:
Obtaining file:///Users/adonath/github/xpsi-group/neost
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... error
  error: subprocess-exited-with-error
  
  × Getting requirements to build editable did not run successfully.
  │ exit code: 1
  ╰─> [22 lines of output]
      GSL version: 2.7.1
      Traceback (most recent call last):
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 132, in get_requires_for_build_editable
          return hook(config_settings)
                 ^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-djepltmx/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 464, in get_requires_for_build_editable
          return self.get_requires_for_build_wheel(config_settings)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-djepltmx/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 332, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=[])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-djepltmx/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 302, in _get_build_requires
          self.run_setup()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-djepltmx/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 318, in run_setup
          exec(code, locals())
        File "<string>", line 38, in <module>
      NameError: name 'os' is not defined. Did you mean: 'OS'? Or did you forget to import 'os'?
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build editable did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

@drannawatts
Copy link
Member

Thanks @adonath we're looking into it! Well @nr1118 is :-D

@nr1118
Copy link
Collaborator

nr1118 commented Oct 7, 2024

Hi @adonath, myself and @svisak have updated the installation instructions to discuss MAC M-series installation in the sense that we do have a definitive solution, but can offer some troubleshooting methods. Additionally, we have updated our setup.py file since it seems we forgot a simple import os in that file based on your most recent error message. Hopefully, all this will mean that you can install NEoST.

@adonath
Copy link
Contributor Author

adonath commented Oct 28, 2024

Thanks @nr1118 for the update and fix. I have tried to repeat the procedure and now the local install of neost it fails with:

Building wheels for collected packages: NEoST
  Building wheel for NEoST (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for NEoST (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [140 lines of output]
      /private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/config/expand.py:126: SetuptoolsWarning: File '/Users/adonath/github/xpsi-group/neost/LICENCE' cannot be found
        for path in _filter_existing_files(_filepaths)
      /private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/config/expand.py:126: SetuptoolsWarning: File '/Users/adonath/github/xpsi-group/neost/README.md' cannot be found
        for path in _filter_existing_files(_filepaths)
      GSL version: 2.7.1
      running bdist_wheel
      running build
      running build_py
      creating build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/global_imports.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/PosteriorAnalysis.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/Star.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/__init__.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/Prior.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/utils.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      copying neost/Likelihood.py -> build/lib.macosx-11.1-arm64-cpython-312/neost
      creating build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      copying neost/eos/speedofsound.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      copying neost/eos/polytropes.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      copying neost/eos/__init__.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      copying neost/eos/tabulated.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      copying neost/eos/base.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/eos
      creating build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/TOVr_python.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/TidalDef.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/__init__.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/TOVdm_python.py -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      running egg_info
      writing NEoST.egg-info/PKG-INFO
      writing dependency_links to NEoST.egg-info/dependency_links.txt
      writing requirements to NEoST.egg-info/requires.txt
      writing top-level names to NEoST.egg-info/top_level.txt
      reading manifest file 'NEoST.egg-info/SOURCES.txt'
      adding license file 'LICENSE'
      adding license file 'COPYING'
      writing manifest file 'NEoST.egg-info/SOURCES.txt'
      copying neost/tovsolvers/TOVdm.pyx -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/TOVh.pyx -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      copying neost/tovsolvers/TOVr.pyx -> build/lib.macosx-11.1-arm64-cpython-312/neost/tovsolvers
      running build_ext
      Traceback (most recent call last):
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/Users/adonath/software/mambaforge/envs/neost/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 434, in build_wheel
          return _build(['bdist_wheel', '--dist-info-dir', metadata_directory])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 422, in _build
          return self._build_with_temp_dir(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 403, in _build_with_temp_dir
          self.run_setup()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/build_meta.py", line 318, in run_setup
          exec(code, locals())
        File "<string>", line 86, in <module>
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/__init__.py", line 117, in setup
          return distutils.core.setup(**attrs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 183, in setup
          return run_commands(dist)
                 ^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/core.py", line 199, in run_commands
          dist.run_commands()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 954, in run_commands
          self.run_command(cmd)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/dist.py", line 991, in run_command
          super().run_command(command)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
          cmd_obj.run()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/command/bdist_wheel.py", line 407, in run
          self.run_command("build")
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
          self.distribution.run_command(command)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/dist.py", line 991, in run_command
          super().run_command(command)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
          cmd_obj.run()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/build.py", line 135, in run
          self.run_command(cmd_name)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
          self.distribution.run_command(command)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/dist.py", line 991, in run_command
          super().run_command(command)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/dist.py", line 973, in run_command
          cmd_obj.run()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/command/build_ext.py", line 98, in run
          _build_ext.run(self)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/build_ext.py", line 359, in run
          self.build_extensions()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/build_ext.py", line 476, in build_extensions
          self._build_extensions_serial()
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/_distutils/command/build_ext.py", line 502, in _build_extensions_serial
          self.build_extension(ext)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/setuptools/command/build_ext.py", line 263, in build_extension
          _build_ext.build_extension(self, ext)
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Distutils/build_ext.py", line 130, in build_extension
          new_ext = cythonize(
                    ^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 1010, in cythonize
          module_list, module_metadata = create_extension_list(
                                         ^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 859, in create_extension_list
          kwds = deps.distutils_info(file, aliases, base).values
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 707, in distutils_info
          return (self.transitive_merge(filename, self.distutils_info0, DistutilsInfo.merge)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 716, in transitive_merge
          return self.transitive_merge_helper(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 728, in transitive_merge_helper
          for next in outgoing(node):
                      ^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Utils.py", line 129, in wrapper
          res = cache[args] = f(self, *args)
                              ^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 629, in cimported_files
          pxd_file = self.find_pxd(module, filename)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Utils.py", line 129, in wrapper
          res = cache[args] = f(self, *args)
                              ^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Build/Dependencies.py", line 610, in find_pxd
          pxd = self.context.find_pxd_file(relative, source_file_path=filename)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Compiler/Main.py", line 281, in find_pxd_file
          pxd = self.search_include_directories(
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Compiler/Main.py", line 309, in search_include_directories
          return search_include_directories(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/private/var/folders/bt/7xysb53d3vj7m_snm7wt9jhc0000gp/T/pip-build-env-3oh5vqqy/overlay/lib/python3.12/site-packages/Cython/Utils.py", line 88, in wrapper
          res = cache.get(args, uncomputed)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      TypeError: unhashable type: 'list'
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for NEoST
Failed to build NEoST
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (NEoST)

I am using Python 3.12.6 with pip 24.2.

@svisak
Copy link
Collaborator

svisak commented Oct 28, 2024

Thanks for the information, @adonath. We will investigate this and try to come up with a fix. Unfortunately none of us has an M-series Mac, so we're a bit blind. Could you try to install v0.10.0 (git checkout v0.10.0 ; pip install .) and see if you get the same error? We have changed the installation scripts since v0.10.0 and I'm wondering if it's our update that has caused the problem. This should help us identify it.

@adonath
Copy link
Contributor Author

adonath commented Oct 28, 2024

Thanks for the quick response @svisak! Unfortunately this also fails. I will spare the log output here and instead suggest that you maybe setup a Mac arm64 runner on GitHub (https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories).

I would not make this a requirement for the JOSS review (however installation hints need to be verified for this...). Still I think the user base with M architectures is large, so it is probably worth the effort.

@svisak
Copy link
Collaborator

svisak commented Oct 29, 2024

Alright, thanks for checking! Then at least we haven't introduced any new issues. I'm hoping we can fix this by simply changing the type of the ext_modules in setup.py to something other than a list, but I haven't had a change to test this yet.

I agree that we should set up an arm64 runner. @nr1118, @MelissaMendes-phys, @drannawatts, could one of you perhaps look into this?

@svisak
Copy link
Collaborator

svisak commented Oct 29, 2024

While we're working on a fix for this, @adonath, you could try installation without cythonizing the TOV solvers. Simply renaming or deleting setup.py should install NEoST using the backup Python TOV solvers instead. These are slower of course, but should work OK; though note that the unit tests will fail due to small numerical differences.

@adonath
Copy link
Contributor Author

adonath commented Oct 29, 2024

Thanks @svisak! I can confirm the install with a minimal setup.py works just fine. I could run the tests, but they fails (as you mentioned) due to numerical differences. As you look into the arm64 installation I will proceed with the JOSS review and open issues as they come up.

@svisak
Copy link
Collaborator

svisak commented Oct 29, 2024

Great :) Sounds like a good plan.

Reading the error message a bit more closely, I think the problem might be that the include_dirs variable (and possibly library_dirs and extra_compile_args) is a mutable type (a list in this case). Thus changing its type to tuple (which is immutable) might solve the problem. In case you want to test this out, you can add include_dirs = tuple(include_dirs) somewhere between lines 53 and 56, i.e., right before the Extensions are specified. This works fine for me on Linux, but obviously I didn't experience the issue in the first place so I can't be sure it'll work on a Mac.

Of course you're not a NEoST developer, so feel free to not do this and wait for us to test it out with a Mac arm64 runner if you prefer! @nr1118 is working on such a runner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants