Also bump the version to 0.1.0.2.
Originally we had `extra-lib-dirs: /usr/local/lib` in `stack.yaml`.
I removed it because it wasn't necessary on my Mac. However,
it turns out that it is necessary for machines with the default installation
of XCode, which *doesn't* search that path by default.
(On my machine, it wasn't necessary because I had run `xcode-select --install`
which adds that path permanently to your search path. For more context, see
https://github.com/Homebrew/brew/issues/556.)
I'm adding the setting back to `tensorflow.cabal` as well as `stack.yaml` so
that the Hackage release also contains this fix. Changing `stack.yaml` is
still necessary in order to fix linkage in the `snappy` package (which
`tensorflow-records` depends on). Hopefully that will go away once we remove
the dependency (#118).
As far as I can tell they're not necessary anymore with the current OS X
script that calls `install_name_tool`. Both "stack test" and "stack ghci"
work without those settings.
Use the same trick as for `proto-lens-protoc`: hack the package description
during the `sdist` step to include the autogen directory in hs-source-dirs.
- Merge tensorflow-nn and tensorflow-queue into tensorflow-ops.
They don't add extra dependencies and each contain a single module, so I
don't think it's worth separating them at the package level.
- Remove google-shim in favor of direct use of test-framework.
- Add LICENSE files for all packages.
- Add descriptions for packages that were missing one.
- Work around google/proto-lens#69 by symlinking third_party into
tensorflow-proto.
* Switched to lts-8.13, added custom-setup.
Our packages no longer elicit complaints like this:
Package tensorflow-foo uses a custom Cabal build, but does not use a
custom-setup stanza.
* Removed some extra-deps and explicit-setup-deps
* Removed provisions for different versions of stack lts.
We are now solidly in the 8-only territory.
The number of iterations was reduced from 1000 to 300 during review, but that
turned out to be too low and the test now fails about 20% of the time.
After changing it back to 1000, the test succeeded at 50 out of 50 runs.
It would be better to avoid the copy when it's not necessary, but
that will require more involved changes to the internal API. (For example,
Fetchable might need to allow IO or ST actions.)
The main difference between these and the `Ref`-bases ops is the explicit
`readValue` op. I'm not sure how this should interact with gradients
and save/restore, so I'm keeping it as a separate module for now. Once we
figure out the details, we can merge it into `TensorFlow.Ops` and replace
all uses of the old `Ref`-based ops. (That would also fix #92.)
Also replaces our special case newtype `ResourceHandle` to
`Tensor Value ResourceHandle`, where `ResourceHandle` is the TF proto
corresponding to `DT_RESOURCE`.
Distinguish between "rendered" and "unrendered" Tensors.
There are now three types of `Tensor`:
- `Tensor Value a`: rendered value
- `Tensor Ref a`: rendered reference
- `Tensor Build a` : unrendered value
The extra bookkeeping makes it easier to track (and enforce) which tensors are
rendered or not. For examples where this has been confusing in the past, see
With this change, pure ops look similar to before, returning `Tensor Build`
instead of `Tensor Value`. "Stateful" (monadic) ops are unchanged. For
example:
add :: OneOf [..] t => Tensor v'1 t -> Tensor v'2 t -> Tensor Build t
assign :: (MonadBuild m, TensorType t)
=> Tensor Ref t -> Tensor v'2 t -> m (Tensor Ref t)
The `gradients` function now requires that the variables over which it's
differentiating are pre-rendered:
gradients :: (..., Rendered v2) => Tensor v1 a -> [Tensor v2 a]
-> m [Tensor Value a]
(`Rendered v2` means that `v2` is either a `Ref` or a `Value`.)
Additionally, the implementation of `gradients` now takes care to render every
intermediate value when performing the reverse accumulation. I suspect this
fixes an exponential blowup for complicated expressions.
Each op `foo :: ...` now has a corresponding `foo' :: OpParams -> ...`
which lets you set optional attributes. `OpParams` is currently a type alias for
`OpDef -> OpDef`. In the future we should consider more type safety, e.g.,
using type-level strings and OverloadedLabels for optional attributes.
I used it to replace a few manual `buildOp`s in our code with the codegenerated
ops, now that it's easier to set attributes. I also removed `tensorAttr` and
`named` since it's now possible to set those op attributes directly.
Although this clutters up the API a bit, I think it's simpler than using type
classes to implement optional arguments (as in, for example, `Text.Printf`) --
especially in terms of type inference with the rest of the library.
This change adds a class that both `Build` and `Session` are instances of:
class MonadBuild m where
build :: Build a -> m a
All stateful ops (generated and manually written) now have a signature that returns
an instance of `MonadBuild` (rather than just `Build`). For example:
assign_ :: (MonadBuild m, TensorType t)
=> Tensor Ref t -> Tensor v t -> m (Tensor Ref t)
This lets us remove a bunch of spurious calls to `build` in user code. It also
lets us replace the pattern `buildAnd run foo` with the simpler pattern `foo >>= run`
(or `run =<< foo`, which is sometimes nicer when foo is a complicated expression).
I went ahead and deleted `buildAnd` altogether since it seems to lead to
confusion; in particular a few tests had `buildAnd run . pure` which is
actually equivalent to just `run`.
Adds a new type `ListOf` which wraps a heterogeneous list; for example,
`ListOf (Tensor Value) '[Int32, Float]` represents a list of two
elements: a tensor of int32s and a tensor of floats.
Also changes the `Queue2` type (which suppored pairs of tensors) to
`Queue` (which supports arbitrary lists).
This change allows us to reenable the rest of the ResourceHandle ops, and
future-proofs us against more being added. It removes the custom logic that
assumed there was a "dtype" attribute to guess what the type parameter is
(which wasn't true in general.)
When we switch to ResourceHandle (e.g., for queues and variables) we can add
parameters to the wrapper types like "Queue" on a case-by-case basis.
Add support for logging to tensorboard
Based on @gnezdo's internal version with some differences:
* Uses a pure haskell implementation of EventWriter instead of FFI.
* Special `buildAnd*` functions were dropped in favor of using
`mergeAllSummaries :: Build SummaryTensor` with the normal
`build` function.
The tensorflow-records package implements encoding/decoding of the
format, and the tensorflow-records-conduit package provides wrappers and
utilities for use with Conduit.
- More heterogeneous list ops
- Resource ops that don't use "dtype" as the type parameter
For the latter, we may need an upstream fix, or else to change the convention
of how we can tell what the type parameter is.