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

Replace hard-wired DFT functions with IDFT #136

Merged
merged 46 commits into from
Dec 10, 2021
Merged

Replace hard-wired DFT functions with IDFT #136

merged 46 commits into from
Dec 10, 2021

Conversation

brettviren
Copy link
Member

This PR is on top of #135 and will stay draft until that one is merged. I also still need to do more testing on this one.

This removes and replaces the hard-wired DFT functions from Waveform and Array used in various components and tests with methods called through an IDFT.

@brettviren
Copy link
Member Author

Some mid-PR notes:

The above commits replace use of the old hard-wired DFT functions from Waveform.h and Array.h with calls that go through an IDFT instance. The old functions and their call sites have been commented out but remain as temporary place holders to help make sure the transliteration to the new call patterns is correct. After testing, they will be removed.

Here is a source file level list of current IDFT users.

❯ grep '\["dft"\]' */src/*.cxx|sed -e 's/:.*//g'
gen/src/AddCoherentNoise.cxx
gen/src/AddNoise.cxx
gen/src/DepoTransform.cxx
gen/src/EmpiricalNoiseModel.cxx
gen/src/Misconfigure.cxx
gen/src/NoiseSource.cxx
gen/src/PerChannelVariation.cxx
gen/src/PlaneImpactResponse.cxx
gen/src/TruthSmearer.cxx
sig/src/Decon2DFilter.cxx
sig/src/Decon2DResponse.cxx
sigproc/src/L1SPFilter.cxx
sigproc/src/Microboone.cxx
sigproc/src/Microboone.cxx
sigproc/src/OmnibusSigProc.cxx
sigproc/src/OmniChannelNoiseDB.cxx
sigproc/src/Protodune.cxx
sigproc/src/Protodune.cxx
sigproc/src/SimpleChannelNoiseDB.cxx

Some of these source files define more than one component.

These are the types of changes to the configuration which are needed and will come in subsequent commits:

  1. Get the default FftwDFT config object into the configuration sequence. This must be done even if we never touch individual component config. OTOH, this is automatic when we we do that touching (via the use lists).
  2. For any existing configuration of components in the above list, have a way to set their dft config parameter.
  3. Provide a global spot to set a non-default dft that then makes it into these per-component settings.

@brettviren
Copy link
Member Author

That last commit added an IDFT config to all locations I could find.

A few caveats and comments.

There is a really distressing amount of copy-paste that has crept into our configuration. I think we must wait for PR #105 to be ready and merged before coming up with a serious rewrite.

The tools object holds the default IDFT (FftwDFT). This object can be overridden to use a non-default IDFT.

local default_tools = tools_maker(params)
local tools = std.mergePatch(default_tools, {
  dft: {type: "TorchDFT", data: {device: "gpu"}}});

However, the PlaneImpactResponse is itself created in tools and thus there is no way to provide a non-default IDFT. Fixing this must wait until the config rewrite.

Top level cfg/l1sp/ and cfg/uboone/ directories are seen. These are not "standard" and I do not know their purpose so I have ignored them. If they are not used they should be deleted. If used, they likely are now broken w.r.t IDFT.

