deisseroth-lab / two-photon

Common scripts, libraries, and utilities for 2p experiments
5 stars 6 forks source link

Updating Singularity container #3

Closed vsoch closed 4 years ago

vsoch commented 4 years ago

Here is an update to building and interacting with the Singularity container to perform the ripping! (Why is it called ripping, by the way?) @chrisroat you did everything right, you actually just did a bit too much in terms of trying to control the display for Singularity - it doesn't need anything like xvfb-run because it works fairly seamlessly with the host! The other adjustment is with respect to the user name space - in Docker you can get an isolated container and define the user to whatever you like, but for Singularity the user inside the container is the user outside the container. Thus, if you want a reproducible setup, the approach I suggest (taken here) is to create a new wineprefix on the fly in a temporary folder, and then run what you need, and clean it up.

The runscript I added is more interactive (e.g., it sets up wine and gives you a bash shell to interact with, and then you can run the python3 command to rip) but you could easily customize this / combine with your current singularity_rip.sh to try for something headless. You'd want to edit this:

echo "To run the two-photon ripper:"
echo "/usr/bin/python3 /app/rip.py --directory /data"
cd $TEMPDIR
env WINEPREFIX="$WINEPREFIX" WINEARCH="$WINEARCH" /bin/bash

to more explicitly check for the /data folder existing and having what you need, and then issuing the python command instead. I wasn't sure what you were going for, and given the GUIs opening up on my host, I thought the interactive method would be reasonable to start with.

And this is super cool! I installed imageJ and loaded the tif locally, just to make sure there really was something there :)

image

@chrisroat please tweak and change this to your liking! Some things you might have preference for:

This pull request will close #2

Thanks for asking me to take a look, it was a lot of fun! :)

chrisroat commented 4 years ago

Thanks so much for jumping in here! I really appreciate it.

My head hurts trying to bridge between Docker and Singularity. Let me try to explain what we've done, and then ask questions regarding the Singularity work.

The goal is to create a non-interactive non-GUI container than can be run in batch on Sherlock, whenever there is a new directory of data detected. The Dockerfile packages up the Prairie View software, as well as a python package that can run that software. We need to wrap it in python in order to kill it when it's finished, as it does not end gracefully in batch mode. (The python also can run some downstream processing, which we can ignore for the moment.)

It was only recently that I got the docker side running -- there was a lot of headache with permissions & wine. @tbenst -- the way I got the Dockerfile working was to set RUN_AS_ROOT -- see this script

@vsoch My questions are

I noticed you dropped all the env variables for XVFB. Why should we not use xvfb-run (USE_XVFB)? Is there an alternate way to run headless? Should I set those variables within the runscript?

You bind "$PWD/Prairie View", but the software was already installed inside the Docker container. Was that an oversight, or did you find it necessary? (Similarly, did you find you needed DirectX installed?)

Is there no way to avoid the temp directory and external profile? It seems overkill setup a whole new wine environment each time we launch to run a dataset . (We also should remove the winetricks call from the Dockerfile). In my ideal world, there would be no external interaction from the container, other than reading the input data and writing the output data. I always get worried that multiple launches of the container, or other processes, could change that directory. Could we set up a world-readable profile in the Singularity recipe?

.

vsoch commented 4 years ago

The goal is to create a non-interactive non-GUI container than can be run in batch on Sherlock, whenever there is a new directory of data detected. The Dockerfile packages up the Prairie View software, as well as a python package that can run that software. We need to wrap it in python in order to kill it when it's finished, as it does not end gracefully in batch mode. (The python also can run some downstream processing, which we can ignore for the moment.)

Ah! So it makes sense to me now why you were wanting Singularity (I wasn't sure). Indeed if you want the container to run completely headless, you'd want to adjust the entrypoint to run the command instead of bash, and you would need to add xvbf-run to emulate having a display.

I noticed you dropped all the env variables for XVFB. Why should we not use xvfb-run (USE_XVFB)? Is there an alternate way to run headless? Should I set those variables within the runscript?

My thinking is that the container should support both execution scenarios - perhaps one with a set of XVFB_* variables that, if found, will assume headless. I suspect a user would be less likely to use Singularity on a local machine, but you never know! Arguably the container should be able to run in both cases.

You bind "$PWD/Prairie View", but the software was already installed inside the Docker container. Was that an oversight, or did you find it necessary? (Similarly, did you find you needed DirectX installed?)

I've done other wine + windows apps before, and sometimes have found it easier or needed to bind (so there is write). That said, I did not test not doing it via a bind, and it would be good to do because it would make the container more reproducible not needing it. It should also be checked that you have permission to re-distribute the software in this fashion (I'm guessing it's an open source license? It should be mentioned in the README or even included alongside the code).

Ha, and I don't think DirectX is required, that was me futzing around and not removing it :P

Is there no way to avoid the temp directory and external profile? It seems overkill setup a whole new wine environment each time we launch to run a dataset . (We also should remove the winetricks call from the Dockerfile). In my ideal world, there would be no external interaction from the container, other than reading the input data and writing the output data. I always get worried that multiple launches of the container, or other processes, could change that directory. Could we set up a world-readable profile in the Singularity recipe?

I think that you will generally need write for this. That said, I'm not 100% sure. It would be worth to try. If you look at the script, I had previously had the profiles mounted for the sole purpose of being able to re-use. If you need write, that could be a strategy. if you don't need write, then you could try to create an environment at build to be used at runtime. The original container I designed was meant to be "use once and throw away" which is why I did it like that.

vsoch commented 4 years ago

And I can help with this more tomorrow, I’m a pumpkin now and pumpkins don’t know how to program! 🎃 gnite!

vsoch commented 4 years ago

Heyo! Okay I've done some more testing and updated the container so it's more true for your use case. Here are some notes:

I've updated the documentation to include these details explicitly, so now we have several use cases:

I tested this on my local machine and can produce the same image headlessly, and without interaction to run and exit cleanly. I've also removed installing direct x. What I haven't updated (and I'll leave up to you) is a strategy for saving a particular profile or wine prefix - my preference is to have it be "throw away" and not require some pre-existing setup on the host (what happens when it goes away or is corrupted and the user is confused about why it doesn't work?) but what you could try is to have a consistent path in the container that looks for a bind there with an existing setup. You would probably need to generate it once on the host (using the container), not throw it away, and then bind where it's expected in the future. This is more complicated setup, hence why I didn't add it here. But of course you should modify to be something like this to work for your lab (and take detailed notes when you decide on the setup that you like). I hope this is helpful!

chrisroat commented 4 years ago

First off, another HUGE thank-you! My questions weren't met to create work, but instead to understand things better myself. I fully did not expect you to do any further updates.

This is amazing... and totally works on my system. I will try exporting to Sherlock and running some batch jobs.

I may continue to work toward removing the need for a profile / home-directory. But that is for a future day!

vsoch commented 4 years ago

Hey that’s what I’m here for! It was a lot of fun and I hope you ping me in the future to help! 👾