-
Notifications
You must be signed in to change notification settings - Fork 9
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
Incompatibility of SD1D output data format with xBOUT #3
Comments
collect just takes the variable from the first dump file ...
Similar with 3 applied, collect fails (as it only checks the first file) and only directly reading from that file works. |
I think we may have closed this issue prematurely, this actually still won't work even with @dschwoerer 's patch (it's my fault, this is more complex to solve than I originally thought).
I'm not sure I understand your point here. I get that if BOUT crashes before all variables have been communicated properly then you would end up with inconsistent dump files, but we have to communicate anyway so how would communicating this BoutReal make that any worse?
Do we really need to support writing different variables to different files at all though? It makes the problem of concatenation considerably more complicated (I will explain why in a sec), and doesn't seem to give much benefit over just defining the variable globally. The cost of communicating the scalar will never be a limiting factor in performance scaling. If you want to print one number or string per process to a file for debugging purposes then you can always put it in the attributes, which will then basically be ignored on concatenation. Also it seems to me that there is no physically-meaningful variable which is only defined on one process. You either have global quantities or spatially-varying ones, it doesn't make physical sense to have quantities which are only defined on part of the domain. Essentially, Why different variables in different files is so inconvenient for xBOUTFirstly, I am assuming that we eventually want a replacement for That means the output of BOUT++ has to conform to some restrictions. Firstly it has to conform to the netCDF data model, because xarray is trying to combine all the dump files into a single netCDF dataset. That was the original problem with What I didn't realise until now was that the exact Unfortunately BOUT++ does not have global coordinates so we can't use
|
Is it possible to ask x-array to ignore certain variables, this would seem like the easiest and least restrictive "fix"? |
Yes, you could pass a function to the def ignore(ds, vars):
return ds.drop(vars) You still can't use this method unless you know in advance that this data isn't just BOUT data, it's SD1D data for which I don't think solving this for SD1D is the hard bit, I'm more trying to formalise how BOUT should behave in order to make a sensible and general replacement for collect using xarray possible. |
Is boutproject/BOUT-dev#1531 a more interresting example? It adds performance information for each proc to the dump file - which would vary from proc to proc. I think a general solution is not possible - as SD1D uses that to dump basically just a FieldPerp, while BOUT++ now uses it to store non-physical data. Can we Than (potentially) BOUT++ specific functions like getting the average, all, or from a specific proc could be implemented ... Disallowing that use in BOUT++ seems to me like a significant disadvantage, and I am failing to see why we should disallow ... |
Yes I think it's best if analysis code doesn't impose restrictions on the simulation. Presumably the new "collect" like interface could take a list of variables to ignore in order to make this more general (this isn't exclusive to SD1D)? If it really is meant to act like collect, such that you ask it to read a specific variable then we could perhaps auto generate the ignore list by getting a list of all variables and then just removing the one we asked for (this is said without looking at any of the code)? |
It is more interesting, but it sort of highlights my point that it never makes sense to do this with physically-meaningful variables. In the case of performance information then it makes sense to write them differently to each file, but only because they aren't physical values. This would just be a good example of a set of variables to drop before concatenation - you want them in the dump files, but not in the final concatenated dataset.
It's not quite the same as collect because you join up all the dump files and then choose a variable afterwards, not the other way around. (This is still fast because with xarray the variable values are lazily loaded.) We could easily have a list of variables to drop though. In fact you could label them as ones you wanted to drop by using the netCDF attributes of the variable (like we do for staggered grids now). And it would also be easy to have a module-specific
This could work but would likely be slow (you're going through all of the opening and concatenation logic again for every variable that you end up ignoring).
The thing is you can't have it both ways, you can't replace collect with something that uses xarray's (still extremely general!) data structures, while at the same time retaining total flexibility in the output of BOUT.
I'm not suggesting actually restricting what BOUT can do, just not explicitly supporting everything it can possibly write out with the new collect function, so individual cases (like this one) might have to be worked around (e.g. with an
If you really wanted to retain the information about which processor certain points were calculated by then you just write out a avg = ds.where(ds['proc'] == 5, drop=True).mean() |
So this isn't replacing |
Maybe we could add a Field0D - that does wrap a BoutReal - which adds (if dumped) metadata to that variable saying that all variables are the same - other BoutReals which are getting dumped can thus be ignored? |
Sort of. Really it's not exactly analogous to either, but a more powerful tool which allows you to use xarray methods to get behaviour like T = open_boutdataset('BOUT.dmp.*.nc')['T'].values or like open_boutdataset('BOUT.dmp.*.nc').to_netcdf('single_file.nc')
We could potentially do this... I am essentially treating I should also probably mention that I'm already special-casing some of the BoutReals which are written to the dump files such as |
As this is not SD1D specific, could we discuss this in BOUT-dev?
|
So @omyatra asked me for help loading some SD1D data with xBOUT, but it's exposed a problem with the way SD1D (and possibly other modules) write out their data.
Omkar ran one of the examples cases, which creates output data split along the y-direction over 4 dump files. When I try to collect this with xbout I get an error:
SD1D writes the variable
'flux_ion'
out to all dump files, but it's a boundary value so is only actually calculated in the processor which contains the target. This means that processor 3 has an array'flux_ion'
with non-zero values, which varies over time, whereas processors 0 through 2 have the same kind of array but populated with zeros.The problem is that from the point of view of the dump-file-joining-algorithm in xBOUT this data is fundamentally ambiguous. The datasets read from the dump files need to be combined along the dimension
'y'
. If we just consider dump files 2 & 3, then we are asking it to take two 1D arrays, each with just a't'
dimension and combine them along'y'
. The combining algorithm (xarray.auto_combine
) will look at the values in these two'flux_ion'
arrays and if they are the same it will just keep one (becausexarray.auto_combine
will usexarray.merge
). However the values aren't the same, they're zero in one and non-zero in the other, and xBOUT has no way to know whether you want to keep one array or the other, or if you actually want to stack the arrays up by adding a'y'
dimension to the'flux_ion'
variable (usingxarray.concat
).If we compare against the BOUT++ default output variable
't_array'
it becomes even clearer whyflux_ion
is ambiguous.'t_array'
is also 1D along't'
and is also written to all files. But as simulation time is clearly a global variable then it would be nonsense for thist_array
to take different values in different processors.There are a few ways we could deal with this:
Change BOUT++ to write out variables consistently in all files. If the values in the arrays were consistent across different processors then it would be fine. I guess this would require extra processor communications though.
Change SD1D to never write out flux ion. I think that flux ion can be rederived from the other variables, in which case it never needs to be written at all, it can be recreated in post-processing instead.
Change SD1D to only write out flux ion to a single dump file. I don't know whether BOUT's
Field
objects have the ability to handle that.Load flux ion from the data separately in a
open_sd1ddataset
function. This would be a workaround in this specific case, but it really doesn't solve the underlying issue.@bendudson How does
boutdata.collect
handle this ambiguity? Is this likely to be a problem in other BOUT++ modules too? What do you think the best way of dealing with this in general is? I actually think that it should not be possible to write output like this in BOUT++ - perhaps a processor communication to verify consistency before writing would be the simplest general solution?@ZedThree @d7919 @johnomotani
The text was updated successfully, but these errors were encountered: