Skip to content

Commit e0f4612

Browse files
authored
Merge branch 'master' into export-saved-model
2 parents 91d2a39 + 022f4d0 commit e0f4612

File tree

12 files changed

+1175
-644
lines changed

12 files changed

+1175
-644
lines changed

.travis.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
language: rust
22
sudo: false
3+
dist: trusty # still in beta, but required for the prebuilt TF binaries
34

45
cache:
56
cargo: true
67
directories:
78
- $HOME/.cache/bazel
89

9-
rust: nightly
10+
rust: stable
1011

1112
install:
1213
- export CC="gcc-4.9" CXX="g++-4.9"
1314
- source travis-ci/install.sh
1415

1516
script:
17+
- export RUST_BACKTRACE=1
1618
- cargo test -vv -j 2 --features tensorflow_unstable
1719
- cargo run --example regression
1820
- cargo run --features tensorflow_unstable --example expressions
1921
- cargo doc -vv --features tensorflow_unstable
20-
- (cd tensorflow-sys && cargo test -vv -j 1)
22+
- # TODO(#66): Re-enable: (cd tensorflow-sys && cargo test -vv -j 1)
2123
- (cd tensorflow-sys && cargo doc -vv)
2224

2325
addons:

README.md

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,105 @@
1-
#TensorFlow Rust
1+
# <img alt="TensorFlow" src="https://www.tensorflow.org/images/tf_logo_transp.png" width="170"/> Rust Binding
22
[![Version](https://img.shields.io/crates/v/tensorflow.svg)](https://crates.io/crates/tensorflow)
33
[![Status](https://travis-ci.org/tensorflow/rust.svg?branch=master)](https://travis-ci.org/tensorflow/rust)
44

55
TensorFlow Rust provides idiomatic [Rust](https://www.rust-lang.org) language
66
bindings for [TensorFlow](http://tensorflow.org).
77

8-
This project is still under active development and not guaranteed to have a
9-
stable API. This is especially true because the TensorFlow C API used by this
10-
project has not yet stabilized.
8+
**Notice:** This project is still under active development and not guaranteed to have a
9+
stable API. This is especially true because the underlying TensorFlow C API has not yet
10+
been stabilized as well.
1111

12-
## Using
12+
* [Documentation](https://tensorflow.github.io/rust/tensorflow/)
13+
* [TensorFlow website](http://tensorflow.org)
14+
* [TensorFlow GitHub page](https://github.com/tensorflow/tensorflow)
15+
16+
## Getting Started
17+
Since this crate depends on the TensorFlow C API, it needs to be compiled first. This crate will
18+
automatically compile TensorFlow for you, but it is also possible to manually install TensorFlow
19+
and the crate will pick it up accordingly.
20+
21+
### Prerequisites
22+
The following dependencies are needed to compile and build this crate (assuming TensorFlow itself
23+
should also be compiled transparently):
24+
25+
- git
26+
- [bazel](https://bazel.build/)
27+
- Python Dependencies `numpy`, `dev`, `pip` and `wheel`
28+
- Optionally, CUDA packages to support GPU-based processing
1329

14-
If you only wish to use TensorFlow within your own project, simply include
15-
`tensorflow = "*"` in your `Cargo.toml` file. If the TensorFlow library is
16-
not already installed on your computer in a place it can be found, you will
17-
need the requirements listed in "Automatically Building Tensorflow" below,
18-
and Cargo will build the library for you.
30+
The TensorFlow website provides detailed instructions on how to obtain and install said dependencies,
31+
so if you are unsure please [check out the docs](https://www.tensorflow.org/install/install_sources)
32+
for further details.
1933

20-
## Building
34+
### Usage
35+
Add this to your `Cargo.toml`:
2136

22-
If you only intend to use TensorFlow from within Rust, then you don't need to
23-
build TensorFlow manually and can follow the automatic steps. If you do need to
24-
use TensorFlow outside of Rust, the manual steps will provide you with a
25-
TensorFlow header file and shared library that can be used by other languages.
37+
```toml
38+
[dependencies]
39+
tensorflow = "0.3"
40+
```
2641

27-
### Automatically building TensorFlow
42+
and this to your crate root:
43+
44+
```rust
45+
extern crate tensorflow;
46+
```
2847

29-
Install [SWIG](http://www.swig.org) and [NumPy](http://www.numpy.org). The
30-
version from your distro's package manager should be fine for these two. Also
31-
install [Bazel](http://bazel.io/docs/install.html), which you may need to do
32-
from source.
3348
Then run `cargo build -j 1`. Since TensorFlow is built during this process, and
3449
the TensorFlow build is very memory intensive, we recommend using the `-j 1`
3550
flag which tells cargo to use only one task, which in turn tells TensorFlow to
3651
build with only on task. Of course, if you have a lot of RAM, you can use a
3752
higher value.
53+
3854
To include the especially unstable API (which is currently the `expr` module),
3955
use `--features tensorflow_unstable`.
4056

41-
### Manually building TensorFlow
57+
For now, please see the [Examples](https://github.com/tensorflow/rust/tree/master/examples) for more
58+
details on how to use this binding.
4259

43-
Install [TensorFlow from source](https://www.tensorflow.org/versions/master/get_started/os_setup.html#source).
60+
## Manual TensorFlow Compilation
61+
If you don't want to build TensorFlow after every `cargo clean` or you want to work against
62+
unreleased/unsupported TensorFlow versions, manual compilation is the way to go.
63+
64+
See [TensorFlow from source](https://www.tensorflow.org/install/install_sources) first.
4465
The Python/pip steps are not necessary, but building `tensorflow:libtensorflow.so` is.
4566

4667
In short:
4768

4869
1. Install [SWIG](http://www.swig.org) and [NumPy](http://www.numpy.org). The
4970
version from your distro's package manager should be fine for these two.
50-
1. [Install Bazel](http://bazel.io/docs/install.html), which you may need to do
71+
2. [Install Bazel](http://bazel.io/docs/install.html), which you may need to do
5172
from source.
52-
1. `git clone --recurse-submodules https://github.com/tensorflow/tensorflow`
53-
1. `cd tensorflow`
54-
1. `./configure`
55-
1. `bazel build -c opt --jobs=1 tensorflow:libtensorflow.so`
73+
3. `git clone https://github.com/tensorflow/tensorflow`
74+
4. `cd tensorflow`
75+
5. `./configure`
76+
6. `bazel build --compilation_mode=opt --copt=-march=native --jobs=1 tensorflow:libtensorflow.so`
5677

57-
Using --jobs=1 is recommended unless you have a lot of RAM, because
78+
Using `--jobs=1` is recommended unless you have a lot of RAM, because
5879
TensorFlow's build is very memory intensive.
5980

60-
Copy $TENSORFLOW_SRC/bazel-bin/tensorflow/libtensorflow.so to /usr/local/lib.
61-
If this is not possible, add $TENSORFLOW_SRC/bazel-bin/tensorflow to
62-
LD_LIBRARY_PATH.
81+
Copy `$TENSORFLOW_SRC/bazel-bin/tensorflow/libtensorflow.so` to `/usr/local/lib`.
82+
If this is not possible, add `$TENSORFLOW_SRC/bazel-bin/tensorflow` to
83+
`LD_LIBRARY_PATH`.
6384

64-
You may need to run `ldconfig` to reset `ld`'s cache after copying libtensorflow.so.
85+
You may need to run `ldconfig` to reset `ld`'s cache after copying `libtensorflow.so`.
6586

66-
Now run `cargo build` as usual.
67-
To include the especially unstable API (which is currently the `expr` module),
68-
use `--features tensorflow_unstable`.
69-
70-
## RFCs
71-
RFCs are [issues tagged with RFC](https://github.com/tensorflow/rust/labels/rfc).
72-
Check them out and comment. Discussions are welcome. After all, thats what a Request For Comment is for!
87+
**OSX Note**: If you are running on OSX, there is a
88+
[Homebrew PR](https://github.com/Homebrew/homebrew-core/pull/10273) in process which, once merged,
89+
will make it easy to install `libtensorflow` wihout hassle. In the meantime, you can take a look at
90+
[snipsco/tensorflow-build](https://github.com/snipsco/tensorflow-build) which provides a homebrew
91+
tap that does essentially the same.
7392

74-
## FAQs
93+
## FAQ's
7594

76-
#### Why does the compiler say that parts of the API don't exist?
95+
### Why does the compiler say that parts of the API don't exist?
7796
The especially unstable parts of the API (which is currently the `expr` modul) are
7897
feature-gated behind the feature `tensorflow_unstable` to prevent accidental
7998
use. See http://doc.crates.io/manifest.html#the-features-section.
8099
(We would prefer using an `#[unstable]` attribute, but that
81100
[doesn't exist](https://github.com/rust-lang/rfcs/issues/1491) yet.)
82101

83-
## Other
84-
85-
This project is not directly affiliated with the TensorFlow project, although we
86-
do intend to communicate and cooperate with them.
87-
102+
## Contributing
88103
Developers and users are welcome to join
89104
[#tensorflow-rust](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23tensorflow-rust)
90105
on irc.mozilla.org.
@@ -93,8 +108,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for information on how to contribute code
93108

94109
This is not an official Google product.
95110

96-
##For more information
111+
RFCs are [issues tagged with RFC](https://github.com/tensorflow/rust/labels/rfc).
112+
Check them out and comment. Discussions are welcome. After all, thats what a Request For
113+
Comment is for!
97114

98-
* [API docs](https://tensorflow.github.io/rust)
99-
* [TensorFlow website](http://tensorflow.org)
100-
* [TensorFlow GitHub page](https://github.com/tensorflow/tensorflow)
115+
## License
116+
This project is licensed under the terms of the [Apache 2.0 license](https://github.com/tensorflow/rust/blob/master/LICENSE).

src/buffer.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::ops::Range;
1717
use std::ops::RangeFrom;
1818
use std::ops::RangeFull;
1919
use std::ops::RangeTo;
20+
use std::os::raw::c_void as std_c_void;
2021
use std::ptr;
2122
use std::slice;
2223
use super::BufferTrait;
@@ -65,7 +66,7 @@ impl<T: TensorType> Buffer<T> {
6566
let msg = CStr::from_ptr(c_msg);
6667
panic!("Failed to allocate: {}", msg.to_str().unwrap());
6768
}
68-
(*inner).data = ptr;
69+
(*inner).data = ptr as *mut std_c_void;
6970
(*inner).length = len;
7071
(*inner).data_deallocator = Some(deallocator);
7172
Buffer {
@@ -81,7 +82,7 @@ impl<T: TensorType> Buffer<T> {
8182
/// The underlying data is *not* freed when the buffer is destroyed.
8283
pub unsafe fn from_ptr(ptr: *mut T, len: usize) -> Self {
8384
let inner = tf::TF_NewBuffer();
84-
(*inner).data = ptr as *const c_void;
85+
(*inner).data = ptr as *const std_c_void;
8586
(*inner).length = len;
8687
Buffer {
8788
inner: inner,
@@ -155,8 +156,8 @@ impl<T: TensorType> BufferTrait for Buffer<T> {
155156
}
156157
}
157158

158-
unsafe extern "C" fn deallocator(data: *mut c_void, _length: size_t) {
159-
libc::free(data);
159+
unsafe extern "C" fn deallocator(data: *mut std_c_void, _length: size_t) {
160+
libc::free(data as *mut c_void);
160161
}
161162

162163
impl<T: TensorType> Drop for Buffer<T> {

src/graph.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std;
99
use std::ffi::CStr;
1010
use std::ffi::CString;
1111
use std::ffi::NulError;
12+
use std::os::raw::c_void as std_c_void;
1213
use std::ptr;
1314
use std::str::Utf8Error;
1415
use std::sync::Arc;
@@ -302,7 +303,7 @@ impl Operation {
302303
pub fn output_type(&self, index: usize) -> DataType {
303304
unsafe {
304305
DataType::from_c(tf::TF_OperationOutputType(tf::TF_Output {
305-
operation: self.inner,
306+
oper: self.inner,
306307
index: index as c_int,
307308
}))
308309
}
@@ -332,7 +333,7 @@ impl Operation {
332333
pub fn input_type(&self, index: usize) -> DataType {
333334
unsafe {
334335
DataType::from_c(tf::TF_OperationInputType(tf::TF_Input {
335-
operation: self.inner,
336+
oper: self.inner,
336337
index: index as c_int,
337338
}))
338339
}
@@ -359,11 +360,11 @@ impl Operation {
359360
pub fn input(&self, index: usize) -> (Operation, usize) {
360361
unsafe {
361362
let port = tf::TF_OperationInput(tf::TF_Input {
362-
operation: self.inner,
363+
oper: self.inner,
363364
index: index as c_int,
364365
});
365366
(Operation {
366-
inner: port.operation,
367+
inner: port.oper,
367368
gimpl: self.gimpl.clone(),
368369
},
369370
port.index as usize)
@@ -374,7 +375,7 @@ impl Operation {
374375
pub fn output_num_consumers(&self, index: usize) -> usize {
375376
unsafe {
376377
tf::TF_OperationOutputNumConsumers(tf::TF_Output {
377-
operation: self.inner,
378+
oper: self.inner,
378379
index: index as c_int,
379380
}) as usize
380381
}
@@ -387,12 +388,12 @@ impl Operation {
387388
pub fn output_consumers(&self, index: usize) -> Vec<(Operation, usize)> {
388389
unsafe {
389390
let num_consumers = tf::TF_OperationOutputNumConsumers(tf::TF_Output {
390-
operation: self.inner,
391+
oper: self.inner,
391392
index: index as c_int,
392393
});
393394
let mut vec = <Vec<tf::TF_Input>>::with_capacity(num_consumers as usize);
394395
let len = tf::TF_OperationOutputConsumers(tf::TF_Output {
395-
operation: self.inner,
396+
oper: self.inner,
396397
index: index as c_int,
397398
},
398399
vec.as_mut_ptr(),
@@ -401,7 +402,7 @@ impl Operation {
401402
vec.into_iter()
402403
.map(|port| {
403404
(Operation {
404-
inner: port.operation,
405+
inner: port.oper,
405406
gimpl: self.gimpl.clone(),
406407
},
407408
port.index as usize)
@@ -483,7 +484,7 @@ pub struct Input<'a> {
483484
impl<'a> Input<'a> {
484485
fn to_c(&self) -> tf::TF_Input {
485486
tf::TF_Input {
486-
operation: self.operation.inner,
487+
oper: self.operation.inner,
487488
index: self.index,
488489
}
489490
}
@@ -505,7 +506,7 @@ pub struct Output<'a> {
505506
impl<'a> Output<'a> {
506507
fn to_c(&self) -> tf::TF_Output {
507508
tf::TF_Output {
508-
operation: self.operation.inner,
509+
oper: self.operation.inner,
509510
index: self.index,
510511
}
511512
}
@@ -606,7 +607,7 @@ impl<'a> OperationDescription<'a> {
606607
unsafe {
607608
tf::TF_SetAttrString(self.inner,
608609
c_attr_name.as_ptr(),
609-
c_value.as_ptr() as *const c_void,
610+
c_value.as_ptr() as *const std_c_void,
610611
c_value.len() as size_t);
611612
}
612613
Ok(())
@@ -625,7 +626,7 @@ impl<'a> OperationDescription<'a> {
625626
unsafe {
626627
tf::TF_SetAttrStringList(self.inner,
627628
c_attr_name.as_ptr(),
628-
ptrs.as_ptr(),
629+
ptrs.as_ptr() as *const *const std_c_void,
629630
lens.as_ptr(),
630631
ptrs.len() as c_int);
631632
}
@@ -821,7 +822,7 @@ impl<'a> OperationDescription<'a> {
821822
unsafe {
822823
tf::TF_SetAttrTensorShapeProto(self.inner,
823824
c_attr_name.as_ptr(),
824-
value.as_ptr() as *const c_void,
825+
value.as_ptr() as *const std_c_void,
825826
value.len() as size_t,
826827
status.inner());
827828
}
@@ -843,7 +844,7 @@ impl<'a> OperationDescription<'a> {
843844
unsafe {
844845
tf::TF_SetAttrTensorShapeProtoList(self.inner,
845846
c_attr_name.as_ptr(),
846-
ptrs.as_ptr(),
847+
ptrs.as_ptr() as *const *const std_c_void,
847848
lens.as_ptr(),
848849
ptrs.len() as c_int,
849850
status.inner());
@@ -878,7 +879,7 @@ impl<'a> OperationDescription<'a> {
878879
let ptrs: Vec<*mut tf::TF_Tensor> = value.into_iter().map(|x| x.into_ptr()).collect();
879880
tf::TF_SetAttrTensorList(self.inner,
880881
c_attr_name.as_ptr(),
881-
ptrs.as_ptr(),
882+
ptrs.as_ptr() as *const *const tf::TF_Tensor,
882883
ptrs.len() as c_int,
883884
status.inner());
884885
}
@@ -893,7 +894,7 @@ impl<'a> OperationDescription<'a> {
893894
unsafe {
894895
tf::TF_SetAttrValueProto(self.inner,
895896
c_attr_name.as_ptr(),
896-
value.as_ptr() as *const c_void,
897+
value.as_ptr() as *const std_c_void,
897898
// Allow trivial_numeric_casts because usize is not
898899
// necessarily size_t.
899900
value.len() as size_t,

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::ops::Deref;
3030
use std::ops::DerefMut;
3131
use std::ops::Drop;
3232
use std::ops::Index;
33+
use std::os::raw::c_void as std_c_void;
3334
use std::str::Utf8Error;
3435

3536
////////////////////////
@@ -844,9 +845,9 @@ pub struct Tensor<T: TensorType> {
844845
owned: bool,
845846
}
846847

847-
unsafe extern "C" fn noop_deallocator(_: *mut c_void, _: size_t, _: *mut c_void) -> () {}
848+
unsafe extern "C" fn noop_deallocator(_: *mut std_c_void, _: size_t, _: *mut std_c_void) -> () {}
848849

849-
unsafe extern "C" fn deallocator(_: *mut c_void, _: size_t, buffer: *mut c_void) -> () {
850+
unsafe extern "C" fn deallocator(_: *mut std_c_void, _: size_t, buffer: *mut std_c_void) -> () {
850851
tf::TF_DeleteBuffer(buffer as *mut tf::TF_Buffer);
851852
}
852853

0 commit comments

Comments
 (0)