Here is a summary of the files changed:

  • 19 files ( grep '\["dft"\]' ) in gen, sigproc and sig need to use tools.dft.
    • gen/src/AddCoherentNoise.cxx
    • gen/src/AddNoise.cxx
    • gen/src/DepoTransform.cxx
    • gen/src/EmpiricalNoiseModel.cxx
    • gen/src/Misconfigure.cxx
    • gen/src/NoiseSource.cxx
    • gen/src/PerChannelVariation.cxx (unused?)
    • gen/src/PlaneImpactResponse.cxx (no way to set non-default in old config)
    • gen/src/TruthSmearer.cxx (unused?)
    • sig/src/Decon2DFilter.cxx (unused?)
    • sig/src/Decon2DResponse.cxx (unused?)
    • sigproc/src/L1SPFilter.cxx
    • sigproc/src/Microboone.cxx
      • mbOneChannelStatus (find mb* components used in dune10kt-1x2x6)
      • mbCoherentNoiseSub
      • mbOneChannelNoise
    • sigproc/src/OmnibusSigProc.cxx
    • sigproc/src/OmniChannelNoiseDB.cxx (nightmare, it's copy-pasted everywhere!)
    • sigproc/src/Protodune.cxx
      • pdStickyCodeMitig
      • pdOneChannelNoise
    • sigproc/src/SimpleChannelNoiseDB.cxx (namned testChannelNoiseDB, unused?)

@brettviren brettviren marked this pull request as ready for review December 3, 2021 17:31
@brettviren brettviren requested a review from HaiwangYu December 3, 2021 17:32
@brettviren
Copy link
Member Author

Some additional info

Besides the unit tests passing, this high-level test gives reasonable looking results:

  wire-cell -l stdout -L debug \
      -c test/test-pdsp-sim-sp-dnnroi.jsonnet

  wirecell-plot ntier-frames -o foo.pdf \
    test-pdsp-ssd-orig0.tar.bz2 \
    test-pdsp-ssd-wiener0-gauss0.tar.bz2 \
    test-pdsp-ssd-dnnsp0.tar.bz2

There is also a correctness tester:

  wirecell-aux run-idft

Note, this sometimes "fails" due to round-off errors slightly greater than 1e-6. And, run it from the top of wire-cell-toolkit/ directory so it can find the build/aux/check_idft program.

And there is a benchmark program.

It runs with FftwDFT by default:

  wirecell-aux run-idft-bench -o fftw-cpu.json \
    build/aux/check_idft_bench

or Torch/CPU:

  wirecell-aux run-idft-bench -o torch-cpu.json \
    -p WireCellPytorch -t TorchDFT \
    build/aux/check_idft_bench

or Torch/GPU:

  wirecell-aux run-idft-bench -o torch-gpu.json \
    -p WireCellPytorch -t TorchDFT \
    -c aux/test/test_idft_pytorch.jsonnet \
    build/aux/check_idft_bench

and then make plots from the *.json files:

  wirecell-aux plot-idft-bench -o idft-bench.pdf \
    fftw-cpu.json torch-cpu.json torch-gpu.json

Copy link
Member

@HaiwangYu HaiwangYu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to comment out this line due to removal of gen/inc/WireCellGen/ImpactZipper.h

#include "WireCellUtil/NamedFactory.h"

#include <torch/script.h>
#include <torch/csrc/api/include/torch/fft.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems this file is not available for older libtorch versions, e.g. 1.6 which is the latest version on gpvm.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this takes me by surprise.

Fermilab should upgrade. IIRC, they also do not build libtorch with CUDA support which also limits their usefulness.

I am inclined to say that we simply do not include WCT's pytorch sub-package for the wirecell UPS product until they upgrade. To avoid a build-time error in the case that libtorch is found automatically would rquire adding --with-libtorch=no to wcb configure. My own intention is to use this new torch support in a stand-alone build of WCT so I don't care about this UPS breakage.

An innocent bystander of that choice would be that dnnroi will also not be available in a UPS environment until Fermilab upgrades. If we "hide" the libtorch based DFT behind some #ifdef then at least dnnroi could run on CPU at Fermilab. But, I don't know if doing that is on any immediate goal (is it?).

What's your opinion on either of these approaches, @HaiwangYu ? Any other solution?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems this fft.h is available from 1.7. https://github.com/pytorch/pytorch/tree/v1.6.0/torch/csrc/api/include/torch
And the versioning macros are available from 1.8 https://pytorch.org/cppdocs/notes/versioning.html
I think we can skip the pytorch folder until gpvm has a newer version. Before that, if DNNROI is needed, we can remove DFT.cxx source file in the building shims. How about this? @brettviren

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds very good to me. Thanks.

@HaiwangYu HaiwangYu self-requested a review December 8, 2021 19:37
My build was picking up a stale copy in the install dir
}
}, nin=1, nout=1),
}, nin=1, nout=1, uses[tools.dft]),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uses=[tools.dft]

// The IDFT FFT implementation
dft : {
type: "FftwDFT",
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

},

@HaiwangYu
Copy link
Member

I did some tests for Vertical Drift 3view30 with default FftwDFT seems the results are consistent with current master
pr136.pdf
.

@brettviren brettviren merged commit 79ca54e into master Dec 10, 2021
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

Successfully merging this pull request may close these issues.

2 participants